Connect-4-Code analysieren

morry329

Mitglied
Hallo zusammen,

ich habe von einer Webseite die folgende Code-Snippet eingetippt zum üben. Das Programm bricht sich ab als ein beliebiges Zahl 0-6 eingetragen wird. Das gewünschte Ergebnis wäre es so, dass das Programm geht weiter bis vier O oder X in einer Reihe gesammelt werden. Kann jemand mir eine Hilfsstellung geben?

Java:
package CC4PlayGround;

import java.util.Scanner;

public class JProbs {
    public static String[][] createPattern(){ //the "printBoard" method
        /**
         * the y-axis is set to 15 as graphically there's an extra row to show the _
         * at the bottom and you have doubled the cols that show ||| btw each nums.
         */

        String[][] f = new String[7][15];
        //loop over each row from up to down
        for(int i = 0; i < f.length; i++){
            //loop over each col from left to right
            for(int j = 0; j <f[i].length; j++){
                if(j % 2 == 0){
                    f[i][j] = " | ";
                } else {
                    f[i][j] = " ";
                }

                //make the lowest row;
                if(i == 6){
                    f[i][j] = " - ";
                }
            }
        }
        return f;
    }

    //print the board just created
    public static void printPattern(String[][] f){
        for(int i = 0; i < f.length; i++){
            for(int j = 0; j < f.length; j++){
                System.out.print(f[i][j]);
            }
            System.out.println();
        }
    }

    //make a basic move
    public static void dropPattern1(String f[][]){
        //determine what col the user drops the Pat 1 into
        System.out.println("Drop a Pat1 at col (0-6)");

        //user col nums into a 1-3-5-7-9-11-13 (convert 1-2-3-4-5-6)
        Scanner sc = new Scanner(System.in);
        int c = 2*sc.nextInt()+1;
        System.out.println("user1 entered");

        for(int i = 5; i>=0; i--){
            if(f[i][c] == " "){
                f[i][c] = "O";
                 //the empty space has been found, break the loop out
                break;
            }
        }
    }

    //the same step for the other pattern (pat2)
    public static void dropPattern2(String f[][]){
        System.out.println("Drop a Pat2 at col (0-6)");
        Scanner sc = new Scanner(System.in);
        int c = 2*sc.nextInt()+1;
        System.out.println("user2 entered");
        for(int i = 5; i>=0; i--){
            if(f[i][c] == " "){
                f[i][c] = "X";
                //the empty space has been found, break the loop out
                break;
            }
        }
    }

    //so, check the winner now!
    public static String checkWinner(String f[][]){
        /*
        horizontal winner - it can be found on any row, so loop over each row starting from 0 to 5
         */
        for(int i = 0; i < 6; i++){
            //it can be found on any col also, loop over each col starting from 0 to 6 also
            for(int j = 0; j < 7; j+=2)  {
                //the increment is 2 as the col is doubled here
                if((f[i][j+1] != " ")
                   &&(f[i][j+3] != " ")
                   &&(f[i][j+5] != " ")
                   &&(f[i][j+7] != " ")
                   &&(f[i][j+1] == f[i][j+3])
                   &&(f[i][j+3] == f[i][j+5])
                   &&(f[i][j+5] == f[i][j+7])){
                    return f[i][j+1];
                }
            }
        }

        /*loop over each odd-numbered col by incrementing with 2 then check for consecutive boxes in the same col
        that are the same colour
         */
        for(int i = 0; i < 15; i+=2){ //if we need to check each odd-numbered col then the range is set to 15
            //the y-axis range shall not go over 4 so it's j < 3 (we need 4 patterns vertically anyway)
            for(int j = 0; j < 3; j++){
                if((f[j][i] != " ")
                        &&(f[j+1][i] != " ")
                        &&(f[j+2][i] != " ")
                        &&(f[j+3][i] != " ")
                        &&(f[j][i] == f[j+1][i])
                        &&(f[j+1][i] == f[j+2][i])
                        &&(f[j+2][i] == f[j+3][i])){
                    return f[j][i];
                }
            }
        }

        /*leftup-rightdown diagonal *
        loop over the 3 uppermost rows then go from let to right col-wise
         */
        for(int i = 0; i < 6; i++){
            /*
             the j start from 1 and increment by 2 until it reaches 7
             */
            for(int j = 0; j < 9; j+=2)  {

                if((f[i][j+1] != " ")
                        &&(f[i+1][j+2] != " ")
                        &&(f[i+2][j+4] != " ")
                        &&(f[i+3][j+6] != " ")
                        &&(f[i][j] == f[i+1][j+2])
                        &&(f[i+1][j+2] == f[i+2][j+4])
                        &&(f[i+2][j+4] == f[i+3][j+6])){
                    return f[i][j];
                }
            }
        }

        /*we're just reversing our trajectory like the above method i.e.
        we're starting from the rightmost column instead of the leftmost one like we did above
        (leftdown-rightup)
         */
        for(int i = 0; i < 3; i++){
            for(int j = 7; j < 15; j+=2){
                if((f[i][j] != " ")
                        &&(f[i+1][j-2] != " ")
                        &&(f[i+2][j-4] != " ")
                        &&(f[i+3][i-6] != " ")
                        &&(f[i][j] == f[i+1][j-2])
                        &&(f[i+1][j-2] == f[i+2][j-4])
                        &&(f[i+2][j-4] == f[i+3][j-6])){
                    return f[i][j];
                }
            }
        }
        //we need to tell the system we could find any winning match (if our search does not fall into any of these four cases)
        return null;
    }

