-4

So i am having problem checking the winner diagonally in a game called connect 4. I didn't have any problem checking vertically and horizontally. So.. Can u please help me check diagonally?

Code so far:

import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;

public class connectFourDesign extends JPanel { 

  private static final long serialVersionUID = 1L;   

  // Welcome Screen
  private JLabel lblWelcome;

  // Buttons for Welcome Screen
  private JButton playButton;
  private JButton helpButton; 
  private JButton quitButton;  

  // Game Modes  
  private JButton onePlayer;
  private JButton twoPlayer;

  // Go Back Button
  private JButton goBack;    

  private JButton clickMeOne;
  private JButton clickMeTwo;
  private JButton clickMeThree;
  private JButton clickMeFour;
  private JButton clickMeFive;
  private JButton clickMeSix;
  private JButton clickMeSeven;  

  // Grid xSize,ySize and 2D Array
  private int ysize = 7;
  private int xsize = 8;
  private JButton[][] slots;  

  public static void main(String[] args) {

    JFrame frame = new JFrame(" Connect Four ");
    frame.setSize(500, 500);
    frame.getContentPane().add(new connectFourDesign());
    frame.setVisible(true);
    frame.setResizable(false);
  }  

  public connectFourDesign () { 

    setBackground(Color.black);        

    lblWelcome = new JLabel (" Connect 4 ", SwingConstants.CENTER);    
    lblWelcome.setFont(new Font("Astron Boy Rg", Font.ITALIC, 90));
    lblWelcome.setForeground(Color.white);
    add(lblWelcome);
    lblWelcome.setVisible(true);

    playButton = new JButton (" Play ");
    playButton.setFont(new Font("Astron Boy Rg", Font.ITALIC, 75));
    playButton.setBackground(Color.black);
    playButton.setForeground(Color.GREEN);
    add(playButton);
    playButton.setVisible(true);
    playButton.addActionListener(new playButtonListener());

    onePlayer = new JButton (" 1 Player ");
    onePlayer.setFont(new Font("Astron Boy Rg", Font.ITALIC, 55));
    onePlayer.setBackground(Color.black);
    onePlayer.setForeground(Color.GREEN);
    add(onePlayer);
    onePlayer.setVisible(false);
    onePlayer.addActionListener(new onePlayerButtonListener());

    twoPlayer = new JButton (" 2 Player ");
    twoPlayer.setFont(new Font("Astron Boy Rg", Font.ITALIC, 55));
    twoPlayer.setBackground(Color.black);
    twoPlayer.setForeground(Color.GREEN);
    add(twoPlayer);
    twoPlayer.setVisible(false);
    twoPlayer.addActionListener(new twoPlayerButtonListener());     

    helpButton = new JButton ( " Help ");
    helpButton.setFont(new Font("Astron Boy Rg", Font.ITALIC, 75));
    helpButton.setBackground(Color.black);
    helpButton.setForeground(Color.magenta);
    add(helpButton);
    helpButton.setVisible(true);
    helpButton.addActionListener(new helpListener()); 

    quitButton = new JButton ( " Quit ");
    quitButton.setFont(new Font("Astron Boy Rg", Font.ITALIC, 75));
    quitButton.setBackground(Color.black);
    quitButton.setForeground(Color.orange);
    add(quitButton);
    quitButton.setVisible(true); 
    quitButton.addActionListener(new CloseListener());     

    goBack = new JButton ( " Go Back "); 
    goBack.setFont(new Font("Astron Boy Rg", Font.ITALIC, 60));
    goBack.setBackground(Color.black);
    goBack.setForeground(Color.BLUE);
    add(goBack);
    goBack.setVisible(false); 
    goBack.addActionListener(new goBackButtonListener());

    clickMeOne = new JButton ();
    clickMeOne.setFont(new Font("Astron Boy Rg", Font.ITALIC, 20));
    clickMeOne.setBackground(Color.gray);
    clickMeOne.setForeground(Color.CYAN);
    clickMeOne.setName("clickMeOne");
    add(clickMeOne);
    clickMeOne.setVisible(false); 
    clickMeOne.addActionListener(new clikMeOneButtonListener());

    clickMeTwo = new JButton ();
    clickMeTwo.setFont(new Font("Astron Boy Rg", Font.ITALIC, 20));
    clickMeTwo.setBackground(Color.gray);
    clickMeTwo.setForeground(Color.CYAN);
    clickMeTwo.setName("clickMeTwo");
    add(clickMeTwo);
    clickMeTwo.setVisible(false); 
    clickMeTwo.addActionListener(new clikMeOneButtonListener());

    clickMeThree = new JButton ();
    clickMeThree.setFont(new Font("Astron Boy Rg", Font.ITALIC, 20));
    clickMeThree.setBackground(Color.gray);
    clickMeThree.setForeground(Color.CYAN);
    clickMeThree.setName("clickMeThree");
    add(clickMeThree);
    clickMeThree.setVisible(false); 
    clickMeThree.addActionListener(new clikMeOneButtonListener());

    clickMeFour = new JButton ();
    clickMeFour.setFont(new Font("Astron Boy Rg", Font.ITALIC, 20));
    clickMeFour.setBackground(Color.gray);
    clickMeFour.setForeground(Color.CYAN);
    clickMeFour.setName("clickMeFour");
    add(clickMeFour);
    clickMeFour.setVisible(false); 
    clickMeFour.addActionListener(new clikMeOneButtonListener());

    clickMeFive = new JButton ();
    clickMeFive.setFont(new Font("Astron Boy Rg", Font.ITALIC, 20));
    clickMeFive.setBackground(Color.gray);
    clickMeFive.setForeground(Color.CYAN);
    clickMeFive.setName("clickMeFive");
    add(clickMeFive);
    clickMeFive.setVisible(false); 
    clickMeFive.addActionListener(new clikMeOneButtonListener());

    clickMeSix = new JButton ();
    clickMeSix.setFont(new Font("Astron Boy Rg", Font.ITALIC, 20));
    clickMeSix.setBackground(Color.gray);
    clickMeSix.setForeground(Color.CYAN);
    clickMeSix.setName("clickMeSix");
    add(clickMeSix);
    clickMeSix.setVisible(false);  
    clickMeSix.addActionListener(new clikMeOneButtonListener());

    clickMeSeven = new JButton ();
    clickMeSeven.setFont(new Font("Astron Boy Rg", Font.ITALIC, 20));
    clickMeSeven.setBackground(Color.gray);
    clickMeSeven.setForeground(Color.CYAN);
    clickMeSeven.setName("clickMeSeven");
    add(clickMeSeven);
    clickMeSeven.setVisible(false); 
    clickMeSeven.addActionListener(new clikMeOneButtonListener());

    clickMeOne.setIcon(new ImageIcon("kdevelop_down.png"));   
    clickMeTwo.setIcon(new ImageIcon("kdevelop_down.png"));
    clickMeThree.setIcon(new ImageIcon("kdevelop_down.png"));
    clickMeFour.setIcon(new ImageIcon("kdevelop_down.png"));
    clickMeFive.setIcon(new ImageIcon("kdevelop_down.png"));
    clickMeSix.setIcon(new ImageIcon("kdevelop_down.png"));
    clickMeSeven.setIcon(new ImageIcon("kdevelop_down.png"));

    clickMeOne.setBorder(new LineBorder(Color.black));
    clickMeTwo.setBorder(new LineBorder(Color.black)); 
    clickMeThree.setBorder(new LineBorder(Color.black)); 
    clickMeFour.setBorder(new LineBorder(Color.black)); 
    clickMeFive.setBorder(new LineBorder(Color.black)); 
    clickMeSix.setBorder(new LineBorder(Color.black)); 
    clickMeSeven.setBorder(new LineBorder(Color.black));    

    validate();

  }

