Java: Connect 4 Diagonal Win

I recently made a Connect4 game and my Connect4 did not win the game when it was pointed diagonally to the right. And it only works for some combinations when it is linked diagonally to the left. Coordinates: - Top left: (0,0), Bottom left: (5.0), Top right: (0.6), Bottom right: (5.6). Connect4 board is 6 by 7.

Problem: Joining diagonally to the left only works fine for some combinations. But none of the diagonally connected connections work properly.

/** A method of winning diagonally towards the left side when playing connect 4 two player*/
/** Giving the new method with all the possible possibilities for a user to win diagonally-left */
public static void diagWinningLeft() {
    for (int x = 5; x > 2; x--) { // Checks to see if same colored pegs are lining diagonally to the left
        for (int y = 6; y > 3; y--) {
            if (board[x][y] == 1 && board[x - 1][y - 1] == 1 && board[x - 2][y - 2] == 1 && board[x - 3][y - 3] == 1) {
                JOptionPane.showMessageDialog(null, playerNames[0]+" has connected four diagonally-left in a row in " +(countForRed)+ " turns!");
                b.drawLine(x,y,x-3,y-3);
            }
            if (board[x - 1][y - 1] == 1 && board[x - 2][y - 2] == 1 && board[x - 3][y - 3] == 1 && board[x - 4][y - 4] == 1) {
                JOptionPane.showMessageDialog(null, playerNames[0]+" has connected four diagonally-left in a row in " +(countForRed)+ " turns!");
                b.drawLine(x,y,x-3,y-3);
            }

            if (board[x][y] == 2 && board[x - 1][y - 1] == 2 && board[x - 2][y - 2] == 2 && board[x - 3][y - 3] == 2) {
                JOptionPane.showMessageDialog(null, playerNames[1]+ " has connected four diagonally-left in a row in " +(countForYellow)+ " turns!");
                b.drawLine(x,y,x-3,y-3);
            }
        }
    }
}

/** Another method of winning diagonally towards the right side when playing connect 4 two player*/
/** Giving the new method with all the possible possibilities for a user to win diagonally-right*/
public static void diagWinningRight()  {
    for (int x = 0; x < 2; x++) { // Check to see if same colored pegs are lining diagonally to the right
        for (int y = 0; y < 3; y++) {
            if (board[x][y] == 1 && board[x + 1][y + 1] == 1 && board[x + 2][y + 2] == 1 && board[x + 3][y + 3] == 1) {
                JOptionPane.showMessageDialog(null, playerNames[0]+" has connected four diagonally-right in a row in " +(countForRed)+ " turns!");
            }
            if (board[x][y] == 2 && board[x + 1][y + 1] == 2 && board[x + 2][y + 2] == 2 && board[x + 3][y + 3] == 2) {
                JOptionPane.showMessageDialog(null, playerNames[1]+" has connected four diagonally-right in a row in " +(countForYellow)+ " turns!");
            }

        }
    }
}

      

+3


source to share


2 answers


Forgive me for not answering this question directly, but this is stuff that will help you fix it and get better code and better code writing in the future.

Extracting the logic of your if condition into a separate method makes it easier to think about that logic yourself and allows you to test it independently of the rest of the program.

So instead of:

  if (board[x][y] == 1 && board[x - 1][y - 1] == 1 && board[x - 2][y - 2] == 1 && board[x - 3][y - 3] == 1) {
       JOptionPane.showMessageDialog(...)
  }

      

