How to make a Tic Tac Toe (noughts and crosses) game in Java


Learn how to make the Tic Tac Toe game in Java! Commented and well explained code!It's time to put our knowledge into practice to do something really cool and useful:
The Tic Tac Toe game in Java! Also known as noughts and crosses!

This is a simple version, to be played with two people. Note that in a simple Java application like this, the result came out around 300 lines of code.

If you are Java programmer, click to see the full commented code and explanation about the Tic Tac Toe Java Game creation.

Yes, there is a strategy we can adopt (or the computer may adopt) to never lose a game of tic tac toe:
http://en.wikipedia.org/wiki/Tic-tac-toe

How to play our Tic Tac Toe game made in Java

First, as this version is simpler, you can only play Human vs Human. Soon we will teach how to program the computer to play.

So choice as Player 1 and Player 2 as humans.
After that, just select the line and column of the board where you want to play.
Recalling that Player 1 is always the 'X' and Player 2 is always the 'O'.

After that, just play normally. When the player complete a line, column or diagonal, the game stops.
O when the tray is full and a tie happens.

For Java programmers: How to create a Tic Tac Toe in Java


Our Tic Tac Toe game have over 300 lines of Java code, we will explain each class, method and idea in another post:
Code about how to create the Tic Tac Toe in Java


Code Java Tic Tac Toe, text mode Human x Human


Create a project named 'TicTacToe', and add the following 6 classes, run and be happy.


-->TicTacToe.java


public class TicTacToe {

    public static void main(String[] args) {
        Game game = new Game();
        
    }
}


-->Board.java

public class Board {
    private int[][] Board= new int[3][3];
    
    public Board(){
        clearBoard();
    }
    
    public void clearBoard(){
        for(int line=0 ; line<3 ; line++)
            for(int column=0 ; column<3 ; column++)
                Board[line][column]=0;
    }
    
    public void showBoard(){
        System.out.println();
        for(int line=0 ; line<3 ; line++){
        
            for(int column=0 ; column<3 ; column++){
                
                if(Board[line][column]==-1){
                    System.out.print(" X ");
                }
                if(Board[line][column]==1){
                    System.out.print(" O ");
                }
                if(Board[line][column]==0){
                    System.out.print("   ");
                }
                
                if(column==0 || column==1)
                    System.out.print("|");
            }
            System.out.println();
        }
                
    }

    public int getPosition(int[] attempt){
        return Board[attempt[0]][attempt[1]];
    }
    
    public void setPosition(int[] attempt, int player){
        if(player == 1)
            Board[attempt[0]][attempt[1]] = -1;
        else
            Board[attempt[0]][attempt[1]] = 1;
    }

    public int checkLines(){
        for(int line=0 ; line<3 ; line++){

            if( (Board[line][0] + Board[line][1] + Board[line][2]) == -3)
                return -1;
            if( (Board[line][0] + Board[line][1] + Board[line][2]) == 3)
                return 1;
        }
        
        return 0;
                
    }
    
    public int checkColumns(){
        for(int column=0 ; column<3 ; column++){

            if( (Board[0][column] + Board[1][column] + Board[2][column]) == -3)
                return -1;
            if( (Board[0][column] + Board[1][column] + Board[2][column]) == 3)
                return 1;
        }
        
        return 0;
                
    }
    
    public int checkDiagonals(){
        if( (Board[0][0] + Board[1][1] + Board[2][2]) == -3)
            return -1;
        if( (Board[0][0] + Board[1][1] + Board[2][2]) == 3)
            return 1;
        if( (Board[0][2] + Board[1][1] + Board[2][0]) == -3)
            return -1;
        if( (Board[0][2] + Board[1][1] + Board[2][0]) == 3)
            return 1;
        
        return 0;
    }

    public boolean fullBoard(){
        for(int line=0 ; line<3 ; line++)
            for(int column=0 ; column<3 ; column++)
                if( Board[line][column]==0 )
                    return false;
        return true;
    }
}


-->Game.java
import java.util.Scanner;

public class Game {
    private Board board;
    private int turn=1, who=1;
    private Player player1;
    private Player player2;
    public Scanner input = new Scanner(System.in);

    
    public Game(){
        board = new Board();
        startPlayers();
        
        while( Play() );
    }
    
    public void startPlayers(){
        System.out.println("Who will be player1 ?");
        if(choosePlayer() == 1)
            this.player1 = new Human(1);
        else
            this.player1 = new Computer(1);
        
        System.out.println("----------------------");
        System.out.println("Who will be Player 2 ?");
        
        if(choosePlayer() == 1)
            this.player2 = new Human(2);
        else
            this.player2 = new Computer(2);
        
    }
    
    public int choosePlayer(){
        int option=0;
        
        do{
            System.out.println("1. Human");
            System.out.println("2. Computer\n");
            System.out.print("Option: ");
            option = input.nextInt();
            
            if(option != 1 && option != 2)
                System.out.println("Invalid Option! Try again");
        }while(option != 1 && option != 2);
        
        return option;
    }
    
    public boolean Play(){
        board.showBoard();
        if(won() == 0 ){
            System.out.println("----------------------");
            System.out.println("\nTurn "+turn);
            System.out.println("It's turn of Player " + who() );
            
            if(who()==1)
                player1.play(board);
            else
                player2.play(board);
            
            
            if(board.fullBoard()){
                System.out.println("Full Board. Draw!");
                return false;
            }
            who++;
            turn++;

            return true;
        } else{
            if(won() == -1 )
                System.out.println("Player 1 won!");
            else
                System.out.println("Player 2 won!");
            
            return false;
        }
            
    }
    