  private class onePlayerButtonListener implements ActionListener {
    public void actionPerformed(ActionEvent event) {

      if (event.getSource() == onePlayer) {

        lblWelcome.setVisible(false);
        playButton.setVisible(false);
        helpButton.setVisible(false); 
        quitButton.setVisible(false);
        twoPlayer.setVisible(false);
        onePlayer.setVisible(true);
        goBack.setVisible(false);

        Thread thread =new Thread() {

          public void run() {
            onePlayer.setText(" Game Starts In ");
            onePlayer.setFont(new Font("Astron Boy Rg", Font.ITALIC, 40));
            onePlayer.setBackground(Color.black);
            onePlayer.setForeground(Color.BLUE);
            try {
              Thread.sleep(1000);                        
            }catch (Exception e) {
            }
            onePlayer.setText("3");
            try {
              Thread.sleep(1000);                        
            }catch (Exception e) {
            }
            onePlayer.setText("2");
            try {
              Thread.sleep(1000);                        
            }catch (Exception e) {
            }
            onePlayer.setText("1");  
            try {
              Thread.sleep(1000);                        
            }catch (Exception e) {
            }   

            setLayout(new GridLayout(xsize, ysize));
            slots = new JButton[xsize - 1][ysize];

            for (int column = 0; column < ysize; column++) {
              for (int row = 0; row < xsize - 1; row++) {
                slots[row][column] = new JButton();
                slots[row][column].setHorizontalAlignment(SwingConstants.CENTER); 
                slots[row][column].setBackground(Color.GREEN);
                slots[row][column].setBorder(new LineBorder(Color.black));                      
                add(slots[row][column]);
              }
            }  

            lblWelcome.setVisible(false);
            remove(lblWelcome);
            playButton.setVisible(false);
            remove(playButton);
            helpButton.setVisible(false);
            remove(helpButton);
            quitButton.setVisible(false);
            remove(quitButton);
            goBack.setVisible(false);
            remove(goBack);
            onePlayer.setVisible(false);
            remove(onePlayer);
            twoPlayer.setVisible(false);
            remove(twoPlayer);

            clickMeOne.setVisible(true);
            clickMeTwo.setVisible(true);
            clickMeThree.setVisible(true);
            clickMeFour.setVisible(true);
            clickMeFive.setVisible(true);
            clickMeSix.setVisible(true);
            clickMeSeven.setVisible(true); 

          }
        };
        thread.start();        
      }
    }
  }