... use:

 if(isDiagonalLeft(x,y,1) { ... }

      

... and ...

 boolean isDiagonalLeft(int x, int y, int player) {
      return board[x][y] == player && 
             board[x - 1][y - 1] == player  && 
             board[x - 2][y - 2] == player  && 
             board[x - 3][y - 3] == player 
 }

      

Now you can run unit tests on isDiagonalLeft () to make sure it works. That is, the little program that sets up the board and runs it, isDiagonalLeft (), to make sure it gives the right answer under various circumstances. It looks like extra work, but most people who try to find out are that it saves effort by catching mistakes earlier.

What you did was to separate the game logic somewhat from the presentation code (JOptionPane) so that the presentation code isn't the same when you just want to use the game logic. Later in your programming studies, you will come across the possibility of separating them even more, for example the Model-View-Controller model.



Pulling logic also helps if you need to ask questions about stack overflows - by separating game logic from Swing, you open the question to potential responders who know nothing about Swing.

And you can reuse this method once for each player, rather than copying the logic into two places like you do.

If that doesn't work, use the debugger in your IDE to step through it.

Now that you've done that, you can improve on this method so that the computer does the decrement instead of the programmer ...

  boolean isDiagonalLeft(int x, int y, int player) {
       for(int i = 0; i<4; i++) {
           if(board[x-i][y-i] != player) {
               return false;
           }
       }
       return true;
  }

      

... and you can generalize it to cover both directions of the diagonal:

  boolean isDiagonal(int x, int y, int player, boolean direction) {
       int dirUnit = direction ? -1 : 1;
       for(int i = 0; i<4; i++) {
           if(board[x-i][y + dirUnit] != player) {
               return false;
           }
       }
       return true;
  }

      

... so you can now reuse the method in 4 places; for every player and for every direction.

When you come across a situation where it doesn't work in your GUI, run unit tests that install the board as it is in the GUI and run on it isDiagonal()

. If the test passes, you know the problem is somewhere else. If the test fails, you can work with the debugger and method code to make it pass.

+3


source


The following code should work:



//Winning diagonally towards left
public static void diagWinningLeft() {
    for (int x = 5; x > 2; x--) { // Checks to see if same colored pegs are lining diagonally to the left
        for (int y = 6; y > 2; y--) {
            if (board[x][y] == 1 && board[x - 1][y - 1] == 1 && board[x - 2][y - 2] == 1 && board[x - 3][y - 3] == 1) {
                JOptionPane.showMessageDialog(null, playerNames[0]+" has connected four diagonally-left in a row in " +(countForRed)+ " turns!");
                b.drawLine(x,y,x-3,y-3);
            }
            if (board[x][y] == 2 && board[x - 1][y - 1] == 2 && board[x - 2][y - 2] == 2 && board[x - 3][y - 3] == 2) {
                JOptionPane.showMessageDialog(null, playerNames[1]+ " has connected four diagonally-left in a row in " +(countForYellow)+ " turns!");
                b.drawLine(x,y,x-3,y-3);
            }
        }
    }
}

//Winning diagonally towards right
public static void diagWinningRight()  {
    for (int x = 5; x > 2; x--) { // Check to see if same colored pegs are lining diagonally to the right
        for (int y = 0; y < 4; y++) {
            if (board[x][y] == 1 && board[x - 1][y + 1] == 1 && board[x - 2][y + 2] == 1 && board[x - 3][y + 3] == 1) {
                JOptionPane.showMessageDialog(null, playerNames[0]+" has connected four diagonally-right in a row in " +(countForRed)+ " turns!");
            }
            if (board[x][y] == 2 && board[x - 1][y + 1] == 2 && board[x - 2][y + 2] == 2 && board[x - 3][y + 3] == 2) {
                JOptionPane.showMessageDialog(null, playerNames[1]+" has connected four diagonally-right in a row in " +(countForYellow)+ " turns!");
            }
        }
    }
}
      

Run codeHide result


The problem with your code was that when checking to the right, your coordinates (indices) kept checking the direction to the left (since there are 4 diagonals from [x] [y], and [x-1] [y- 1], a [x + 1] [y + 1] forming a diagonal in the NW-SE (or left diagonal) direction and [x-1] [y + 1], and [x + 1] [y-1] making a diagonal in the NE- direction SW (or right diagonal)).
Also, your inner loop did not go out of bounds. Hand, diagWinningLeft () didn't work at times ..

0


source







All Articles