#! /bin/csh -f
#
#	metage -- meta game engine for MITosis
#
#	Must be run from the top level MITosis directory,
#	which contains the actual game engine "mitosis".
#	Under this are directories called "players" and "boards".
#
#	Arguments:
#
#	  with one argument:
#		$1 = the "flight" (the letter 'a' or 'b')
#
#	  with five arguments, plays exactly one game (the "finals"):
#		$1 = the board name
#		$2-5 = the four players
#

# The list of options to pass to mitosis, except for
# -board, -players, and -player_num, which are computed.
# (This font works well for Solaris 2.5.1.)
set mitosis_options = (	\
	-gfx \
	-fn_x_cour_12pt '*-lucida sans typewriter-bold-r-normal-sans-*-140-*' \
	-num_rounds 1000 \
	-start_energy 200 \
 	-cost_food 10 \
	-cost_toxin 20 \
	-cost_move 1 \
	-cost_stay 1 \
	-cost_split 10 \
	-cost_look_r1 2 \
	-cost_look_r2 4 \
	-cost_look_r3 6 \
	-cost_look_r4 8 \
	-cost_look_r5 10 \
	-sense_radius 100 \
	-cell_size 6 \
	)

# Modify LD_LIBRARY_PATH to include the current directory
setenv LD_LIBRARY_PATH ${cwd}:${LD_LIBRARY_PATH}

if ($#argv == 5) then
	# This is the finals.  Invoke mitosis directly and exit.
 	mitosis -board boards/$1 \
		-players players/$2 players/$3 players/$4 players/$5 \
 		-num_players 4 \
		$mitosis_options:q >/dev/null
	exit
endif	

# Save the flight letter
set flight = $1

# The name of the temp file which holds the winners of each game.
set winner_file = winner_file_$flight
set mitosis_options = (-winner_file $winner_file $mitosis_options:q)

# Get a list of the available boards
set boards = (`echo boards/*`)

# Get a list of the players for the current flight.
# Flight a is sorted by the second character of the filename,
# and flight b by the third character; this gives a kind of
# pseudo-random seeding effect.
echo '----------------------------------------------------------------'
echo "Seeding players for this flight; please wait..."
switch ($flight)
	case a:
		set players = (`echo players/*_$flight | xargs -n 1 | sort -t / -k 2.2`)
	breaksw
	case b:
		set players = (`echo players/*_$flight | xargs -n 1 | sort -t / -k 2.3`)
	breaksw
	default:
		echo '----------------------------------------------------------------'
		echo Invalid flight letter: $flight
		exit 1
	breaksw
endsw

# If the initial number of players is larger than a power of 2,
# then we need to have a play-in round to reduce the number.
# First, calculate the largest power of 2 not greater than
# the number of players.
@ power_of_two = 2
while ($#players - $power_of_two >= $power_of_two)
	@ power_of_two *= 2
end

if ($#players > $power_of_two) then
	# We have an excess number of players and need a play-in round.
	# Calculate how many games we need; the expression is equivalent
	# to "ceil (($#players - $power_of_two) / 2)".
	@ num_playin_games = (($#players - $power_of_two) + 1) / 2

	# Now calculate the number of players: 4 * #games, 
	# except that the last game might only have 3 if
	# the total number of players is odd.
	@ num_playin_players = 4 * $num_playin_games
	if ($#players % 2 == 1) then
		@ num_playin_players -= 1
	endif

	# Split off the players who get a bye in the first round.
	@ first_bye_index = $num_playin_players + 1
	set bye_players = ($players[${first_bye_index}-])
	set players = ($players[1-$num_playin_players])
else
	set bye_players = ()
endif

# Repeat until the flight is whittled down to two players
while ($#players > 2)

	# Display the list of players in the round.
	# (When displaying lists of players here and elsewhere,
	# the "xargs ... | cut ..." idiom causes the players to be
	# listed one per line and without the leading "players/".)
	echo '----------------------------------------------------------------'
	echo '----------------------------------------------------------------'
	echo "Players active in this round:"
	echo $players | xargs -n 1 | cut -d/ -f2
	echo '----------------------------------------------------------------'
	if ($#bye_players > 0) then
		echo "Players receiving a first-round bye:"
		echo $bye_players | xargs -n 1 | cut -d/ -f2
		echo '----------------------------------------------------------------'
	endif
	echo -n "Press RETURN to continue: "
	set dummy = $<

	# Initialize the list of winners for this round
	set winners = ()

	# Loop over the current active players
	while ($#players > 0)
		# Obtain the players for the next game;
		# there may be up to four of them.
		set current_players = ()
		while ($#players > 0 && $#current_players < 4)
			set current_players = ($current_players $players[1])
			shift players
		end

		# Display an introductory banner
		echo '----------------------------------------------------------------'
		echo "Players for next game:"
		echo $current_players | xargs -n 1 | cut -d/ -f2
		echo '----------------------------------------------------------------'
		echo -n "Press RETURN to continue: "
		set dummy = $<

		# Play the next game
  		mitosis -board $boards[1] \
 			-players $current_players \
  			-num_players $#current_players \
 			$mitosis_options:q >/dev/null

		# Get and display the names of the winners
		set current_winners = (`cat $winner_file`)
		echo '----------------------------------------------------------------'
		echo "Advancing to next round:"
		echo $current_winners | xargs -n 1 | cut -d/ -f2
		echo '----------------------------------------------------------------'
		echo -n "Press RETURN to continue: "
		set dummy = $<

		# Append the winners to the list of players for next round
		set winners = ($winners $current_winners)

		# Rotate the boards around
		set boards = ($boards[2-] $boards[1])
	end

	# Advance to the next round
	set players = ($winners $bye_players)
	set bye_players = ()
end

# Display the two finalists from this flight
echo '----------------------------------------------------------------'
echo '----------------------------------------------------------------'
echo "Finalists from flight ${flight}:"
echo $players | xargs -n 1 | cut -d/ -f2
echo '----------------------------------------------------------------'
echo '----------------------------------------------------------------'
