MYSTcommunity: Tic-Tac-Toe in PHP - MYSTcommunity

Jump to content

Page 1 of 1

Tic-Tac-Toe in PHP coders, come hither

#1 User is offline   StevenR 

  • telnahvah (guildmaster)
  • Group: Member
  • Posts: 1,508
  • Joined: 08-January 03
  • Location:Oregon, United States

Posted 22 December 2003 - 02:02 AM

I've been working on a tic-tac-toe game in PHP as a coding exercise (and I'd like to add that it was more difficult than I had anticipated, even for something that appears to be so simple). The game is now working wonderfully, but there are a few areas of the code that are downright ugly. The worst is the win-checking code. I couldn't find a good way to search for a winning play, and was forced to resort to this mangled mess:
if($boardArray[0][0] == "X" && $boardArray[0][1] == "X" && $boardArray[0][2] == "X") {doWin("X","0-0","0-1","0-2");}
if($boardArray[0][0] == "X" && $boardArray[1][1] == "X" && $boardArray[2][2] == "X") {doWin("X","0-0","1-1","2-2");}
if($boardArray[0][0] == "X" && $boardArray[1][0] == "X" && $boardArray[2][0] == "X") {doWin("X","0-0","1-0","2-0");}
if($boardArray[1][0] == "X" && $boardArray[1][1] == "X" && $boardArray[1][2] == "X") {doWin("X","1-0","1-1","1-2");}
if($boardArray[2][0] == "X" && $boardArray[2][1] == "X" && $boardArray[2][2] == "X") {doWin("X","2-0","2-1","2-2");}
if($boardArray[0][1] == "X" && $boardArray[1][1] == "X" && $boardArray[2][1] == "X") {doWin("X","0-1","1-1","2-1");}
if($boardArray[0][2] == "X" && $boardArray[1][2] == "X" && $boardArray[2][2] == "X") {doWin("X","0-2","1-2","2-2");}
if($boardArray[2][0] == "X" && $boardArray[1][1] == "X" && $boardArray[0][2] == "X") {doWin("X","2-0","1-1","0-2");}

if($boardArray[0][0] == "O" && $boardArray[0][1] == "O" && $boardArray[0][2] == "O") {doWin("O","0-0","0-1","0-2");}
if($boardArray[0][0] == "O" && $boardArray[1][1] == "O" && $boardArray[2][2] == "O") {doWin("O","0-0","1-1","2-2");}
if($boardArray[0][0] == "O" && $boardArray[1][0] == "O" && $boardArray[2][0] == "O") {doWin("O","0-0","1-0","2-0");}
if($boardArray[1][0] == "O" && $boardArray[1][1] == "O" && $boardArray[1][2] == "O") {doWin("O","1-0","1-1","1-2");}
if($boardArray[2][0] == "O" && $boardArray[2][1] == "O" && $boardArray[2][2] == "O") {doWin("O","2-0","2-1","2-2");}
if($boardArray[0][1] == "O" && $boardArray[1][1] == "O" && $boardArray[2][1] == "O") {doWin("O","0-1","1-1","2-1");}
if($boardArray[0][2] == "O" && $boardArray[1][2] == "O" && $boardArray[2][2] == "O") {doWin("O","0-2","1-2","2-2");}
if($boardArray[2][0] == "O" && $boardArray[1][1] == "O" && $boardArray[0][2] == "O") {doWin("O","2-0","1-1","0-2");}

Yes, it's checking for every possible winning play. The board information is contained in an array (thus the variable name ;)), $boardArray. [0][0] is upper left, [2][2] is lower right. So, this:
if($boardArray[0][0] == "O" && $boardArray[0][1] == "O" && $boardArray[0][2] == "O") {doWin("O","0-0","0-1","0-2");}
is examining the board variable and checking to see if player O has the upper left square (0-0), the upper square (0-1), and the upper right square (0-2). If it comes up with a match, it tells doWin which player won, and with which squares. This works, of course, but 16 separate checks to see if a player has won is a little ridiculous.

Is there a Better Way? ;)

Working model: http://www.aranai.co...c/tictactoe.php
Full code below:
<?PHP
// If the game has already started, continue
// Else start a new game - X goes first
session_start();
$move = $HTTP_GET_VARS['move'];

