Hi all, I have just finished with my tict-tac-toe program, and I thought I'd post it here if anybody fancy giving
me any feedback. Also, I have a problem with printing the board, probably due to my lack of knowledge in using printf as opposed to println.
Anyway this is the method that prints off the board:

//print board
public void printBoard(){
    System.out.print("\n\n\n\n\n");
    System.out.println("|   " + board[0][0] + "   |   " + board[0][1] + "   |   " + board[0][2] + "   |");
    System.out.println("|   " + board[1][0] + "   |   " + board[1][1] + "   |   " + board[1][2] + "   |");
    System.out.println("|   " + board[2][0] + "   |   " + board[2][1] + "   |   " + board[2][2] + "   |");
    System.out.print("\n\n\n\n\n");
    /* System.out.printf( "%s%d%s%d%s%d%s " ) */
}

Let me give you a bit of background info first: if a square is empty it will have EMPTY printed on it, otherwise it will get a X or a O. I bet you can see the problem already. If an EMPTY is replaced by a X or O the layout of my board is completely messed up:

|   EMPTY   |   0   |   EMPTY   |
|   EMPTY   |   EMPTY   |   EMPTY   |
|   EMPTY   |   EMPTY   |   EMPTY   |

So I have to try to make sure that the same space is preserved whether I have a symbol or an EMPTY in there.
I know I have to use the printf method to achieve that but the thing is EMPTY is of type enum and I am not quite sure how to print that. As you can see I have started my attemp to use the printf method
/* System.out.printf( "%s%d%s%d%s%d%s " ) */
but I am not sure this will work. Surely the "|" can be printed as a string but how about board[n][n]?
Any help is obviously much appreciated as usual

I wanted to attach the fiels but it looks like I am not allowed so -sorry - I paste them in here (or alternatively you can try these 2 links to some kind of online compiler I found, not sure if that will work:
http://ideone.com/BveyvU
http://ideone.com/dlM0VB
):

/*TicTacToeTest.java*/
import java.util.Scanner;

public class TicTacToeTest{

    public static void main( String[] args ){
    boolean isFull = false;//if true all the squares have been assigned.
    boolean isDraw = false;//to check if the game is draw
    boolean squareStatus = false;//returns the status of a square, if false the square is full if true the square is empty
    boolean victory = false;//if returns true one of the players has won
    int playerCounter = 1;//if it is odd it's player1's turn if even it's player2's turn
    int rowInput;
    int colInput;
        Scanner input = new Scanner( System.in );
        TicTacToe myTicTacToe = new TicTacToe();//create object
        myTicTacToe.printBoard();
        while( !isFull ){
            isDraw = myTicTacToe.isDraw();
            if( isDraw ){
                System.out.println( "The game is draw!\n" );
                //print board
                //myTicTacToe.printBoard();
                break;
            }
            //print board
            //myTicTacToe.printBoard();
            //System.out.println("the number is " + playerCounter );
            if( !(myTicTacToe.isOdd( playerCounter ))){//player 1
                System.out.println( "\nPlayer 1: enter the coordinates of the square.\nRow and column - values between 1 and 3." );
            }
            else{//player 2
                System.out.println( "\nPlayer 2: enter the coordinates of the square.\nRow and column - values between 1 and 3." );
            }
            System.out.println( "\nRow: " );
            rowInput = input.nextInt();
            System.out.println( "\nColumn: " );
            colInput = input.nextInt();
            rowInput = myTicTacToe.optimizeInput( rowInput );//to subtract 1 from the input
            colInput = myTicTacToe.optimizeInput( colInput );//to subtract 1 from the input

            //check input
            squareStatus = myTicTacToe.checkSquare( rowInput, colInput );
            //if the square is taken - true - input again row and column till you find a free one
            while( squareStatus ){
                System.out.println( "Square taken, try again. \nEnter the coordinates of the square.\nRow and column - values between 1 and 3." );
                System.out.println( "\nRow: " );
                rowInput = input.nextInt();
                System.out.println( "\nColumn: " );
                colInput = input.nextInt();
                rowInput = myTicTacToe.optimizeInput( rowInput );//to subtract 1 from the input
                colInput = myTicTacToe.optimizeInput( colInput );//to subtract 1 from the input
                //check input
                squareStatus = myTicTacToe.checkSquare( rowInput, colInput );
            }
            //assign the symbol to the chosen square
            myTicTacToe.assignSymbol( rowInput, colInput, playerCounter );
            //print board
            myTicTacToe.printBoard();
            //check for draw
            victory = myTicTacToe.checkVictory( rowInput, colInput, playerCounter );
            //player 1
            if(( victory ) && ( myTicTacToe.isOdd( playerCounter ) )){
                System.out.println( " Player 1 wins!" );
                //print board
                //myTicTacToe.printBoard();
                break;
            }
            //player2
            else if(( victory ) && !( myTicTacToe.isOdd( playerCounter ) )){
                System.out.println( " Player 2 wins!" );
                //print board
                myTicTacToe.printBoard();
                break;
            }           
            playerCounter++;//increment counter to change player's turn
        }//end while loop
    }//end main 
}//end TicTacToeTest class

and the other one

/*TicTacToe.java*/
public class TicTacToe{ 
    //private boolean isFull = false;//if true all the squares have been assigned.
    //private int playerCounter = 1;//if it is odd it's player1's turn if even it's player2's turn
    private TicTacToeEn[][] board = new TicTacToeEn[3][3];//to represent the 3-by-3 board

    //private boolean isDraw;//to check if the game is draw
    //private boolean squareStatus;//returns the status of a square, if false the square is full if true the square is empty
    //private boolean victory;//if returns true one of the players has won  
    //private int row;//row of the 3-by-3 board
    //private int column;//column of the 3-by-3 board   
    //private int gameCounter;//counts the moves


