The Friday Fragment

Published on 10 December 2010
This post thumbnail

It's Friday, and time again for the Friday Fragment: our weekly programming-related puzzle.

This Week's Fragment

With this week's solution, we now have code to match man against machine in tic-tac-toe. Let's do that for our Reversi game:

Write code to let man compete against machine (a game bot) in Reversi. Present the game board on a web page, let the human player make the next move, and then call the game bot for its move. Continue this until one side wins.

To play along, provide either the URL or the code for the solution. You can post it as a comment or send it via email. If you'd like, you can build atop the games, bots, and/or source code at http://writestreams.com/bots.

Last Week's Fragment - Solution

With last week's puzzle, we returned to our game bots to let us humans play along:

Write code to let man compete against machine (a game bot) in rock-paper-scissors, tic-tac-toe, or Reversi (your choice). Present the game board on a web page, let the human player make the next move, and then call the game bot for its move. Continue this until one side wins.

I wrote a basic tic-tac-toe solution, available at http://writestreams.com/bots/tictactoe/playttt.php. I deliberately built it from prior code (like scorettt) and called our tic-tac-toe bot unmodified. Here's the PHP code, with more commenting this time:

<?php
 $url = 'http://writestreams.com/bots/tictactoe';  // Your bot here

 // Set up the session. If this is a new game, show the initial board:
 session_start();
 if (!isset($_SESSION['board'])) {
   $_SESSION['board'] = '         ';
   exit(show_board($_SESSION['board']));
 }

 // Get the board, add X's (the human's) move, and score it:
 $board = $_SESSION['board'];
 $board[($_REQUEST['row'] * 3) + $_REQUEST['col']] = 'X';
 if (!is_null($result = score_board($board, 'X')))
   game_over($board, $result);

 // Call the web service bot to get its (O's) move and score it:
 $board = file_get_contents($url.'?board=|'.rawurlencode($board).'|');
 $board = substr($board, 1, 9);
 if (!is_null($result = score_board($board, 'O')))
   game_over($board, $result);

 // No-one has won yet. Show the board & keep playing:
 show_board($board);
 $_SESSION['board'] = $board;

 // Helper functions:

   function score_board($board, $turn) {

     STATIC $wins = array( array(0,1,2), array(3,4,5), array(6,7,8),
                           array(0,3,6), array(1,4,7), array(2,5,8),
                           array(0,4,8), array(2,4,6) );

     for ($i=0; $i<8; $i++) {
       for ($j=0, $piececount=0; $j<3; $j++) {
         if ($board[$wins[$i][$j]] == $turn)
           $piececount++;
       }
       if ($piececount == 3)
         return $turn.' wins!';
       elseif (substr_count($board, ' ') == 0)
         return 'Tie!';
     }
   }

   function show_board($board) {
     STATIC $images = array( 'X' => 'x.jpg', 'O' => 'o.jpg', ' ' => 'space.jpg');
     echo '<table border="1">';
     for ($i=0; $i<3; $i++) {
       echo '<tr border="1">';
       for ($j=0; $j<3; $j++) {
         $piece = $board[($i*3)+$j];
         if ($piece == ' ')
           printf('<td border="1"><a href="playttt.php?row=%d&col=%d"><img src="%s"></td></a>',
                    $i, $j, $images[$piece]);
         else
           printf('<td border="1"><img src="%s"></td>', $images[$piece]);
       }
       echo '</tr>';
    }
    echo '</table><p>&nbsp;</p>';
   }

   function game_over($board, $result) {
     show_board($board);
     unset($_SESSION['board']);
     exit(printf('<p><b>%s</b></p><a href="playttt.php">Start Over</a>', $result));
   }
?>

To keep it simple, there's not a lot of error handling. Also, you'll notice that our prior tic-tac-toe bot (the O player) isn't very good at it. If you haven't already done so, try coding your own bot, plug it in at the "Your bot here" line, and compete against it. Perhaps you could upgrade the wins map. Then maybe your record will be as good as the NFC-leading Falcons. 10-2 - Rise Up!