// Reset if commanded
if($HTTP_GET_VARS['do'] == "reset") {
	$move = "";
	for($a = "0"; $a <= "2"; $a++) {
  for($b = "0"; $b <= "2"; $b++) {
  $value = "boardArray";
  $value .= $a;
  $value .= $b;
  $_SESSION[$value] = "";
  }
	}
	$_SESSION['whosTurn'] = "";
}

// Check for continuing or new game
if($move == "") {
// Start Game
// Initialize variables
$whosTurn = "X";
$gameRunning = "1";
$boardArray[0][0] = "";
$boardArray[0][1] = "";
$boardArray[0][2] = "";

$boardArray[1][0] = "";
$boardArray[1][1] = "";
$boardArray[1][2] = "";

$boardArray[2][0] = "";
$boardArray[2][1] = "";
$boardArray[2][2] = "";

// Set session variables
$_SESSION['boardArray'] = $boardArray;
$_SESSION['whosTurn'] = "X";
} else {
// Get board values
for($a = "0"; $a <= "2"; $a++) {
	for($b = "0"; $b <= "2"; $b++) {
	$value = "boardArray";
	$value .= $a;
	$value .= $b;
	$boardArray[$a][$b] = $_SESSION[$value];
	}
}

// Get game values and move coOrds
$whosTurn = $_SESSION['whosTurn'];
$coOrds = explode("-",$HTTP_GET_VARS['move']);
$x = $coOrds[0];
$y = $coOrds[1];

// Perform move, but check for refresh (F5) first
if($boardArray[$x][$y] == "") {$boardArray[$x][$y] = $whosTurn;} else {$refreshed = "1";}

// Stalemate function
function doStalemate() {
global $staleMate;
$staleMate = "1";
}

// Game win function
$gameWon = "0";
function doWin($whoWon,$wonWith1,$wonWith2,$wonWith3) {

// We want to use the global gameWon variable
global $gameWon;

// Explode the wonWith (which combination won) vars
$wonWith1 = explode("-",$wonWith1);
$wonWith2 = explode("-",$wonWith2);
$wonWith3 = explode("-",$wonWith3);

// Transfer the exploded vars to global vars
$GLOBALS['whoWon'] = $whoWon;
$GLOBALS['wonWith1[0]'] = $wonWith1[0];
	$GLOBALS['wonWith1[1]'] = $wonWith1[1];
$GLOBALS['wonWith2[0]'] = $wonWith2[0];
	$GLOBALS['wonWith2[1]'] = $wonWith2[1];
$GLOBALS['wonWith3[0]'] = $wonWith3[0];
	$GLOBALS['wonWith3[1]'] = $wonWith3[1];
	
// The game has been won
$gameWon = "1";
}

// Check for Win or stalemate
// X First
if($boardArray[0][0] == "X" && $boardArray[0][1] == "X" && $boardArray[0][2] == "X") {doWin("X","0-0","0-1","0-2");}
if($boardArray[0][0] == "X" && $boardArray[1][1] == "X" && $boardArray[2][2] == "X") {doWin("X","0-0","1-1","2-2");}
if($boardArray[0][0] == "X" && $boardArray[1][0] == "X" && $boardArray[2][0] == "X") {doWin("X","0-0","1-0","2-0");}
if($boardArray[1][0] == "X" && $boardArray[1][1] == "X" && $boardArray[1][2] == "X") {doWin("X","1-0","1-1","1-2");}
if($boardArray[2][0] == "X" && $boardArray[2][1] == "X" && $boardArray[2][2] == "X") {doWin("X","2-0","2-1","2-2");}
if($boardArray[0][1] == "X" && $boardArray[1][1] == "X" && $boardArray[2][1] == "X") {doWin("X","0-1","1-1","2-1");}
if($boardArray[0][2] == "X" && $boardArray[1][2] == "X" && $boardArray[2][2] == "X") {doWin("X","0-2","1-2","2-2");}
if($boardArray[2][0] == "X" && $boardArray[1][1] == "X" && $boardArray[0][2] == "X") {doWin("X","2-0","1-1","0-2");}

// Now O
if($boardArray[0][0] == "O" && $boardArray[0][1] == "O" && $boardArray[0][2] == "O") {doWin("O","0-0","0-1","0-2");}
if($boardArray[0][0] == "O" && $boardArray[1][1] == "O" && $boardArray[2][2] == "O") {doWin("O","0-0","1-1","2-2");}
if($boardArray[0][0] == "O" && $boardArray[1][0] == "O" && $boardArray[2][0] == "O") {doWin("O","0-0","1-0","2-0");}
if($boardArray[1][0] == "O" && $boardArray[1][1] == "O" && $boardArray[1][2] == "O") {doWin("O","1-0","1-1","1-2");}
if($boardArray[2][0] == "O" && $boardArray[2][1] == "O" && $boardArray[2][2] == "O") {doWin("O","2-0","2-1","2-2");}
if($boardArray[0][1] == "O" && $boardArray[1][1] == "O" && $boardArray[2][1] == "O") {doWin("O","0-1","1-1","2-1");}
if($boardArray[0][2] == "O" && $boardArray[1][2] == "O" && $boardArray[2][2] == "O") {doWin("O","0-2","1-2","2-2");}
if($boardArray[2][0] == "O" && $boardArray[1][1] == "O" && $boardArray[0][2] == "O") {doWin("O","2-0","1-1","0-2");}

// No win. How about stalemate?
if($gameWon != "1"){
	if($boardArray[0][0] != "" && $boardArray[0][1] != "" && $boardArray[0][2] != "" && $boardArray[1][0] != "" && $boardArray[1][1] != "" && $boardArray[1][2] != "" && $boardArray[2][0] != "" && $boardArray[2][1] != "" && $boardArray[2][2] != "") {
	// Stalemate
	doStalemate();
	}
}

// Update turn
if($refreshed != "1") {if($whosTurn == "X") {$whosTurn = "O";} else {$whosTurn = "X";}}
$_SESSION['whosTurn'] = $whosTurn;

// Save board values
for($a = "0"; $a <= "2"; $a++) {
	for($b = "0"; $b <= "2"; $b++) {
	$value = "boardArray";
	$value .= $a;
	$value .= $b;
	$_SESSION[$value] = $boardArray[$a][$b];
	}
}
}
?>
<html>
<head>
<title>Tic-Tac-Toe</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
a {color: gray; text-decoration: none;}
a:hover {color: black; text-decoration: none;}
.gameSquare {width: 100px; height: 100px; font-family: Tahoma; font-size: 36pt; color: black;}
.gameSquareWon {width: 100px; height: 100px; font-family: Tahoma; font-size: 36pt; color: red;}
</style>
</head>
<body>
<div align="center">
<font face="Tahoma" size="5">Tic-Tac-Toe</font><br>
<font face="Tahoma" size="3"><?PHP if($staleMate == "1") {echo("Stalemate.");} else {if($gameWon != "1") {echo $whosTurn; ?>'s Turn<?PHP } else {echo $GLOBALS['whoWon']; echo(" WON!");}} ?></font>
<table width="300" height="300" border="1" cellpadding="5" cellspacing="0" bordercolor="#000000">
<?PHP
	$draw_x = "-1";
	$draw_y = "-1";
	for($row = 0; $row < 3; $row++) {
  echo("<tr align=\"center\" valign=\"middle\">");
  $draw_x++;
  for($col = 0; $col < 3; $col++) {
  $draw_y++;
   	 echo("<td class=\"gameSquare");
  if($gameWon == "1") {
   if($draw_x == $GLOBALS['wonWith1[0]'] && $draw_y == $GLOBALS['wonWith1[1]']) {$winningSpot = "1";}
   else if($draw_x == $GLOBALS['wonWith2[0]'] && $draw_y == $GLOBALS['wonWith2[1]']) {$winningSpot = "1";}
   else if($draw_x == $GLOBALS['wonWith3[0]'] && $draw_y == $GLOBALS['wonWith3[1]']) {$winningSpot = "1";}
   if($winningSpot == "1") {echo("Won");$winningSpot = "0";}
  }
  echo("\">");
  if($boardArray[$draw_x][$draw_y] != "") {
 	 echo $boardArray[$draw_x][$draw_y];
  } else {
 	 if($gameWon != "1") {
    echo("<A HREF=\"tictactoe.php?do=move&move=".$draw_x."-".$draw_y."&which=".$whosTurn."\">?</A>");
 	 } else {
    echo("-");
 	 }
  }
  echo("</td>");
  }
  $draw_y = "-1";
	echo("</tr>");
	}
?>
</table>
<font face="tahoma" size="2"><a href="tictactoe.php?do=reset">Reset Game / Play Again</a></font>
</div>
</body>
</html>

0

#2 User is offline   Sigma 

  • glotahn (beginner)
  • Group: Member
  • Posts: 338
  • Joined: 23-August 01
  • Location:Switzerland

Posted 22 December 2003 - 05:29 AM

You could combine the checks for O and X into a loop. Something like

foreach (array("X", "O") as $mark) {
  if($boardArray[0][0] == $mark && $boardArray[0][1] == $mark && $boardArray[0][2] == $mark) doWin($mark, "0-0", "0-1", "0-2");
  ...etc.
}


(not tested).

I didn't find an easier way back when I programmed my Tic-Tac-Toe, but I don't feel like thinking about it thoroughly right now ;).

(Of course you could check the three rows in a loop, then the three columns in a loop, then the two diagonals, but I doubt that that would qualify as "easier")
0

#3 User is offline   dnwq 

  • telnahvah (guildmaster)
  • Group: Veteran Member
  • Posts: 1,520
  • Joined: 14-August 03
  • Location:Far, far away, in a distant land...

Posted 22 December 2003 - 06:54 AM

I absolutely suck at PHP, but here's a possible method:

*is happy with self for thinking of it*

Give every square a value - such that is becomes like this:

1 2 4
8 16 32
64 128 256

Yes, it's just doubling the numbers.

Now, create an array with this set of numbers:

[7, 56, 73, 86, 146, 273, 292, 448]

And another array:

[1, 2, 4, 8, 16, 32, 64, 128, 256]

Anyway, notice that there's no way you can take a group of numbers from the square, and another group of numbers, and have the same total.

So, suppose that X chose 8, 16 and 32. Totaling them up, X gets 56. Loop through the first array, and since 56 is in the list, X wins!

;)

