1

I am writing a basic Tic-Tac-Toe Single player game using basic swing graphics. I completed the game, but there is a weird problem I am facing. At one place, I used a while loop with a SOP statement. If I omit this statement, program works differently and nothing happens (like some kind of infinite loop), and if I keep it, it works just fine. I don't know what's happening in the code. Please help.

Below is the source code which causing problem. Sorry for my amateur coding style.

import java.util.Random;

public class SinglePlayer implements Runnable{

    public final int MINIMUM = -1000000;
    private GameBoard game;

    public SinglePlayer(){
        game = new GameBoard("Single Player");
    }

    public static void main(String[] args){
        SinglePlayer gameSingle = new SinglePlayer();
        gameSingle.run();
    }

    public void run(){
        boolean machinePlayed = true, userPlayed = false;

        // Outer loop is to maintain re-match option of program
        while(this.game.quitTwoPlayer == false){
            // Inner loop is a single game b/w user and machine
            while(this.game.GameQuitStatus() == false){

                /* I kept two conditions to switch b/w machine and user mode 
                 * of game and they just keep changing to simulate the game
                 * b/w machine and user.
                 */
                if(machinePlayed == false && userPlayed){
                    try {
                        MachineMove("O");
                    } catch (CloneNotSupportedException e) {
                        e.printStackTrace();
                        break;
                    }
                    this.game.ChangePlayerLabels();
                    machinePlayed = true;
                    userPlayed = false;
                }
                else if(machinePlayed && userPlayed == false){
                    int earlierCount = this.game.CountSteps();

                    /* THIS IS THE WHILE LOOP I AM TALKING ABOUT. 
                     * If I omit the print statement inside the body of loop,
                     * program behaves differently, but when I keep it,
                     * it working just fine. 
                     * */ 
                    while(earlierCount == this.game.CountSteps()){
                        System.out.println("Player User thinking");
                    }

                    this.game.ChangePlayerLabels();
                    machinePlayed = false;
                    userPlayed = true;                  
                }
                this.game.DeclareResult();
            }
            this.game.dispose();
        }
    }

    public void MachineMove(String player) throws CloneNotSupportedException{

        /* If board is empty, play at center of the board */
        if(this.game.CountSteps() == 0){
            this.game.MakeMove(1, 1);
        }

        /* If center is blank, play it there. Otherwise, pick a corner randomly */
        else if(this.game.CountSteps() == 1){
            if(this.game.IsEmpty(1, 1))
                this.game.MakeMove(1, 1);
            else{
                Random randomNum = new Random();
                int num = randomNum.nextInt(4);
                if(num == 0)
                    this.game.MakeMove(0, 0);
                else if(num == 1)
                    this.game.MakeMove(2, 0);
                else if(num == 2)
                    this.game.MakeMove(0, 2);
                else if(num == 3)
                    this.game.MakeMove(2, 2);
            }
        }
        else{           
            /* If the next move is such that it should be taken, otherwise opponent will win */
            String opponent = "";
            if(this.game.GetCurrentPlayer().equals("O"))
                opponent = "X";
            else
                opponent = "O";
            for(int i = 0; i<3; i++){
                for(int j = 0; j<3; j++){
                    if(this.game.IsEmpty(i,j)){
                        GameBoard tempGame = new GameBoard(this.game, "Single Player");
                        tempGame.MakePossibleMove(i, j, opponent);
                        if(tempGame.GameWinner().equals(opponent + " wins")){
                            this.game.MakeMove(i,j);
                            return;
                        }
                    }
                }
            }

            /* If the next move is not such that if missed, game is lost, then play most optimal move towards winning */
            Move tempMove = new Move(MINIMUM, 0, 0);
            Move bestMove = new Move(MINIMUM, 0, 0);
            for(int i = 0; i<3; i++){
                for(int j = 0; j<3; j++){
                    if(this.game.IsEmpty(i,j)){
                        GameBoard tempGame = new GameBoard(this.game, "Single Player");
                        tempMove = MakeMoves(tempGame, i, j);
                        if(tempMove.score > bestMove.score){
                            bestMove.row = tempMove.row;
                            bestMove.col = tempMove.col;
                            bestMove.score = tempMove.score;
                        }
                    }
                }
            }
            this.game.MakeMove(bestMove.row, bestMove.col);
        }
    }

    public Move MakeMoves(GameBoard tempGame, int row, int col){
        String player = tempGame.GetCurrentPlayer(); 
        tempGame.MakeMove(row, col);
        if(tempGame.GameWinner().equals("Match Draw")){
            return new Move(0, row, col);
        }
        else if(tempGame.GameWinner().equals("X wins")){
            if(player.equals("X")){ 
                return new Move(1, row, col);
            }
            else{
                return new Move(-1, row, col);
            }
        }
        else if(tempGame.GameWinner().equals("O wins")){
            if(player.equals("O")){
                return new Move(1, row, col);
            }
            else{
                return new Move(-1, row, col);
            }
        }
        else{
            Move bestMove = new Move(MINIMUM, 0, 0);
            Move tempBestMove = new Move(0, 0, 0);
            for(int i = 0; i<3; i++){
                for(int j = 0; j<3; j++){
                    if(tempGame.IsEmpty(i,j)){
                        GameBoard newGame = new GameBoard(tempGame, "Single Player");
                        tempBestMove = MakeMoves(newGame, i, j);
                        if(tempBestMove.score > bestMove.score)
                            bestMove = tempBestMove;
                    }
                }
            }
            return bestMove;
        }
    }
}

class Move{
    public int score;
    public int row;
    public int col;

    public Move(int score, int row, int col){
        this.score = score;
        this.row = row;
        this.col = col;
    }
}

1 Answers1

3

Your loop is likely typing up your processor, and the SOP slows the loop enough to allow other processes to occur. But regardless and most importantly, you don't want to have this loop present in the first place. You state that you have a,

Tic-Tac-Toe Single player game using basic swing graphics

Remember that Swing is an event driven GUI library, so rather than loop as you would in a linear console program, let events occur, but respond to them based on the state of the program.

In other words, give your class several fields including a boolean variable that tells whose turn it is, such as boolean playersTurn, a boolean variable gameOver, ..., and change the state of these variables as the game is played, and base the games behavior depending on these states. For instance the game would ignore the player's input if it was not his turn.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373