  private class twoPlayerButtonListener implements ActionListener {
    public void actionPerformed(ActionEvent event) {

      if (event.getSource() == twoPlayer) {

        lblWelcome.setVisible(false);
        playButton.setVisible(false);
        helpButton.setVisible(false); 
        quitButton.setVisible(false);
        twoPlayer.setVisible(true);
        onePlayer.setVisible(false);
        goBack.setVisible(false);


        Thread thread =new Thread() {

          public void run() {
            twoPlayer.setText(" Game Starts In ");
            twoPlayer.setFont(new Font("Astron Boy Rg", Font.ITALIC, 40));
            twoPlayer.setBackground(Color.black);
            twoPlayer.setForeground(Color.blue);
            try {
              Thread.sleep(1000);                        
            }catch (Exception e) {
            }
            twoPlayer.setText("3");
            try {
              Thread.sleep(1000);                        
            }catch (Exception e) {
            }
            twoPlayer.setText("2");
            try {
              Thread.sleep(1000);                        
            }catch (Exception e) {
            }
            twoPlayer.setText("1");  
            try {
              Thread.sleep(1000);                        
            }catch (Exception e) {
            }   

            setLayout(new GridLayout(xsize, ysize));
            slots = new JButton[xsize - 1][ysize];

            for (int column = 0; column < ysize; column++) {
              for (int row = 0; row < xsize - 1; row++) {
                slots[row][column] = new JButton();
                slots[row][column].setHorizontalAlignment(SwingConstants.CENTER); 
                slots[row][column].setBackground(Color.GREEN);
                slots[row][column].setBorder(new LineBorder(Color.black));                      
                add(slots[row][column]);
              }
            }  

            lblWelcome.setVisible(false);
            remove(lblWelcome);
            playButton.setVisible(false);
            remove(playButton);
            helpButton.setVisible(false);
            remove(helpButton);
            quitButton.setVisible(false);
            remove(quitButton);
            goBack.setVisible(false);
            remove(goBack);
            onePlayer.setVisible(false);
            remove(onePlayer);
            twoPlayer.setVisible(false);
            remove(twoPlayer);


            clickMeOne.setVisible(true);
            clickMeTwo.setVisible(true);
            clickMeThree.setVisible(true);
            clickMeFour.setVisible(true);
            clickMeFive.setVisible(true);
            clickMeSix.setVisible(true);
            clickMeSeven.setVisible(true);  

          }
        };
        thread.start();        
      }
    }
  }

  private class playButtonListener implements ActionListener {
    public void actionPerformed(ActionEvent event) {      

      if (event.getSource() == playButton) {         

        lblWelcome.setVisible(true);
        playButton.setVisible(false);
        helpButton.setVisible(false); 
        quitButton.setVisible(false); 
        onePlayer.setVisible(true);
        twoPlayer.setVisible(true);
        goBack.setVisible(true);        
      }
    }
  }


  private class goBackButtonListener implements ActionListener {
    public void actionPerformed(ActionEvent event) {      

      if (event.getSource() == goBack) {         

        lblWelcome.setVisible(true);
        playButton.setVisible(true);
        helpButton.setVisible(true); 
        quitButton.setVisible(true); 
        onePlayer.setVisible(false);
        twoPlayer.setVisible(false);
        goBack.setVisible(false);        
      }
    }
  }

