
Task

Play a game of tic-tac-toe.

Ensure that legal moves are played and that a winning position is notified.


Tic-tac-toe   is also known as:

   naughts and crosses 
   tic tac toe 
   tick tack toe 
   three in a row 
   tres en rayo       and
   Xs  and  Os


See also
   MathWorld™, Tic-Tac-Toe game.
   Wikipedia tic-tac-toe.


 
processor Tic-Tac-Toe
  @: [1..9 -> (position:$) -> $::value];
 
  source isWonOrDone
    [$@Tic-Tac-Toe(1..3) -> #, $@Tic-Tac-Toe(4..6) -> #, $@Tic-Tac-Toe(7..9) -> #,
      $@Tic-Tac-Toe(1..9:3) -> #, $@Tic-Tac-Toe(2..9:3) -> #, $@Tic-Tac-Toe(3..9:3) -> #,
      $@Tic-Tac-Toe([1,5,9]) -> #, $@Tic-Tac-Toe([3,5,7]) -> #
    ] -> \(
        when <=[]?($@Tic-Tac-Toe <~[<1..9>]>)> do 'draw' !
        when <~=[]> do $(1) !
      \) !
    when <[<=$(first)::raw>+ VOID]> do '$(first); wins!'!
  end isWonOrDone
 
  source validMoves
    $@Tic-Tac-Toe -> \[i](<1..9> $ !\) !
  end validMoves
 
  templates move
    when <?($@Tic-Tac-Toe($.position) <position>)> do @Tic-Tac-Toe($.position): $.mark;
      $ !
    otherwise
      'Incorrect move$#10;' -> !OUT::write
  end move
 
  source showString
    '$:1..9:3 -> '$#10;$@Tic-Tac-Toe($..$+2)...;';$#10;' !
  end showString
end Tic-Tac-Toe
 
composer toInt
  <INT>
end toInt
 
source play
  def board: $Tic-Tac-Toe;
  @: 'X';
  templates getMove
    [] -> #
    when <=[]> do
      $board::showString -> !OUT::write
      '$@play; to move $board::validMoves;:$#10;' -> !OUT::write
      [{mark: $@play, position: $IN::readline -> toInt} -> board::move] -> #
    otherwise
      $(1) !
  end getMove
 
  $getMove -> #
  when <{}> do
    '$.mark; played $.position;$#10;' -> !OUT::write
    @: $@ -> \(<='X'> 'O'! <='O'> 'X' !\);
    [$board::isWonOrDone] -> \(
      when <=[]> do $getMove!
      otherwise '$(1);$#10;' -> !OUT::write
    \) -> #
end play
 
$play -> !VOID