    public enum TicTacToeEn{
        X, O, EMPTY 
    }//end of enum
    TicTacToeEn theSymbol;//of type enum holds the current theSymbol, X or O 
    //constructor
    public TicTacToe(){
        for( int i = 0; i < board.length; i++ ){
            for( int j = 0; j < board[i].length; j++ ){
                board[i][j] = TicTacToeEn.EMPTY;
            }//columns
        }//rows         
    }//end of constructor

    //checks if square is empty
    public boolean checkSquare( int row, int column ){
        if(board[row][column] == TicTacToeEn.EMPTY){
            return false;
        }
        else{
            return true;
        }       
    }//end of checkSquare()

    //assigns X or O to the square
    public void assignSymbol( int row, int column, int counter ){
        if( isOdd( counter )){//it's player1
            board[row][column] = TicTacToeEn.X;     
        }
        else{//it's player2
            board[row][column] = TicTacToeEn.O;     
        }
    }//end of assignSymbol()

    //check if the game is draw
    public boolean isDraw(){
        for( int i = 0; i < board.length; i++ ){
            for(int j = 0; j < board[i].length; j++ ){
                if( board[i][j] == TicTacToeEn.EMPTY ){//if there is an empty square
                    return false;
                }               
            }//end of column array
        }//end of row array
        return true;//if there isn't an empty square
    }//end of isDraw()

    //checks if anybody has won the game
    public boolean checkVictory( int row, int column, int counter ){
        if( isOdd( counter )){//it's player1
            theSymbol = TicTacToeEn.X;
        }
        else{//it's player2
            theSymbol = TicTacToeEn.O;
        }
        //determine victory
        if( 
            ( board[row][0] == theSymbol && board[row][1] == theSymbol &&   board[row][2] == theSymbol )//check 3-in-the-row horizontally   
            ||  ( board[0][column] == theSymbol && board[1][column] == theSymbol && board[2][column] == theSymbol )//check 3-in-the-row vertically          
            ||  ( board[0][0] == theSymbol && board[1][1] == theSymbol && board[2][2] == theSymbol )//check 3-in-the-row 1st diagonal           
            ||  ( board[0][2] == theSymbol && board[1][1] == theSymbol && board[2][0] == theSymbol )//check 3-in-the-row 2nd diagonal
        ){
            return true;
        }

        else{
            return false;
        }       
    }//end of checkVictory()

    //determine if the argument is odd or even
    public boolean isOdd( int number){
        if( number % 2 == 0){//it's even
            return true;
        }
        else{//it's odd
            return false;
        }
    }//end of isOdd()

    /*get the right input for the array, 
    effectively subtracting 1 to the input so that the 
    index is still within the array range*/
    public int optimizeInput( int theInput ){
            int newInput = theInput - 1;
            return newInput;
    }

    //print board
    public void printBoard(){
        System.out.print("\n\n\n\n\n");
        System.out.println("|   " + board[0][0] + "   |   " + board[0][1] + "   |   " + board[0][2] + "   |");
        System.out.println("|   " + board[1][0] + "   |   " + board[1][1] + "   |   " + board[1][2] + "   |");
        System.out.println("|   " + board[2][0] + "   |   " + board[2][1] + "   |   " + board[2][2] + "   |");
        System.out.print("\n\n\n\n\n");
        /* System.out.printf( "%s%d%s%d%s%d%s " ) */
    }
}//end of class

Recommended Answers

All 8 Replies

There's no problem using an s format for enums - print will actually use the enum's .toString() anyway, so you can use a fixed-width string format like
printf("| %6s | %6s | %6s |", board[0][0], board[0][1], board[0][2])
Where it all falls down is if you want to center the shorter strings in their width - there's no format for that so you have to do tacky stuff with calculating how many blanks to add (AFAIK)

ps
boolean squareStatus = false;// needs comment because you have no idea what true or false would mean much better just to give it a good name, egboolean squareIsFull = false; // obvious what that means!`

Fab thanks. I have changed the boolean variable to a the one you suggested and I have used the printf as indicated, it works great. Can I ask you a few questions about it? Like, that 6 number means that it will print 6 characters right? If it's less than 6 it will justify the text on the right?

The details are available here: http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html

Format specifiers look like this: %[argument_index$][flags][width][.precision]conversion

The number 6 is in the [width] position, which means that 6 is the minimum number of characters in the result. If the argument string has 6 characters or more, the argument string will be output as it is, no matter how long. If the argument string is less than 6 long, then spaces will be inserted on the left side to make the output 6 characters long. You can include - in the [flags] position if you want the spaces to be on the right side.

right so essentially the width is a kind of tipping point before which the output is forced to justify.
I was just wondering, do you guys reckon Ishould test the input as well? I mean I have no idea how to it at this stage, but do you think it is something I should look into and implement on the program? So something like if users insert a letter or a number bigger than 3 they get a message saying input non valid try again?

It's always a good idea to protect your program from bad user input. The alternative is just to let it all crash, which will upset the user and reflect badly on your programming skills!
It's not hard - a simple loop that keeps prompting the user and validating the input until the input is valid. You are going to have to do this in almost every program you write, so it's a bit of an effort to get it right the first time, but then you'll know how to do it and the rest will be easy.

I am happy to do it, sure. I will gather some info, have a look online and try to understand what to do, but I suspect I will need some help with it considering what I have seen so far. I will give it a go first of course. Should I start a new thread just for validation? It probably makes sense!

A new thread sounds like a good idea - the question is relevent to so many applications other than just t-t-t

ok fab, will do that, thanks a lot for your help!

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.