Should there be four moves, then do TWO loops.

Let's say X chose 8, 256, 16, and 32:

initialise variable Total as total of X = 312
loop 9 times(i as integer representing loop number; start 0 end 8){

loop 8 times(j as integer representing loop number; start 0 end 7){
if(Total - secondArray[i] == firstArray[j]) X wins!
}

}


Should there be FIVE moves, loop THREE times:

initialise variable Total as total of X = (something)
loop 9 times(i as integer representing loop number; start 0 end 8){

loop 9 times(j as integer representing loop number; start 0 end 8){

loop 8 times(k as integer representing loop number; start 0 end 7){
if(Total - secondArray[i] - secondArray[j] == firstArray[k]) X wins!
}

}

}


This results in, maximum, a 8*9*9 loop count. 648 reiterations - not too much!

;) ;) ;)

:D

Fancy Math™
0

#4 User is offline   dnwq 

  • telnahvah (guildmaster)
  • Group: Veteran Member
  • Posts: 1,520
  • Joined: 14-August 03
  • Location:Far, far away, in a distant land...

Posted 22 December 2003 - 07:03 AM

Thought of another script-saver.

*is even happier*

Now, it's going to take no less than 9 lines of code just to assign them values. So here's another mathematical thingy you can exploit:

I suppose your square goes like this -

