Hello there,
I am having problems with this code i have written and it is a tic tac toe program. It runs and everything but it doesn't get a winner when i call the method getWinner. this method is suppose to return 'x', 'o' , or ' ' depending onwhether X, O or no one is the winner. Oh yeah a player wins only if they have three-in-a-row, in a row, a column, or a diagonal.. ?? I am just stuck on what to do.. i need your advice or something.. Oh yeah i'm using BlueJay.. thanks ..

JT ....

/**
* A class that represents a tic-tac-toe board
*
*
* @author J T ...
*/
public class TicTacToe {
private char[][] board;
private static final int ROWS = 3;
private static final int COLUMNS = 3;


/**
* Build an empty tic-tac-toe board
*/
public TicTacToe() {
board = new char[ROWS][COLUMNS];


// fill board with spaces
for ( int i = 0; i < ROWS; i++ ) {
for ( int j = 0; j < COLUMNS; j++ ) {
board[j] = ' ';
}
}
}


/**
* Put an X or an O on the board at position i,j
*
* @param i  The row number
* @param j  The column number
* @param player  the current player (either X or O)
*
* @return true if the player made a mark at position i,j
*         false if that position already contained a mark
*/
public boolean set( int i, int j, char player ) {
if ( ( i < 0 ) || ( i > 2 ) || ( j < 0 ) || ( j > 2 ) )
return false;
if ( board[j] != ' ' )
return false;


board[j] = player;
return true;
}


/**
* Evaluate the board to determine a winner
*
* @return 'x' if X is the winner, 'o' if O is the winner, ' ' if no one
*             is the winner.
*/
public char getWinner()
{
int Xrow = 0;
int Orow = 0;
int Xcol = 0;
int Ocol = 0;
for ( int row = 0; row < 3; row++ ) {
for ( int col = 0; col < 3; col++ ) {
if ( board[row][col] == 'X' )
Xrow += 1;
if ( board[row][col] == 'O' )
Orow += 1;
}
}


for ( int col = 0; col < 3; col++){
for ( int row = 0; row < 3; row++){
if ( board[row][col] == 'X' )
Xcol += 1;
if ( board[row][col] == 'O' )
Ocol += 1;
}
}
if ( (Xrow > 3) || (Xcol > 3) )
return 'x';
if ( (Ocol > 3) || (Ocol > 3) )
return 'o';
if ( (board[0][0] == 'X') && (board[1][1] == 'X') && (board[2][2] == 'X') )
return 'x';
if ( (board[0][0] == 'O') && (board[1][1] == 'O') && (board[2][2] == 'O') )
return 'o';
if ( (board[0][2] == 'X') && (board[1][1] == 'X') && (board[2][0] == 'X') )
return 'x';
if ( (board[0][2] == 'O') && (board[1][1] == 'O') && (board[2][0] == 'O') )
return 'o';
else {
return ' ';
}// no one has won
}


/**
* Return a String representation of the board
*
* @return The current board represented as a String
*/
public String toString() {
String s = "";
for ( int i = 0; i < ROWS; i++ ) {
s += "|";
for ( int j = 0; j < COLUMNS; j++ ) {
s += board[j];
}
s += "|\n";
}
return s;
}
}


If you need to view the board class.. here it is..
this uses the tictactoe class..


import javax.swing.*;


/**
* Play tic-tac-toe.
*
* Game derived from Big Java, by Cay Horstmann, pages 545-547.
*
* @author Cay Horstmann
*
* @version 1.0
*/
public class TicTacToeGame {


private TicTacToe game;


/**
* Play a game of tic-tac-toe
*/
public TicTacToeGame()
{
game = new TicTacToe();
int numMoves = 0;


char player = 'x';
while ( numMoves < 9 ) {
// display board
System.out.println( game );


makeMove( player );
numMoves++;
player = switchPlayer( player );


}


System.out.println( game );
System.exit(0);
}



/**
* Let a player make a move. Ask the player for the row and column
* position where he wishes to put his mark, and then place the mark
* at that position on the board.
*
* @param player The player whose turn it is.
*/
private void makeMove( char player )
{
boolean goodMove = false;
while( goodMove == false ) {
int row = getRow( player );
int column = getColumn( player );


// try to place an X or O at that position


goodMove = game.set( row, column, player );
}
}


/**
* Switch from 'x' to 'o' or vice versa
*
* @param player The current player
* @return The new player
*/
private char switchPlayer( char player )
{
if ( player == 'x' )
return 'o';
else
return 'x';
}


/**
* Get a row number for where the given player wants to place a mark
*
* @param player the player who wants to place a mark
* @return the row number of the row where the player wants to put a mark
*/
private int getRow( char player )
{
String input =
JOptionPane.showInputDialog("Enter row for '" + player + "'" );
if ( input == null || input.equals("") )
System.exit( 0 );
return Integer.parseInt( input );
}


/**
* Get a column number for where the given player wants to place a mark
*
* @param player the player who wants to place a mark
* @return the column number of the row where the player wants to put a mark
*/
private int getColumn( char player )
{
String input =
JOptionPane.showInputDialog("Enter column for '" + player + "'" );
if ( input == null || input.equals("") )
System.exit( 0 );
return Integer.parseInt( input );
}


}

Dani AI

Generated

Several concrete bugs explain why getWinner never reports a win. The most important are: wrong array indexing (many places use board[j] instead of the required board[i][j]), a letter-case mismatch between the game loop (which uses lowercase x/o) and getWinner (which checks uppercase), and the row/column logic in getWinner that sums across the whole board instead of checking each row or column independently. was right to point out the case mismatch; that one alone will prevent any match from being found.

Practical fixes to make first:

  • Initialize and access the 2D array with two indices everywhere: board[i][j]. Fix the constructor, set, and toString so each cell is set/read as board[row][col].
  • Make sure empty cells are a known value (e.g. a space ' '), or explicitly check for the default \0.
  • In set, check the cell with board[i][j] before writing and use bounds tests like i < 0 || i >= ROWS.
  • Replace the aggregated-count approach in getWinner with per-row / per-column checks and handle diagonals explicitly. Also correct the duplicated/incorrect conditional (the code repeats Ocol and compares with > 3).

A compact pattern that reliably finds a winner (use this logic inside getWinner) is:

for (int r = 0; r < ROWS; r++) {
  char m = board[r][0];
  if (m != ' ' && m == board[r][1] && m == board[r][2]) return m;
}
for (int c = 0; c < COLUMNS; c++) {
  char m = board[0][c];
  if (m != ' ' && m == board[1][c] && m == board[2][c]) return m;
}
char m = board[1][1];
if (m != ' ' && ((m == board[0][0] && m == board[2][2]) || (m == board[0][2] && m == board[2][0])))
  return m;
return ' ';

Quick debugging tips: print the board after each move, log the character codes if a case/initialization problem is suspected, and write a short test sequence that creates a known row/col/diagonal win to verify getWinner. Mention 's current game loop uses lowercase marks, so either change the game to use uppercase consistently or make getWinner check lowercase.

Maybe you should test lowercase letters instead of uppercase?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.