    public int who(){
        if(who%2 == 1)
            return 1;
        else
            return 2;
    }
    
    public int won(){
        if(board.checkLines() == 1)
            return 1;
        if(board.checkColumns() == 1)
            return 1;
        if(board.checkDiagonals() == 1)
            return 1;
        
        if(board.checkLines() == -1)
            return -1;
        if(board.checkColumns() == -1)
            return -1;
        if(board.checkDiagonals() == -1)
            return -1;
        
        return 0;
    }
    
    
}


-->Player.java


public abstract class Player {
    
    protected int[] attempt = new int[2];
    protected int player;

    
    public Player(int player){
        this.player = player;
    }
    
    public abstract void play(Board board);
    
    public abstract void Try(Board board);

    public boolean checkTry(int[] attempt, Board board){
        if(board.getPosition(attempt) == 0)
            return true;
        else
            return false;
            
    }
    
}

-->Human.java


import java.util.Scanner;

public class Human extends Player{
    public Scanner input = new Scanner(System.in);
    
    public Human(int player){
        super(player);
        this.player = player;
        System.out.println("Player 'Human' created!");
    }
    
    @Override
    public void play(Board board){
        Try(board);
        board.setPosition(attempt, player);
    }
    
    @Override
    public void Try(Board board){
        do{
            do{
                System.out.print("Line: ");
                attempt[0] = input.nextInt();
                
                if( attempt[0] > 3 ||attempt[0] < 1)
                    System.out.println("Invalid line. It's 1, 2 or 3");
                
            }while( attempt[0] > 3 ||attempt[0] < 1);
            
            do{
                System.out.print("Column: ");
                attempt[1] = input.nextInt();
                
                if(attempt[1] > 3 ||attempt[1] < 1)
                    System.out.println("Invalid column. É 1, 2 or 3");
                
            }while(attempt[1] > 3 ||attempt[1] < 1);
            
            attempt[0]--; 
            attempt[1]--;
            
            if(!checkTry(attempt, board))
                System.out.println("Placed already marked. Try other.");
        }while( !checkTry(attempt, board) );
    }
}




-->Computer.java


public class Computer extends Player{
    
    public Computer(int player){
        super(player);
        System.out.println("Player 'Computer' created");
    }
    
    @Override
    public void play(Board board){
        
    }
    
    @Override
    public void Try(Board board){
        
    }
}

14 comments:

Anonymous said...

Very good and well explained! Such a Java lesson!

1039141805 said...

Hi there, how would you go about changing this to a person vs person game rather than human vs computer?

Unknown said...

Hey Man,
Congo!!!!! u did a great job the code is quite simple and easy to understand for the beginner of java..
but u have not added anything when when one want to compete against a computer..
so here the code goes::::::::
Features of the code.......
1. one can against another human or a computer or even take experience by competing two computer players against each other :P :P :P
2. when a Human competes against a computer he can choose difficulty level.
if he/she choose easy level computer choose a number between 0 to 9.... if it choose less than 5 it will play wise game otherwise play random game
if he/she choose medium level
upto 7 it will play wise game, otherwise random game
in hard level upto 8 computer will play wise game and for 9 it will play random game
3.when computer choose to play wise game it can win in game or worst case is TIE of that game
means a computer can never be beatable if he choose wise play
4. if computer choose random game he will choose random square when ooponent have no chance of winning(means when sum of any row,column,diagonal is not 2 if opponent is player 1 or -2 when opponent is player2)
5.also if one choose has first chance in a game and he is not able to win in that game opponent player will have 1st chance to go in next game
6.one can play the number of matches with same player until he does not want

Progressive Java said...

Hi Vijender!

We're a little busy in college now, so we take some time until we post the remaining code.

So, we would like to receive your code, surely.
Please, send a e-mail to: java.progressivo [a] gmail .com

With the code, your nome and site (if you have one), that we will format, comment and add here for everybody.

Drama World said...

hey! its too easy to understand.

Drama World said...

its too easy to understand.....

Anonymous said...

i want to know how to implements the Computer class using Minimax algorithm?
can you learn to us?

thanks! ;D

Reyhan Bhaskara said...

Thank's bro ur code is easy to understand for newbie programmer like me...XD

Haxcoder said...

hey! bro? i'm a newbie, could give me link for the installer for coding the codes you presented?

Anonymous said...

Can i get tic-tac-toe human Vs human code?

Matthew said...

The game logic is excellent (using an array of ints sure beats what I was thinking originally) but there is a problem with the algorithm that determines a tied game. If the game is manipulated to fill the board in a certain way (X1,1; Y2,1; X1,2; Y2,2; X2,3; Y3,3; X3,2; Y3,1; X1,3), this should end with X winning across the top, but the game says it ends in a tie. A better way might be to run a scan looking for any remaining zeros in the array. If there are no winners and no zeros left, then it is a tie. Keep in mind that no human (who even slightly understands Tic-Tac-Toe) would ever play a game like this, but that is our job as programmers to program against the most absurd, right. :)

Matthew said...

After looking at the program again, it looks like if you just move the code block that checks for a full board to after the code block that checks for a winner in the Play() method of the Game.java file, that would squash this bug. Still, thanks for the logic.

Unknown said...

I also tried like this method using minimax algorithm,http://themakeinfo.com/2015/02/ai-based-tic-tac-toe-in-java/

Anonymous said...

Can you please post the computer player code?