I am a beginner java student writing a gui tic-tac-toe program for my class. (No players, just computer generated).
Everything in my program works as expected, except for one thing; it seems that the placement of my method call for checkWinner
is not place correctly, because the assignment for the X's and O's always finish. Why won't the loop end as soon as there is a winner?
It will return the correct winner based on the method call, but the for-loop will continue to iterate and fill in the rest (so sometimes it looks like both the x and o win or one wins twice). I've been going crazy, thinking it might be the placement of my checkWinner
method call and if statement. When I set the winner = true;
shouldn't that cancel the loop? I have tried putting it between, inside and outside each for-loop with no luck :(
I have marked the area I think is the problem //What is wrong here?// off to the right of that part the code. Thank you for any input!! :)
public void actionPerformed(ActionEvent e)
{
int total = 0, i = 0;
boolean winner = false;
//stop current game if a winner is found
do{
// Generate random # 0-1 for the labels and assign
// X for a 0 value and O for a 1 value
for (int row = 0; row < gameboard.length; row++) //rows
{
for (int col = 0; col < gameboard[row].length; col++) //columns
{
//Generate random number
gameboard[row][col] = (int)(Math.random() * 2);
//Assign proper values
if(gameboard[row][col] == 0)
{
labels[i].setText("X");
gameboard[row][col] = 10; //this will help check for the winner
}
else if(gameboard[row][col] == 1)
{
labels[i].setText("O");
gameboard[row][col] = 100; //this will help check for winner
}
/**Send the array a the method to find a winner
The x's are counted as 10s
The 0s are counted as 100s
if any row, column or diag = 30, X wins
if any row, column or diag = 300, Y wins
else it will be a tie
*/
total = checkWinner(gameboard); **//Is this okay here??//**
if(total == 30 || total == 300) //
winner = true; //Shouldn't this cancel the do-while?
i++; //next label
}
}//end for
}while(!winner);//end while
//DISPLAY WINNER
if(total == 30)
JOptionPane.showMessageDialog(null, "X is the Winner!");
else if(total == 300)
JOptionPane.showMessageDialog(null, "0 is the Winner!");
else
JOptionPane.showMessageDialog(null, "It was a tie!");
}
First of all, your code iterates through a board and generates random marks of X and O. This leads to some very odd board states, being always filled row-by-row, and possibly with unbalanced number of X and O marks.
IMHO you should organize your code in opposite manner to fill a board similary to a true game. I mean a series of 9 marks 'XOXOXOXOX' spreaded over the board.
Let Labels labels
be a nine-character array, initialized to 9 spaces.
public int doGame( Labels labels)
{
labels = " ";
int itisXmove = true; // player X or O turn
for( int movesLeft = 9; movesLeft > 0; movesLeft --)
{
int position = // 0 .. movesLeft-1
(int) Math.floor(Math.random() * movesLeft);
for( int pos = 0; pos < 9; pos ++) // find position
if( labels[ pos] == " ") // unused pos?
if( position-- == 0) // countdown
{
if( itisXmove) // use the pos
labels[ pos] = "X"; // for current player
else
labels[ pos] = "O";
break;
}
int result = checkWinner( labels); // who wins (non-zero)?
if( result != 0)
return result;
itisXmove = ! itisXmove; // next turn
}
return 0; // a tie
}
then
public void actionPerformed(ActionEvent e)
{
Labels labels;
int result = doGame( labels);
if( result == valueForX)
JOptionPane.showMessageDialog(null, "X is the Winner!");
else if( result == valueForO)
JOptionPane.showMessageDialog(null, "O is the Winner!");
else
JOptionPane.showMessageDialog(null, "It's a tie!");
for( int rowpos = 0; rowpos < 9; rowpos += 3)
{
for( int colpos = 0; colpos < 3; colpos ++)
/* output (char)label[ rowpos + colpos] */;
/* output (char)newline */;
}
}