0-0 0-1 0-2

1-0 1-1 1-2

2-0 2-1 2-2

I assign each one to be in the format x-y.

Then, to find the numerical value in the square above, or their respective number in the box, use 2^[(x*3) + y].

For instance

0-0 becomes 2^[(0*3) + 0], or 1. Anything to the power of 0 becomes 1.

Or,

1-1 becomes 2^[(1*3) + 1], or 2^4, or 16.

;)

More Fancy Math™
0

#5 User is offline   dnwq 

  • telnahvah (guildmaster)
  • Group: Veteran Member
  • Posts: 1,520
  • Joined: 14-August 03
  • Location:Far, far away, in a distant land...

Posted 22 December 2003 - 07:44 AM

I've a friend - J.C.S.H, Ahsirakh - whom I asked, and his method requires - at most - 10 loops. More if one counts a minor one inside, but it's still less than mine.

;) ;) ;) ;) :D

Oh well.

Here's how he did it:

Suppose X has 3 steps:
if(( X's steps[0].[xcoordinate] == X's steps[1].[xcoordinate] )&&( X's steps[1].[xcoordinate] == X's steps[2].[xcoordinate] )){
then X wins.
}
else 
if(( X's steps[0].[ycoordinate] == X's steps[1].[ycoordinate] )&&( X's steps[1].[ycoordinate] == X's steps[2].[ycoordinate] )){
then X wins.
}
else
if( X's steps[0] == "0-0" && X's steps[1] == "1-1" && X's steps[2] == "2-2"){
then X wins.
}
else
if( X's steps[0] == "2-0" && X's steps[1] == "1-1" && X's steps[2] == "0-2"){
then X wins.
}


