RosettaCodeData/Task/Tic-tac-toe/Icon/tic-tac-toe.icon
Ingy döt Net 68f8f3e56b all tasks
2013-04-11 01:07:29 -07:00

112 lines
3 KiB
Text

# Play TicTacToe
$define E " " # empty square
$define X "X" # X piece
$define O "O" # O piece
# -- define a board
record Board(a, b, c, d, e, f, g, h, i)
procedure display_board (board, player)
write ("\n===============")
write (board.a || " | " || board.b || " | " || board.c)
write ("---------")
write (board.d || " | " || board.e || " | " || board.f)
write ("---------")
write (board.g || " | " || board.h || " | " || board.i)
end
# return a set of valid moves (empty positions) in given board
procedure empty_fields (board)
fields := set()
every i := !fieldnames(board) do
if (board[i] == E) then insert (fields, i)
return fields
end
procedure game_start ()
return Board (E, E, E, E, E, E, E, E, E)
end
procedure game_is_drawn (board)
return *empty_fields(board) = 0
end
procedure game_won_by (board, player)
return (board.a == board.b == board.c == player) |
(board.d == board.e == board.f == player) |
(board.g == board.h == board.i == player) |
(board.a == board.d == board.g == player) |
(board.b == board.e == board.h == player) |
(board.c == board.f == board.i == player) |
(board.a == board.e == board.i == player) |
(board.g == board.e == board.c == player)
end
procedure game_over (board)
return game_is_drawn (board) | game_won_by (board, O) | game_won_by (board, X)
end
# -- players make their move on the board
# assume there is at least one empty square
procedure human_move (board, player)
choice := "z"
options := empty_fields (board)
# keep prompting until player selects a valid square
until member (options, choice) do {
writes ("Choose one of: ")
every writes (!options || " ")
writes ("\n> ")
choice := read ()
}
board[choice] := player
end
# pick and make a move at random from empty positions
procedure random_move (board, player)
board[?empty_fields(board)] := player
end
# -- manage the game play
procedure play_game ()
# hold procedures for players' move in variables
player_O := random_move
player_X := human_move
# randomly determine if human or computer moves first
if (?2 = 0)
then {
write ("Human plays first as O")
player_O := human_move
player_X := random_move
}
else write ("Computer plays first, human is X")
# set up the game to start
board := game_start ()
player := O
display_board (board, player)
# loop until the game is over, getting each player to move in turn
until game_over (board) do {
write (player || " to play next")
# based on player, prompt for the next move
if (player == O)
then (player_O (board, player))
else (player_X (board, player))
# change player to move
player := if (player == O) then X else O
display_board (board, player)
}
# finish by writing out result
if game_won_by (board, O)
then write ("O won")
else if game_won_by (board, X)
then write ("X won")
else write ("draw") # neither player won, so must be a draw
end
# -- get things started
procedure main ()
play_game ()
end