  private class CloseListener implements ActionListener{
    public void actionPerformed(ActionEvent event) {

      if (event.getSource() == quitButton) { 

        int quitTheGame = JOptionPane.showConfirmDialog(null, " Are You Sure You Want to Leave The Game? ", " Quit? "
                                                          , JOptionPane.YES_NO_OPTION);        

        if (quitTheGame == JOptionPane.YES_OPTION)  {
          System.exit(0);
        }        
      }
    }
  }

  private class helpListener implements ActionListener{
    public void actionPerformed(ActionEvent event) {

      if (event.getSource() == helpButton) {           
        JOptionPane.showMessageDialog(null, " 1) Choose who plays first.", " Help ", JOptionPane.INFORMATION_MESSAGE);

      }
    }
  } 

  private Color playerColor = Color.red;
  private class clikMeOneButtonListener implements ActionListener{
    public void actionPerformed(ActionEvent event) {


      if (event.getSource() == clickMeOne 
            || event.getSource() == clickMeTwo
            || event.getSource() == clickMeThree
            || event.getSource() == clickMeFour
            || event.getSource() == clickMeFive
            || event.getSource() == clickMeSix
            || event.getSource() == clickMeSeven
         ) {

        JButton b = (JButton)event.getSource();

        int column = 0;
        switch ( b.getName() ) {

          case "clickMeOne" : column = 0; break;
          case "clickMeTwo" : column = 1; break;
          case "clickMeThree" : column = 2; break;
          case "clickMeFour" : column = 3; break;
          case "clickMeFive" : column = 4; break;
          case "clickMeSix" : column = 5; break;
          case "clickMeSeven" : column = 6; break;
        }

        int lastEmptyIdx = -1;

        for ( int i = 0; i < slots[column].length; i++ ) {

          if ( slots[column][i].getBackground() != Color.green ) {

            break;
          }
          else {

            lastEmptyIdx = i;
          }
        }

        if ( lastEmptyIdx != -1 ) {

          slots[column][lastEmptyIdx].setBackground(playerColor);

          if ( IsWin(column, lastEmptyIdx) ) {

            String message = playerColor == Color.red ? " Player One Won!" : " Player Two Won!";
            JOptionPane.showMessageDialog(null, message, " Results ", JOptionPane.INFORMATION_MESSAGE);
            System.exit(0);

          } else {               
            playerColor = playerColor == Color.red ? Color.yellow : Color.red;  
          }      
        }
      } 
    }

    public boolean IsWin(int column, int row) {   

      boolean result = false;

      // horizontal
      boolean found = false;

      int counter = 0;

      for ( int i = 0; i < slots.length; i++ ) {

        if ( slots[i][row].getBackground().equals(playerColor)) { 

          counter++;

          if ( found == true ) {

            if ( counter == 4 ) { // win \o/
              result = true;          
              break;
            }         
          }        
          else {

            found = true;
          }
        }
        else {

          if ( found == true ) { // reset counter

            counter = 0;
          }

          found = false;
        }
      }

      // vertical 
      for ( int i = 0; i < slots.length; i++ ) {          
        if ( slots[column][i].getBackground().equals(playerColor)) { 

          counter++;

          if ( found == true ) {

            if ( counter == 4 ) { // win \o/
              result = true;          
              break;
            }         
          }        
          else {

            found = true;
          }
        }
        else {

          if ( found == true ) { // reset counter

            counter = 0;
          }

          found = false;
        }
      }

      // diagonal
      // TODO      

      return result;
    }
  }
}

UPDATE:

 for ( int i = 0; i < slots.length; i++ ) {          
          if ( slots[column][i].getBackground().equals(playerColor)) { 

        counter++;  
        column ++;

        if (column >= slots.length - 1){
            found = false;
            break;
        }

        if ( found == true ) {

          if ( counter == 4 ) { // win \o/
            result = true;          
            break;
          }         
        }        
        else {

          found = true;
        }
      }
      else {

        if ( found == true ) { // reset counter

          counter = 0;
        }

        found = false;
      }        

     }
Jainam Patel
  • 41
  • 2
  • 3
  • 12

1 Answers1

0

Your check needs to not only increment one direction of the slot pane (i), but also needs to increment or decrement what is column in this supposed-to-check-diagonal code to really check along a diagonal.

You also may know there can not be a diagonal win towards a direction if there are less than 4 columns to that side.