Suppose X has 4 steps:
loop(4 times, i as integer){

init TempArray as Array[4 length];

init TempArrayCounter as Number(single-digit, value 0);

loop(4 times, j as integer){
if( j == i ) continue;
else
TempArray[TempArrayCounter] = X's steps[i];
TempArrayCounter++;
} //minor loop to remove one step from list

RUN ABOVE CODE USING TempArray AS 3-STEP LIST OF VALUES

}


etc, etc. Same with 5 steps.

Oh well.
0

#6 User is offline   StevenR 

  • telnahvah (guildmaster)
  • Group: Member
  • Posts: 1,508
  • Joined: 08-January 03
  • Location:Oregon, United States

Posted 22 December 2003 - 01:31 PM

Sigma, on Dec 22 2003, 04:29 AM, said:

You could combine the checks for O and X into a loop. Something like

foreach (array("X", "O") as $mark) {
  if($boardArray[0][0] == $mark && $boardArray[0][1] == $mark && $boardArray[0][2] == $mark) doWin($mark, "0-0", "0-1", "0-2");
  ...etc.
}


(not tested).

That's a great idea. I figured I could cut it down to 8 steps, but I hadn't gone looking through the 'for' references yet. Thanks. ;)

Quote

(Of course you could check the three rows in a loop, then the three columns in a loop, then the two diagonals, but I doubt that that would qualify as "easier")
That idea is looking more and more appealing after looking at Dnwq's last post ;) (Not your fault, Dnwq...it's just early, and I'm not comprehending that block of code ;))

This reminds me of calendar coding. There are some things that computers just don't handle well. ;)

Here's the new code. I don't think it's much smaller, but at least it doesn't look as hideous:
// Check horizontal
for($do_x = "0";$do_x < "3";$do_x++) {
	$with1 = $do_x;$with2 = $do_x;$with3 = $do_x;$x0var = "-0";$x1var = "-1";$x2var = "-2";
	if($boardArray[$do_x][0] == $player && $boardArray[$do_x][1] == $player && $boardArray[$do_x][2] == $player) {
  $with1.=$x0var;$with2.=$x1var;$with3.=$x2var;
  doWin($player,$with1,$with2,$with3);break;
	}
}
// Vertical
for($do_y = "0";$do_y < "3";$do_y++) {
	$with1 = $do_y;$with2 = $do_y;$with3 = $do_y;$y0var = "0-";$y1var = "1-";$y2var = "2-";
	if($boardArray[0][$do_y] == $player && $boardArray[1][$do_y] == $player && $boardArray[2][$do_y] == $player) {
  $y0var.=$with1;$y1var.=$with2;$y2var.=$with3;
  doWin($player,$y0var,$y1var,$y2var);break;
	}
}
// Diagonal
if($boardArray[0][0] == $player && $boardArray[1][1] == $player && $boardArray[2][2] == $player) {doWin($player,"0-0","1-1","2-2");}
if($boardArray[0][2] == $player && $boardArray[1][1] == $player && $boardArray[2][0] == $player) {doWin($player,"0-2","1-1","2-0");}

0

#7 User is offline   J'ohn 

  • oglahnth (ancient one)
  • Group: Member
  • Posts: 10,928
  • Joined: 01-June 01
  • Gender:Male
  • Location:Athens, Greece

Posted 22 December 2003 - 04:19 PM

I found two important problems in your code, StevenR. The first is that you have used modular programming for a completely sequential process. You don't really need all those flags about wins and stalemates.
Secondly, when you check for a win, you don't need to check if the other player has won. In noughts and crosses, it is impossible for you to win on the opponent's round.

