Search code examples
javaswinguser-interfacejbuttontic-tac-toe

Tic-Tac-Toe VS. CPU Mode stopping after 3-4 turns played (JAVA SWING)


I've made a Tic-Tac-Toe game, and yes some of you probably think my program is not very good. I am a new programmer and have never used swing or anything related to a JAVA GUI before this game. The program works, MOSTLY. When you compile and run it, and click player vs computer, the game gets stuck after 3-4 turns. I've been trying to figure out what the problem is for hours and can't seem to figure it out. The code is quite long... Any help is appreciated!

Here is the code: http://txt.do/6dvm


Solution

  • your computers logic is a bit... flawed:

    int row = (int)(2*Math.random())+1;
    int column = (int)(2*Math.random())+1;
    while (button[row][column].isEnabled()==false)
    {
      row = (int)(2*Math.random())+1;
      column = (int)(2*Math.random())+1;
    }
    

    in an array of size 3x3 do you see any problem with the numbers its generating? What I see here is numbers 1<=x<=2 being generated. What that means is nothing in column 1 (or array index of 0) ever being chosen. What this means is when all locations other than the first row and column are taken you get stuck in an endless loop. The logic should read:

    int row = (int)(3*Math.random());
    int column = (int)(3*Math.random());
    while (button[row][column].isEnabled()==false)
    {
      row = (int)(3*Math.random());
      column = (int)(3*Math.random());
    }
    

    or better:

    int row, column;
    do
    {
      row = (int)(3*Math.random());
      column = (int)(3*Math.random());
    } while (!button[row][column].isEnabled()); // stop with the == boolean
    

    this still leaves you with and infinite loop if no rows are enabled and a very bad implementation of a random selection that could take a while, heres a better way:

    // list containing available locations for the computer to choose
    java.util.List<int[]> availableIndexes = new java.util.ArrayList<int[]>();
    
    // go through all our buttons and make a list of ones that are enabled
    for(int r=0;r<button.length;r++) {
        for(int c=0;c<button[r].length;c++) {
            if(button[r][c].isEnabled()) {
                availableIndexes.add(new int[]{r, c});
            }
        }
    }
    
    // see if we can even do anything
    if(availableIndexes.isEmpty()) {
        // cats game, i dont know what you want to do there....
    } else {
        // choose one of our avaible buttons at random
        int [] randomButtonIndex = availableIndexes.get((int)(Math.random()*availableIndexes.size()));
        int row = randomButtonIndex[0];
        int column = randomButtonIndex[1];
    
    
        // .... continue what you were doing
    }
    


    Some other stuff from comments I saw:

    • Learn to use an IDE, Netbeans, IntelliJ or Eclipse are good ones to look at.
    • Use data structures, loops and methods to your advantage. Things like button[0][0].addActionListener(new playerVSComputer()); button[0][1].addActionListener(new playerVSComputer());.... can be done with a loop and will help your code become more clear.

    For further help try posting a question on the code review section of stack exchange.