**EDIT*: You really should read about language concepts and especially try to understand the concept beyond the syntax! For understanding what is going on, a debugger is an essential tool. If you have a specific algorithm (e.g. your IsWin() method that you need to get insight into, use paper and pencil and do a "manual" execution. This will give you more hints on what might be wrong than any answer to a question with SO. Nevertheless, the references to duplicates of your problem perfectly show what a solution could look like. It is up to you to understand and transfer that to your specific code environment.

To help you a bit further, find below a version of your IsWin() that is working with your code logic. You just need to provide the current playerColor as another parameter. It then will indicate whether the last move lead to a win. (As there can not have been a win before, otherwise it would have been indicated before!). Thus, you just need to check the last move completed a sequence of four in any direction. The code is not truely optimized. There still is room for shortening. But maybe you should first start understanding what you are doing and remove unnecessary garbage from your code....

Suggested code:

    public boolean IsWin(final int column, final int row, final Color playerColor) {

        boolean won = true;
        // vertical
        if (row < slots[column].length - 3) {
            for (int i = 0; i < 4; i++ ) {
                if ( !slots[column][row + i].getBackground().equals(playerColor)) {
                    won = false;
                    break;
                }
            }
            if (won) {
                return won;
            }
        }
        // to the left
        if (column >= 3) {
            // horizontal
            won = true;
            for (int i = 0; i < 4; i++ ) {
                if ( !slots[column - i][row].getBackground().equals(playerColor)) {
                    won = false;
                    break;
                }
            }
            if (won) {
                return won;
            }
            // diagonal
            if (row < slots[column].length - 3) {
                won = true;
                for (int i = 0; i < 4; i++ ) {
                    if ( !slots[column - i][row + i].getBackground().equals(playerColor)) {
                        won = false;
                        break;
                    }
                }
                if (won) {
                    return won;
                }
            }
        }
        // to the right
        if (slots.length - column > 3) {
            // horizontal
            won = true;
            for (int i = 0; i < 4; i++ ) {
                if ( !slots[column + i][row].getBackground().equals(playerColor)) {
                    won = false;
                    break;
                }
            }
            if (won) {
                return won;
            }
            // diagonal
            if (row < slots[column].length - 3) {
                won = true;
                for (int i = 0; i < 4; i++ ) {
                    if ( !slots[column + i][row + i].getBackground().equals(playerColor)) {
                        won = false;
                        break;
                    }
                }
                if (won) {
                    return won;
                }
            }
        }
        return false;
    }
rpy
  • 3,953
  • 2
  • 20
  • 31
  • I'm not clear with your field model (slots matrix). I'd assumed slots are added to increasing indices starting from `0`. However you are checking for win with increasing indices as well. With my naive assumption that a check will start with the position where a new slot has been marked,, I would have expected indexes to descrease for checking. But then you stated horizintal and vertical checks are working. SoI'm unsure how to fix your checking code. For a "straight" fix I would have added `column++;` and in another instance of the chek loop `column--;` after the `counter++; ` – rpy Mar 28 '16 at 20:05
  • i can post the entire code to check. but please help fix it... – Jainam Patel Mar 28 '16 at 20:10
  • So when H and V checks are already OK, what does prevent you from starting with `column++;' added into what you already have with your diagonal check code (a copy of vertical one). Just mind to check for column ending outside of your slots area (a sure `false` case). And then repeat the full loop for `column--;`. I just had a look at the code callin isWin() you included and recognized that your code fro H and V checks is doing a bit more than needed, but this should not hurt. – rpy Mar 28 '16 at 20:16
  • i did put counter ++; rite under counter ++ for diagonal but is giving me error. – Jainam Patel Mar 28 '16 at 20:20
  • Which one? Compile time error, or `ArrayOutOfBound`? The later eaxctly is what I mentiond: _check for not checking outside slots area`. Add: something along ` if (column >= slots.length) { found = false; break;} ` – rpy Mar 28 '16 at 20:36
  • I added the Followin,, check the description – Jainam Patel Mar 28 '16 at 20:40
  • Ah, of course my fault, should have been `coumn >= slots.length-1` as the access is happening _before_ the condition. – rpy Mar 28 '16 at 21:00
  • still not printting anything....check the updated code – Jainam Patel Mar 28 '16 at 21:02
  • So, no more error now? But not detecting valid win condition? Or what is _still not printing anything_ referring to? And... what is the debuggger telling you? – rpy Mar 28 '16 at 21:13
  • it is not detecting the winner.. that is it. no error everything works but cant check for the winner – Jainam Patel Mar 28 '16 at 21:15