    public static void main(String[] args) {
        String[][] f = createPattern();
        boolean loop = true;
        int count = 0;
        printPattern(f);
        while(loop){
            if(count % 2 == 0){
                dropPattern1(f);
            } else {
                dropPattern2(f);
            }
            count++;
            printPattern(f);


            if(checkWinner(f) != null){
                if(checkWinner(f) == "1"){
                    System.out.println("the Pl1 won");
                } else if (checkWinner(f) == "0"){
                    System.out.println("the PL2 won");
                }
                loop = false; //no winner, then end the game.
            }
        }
    }
}
 
Das Programm bricht sich ab als ein beliebiges Zahl 0-6 eingetragen wird.
Der erste Schritt ist, dass Du siehst, was für ein Fehler aufgetreten ist. Das Programm dürfte nicht einfach abbrechen sondern es dürfte eine Fehlermeldung kommen. Um es genauer auszudrücken: Eine Exception zusammen mit einem sogenannten Stacktrace sollte ausgegeben werden.

Schauen wir uns einfach einmal an, was passiert bzw. wo denn eine Zahl von 0-6 eingegeben wird:
Das sind die dropPattern Methoden. Da wird ein int Wert eingelesen (sc.nextInt() Aufruf)

Da kann also die erste Möglichkeit sein: Wenn man keine Zahl eingibt sondern einen Text, dann bekommt man vom Scanner eine Exception. Also wenn man statt einer Zahl z.B. "Hallo" eingibt, dann wirft sc.nextInt() eine Exception.

Nun lass uns einmal eine 7 eingeben. Dann wird c = 2*7 + 1 = 15.
Und dann wird in einer for Schleife i heruntergezählt. i startet mit 5.
Damit wird dann auf f[5][15] zugegriffen. Das Array f wird aber erstellt als: new String[7][15];

Der erste Array Operator nimmt also Indices von 0..6 an und der zweite Indices von 0..14. Die 15 ist damit außerhalb der Array Grenzen.
 
Der erste Schritt ist, dass Du siehst, was für ein Fehler aufgetreten ist. Das Programm dürfte nicht einfach abbrechen sondern es dürfte eine Fehlermeldung kommen. Um es genauer auszudrücken: Eine Exception zusammen mit einem sogenannten Stacktrace sollte ausgegeben werden.

Schauen wir uns einfach einmal an, was passiert bzw. wo denn eine Zahl von 0-6 eingegeben wird:
Das sind die dropPattern Methoden. Da wird ein int Wert eingelesen (sc.nextInt() Aufruf)

Da kann also die erste Möglichkeit sein: Wenn man keine Zahl eingibt sondern einen Text, dann bekommt man vom Scanner eine Exception. Also wenn man statt einer Zahl z.B. "Hallo" eingibt, dann wirft sc.nextInt() eine Exception.

Nun lass uns einmal eine 7 eingeben. Dann wird c = 2*7 + 1 = 15.
Und dann wird in einer for Schleife i heruntergezählt. i startet mit 5.
Damit wird dann auf f[5][15] zugegriffen. Das Array f wird aber erstellt als: new String[7][15];

Der erste Array Operator nimmt also Indices von 0..6 an und der zweite Indices von 0..14. Die 15 ist damit außerhalb der Array Grenzen.
Vielen herzlichen Dank für die sehr ausführliche Analyse!

Ich habe die For-Schleife gefixt, die eine String auf einem leeren String-Array ergibt:

Java:
 for(int i = 7; i>=0; i--){ //i = 7 statt i = 5
            if(f[i][c] == " "){
                f[i][c] = "O";
                 //the empty space has been found, break the loop out
                break;
            }
        }

Das war den Fehler gewesen, nach dieser Fix läuft das Programm wie erwartet.
 

Zurück
Oben