Given all this, I propose the following code:
session_start();
$move = $HTTP_GET_VARS['move'];

if($HTTP_GET_VARS['do'] == "reset")
{
	$move = "";
	for($a = "0"; $a <= "2"; $a++)
	{
  for($b = "0"; $b <= "2"; $b++)
  {
  	$value = "boardArray";
  	$value .= $a;
  	$value .= $b;
  	$_SESSION[$value] = "";
   }
	}
	$_SESSION['whosTurn'] = "";
}

if($move == "")
{
	$whosTurn = "X";
	for($a = "0"; $a <= "2"; $a++)
	{
  for($b = "0"; $b <= "2"; $b++)
  {
  	$boardArray[$a][$b] = "";
  }
	}

	$_SESSION['boardArray'] = $boardArray;
	$_SESSION['whosTurn'] = "X";
}
else
{
	for($a = "0"; $a <= "2"; $a++)
	{
  for($b = "0"; $b <= "2"; $b++)
  {
  	$value = "boardArray";
  	$value .= $a;
  	$value .= $b;
  	$boardArray[$a][$b] = $_SESSION[$value];
  }
	}

	$whosTurn = $_SESSION['whosTurn'];
	$coOrds = explode("-",$HTTP_GET_VARS['move']);
	$x = $coOrds[0];
	$y = $coOrds[1];

	if($boardArray[$x][$y] == "") {$boardArray[$x][$y] = $whosTurn;} else {$refreshed = "1";}

	function doWin($wonWith1,$wonWith2,$wonWith3)
	{
  $wonWith1 = explode("-",$wonWith1);
  $wonWith2 = explode("-",$wonWith2);
  $wonWith3 = explode("-",$wonWith3);

  $GLOBALS['whosTurn'] = $whosTurn;
  $GLOBALS['wonWith1[0]'] = $wonWith1[0];
  $GLOBALS['wonWith1[1]'] = $wonWith1[1];
  $GLOBALS['wonWith2[0]'] = $wonWith2[0];
  $GLOBALS['wonWith2[1]'] = $wonWith2[1];
  $GLOBALS['wonWith3[0]'] = $wonWith3[0];
  $GLOBALS['wonWith3[1]'] = $wonWith3[1];
	}

	if($boardArray[0][0] != "" && $boardArray[0][1] != "" && $boardArray[0][2] != "" && $boardArray[1][0] != "" && $boardArray[1][1] != "" && $boardArray[1][2] != "" && $boardArray[2][0] != "" && $boardArray[2][1] != "" && $boardArray[2][2] != "")
	{ doStalemate();}
	else
	{
  if($boardArray[0][0] == $whosTurn && $boardArray[0][1] == $whosTurn && $boardArray[0][2] == $whosTurn) {doWin("0-0","0-1","0-2");}
  if($boardArray[0][0] == $whosTurn && $boardArray[1][1] == $whosTurn && $boardArray[2][2] == $whosTurn) {doWin("0-0","1-1","2-2");}
  if($boardArray[0][0] == $whosTurn && $boardArray[1][0] == $whosTurn && $boardArray[2][0] == $whosTurn) {doWin("0-0","1-0","2-0");}
  if($boardArray[1][0] == $whosTurn && $boardArray[1][1] == $whosTurn && $boardArray[1][2] == $whosTurn) {doWin("1-0","1-1","1-2");}
  if($boardArray[2][0] == $whosTurn && $boardArray[2][1] == $whosTurn && $boardArray[2][2] == $whosTurn) {doWin("2-0","2-1","2-2");}
  if($boardArray[0][1] == $whosTurn && $boardArray[1][1] == $whosTurn && $boardArray[2][1] == $whosTurn) {doWin("0-1","1-1","2-1");}
  if($boardArray[0][2] == $whosTurn && $boardArray[1][2] == $whosTurn && $boardArray[2][2] == $whosTurn) {doWin("0-2","1-2","2-2");}
  if($boardArray[2][0] == $whosTurn && $boardArray[1][1] == $whosTurn && $boardArray[0][2] == $whosTurn) {doWin("2-0","1-1","0-2");}
	}
	
	if($refreshed != "1") {if($whosTurn == "X") {$whosTurn = "O";} else {$whosTurn = "X";}}
	$_SESSION['whosTurn'] = $whosTurn;

	for($a = "0"; $a <= "2"; $a++)
	{
  for($b = "0"; $b <= "2"; $b++)
  {
  	$value = "boardArray";
  	$value .= $a;
  	$value .= $b;
  	$_SESSION[$value] = $boardArray[$a][$b];
  }
	}
}

