441c4f02db55ef2cbe96027af7012e01

Just wondering if there are any ways to make this smaller.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
$std = fopen("php://stdin", "r");
echo "TICTACTOE\n\n\n\n";
function letsSeeUm($taken){
  foreach(range(1, 9) as $i) ${"s" . $i} = array_key_exists($i, $taken) ? $taken[$i]:" ";
  echo "   +   +   \n $s1 + $s2 + $s3 \n   +   +   \n+++++++++++\n   +   +   \n $s4 + $s5 + $s6 \n   +   +   \n+++++++++++\n   +   +   \n $s7 + $s8 + $s9 \n   +   +   \n\n";
}
function check($squ, $em = "x"){
  if(($squ[1] == $em && $squ[2] == $em && $squ[3] == $em) || ($squ[4] == $em && $squ[5] == $em && $squ[6] == $em) || ($squ[7] == $em && $squ[8] == $em && $squ[9] == $em) || ($squ[1] == $em && $squ[4] == $em && $squ[7] == $em) || ($squ[2] == $em && $squ[5] == $em && $squ[8] == $em) || ($squ[3] == $em && $squ[6] == $em && $squ[9] == $em) || ($squ[1] == $em && $squ[5] == $em && $squ[9] == $em) || ($squ[3] == $em && $squ[5] == $em && $squ[7] == $em)) return true;
  return false;
}
$squares = array();
$player = 1;
while(1){
  echo str_repeat("\n", 100);
  letsSeeUm($squares);
  echo "Player $player> ";
  $input = (int) fgets($std);
  if(!array_key_exists($input, $squares) && in_array($input, range(1, 9))){
    $squares[$input] = ($player == 1) ? "x":"o";
    if(check($squares) || check($squares, "o")){
      echo str_repeat("\n", 100);
      letsSeeUm($squares);
      echo "\nPlayer $player Wins!";
      die;
    }
    if(count($squares) == 9){
      echo str_repeat("\n", 100);
      letsSeeUm($squares);    
      echo "\nDraw!";
      die;
    }
    $player = $player == 1 ? 2:1;
  }
}

Refactorings

No refactoring yet !

5a00a3a98dcf6f9cd717440fd2b606e5

Eineki

March 24, 2008, March 24, 2008 20:33, permalink

No rating. Login to rate!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
$board = str_repeat("\n",100) . "TICTACTOE\n\n\n\n" . "   +   +   \n %s + %s + %s \n   +   +   \n+++++++++++\n"
       . "   +   +   \n %s + %s + %s \n   +   +   \n+++++++++++\n   +   +   \n %s + %s + %s \n   +   +   \n\n";
$std = fopen("php://stdin", "r");

function check($squ, $em){
  foreach (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)) as $t)  
    if(($squ[$t[0]]==$squ[$t[1]]) && ($squ[$t[1]]==$squ[$t[2]]) && ($squ[$t[2]]==$em)) return true;
  return false;
}

$squares = array(' ',' ',' ',' ',' ',' ',' ',' ',' ',1);
$player = 'x';
while($squares[9]<=9) {
  echo vsprintf($board,$squares) . "\n Player $player > ";
  $input = (int) fgets($std);
  if(((0<$input) && (10>$input)) && $squares[$input-1]==' ') {
    $squares[$input-1] = $player;
    $squares[9]++;
    if(check($squares, $player)) die(vsprintf($board, $squares) . "\nPlayer $player Wins!"); 
    $player = $player == 'x' ? 'o':'x';
  } 
}
echo vsprintf($board, $squares) . "\nDraw!";
8bba46dba9043c254e6eef1aa664e6f0

ellisgl.myopenid.com

May 24, 2008, May 24, 2008 09:33, permalink

No rating. Login to rate!

Made it a bit more readable. First time I've seen vsprintf in use. Some very minor speed opimizations.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php
$board = str_repeat("\n",100) . "TICTACTOE\n\n\n\n" . "   +   +   \n %s + %s + %s \n   +   +   \n+++++++++++\n"
       . "   +   +   \n %s + %s + %s \n   +   +   \n+++++++++++\n   +   +   \n %s + %s + %s \n   +   +   \n\n";
$std   = fopen('php://stdin', 'r');

function check($squ, $em)
 {
  foreach(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)) as $t)
   {
    if(($squ[$t[0]]===$squ[$t[1]]) && ($squ[$t[1]]===$squ[$t[2]]) && ($squ[$t[2]]===$em))
     {
      return true;
     }
   }
  return false;
 }
 
$squares = array(' ',' ',' ',' ',' ',' ',' ',' ',' ',1);
$player  = 'x';

while($squares[9]<=9)
 {
  echo vsprintf($board,$squares) . "\n".'Player '.$player.' >';

  $input = (int)fgets($std);

  if(((0<$input) && (10>$input)) && $squares[$input-1]==' ')
   {
    $squares[$input-1] = $player;
    ++$squares[9];
    
    if(check($squares, $player))
     {
      die(vsprintf($board, $squares) . "\n".'Player '.$player.' Wins!'); 
     }
    $player = $player === 'x' ? 'o':'x';
   } 
 }

echo vsprintf($board, $squares) . "\n".'Draw!';
Avatar

sMAshdot

June 11, 2008, June 11, 2008 09:39, permalink

No rating. Login to rate!

@ellisgl.myopenid.com
I think your version is _less_ readable than Eineki's, but that may be due to the curly braces and personal taste.

I gave it another try...
The board doesn't get redrawn as long as the input is invalid.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
TICTACTOE

<?php
$stdin   = fopen("php://stdin", "r");
$squares = array(' ',' ',' ',' ',' ',' ',' ',' ',' ',0);
$board   = 
  "               \n".
  "    +   +      \n".
  "  %s + %s + %s \n".
  "    +   +      \n".
  " +++++++++++   \n".
  "    +   +      \n".
  "  %s + %s + %s \n".
  "    +   +      \n".
  " +++++++++++   \n".
  "    +   +      \n".
  "  %s + %s + %s \n".
  "    +   +    \n\n";

function check($squ) {
  foreach ( array(array(0,1,2), array(3,4,5), array(6,7,8), // lines
                  array(0,3,6), array(1,4,7), array(2,5,8), // columns
                  array(0,4,8), array(2,4,6))               // diagonals
            as $i ) {
    if ( $squ[$i[0]]!=' ' && $squ[$i[0]]==$squ[$i[1]] && $squ[$i[1]]==$squ[$i[2]] )
      return TRUE;
  }
  return FALSE;
}

echo vsprintf($board,$squares);

while ( $squares[9]<9 ) {
  $token = $token == 'x' ? 'o':'x';

  do {
    echo " Player $token > ";
    $input = (int) fgets($stdin);
  } while ( $input<1 || $input>9 || $squares[$input-1]!=' ' );

  $squares[$input-1] = $token;
  $squares[9]++;
  echo vsprintf($board,$squares);
  if( check($squares) )
    die("\nPlayer $token Wins!\n"); 
}

echo "\nDraw!\n";
?>

Your refactoring





Format Copy from initial code

or Cancel