Help needed with Connect4 game

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • aboolamoola
    New Member
    • Jan 2008
    • 5

    #1

    Help needed with Connect4 game

    hi, I recently started programing about a month ago. my teacher ask me to make a game. A connect 4 game. I try to make, but failed. I need help.

    here is my code:
    [CODE=Java]import java.awt.*;
    import java.awt.event. *;
    import javax.swing.*;

    public class Connect implements ActionListener {
    private JFrame window = new JFrame();
    private JPanel myPanel = new JPanel();
    private JPanel myPanelB = new JPanel();
    private JButton[][] myButtons = new JButton[6][7];
    private JButton[] buttons = new JButton[7];
    private int count = 5;
    private int count2 = 5;
    private int count3 = 5;
    private int count4 = 5;
    private int count5 = 5;
    private int count6 = 5;
    private int count7 = 5;
    private int countA = 0;
    private String letter = "";

    public Connect(){
    window.setSize( 400,400);
    window.setDefau ltCloseOperatio n(JFrame.EXIT_O N_CLOSE);
    myPanel.setLayo ut(new GridLayout(1,7) );
    myPanelB.setLay out(new GridLayout(6,7) );
    for (int i = 0; i < buttons.length; i ++){
    buttons[i] = new JButton();
    myPanel.add(but tons[i]);
    buttons[i].addActionListe ner(this);
    }
    for (int i = 0; i < 6; i ++){
    for (int j = 0; j < 7; j ++){
    myButtons[i][j] = new JButton();
    myPanelB.add(my Buttons[i][j]);
    }
    }
    window.add(myPa nel, BorderLayout.NO RTH);
    window.add(myPa nelB, BorderLayout.CE NTER);
    window.setVisib le(true);
    }

    public void actionPerformed (ActionEvent e){
    countA++;
    if (countA % 2 == 0)
    letter = "X";
    else
    letter = "O";
    if (e.getSource() == buttons[0]){
    myButtons[count][0].setText(letter );
    count --;
    }
    if (e.getSource() == buttons[1]){
    myButtons[count2][1].setText(letter );
    count2 --;
    }
    if (e.getSource() == buttons[2]){
    myButtons[count3][2].setText(letter );
    count3--;
    }
    if (e.getSource() == buttons[3]){
    myButtons[count4][3].setText(letter );
    count4--;
    }
    if (e.getSource() == buttons[4]){
    myButtons[count5][4].setText(letter );
    count5--;
    }
    if (e.getSource() == buttons[5]){
    myButtons[count6][5].setText(letter );
    count6--;
    }
    if (e.getSource() == buttons[6]){
    myButtons[count7][6].setText(letter );
    count7--;
    }
    if (myButtons[0][0].getText().equa ls("O") || myButtons[0][0].getText().equa ls("X")){
    buttons[0].setEnabled(fal se);
    }
    if (myButtons[0][1].getText().equa ls("O") || myButtons[0][1].getText().equa ls("X")){
    buttons[1].setEnabled(fal se);
    }
    if (myButtons[0][2].getText().equa ls("O") || myButtons[0][2].getText().equa ls("X")){
    buttons[2].setEnabled(fal se);
    }
    if (myButtons[0][3].getText().equa ls("O") || myButtons[0][3].getText().equa ls("X")){
    buttons[3].setEnabled(fal se);
    }
    if (myButtons[0][4].getText().equa ls("O") || myButtons[0][4].getText().equa ls("X")){
    buttons[4].setEnabled(fal se);
    }
    if (myButtons[0][5].getText().equa ls("O") || myButtons[0][5].getText().equa ls("X")){
    buttons[5].setEnabled(fal se);
    }
    if (myButtons[0][6].getText().equa ls("O") || myButtons[0][6].getText().equa ls("X")){
    buttons[6].setEnabled(fal se);
    }
    }

    public static void main(String[] args){
    new Connect();
    }
    }[/CODE]
    the problem I ahve is that, how can I make it so that it checks if i've won or not? obviously when 4 buttons are connected i wud display a window saying you won.

    i try to do something like this.
    [CODE=Java]if (e.getSource() == buttons[0]){
    myButtons[count][0].setText(letter );
    if (myButtons[count][1].setText(letter ).equals(letter ) &&
    myButtons[count][2].setText(letter ).equals(letter ) && ... [/CODE]
    ...and so forth, but i put it in, and i tried but it dun't work, im still at the begining stages, plz help!

    THANK YOU IN ADVANCE !! XD
    count --;
    Last edited by BigDaddyLH; Jan 15 '08, 04:17 AM. Reason: Introduced code tags
  • BigDaddyLH
    Recognized Expert Top Contributor
    • Dec 2007
    • 1216

    #2
    Please enclose your posted code in [code] tags (See How to Ask a Question).

    This makes it easier for our Experts to read and understand it. Failing to do so creates extra work for the moderators, thus wasting resources, otherwise available to answer the members' questions.

    Please use [code] tags in future.

    MODERATOR

    Comment

    • BigDaddyLH
      Recognized Expert Top Contributor
      • Dec 2007
      • 1216

      #3
      Please remember to provide a meaningful Title for any threads started (see the FAQ entry Use a Good Thread Title).

      This helps to ensure that other members, and also the general public, will have a better chance of finding answers to any similar questions.

      MODERATOR

      Comment

      • BigDaddyLH
        Recognized Expert Top Contributor
        • Dec 2007
        • 1216

        #4
        Originally posted by aboolamoola
        the problem I ahve is that, how can I make it so that it checks if i've won or not?
        You need to exploit loops and arrays more in your code. For example, instead of count, count2, count3, ... use an array. You should be able to shorten your code.

        Then think of searching for patterns on the game panel to see if a player has won.

        Comment

        • EpicOfChaos
          New Member
          • Jun 2007
          • 15

          #5
          I know when I have done things similar to this, I have used a matrix to store all the meaningful information and then have a function that updates the gui based on the matrix. That way checking for patterns and conditions on the program can be done on the matrix not on the actual gui. Just a thought. . .

          Comment

          • aboolamoola
            New Member
            • Jan 2008
            • 5

            #6
            sry, but i have no idea wut a matrix is.
            but i somehow managed to figure out how to check win it's something like this.

            [code=java]
            public void checkWin1(){
            for ( int i = 0; i <= 3; i ++){
            for ( int j = 0; j < 6; j ++){
            if ( myButtons[j][i].getText().equa ls("X") || myButtons[j][i].getText().equa ls("O")){
            if ( myButtons[j][i].getText().equa ls(myButtons[j][i+1].getText())){
            if ( myButtons[j][i+1].getText().equa ls(myButtons[j][i+2].getText())){
            if ( myButtons[j][i+2].getText().equa ls(myButtons[j][i+3].getText())){
            JOptionPane.sho wMessageDialog( null, letter + " wins!");
            }
            }
            }
            }
            }
            }
            }

            [/code]
            like that and i Have a checkWin1 for horizontal, checkWin2 for verticle, and so forth and it solves my check problem. But now i need some ideas on how to make a AI so that i can play with the user. But the problem is, there is so many combinations, so if i only use "if" and "else" it's gonna take forever. My teacher sed that I can make a "learning" computer, but i think if i do that, den it's gonna take at least 500 games, for the computer to be a little smarter because of the number of possible combinations like 42! ... it's a lot. SO i dun no how i can make a computer AI.

            Comment

            • Laharl
              Recognized Expert Contributor
              • Sep 2007
              • 849

              #7
              A matrix is an array of arrays, referred to as a 2D array, just like a mathematical matrix.

              Originally posted by Sun Java Tutorial
              In the Java programming language, a multidimensiona l array is simply an array whose components are themselves arrays. This is unlike arrays in C or Fortran. A consequence of this is that the rows are allowed to vary in length, as shown in the following MultiDimArrayDe mo program:

              class MultiDimArrayDe mo {
              public static void main(String[] args) {
              String[][] names = {{"Mr. ", "Mrs. ", "Ms. "},
              {"Smith", "Jones"}};
              System.out.prin tln(names[0][0] + names[1][0]); //Mr. Smith
              System.out.prin tln(names[0][2] + names[1][1]); //Ms. Jones
              }
              }

              The output from this program is:

              Mr. Smith
              Ms. Jones

              Comment

              • chaarmann
                Recognized Expert Contributor
                • Nov 2007
                • 785

                #8
                1.)
                you are not checking for diagonal rows here. Only horizontal and vertical.

                2.)
                Try to simplify your code, which also makes it faster.
                Always calling 'myButtons[j][i].getText()" again is bad. Just store the value once and re-use it.
                Also nested if-statements are bad. Just use boolean AND ("&&")
                If I rewrite your code below, it is:

                [code=java]
                public void checkWin1(){
                for ( int i = 0; i <= 3; i ++){
                for ( int j = 0; j < 6; j ++){
                String currentButton = myButtons[j][i].getText();

                if ((currentButton .equals("X") || currentButton.e quals("O"))
                && currentButton.e quals(myButtons[j][i+1].getText())
                && currentButton.e quals(myButtons[j][i+2].getText())
                && currentButton.e quals(myButtons[j][i+3].getText())
                {
                JOptionPane.sho wMessageDialog( null, letter + " wins!");
                }
                }
                }
                }

                [/code]

                3.)
                Tryto make an Ai that computes only a few steps ahead. So possible combinations are not like 42! You only have 6 slots, that means 6 possibilities for eahcmove. And sometimes slots are filled, so the possibilities are less.
                1 step ahead: max 6 possibilities
                2 step ahead: max 6*6 = 36 possibilities
                3 step ahead: max 6*6*6 = 216 possibilities
                ...
                7 steps ahead : max 279936 possibilities, which is still fast enough to calculate within a few seconds.

                I don't think any "normal" human can calculate more than 7 steps ahead.

                If you want to make an AI that operates on a big number of possibilities (like 42!), read about "genetic algorithms"

                Comment

                • BigDaddyLH
                  Recognized Expert Top Contributor
                  • Dec 2007
                  • 1216

                  #9
                  I think Chaarmann's third point is alluding to the Minimax algorithm:

                  Comment

                  • aboolamoola
                    New Member
                    • Jan 2008
                    • 5

                    #10
                    ty for the responses, but like you sed before, 216 or something combinations is still a lot, but thats not all of it tho 216 is only 3 moves ahead, and in an grid of 6 rows theres much more to it, plus, how do I implement the combinations so that my AI can interact with the user?

                    I've come up with something, but so far, doesn't work.
                    I made a AI method, and in it, i have, it first checks if a place can placed so that the computer wins, if that doesn't work, than it tries to find if the user is wining, and than block it if it's true, than if non of these maches, it jsut randomly selects a move. But this is really hard as well, because I need 4 different method just to search for the place where the computer cn go. it's hard. and i can't do it. my code so far is like
                    similar to the one i showed u before, but it's still doesn't work properly, cuz it's too complex. If i can store all the info on an array, and make this simplar, than plz give me some suggestions.

                    I ahve another question. Is there a method like getIcon so that i can import pictures to my buttons and instead of saying. button[i][j].getText(). i can do smething like button[i][j].getIcon("butto ns.jpg") something like dat, I tried searching on the API, but they weren't helpful, so if u guys can provide me wtih a helpful website, or some accurate API, that would be great,

                    Thanks in advance

                    Comment

                    • chaarmann
                      Recognized Expert Contributor
                      • Nov 2007
                      • 785

                      #11
                      I think your problem is the slowness of the algorithm that you use to check for a win. You can improve it and make it thousand of times faster.
                      1.) Use integers to store the coins, e.g 0=empty, 1=x, 2=o, it's much faster than storing strings and comparing strings!
                      2.) You don't need to loop through all columns and rows to see if you have won!
                      At the time when you place a coin,you only need to track all 6 ways from this coin (left, right, up, down an the diagonals). And if you come to a coin that is wrong color, exit from your loop and check next direction!
                      3.) If you store in all play-fields the number of neighbors (N) with same color as current coin, for each direction, then your evaluation for a win goes down to only 6 comparisons when placing a coin. You just need to check each of the six neighbors around the current coin, if they have the same color and their N (for current direction) is 4, so placing the coin wouldmake it 5 and a win.

                      If you make it that fast, then you can calculate thousands of coin-placements within a second, so even backtracking 6 turns deep should be within a second.

                      And for small gameboards, you can even backtrack the whole game! That means calculate every possible configuration!
                      Remember that at the end of the game, the number of possible moves are becoming rapidly smaller!

                      Comment

                      Working...