I don't know PHP, so it probably doesn't work as is, but I think you'll get the gist of what I'm trying to say here. ;)

SBS ;)

PS: "coordinates" is a single word, and that "whosTurn" makes my head spin. ;)
0

#8 User is offline   StevenR 

  • telnahvah (guildmaster)
  • Group: Member
  • Posts: 1,508
  • Joined: 08-January 03
  • Location:Oregon, United States

Posted 22 December 2003 - 04:34 PM

J'ohn, on Dec 22 2003, 03:19 PM, said:

I found two important problems in your code, StevenR. The first is that you have used modular programming for a completely sequential process. You don't really need all those flags about wins and stalemates.

I'm having trouble understanding what you mean. How is 'modular' a problem?

Quote

Secondly, when you check for a win, you don't need to check if the other player has won. In noughts and crosses, it is impossible for you to win on the opponent's round.
I fixed that in my last post. (Added the $player variable, so it's only checking the person who just played) ;)

Quote

Given all this, I propose the following code:
...code...
What changes have been made? I looked through it, but I haven't found anything different. There's a lot of code there. ;)

Quote

PS: "coordinates" is a single word, and that "whosTurn" makes my head spin. ;)
Coordinates: I know. I'm not as strict with my variable naming conventions as I should be. coOrds looked right to my twisted, late-night mental state. :D

Thanks for the response! ;)
0

#9 User is offline   J'ohn 

  • oglahnth (ancient one)
  • Group: Member
  • Posts: 10,928
  • Joined: 01-June 01
  • Gender:Male
  • Location:Athens, Greece

Posted 22 December 2003 - 05:06 PM

StevenR, on Dec 23 2003, 12:34 AM, said:

I'm having trouble understanding what you mean. How is 'modular' a problem?

In your original code, you completely differentiate the checks about stalemates and wins. In those cases that the one needs to check on the other, you accomplish that using flag variables. This is modular programming. It is not really a problem, but in such a simple application (yes, it's simple ;) ), it actually increases the complexity of the program instead of diminishing it.

Quote

Quote

Given all this, I propose the following code:
...code...
What changes have been made? I looked through it, but I haven't found anything different. There's a lot of code there. ;)

Insolence! ;)
I removed the first argument from the doWin function. The function fishes for $whosTurn (or $player, if you will) on its own instead.
I also placed the two checks (for win and stalemate) sequentially. The win check is now nested in the if clause of the stalemate check (which has been put on top). That way there is no need for flag variables.
I don't think I made any other changes. Oh, I also used two for commands in order to initialise the board, instead of initialising each cell one by one.

SBS ;)
0

#10 User is offline   StevenR 

  • telnahvah (guildmaster)
  • Group: Member
  • Posts: 1,508
  • Joined: 08-January 03
  • Location:Oregon, United States

Posted 22 December 2003 - 10:16 PM

J'ohn, on Dec 22 2003, 04:06 PM, said:

StevenR, on Dec 23 2003, 12:34 AM, said:

I'm having trouble understanding what you mean. How is 'modular' a problem?

In your original code, you completely differentiate the checks about stalemates and wins. In those cases that the one needs to check on the other, you accomplish that using flag variables. This is modular programming. It is not really a problem, but in such a simple application (yes, it's simple :D ), it actually increases the complexity of the program instead of diminishing it.

Ah. ;)
What programming/scripting/whatever language(s) do you use, by the way?

Quote

Oh, I also used two for commands in order to initialise the board, instead of initialising each cell one by one.
Now there's a very good change. ;)


Next up, PHP Chess? ;) ;)
0

#11 User is offline   J'ohn 

  • oglahnth (ancient one)
  • Group: Member
  • Posts: 10,928
  • Joined: 01-June 01
  • Gender:Male
  • Location:Athens, Greece

Posted 23 December 2003 - 03:08 AM

StevenR, on Dec 23 2003, 06:16 AM, said:

What programming/scripting/whatever language(s) do you use, by the way?

Hmmm, let's see. Java and C++ are my most prized assets. Also HTML and CSS, although those are not exactly programming languages. I know a fair deal of Visual Basic, too, which is not necessarily good. And I know Assembly and Fortran 77, which is definitely not good. Um.

PHP sounds quite interesting, though. ;)

SBS ;)
0

#12 User is offline   dnwq 

  • telnahvah (guildmaster)
  • Group: Veteran Member
  • Posts: 1,520
  • Joined: 14-August 03
  • Location:Far, far away, in a distant land...

Posted 23 December 2003 - 08:47 AM

PHP chess?

Are you mad? ;)

It's horrendous programming AI for tic-tac-toe. I've a friend who wrote a VB program that had evolving AI - he pit it against itself.

Another friend wrote a Checkers program. No evolving AI, but I can assure you it's difficult enough.

Chess...? ;) :D ;) ;)
0

#13 User is offline   Free Bird 

  • oglahnth (ancient one)
  • Group: Admin
  • Posts: 4,874
  • Joined: 21-August 01
  • Gender:Male
  • Location:Voorschoten, The Netherlands
  • KI number:343012

Posted 23 December 2003 - 08:57 AM

dnwq, on Dec 23 2003, 02:47 PM, said:

It's horrendous programming AI for tic-tac-toe. I've a friend who wrote a VB program that had evolving AI - he pit it against itself.

Not that hard, since you can simply program every possible move and make it perform the best countermove. And since the number of games is still quite high then, you can significantly reduce it by rotation and mirroring - after all, many situations are equivalent.

And tic tac toe is no fun anyway - with two good players, it'll always end in a draw.
0

#14 User is offline   chaos syndrome 

  • telnahvah (guildmaster)
  • Group: Member
  • Posts: 1,556
  • Joined: 26-April 02

Posted 23 December 2003 - 11:45 AM

I'm considering coding a five-dimensional variant of tic-tac-toe in VB...

I think I have an algorithm that will cycle through all possible lines but I suspect it is ludicrously inefficient and I haven't tested it yet.

Whether I want to program AI for this is another matter.
0

#15 User is offline   StevenR 

  • telnahvah (guildmaster)
  • Group: Member
  • Posts: 1,508
  • Joined: 08-January 03
  • Location:Oregon, United States

Posted 23 December 2003 - 12:01 PM

I wasn't planning on doing AI for any of this. ;)

And yes, I am mad. ;)

Scrabble would be cool too...
0

#16 User is offline   StevenR 

  • telnahvah (guildmaster)
  • Group: Member
  • Posts: 1,508
  • Joined: 08-January 03
  • Location:Oregon, United States

Posted 23 December 2003 - 12:04 PM

J'ohn, on Dec 23 2003, 02:08 AM, said:

PHP sounds quite interesting, though. ;)

PHP would be a breeze to pick up, if you ever decided to. It shares a lot in common with C++. I used to do a bit of C++ (still have Visual C++ 6 around here somewhere...), but was too impatient to ever finish anything. ;)

Free Bird: You are correct that Tic-Tac-Toe isn't any fun. I could, if I wanted, convert it to a multiplayer variation in which the board was stored in a database, and players could use it from different computers...but once I realized I could, I decided I didn't want to. Chess or Scrabble would be a different story.

Or Clue. ;)
0

#17 User is offline   J'ohn 

  • oglahnth (ancient one)
  • Group: Member
  • Posts: 10,928
  • Joined: 01-June 01
  • Gender:Male
  • Location:Athens, Greece

Posted 23 December 2003 - 02:44 PM

Free Bird, on Dec 23 2003, 04:57 PM, said:

Not that hard, since you can simply program every possible move and make it perform the best countermove. And since the number of games is still quite high then, you can significantly reduce it by rotation and mirroring - after all, many situations are equivalent.

True. A friend of mine has made a tic-tac-toe program (in Visual C++) with an adjustable difficulty setting. If set on "Hard", it is impossible to win against the computer's AI.

Quote

Chess or Scrabble would be a different story.

Backgammon would be nicer. All games of it on a single PHP script. ;)

SBS ;)
0

Share this topic:


Page 1 of 1


Fast Reply

  

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users