[C] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

AW: [C] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Ja gut... eh... ich meinte in Java. :lol:
Ja, sorry. C programmier ich eigentlich nicht, da vergisst man solche Kleinigkeiten gerne mal, wobei das mit dem Garbage Collector weiß ich eigentlich... Naja, wurscht. Gibt ja genug schlaue Köpfe hier die mich korrigieren können. :)
 
AW: [C] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Habe heute mal zum Spaß TIC TAC TOE programmiert ... ;)

Bis auf eine (entscheidende :fresse:) Kleinigkeit funktioniert das Programm auch schon sehr gut:
Code:
#include <stdio.h>
#include <time.h>

#define ROWS 3
#define COLUMNS 3

int checkWinner(int matrix[][COLUMNS], int rows) { 
    if (matrix[0][0]==79 && matrix[0][1]==79 && matrix[0][2]==79) {
        return 0;
    } else if (matrix[1][0]==79 && matrix[1][1]==79 && matrix[1][2]==79) {
        return 0;
    } else if (matrix[2][0]==79 && matrix[2][1]==79 && matrix[2][2]==79) {
        return 0;
    } else if (matrix[0][0]==79 && matrix[1][0]==79 && matrix[2][0]==79) {
        return 0;
    } else if (matrix[0][1]==79 && matrix[1][1]==79 && matrix[2][1]==79) {
        return 0;
    } else if (matrix[0][2]==79 && matrix[1][2]==79 && matrix[2][2]==79) {
        return 0;
    } else if (matrix[0][0]==79 && matrix[1][1]==79 && matrix[2][2]==79) {
        return 0;
    } else if (matrix[0][2]==79 && matrix[1][1]==79 && matrix[2][0]==79) {
        return 0;
    } else if (matrix[0][0]==88 && matrix[0][1]==88 && matrix[0][2]==88) {
        return 0;
    } else if (matrix[1][0]==88 && matrix[1][1]==88 && matrix[1][2]==88) {
        return 0;
    } else if (matrix[2][0]==88 && matrix[2][1]==88 && matrix[2][2]==88) {
        return 0;
    } else if (matrix[0][0]==88 && matrix[1][0]==88 && matrix[2][0]==88) {
        return 0;
    } else if (matrix[0][1]==88 && matrix[1][1]==88 && matrix[2][1]==88) {
        return 0;
    } else if (matrix[0][2]==88 && matrix[1][2]==88 && matrix[2][2]==88) {
        return 0;
    } else if (matrix[0][0]==88 && matrix[1][1]==88 && matrix[2][2]==88) {
        return 0;
    } else if (matrix[0][2]==88 && matrix[1][1]==88 && matrix[2][0]==88) {
        return 0;
    } else {
        return 1;
    }
}

void playerOne() {
    int x1=0, y1=0, error=0;
    int matrix[ROWS][COLUMNS] = { 0 };

    printf("Player 1, it's your turn. Please enter coordinates: ");
    scanf("%d %d", &x1, &y1);
    if ((x1 <= 0 || x1 > 3) || (y1 <= 0 || y1 > 3)) { [COLOR=seagreen]/* if Player 1's input is invalid, ask again */        printf("\nINVALID INPUT! Try again ...\n\n");
        playerOne();
        error=1;
    } else if (matrix[x1][y1]==79 || matrix[x1][y1]==88) { [COLOR=seagreen]/* if Player 1 chooses a field that is already taken, ask again */        printf("\nField already taken! Try again ...\n\n");
        playerOne();
        error=2;
    }

    if (error != 1 && error != 2) { [COLOR=seagreen]/* only print matrix if user input is valid */        matrix[x1-1][y1-1]=88; [COLOR=seagreen]/* ASCII value for 'X' */        [COLOR=royalblue][B]matrix[ROWS][COLUMNS]=printMatrix(matrix, ROWS);[/B] [COLOR=seagreen]/* save the result of each round in matrix */        if (checkWinner(matrix, ROWS)==0) {
            printf("Congratulations, Player 1! You won the game.\n");
        }
    }
}

void playerTwo() {
    int x2=0, y2=0, error=0;
    int matrix[ROWS][COLUMNS] = { 0 };

    printf("Player 2, it's your turn. Please enter coordinates: ");
    scanf("%d %d", &x2, &y2);
    if ((x2 <= 0 || x2 > 3) || (y2 <= 0 || y2 > 3)) { [COLOR=seagreen]/* if Player 2's input is invalid, ask again */        printf("\nINVALID INPUT! Try again ...\n\n");
        playerTwo();
        error=1;
    } else if (matrix[x2][y2]==79 || matrix[x2][y2]==88) { [COLOR=seagreen]/* if Player 2 chooses a field that is already taken, ask again */        printf("\nField already taken! Try again ...\n\n");
        playerTwo();
        error=2;
    }

    if (error != 1 && error != 2) { [COLOR=seagreen]/* only print matrix if user input is valid */        matrix[x2-1][y2-1]=79; [COLOR=seagreen]/* ASCII value for 'O' */       [COLOR=royalblue][B] matrix[ROWS][COLUMNS]=printMatrix(matrix, ROWS);[/B] [COLOR=seagreen]/* save the result of each round in matrix */        if (checkWinner(matrix, ROWS)==0) {
            printf("Congratulations, Player 2! You won the game.\n");
        }
    }
}

int printMatrix(int matrix[][COLUMNS], int rows) {
    int i=0, j=0;
    int resultMatrix[ROWS][COLUMNS] = { 0 };

    printf("\n");
    for (i=0; i<rows; i++) {
        for (j=0; j<COLUMNS; j++) {
            if (matrix[i][j] == 88 || matrix[i][j] == 79) {
                (j<2) ? (printf(" %c |", matrix[i][j])) : (printf(" %c", matrix[i][j]));
            } else {
                (j<2) ? (printf("   |", matrix[i][j])) : (printf("", matrix[i][j]));
            }
            [COLOR=royalblue][B]resultMatrix[i][j]=matrix[i][j];[/B]        }
        printf(i<2 ? "\n---+---+---\n" : "");
     }
     printf("\n\n");

     [COLOR=royalblue][B]return resultMatrix[i][j];[/B]}

int main(void) {
    int i=0;
    int matrix[ROWS][COLUMNS] = { 0 };
    double time1=0.0, tstart;

    tstart=clock();
    
    printf("TIC TAC TOE\n");
    printMatrix(matrix, ROWS);
    printf("Player 1 ... X\nPlayer 2 ... O\n\n");

    while (checkWinner(matrix, ROWS)!=0) { [COLOR=seagreen]/* continue game until one player has won ... */        playerOne();
        playerTwo();
    }

    while (i<9) { [COLOR=seagreen]/* ... or the game ends in a tie */        checkWinner(matrix, ROWS);
        if (i==8 && checkWinner(matrix, ROWS)!=0) {
            printf("Oops, the game ended in a tie!\n");
        }
        i++;
    }

    time1+=clock()-tstart;
    time1=time1/CLOCKS_PER_SEC;

    printf("\nThe game lasted %.2f minutes.\n\n", time1/60);

    return 0;
}
Das Problem ist, dass sich das Programm nicht den Zustand der Matrix aus der vorigen Runde merkt. Deswegen kommt das Spiel leider nie zu einem Ende. Den Fehler vermute ich in einer bzw. zwei der markierten Zeilen, aber ich komme einfach nicht darauf.

Ich hätte mir das jedenfalls so vorgestellt, dass das Ergebnis jeder Runde von printMatrix, der Funktion, die für die Ausgabe des aktuellen Zustands zuständig ist, in resultMatrix gespeichert wird. Ab der zweiten Runde sollten dann beide Spieler nur noch den Inhalt der resultMatrix verwenden und da ihre neuen Werte hinzufügen, falls die entsprechenden Felder noch frei sind ...
 
Zuletzt bearbeitet:
AW: [C] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Sorry für DP, habe aber Neuigkeiten ...

Ich konnte zwar das Problem aus dem vorigen Posting nicht lösen, habe aber einen Weg herum gefunden. Jetzt fragen nicht mehr die beiden Spieler den Status der jeweiligen Runde ab, sondern eine eigene Funktion checkStatus überprüft diesen. Dadurch funktioniert mein TIC TAC TOE jetzt endlich! ;)

Dafür habe ich zwei neue, aber kleinere Probleme, die leichter zu lösen sein sollten:

1.) In der Funktion checkStatus funktioniert die Abfrage, ob das Spiel unentschieden ausging, offenbar nicht richtig. Der Unentschieden-Zustand wird nicht erkannt und das Spiel erwartet auch bei bereits vollem Spielfeld weiter Benutzereingaben. :ugly:
Ich habe mir gedacht, ich frage einfach ab, ob bereits alle Felder der Matrix mit 79 oder 88 belegt sind, aber so geht's anscheindend nicht ...

2.) Das Bisschen Code, das in der main nach der while Schleife steht (Zeitmessung), wird aus irgendeinem Grund nicht berücksichtigt bzw. nicht ausgeführt. :huh:

Hier der aktuelle Code:
Code:
#include <stdio.h>
#include <time.h>

#define ROWS 3
#define COLUMNS 3

int checkWinner(int matrix[][COLUMNS], int rows) { 
    if (matrix[0][0]==79 && matrix[0][1]==79 && matrix[0][2]==79) {
        return 0;
    } else if (matrix[1][0]==79 && matrix[1][1]==79 && matrix[1][2]==79) {
        return 0;
    } else if (matrix[2][0]==79 && matrix[2][1]==79 && matrix[2][2]==79) {
        return 0;
    } else if (matrix[0][0]==79 && matrix[1][0]==79 && matrix[2][0]==79) {
        return 0;
    } else if (matrix[0][1]==79 && matrix[1][1]==79 && matrix[2][1]==79) {
        return 0;
    } else if (matrix[0][2]==79 && matrix[1][2]==79 && matrix[2][2]==79) {
        return 0;
    } else if (matrix[0][0]==79 && matrix[1][1]==79 && matrix[2][2]==79) {
        return 0;
    } else if (matrix[0][2]==79 && matrix[1][1]==79 && matrix[2][0]==79) {
        return 0;
    } else if (matrix[0][0]==88 && matrix[0][1]==88 && matrix[0][2]==88) {
        return 0;
    } else if (matrix[1][0]==88 && matrix[1][1]==88 && matrix[1][2]==88) {
        return 0;
    } else if (matrix[2][0]==88 && matrix[2][1]==88 && matrix[2][2]==88) {
        return 0;
    } else if (matrix[0][0]==88 && matrix[1][0]==88 && matrix[2][0]==88) {
        return 0;
    } else if (matrix[0][1]==88 && matrix[1][1]==88 && matrix[2][1]==88) {
        return 0;
    } else if (matrix[0][2]==88 && matrix[1][2]==88 && matrix[2][2]==88) {
        return 0;
    } else if (matrix[0][0]==88 && matrix[1][1]==88 && matrix[2][2]==88) {
        return 0;
    } else if (matrix[0][2]==88 && matrix[1][1]==88 && matrix[2][0]==88) {
        return 0;
    } else {
        return 1;
    }
}

void checkStatus() { [COLOR=seagreen]/* check status of the game after each round */    int i=0, j=0;
    int matrix[ROWS][COLUMNS] = { 0 };
    int newMatrix[ROWS][COLUMNS]= { 0 };

    newMatrix[ROWS][COLUMNS]=printMatrix(matrix, ROWS);

    while (checkWinner(newMatrix, ROWS)!=0) { [COLOR=seagreen]/* continue the game until one player has won ... */        playerOne(newMatrix, ROWS);
        playerTwo(newMatrix, ROWS);
    }

    [COLOR=royalblue][B]for (i=0; i<ROWS; i++) {[/B] [COLOR=seagreen]/* ... or the game has ended in a tie */       [B][COLOR=royalblue] for (j=0; i<COLUMNS; j++) {
            if (newMatrix[i][j]==79 || newMatrix[i][j]==88) {
                printf("Oops, the game ended in a tie!\n");
            }
        }
    }  [/B]
}

int playerOne(int matrix[][COLUMNS], int rows) {
    int x1=0, y1=0, error=0;

    printf("Player 1, it's your turn. Please enter coordinates: ");
    scanf("%d %d", &x1, &y1);
    putchar('\n');
    if ((x1 <= 0 || x1 > 3) || (y1 <= 0 || y1 > 3)) { [COLOR=seagreen]/* if Player 1's input is invalid, ask again */        printf("\nINVALID INPUT! Try again ...\n\n");
        playerOne(matrix, ROWS);
        error=1;
    } else if (matrix[x1-1][y1-1]==79 || matrix[x1-1][y1-1]==88) { [COLOR=seagreen]/* if Player 1 chooses a field that is already taken, ask again */        printf("Field already taken! Try again ...\n\n");
        playerOne(matrix, ROWS);
        error=2;
    }

    if (error != 1 && error != 2) { [COLOR=seagreen]/* only print matrix if user input is valid */        matrix[x1-1][y1-1]=88; [COLOR=seagreen]/* ASCII value for 'X' */        printMatrix(matrix, ROWS);
        if (checkWinner(matrix, ROWS)==0) {
            printf("Congratulations, Player 1! You won the game.\n\n");
        }
    }
    return matrix[ROWS][COLUMNS];
}

int playerTwo(int matrix[][COLUMNS], int rows) {
    int x2=0, y2=0, error=0;

    printf("Player 2, it's your turn. Please enter coordinates: ");
    scanf("%d %d", &x2, &y2);
    putchar('\n');
    if ((x2 <= 0 || x2 > 3) || (y2 <= 0 || y2 > 3)) { [COLOR=seagreen]/* if Player 2's input is invalid, ask again */        printf("\nINVALID INPUT! Try again ...\n\n");
        playerTwo(matrix, ROWS);
        error=1;
    } else if (matrix[x2-1][y2-1]==79 || matrix[x2-1][y2-1]==88) { [COLOR=seagreen]/* if Player 2 chooses a field that is already taken, ask again */        printf("Field already taken! Try again ...\n\n");
        playerTwo(matrix, ROWS);
        error=2;
    }

    if (error != 1 && error != 2) { [COLOR=seagreen]/* only print matrix if user input is valid */        matrix[x2-1][y2-1]=79; [COLOR=seagreen]/* ASCII value for 'O' */        printMatrix(matrix, ROWS);
        if (checkWinner(matrix, ROWS)==0) {
            printf("Congratulations, Player 2! You won the game.\n\n");
        }
    }
    return matrix[ROWS][COLUMNS];
}

int printMatrix(int matrix[][COLUMNS], int rows) {
    int i=0, j=0;
    int resultMatrix[ROWS][COLUMNS] = { 0 };

    for (i=0; i<rows; i++) {
        for (j=0; j<COLUMNS; j++) {
            if (matrix[i][j] == 88 || matrix[i][j] == 79) {
                (j<2) ? (printf(" %c |", matrix[i][j])) : (printf(" %c", matrix[i][j]));
            } else {
                (j<2) ? (printf("   |", matrix[i][j])) : (printf("", matrix[i][j]));
            }
            resultMatrix[i][j]=matrix[i][j];
        }
        printf(i<2 ? "\n---+---+---\n" : "");
     }
     printf("\n\n");

     return resultMatrix[i][j];
}

int main(void) {
    int i=0;
    int matrix[ROWS][COLUMNS] = { 0 };
    double time1=0.0, time2=0.0;

    time1=clock();

    printf("TIC TAC TOE\n\n");
    printf("Player 1 ... X\nPlayer 2 ... O\n\n");

    [B][COLOR=red]while (checkWinner(matrix, ROWS)!=0) {[/B] [COLOR=seagreen]/* continue checking status of the game until it ends one way or another */        checkStatus();
    }

    [B][COLOR=royalblue]time2=clock()-time1;
     time2=time2/CLOCKS_PER_SEC;
 [COLOR=royalblue]      printf("\nThe game lasted %.2lf minutes.\n\n", time2/60);[/B]

    return 0;
}
[EDIT]
Habe jetzt eine neue Version, in der die Überprüfung, ob ein Unentschieden erreicht wurde, von einer eigenen Funktion übernommen wird. Hier allerdings das Problem: Die Funktion meint, schon nach jeweils einer User-Eingabe, also zwei (von insg. neun) belegten Matrix-Feldern, dass es ein Unentschieden gäbe ...

Vielleicht ist es in dieser Variante aber leichter für euch, zu durchschauen, was ich machen möchte, und mir zu helfen. :)
Code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ROWS 3
#define COLUMNS 3

int checkWinner(int matrix[][COLUMNS], int rows) { [COLOR=seagreen]/* all possible ways to win the game */    if (matrix[0][0]==79 && matrix[0][1]==79 && matrix[0][2]==79) {
        return 0;
    } else if (matrix[1][0]==79 && matrix[1][1]==79 && matrix[1][2]==79) {
        return 0;
    } else if (matrix[2][0]==79 && matrix[2][1]==79 && matrix[2][2]==79) {
        return 0;
    } else if (matrix[0][0]==79 && matrix[1][0]==79 && matrix[2][0]==79) {
        return 0;
    } else if (matrix[0][1]==79 && matrix[1][1]==79 && matrix[2][1]==79) {
        return 0;
    } else if (matrix[0][2]==79 && matrix[1][2]==79 && matrix[2][2]==79) {
        return 0;
    } else if (matrix[0][0]==79 && matrix[1][1]==79 && matrix[2][2]==79) {
        return 0;
    } else if (matrix[0][2]==79 && matrix[1][1]==79 && matrix[2][0]==79) {
        return 0;
    } else if (matrix[0][0]==88 && matrix[0][1]==88 && matrix[0][2]==88) {
        return 0;
    } else if (matrix[1][0]==88 && matrix[1][1]==88 && matrix[1][2]==88) {
        return 0;
    } else if (matrix[2][0]==88 && matrix[2][1]==88 && matrix[2][2]==88) {
        return 0;
    } else if (matrix[0][0]==88 && matrix[1][0]==88 && matrix[2][0]==88) {
        return 0;
    } else if (matrix[0][1]==88 && matrix[1][1]==88 && matrix[2][1]==88) {
        return 0;
    } else if (matrix[0][2]==88 && matrix[1][2]==88 && matrix[2][2]==88) {
        return 0;
    } else if (matrix[0][0]==88 && matrix[1][1]==88 && matrix[2][2]==88) {
        return 0;
    } else if (matrix[0][2]==88 && matrix[1][1]==88 && matrix[2][0]==88) {
        return 0;
    } else {
        return 1;
    }
}

[COLOR=royalblue][B]void checkTie(int matrix[][COLUMNS], int rows) { [/B][COLOR=seagreen]/* check if the game ended in a tie */[B]
    int i=0, j=0;
    
    for (i=0; i<ROWS; i++) {
        for (j=0; j<COLUMNS; j++) {
            if (matrix[i][j]==79 || matrix[i][j]==88) {
                printf("Oops, the game ended in a tie!\n\n");
                exit(0);
            }
        }
    }
}[/B]
void checkStatus() { [COLOR=seagreen]/* check status of the game after each round */    int i=0, j=0, k=0;
    int matrix[ROWS][COLUMNS] = { 0 };
    int newMatrix[ROWS][COLUMNS]= { 0 };

    newMatrix[ROWS][COLUMNS]=printMatrix(matrix, ROWS);

    while (checkWinner(newMatrix, ROWS)!=0) { [COLOR=seagreen]/* continue the game until one player has won ... */        playerOne(newMatrix, ROWS);
        playerTwo(newMatrix, ROWS);
        [COLOR=royalblue][B]checkTie(newMatrix, ROWS);[/B] [COLOR=seagreen]/* ... or the game ends in a tie */    }
}

int playerOne(int matrix[][COLUMNS], int rows) {
    int x1=0, y1=0, error=0;

    printf("Player 1, it's your turn. Please enter coordinates: ");
    scanf("%d %d", &x1, &y1);
    putchar('\n');
    if ((x1 <= 0 || x1 > 3) || (y1 <= 0 || y1 > 3)) { [COLOR=seagreen]/* if Player 1's input is invalid, ask again */        printf("\nINVALID INPUT! Try again ...\n\n");
        playerOne(matrix, ROWS);
        error=1;
    } else if (matrix[x1-1][y1-1]==79 || matrix[x1-1][y1-1]==88) { [COLOR=seagreen]/* if Player 1 chooses a field that is already taken, ask again */        printf("Field already taken! Try again ...\n\n");
        playerOne(matrix, ROWS);
        error=2;
    }

    if (error != 1 && error != 2) { [COLOR=seagreen]/* only print matrix if user input is valid */        matrix[x1-1][y1-1]=88; [COLOR=seagreen]/* ASCII value for 'X' */        printMatrix(matrix, ROWS);
        if (checkWinner(matrix, ROWS)==0) {
            printf("Congratulations, Player 1! You won the game.\n\n");
        } 
    }
    return matrix[ROWS][COLUMNS];
}

int playerTwo(int matrix[][COLUMNS], int rows) {
    int x2=0, y2=0, error=0;

    printf("Player 2, it's your turn. Please enter coordinates: ");
    scanf("%d %d", &x2, &y2);
    putchar('\n');
    if ((x2 <= 0 || x2 > 3) || (y2 <= 0 || y2 > 3)) { [COLOR=seagreen]/* if Player 2's input is invalid, ask again */        printf("\nINVALID INPUT! Try again ...\n\n");
        playerTwo(matrix, ROWS);
        error=1;
    } else if (matrix[x2-1][y2-1]==79 || matrix[x2-1][y2-1]==88) { [COLOR=seagreen]/* if Player 2 chooses a field that is already taken, ask again */        printf("Field already taken! Try again ...\n\n");
        playerTwo(matrix, ROWS);
        error=2;
    }

    if (error != 1 && error != 2) { [COLOR=seagreen]/* only print matrix if user input is valid */        matrix[x2-1][y2-1]=79; [COLOR=seagreen]/* ASCII value for 'O' */        printMatrix(matrix, ROWS);
        if (checkWinner(matrix, ROWS)==0) {
            printf("Congratulations, Player 2! You won the game.\n\n");
        } 
    }
    return matrix[ROWS][COLUMNS];
}

int printMatrix(int matrix[][COLUMNS], int rows) {
    int i=0, j=0;
    int resultMatrix[ROWS][COLUMNS] = { 0 };

    for (i=0; i<ROWS; i++) {
        for (j=0; j<COLUMNS; j++) {
            if (matrix[i][j] == 88 || matrix[i][j] == 79) {
                (j<2) ? (printf(" %c |", matrix[i][j])) : (printf(" %c", matrix[i][j]));
            } else {
                (j<2) ? (printf("   |", matrix[i][j])) : (printf("", matrix[i][j]));
            }
            resultMatrix[i][j]=matrix[i][j];
        }
        printf(i<2 ? "\n---+---+---\n" : "");
     }
     printf("\n\n");

     return resultMatrix[i][j];
}

int main(void) {
    int i=0;
    int matrix[ROWS][COLUMNS] = { 0 };
    double time1=0.0, time2=0.0;

    time1=clock();

    printf("TIC TAC TOE\n\n");
    printf("Player 1 ... X\nPlayer 2 ... O\n\n");

    while (checkWinner(matrix, ROWS)!=0) { [COLOR=seagreen]/* continue checking status of the game until it ends one way or another */        checkStatus();
    }

    time2=clock()-time1;
    time2=time2/CLOCKS_PER_SEC;

    printf("\nThe game lasted %.2lf minutes.\n\n", time2/60);

    return 0;
}
 
Zuletzt bearbeitet:
AW: [C] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

hab das ganze nur mal kurz überflogen, und 2 größere Schwachstellen in der Logik gefunden:
1. Position des Aufrufes von checkTie();
Code:
while (checkWinner(newMatrix, ROWS)!=0) 
{ [COLOR=seagreen]/* continue the game until one player has won ... */         
     playerOne(newMatrix, ROWS);        
     playerTwo(newMatrix, ROWS);         
     [COLOR=royalblue][B]checkTie(newMatrix, ROWS);[/B] [COLOR=seagreen]/* ... or the game ends in a tie */    
}
PlayerOne setzt einen Stein, dann PlayerTwo. Unentschieden gibts ja, wenn das Spielbrett voll ist, also nach 9 Zügen( = 9 belegte Felder):
Also folgende Reihenfolge: Zug1: PlayerOne; Zug2: PlayerTwo; Zug3: PlayerOne ...
Wenn du das durchspielst, kommst du drauf, dass Spieler1 den letzten Zug macht, also das Unentschieden nach dem letzten Zug von PlayerOne und vor dem (5.) Zug von PlayerTwo festliegt. checkTie() muss also zwischen playerone() und playertwo()

2. Die funktion checkTie()
Code:
[B]void checkTie(int matrix[][COLUMNS], int rows) 
{ [/B]/* check if the game ended in a tie */[B]    
     int i=0, j=0;         
[COLOR=darkred]     for (i=0; i<ROWS; i++) {        
         for (j=0; j<COLUMNS; j++) {            
             if ([COLOR=navy]matrix[[COLOR=darkred]i][[COLOR=darkred]j]==79 || matrix[[COLOR=darkred]i][[COLOR=darkred]j]==88) {                 
                printf("Oops, the game ended in a tie!\n\n");                
                exit(0);             
             }         
        }    
    } 
}[/B]
Überleg dir mal, was hier denn genau passiert! Du gehst alle 9 Felder durch, und im Falle das:
Spieler1 ein Kreuz gemacht hat
ODER
Spieler2 ein Kreuz gemacht hat

bricht das Spiel ab. Das ist bei jedem Aufruf von checkTie() nach dem ersten Zug der Fall. Verständlich?

Du prüfst nach 2 Zügen das erste Mal die Funktion, also bricht nach 2 Zügen das Spiel auf jeden Fall ab.

Korrekt wäre: Du prüfst, ob auf allen Feldern bereits ein Stein/Kreuz liegt, und nur in diesem Falle brichst du das Spiel ab. Du könntest zB alle bisher gesetzten
Kreuze zählen, und bei 9 brichst du das Spiel ab. Ich denke, dass das auch dein Ansatz war.

Hoffentlich konnte ich dir ein wenig helfen, es sind zwar noch ein paar mehr "Schwachstellen/Logikfehler" drinnen, allerdings betreffen sie dein jetztiges Problem nicht direkt.
Wenns nach den Verbesserungen immer noch nicht klappt, kann ich auch da ein paar Tipps geben.
Plane deinen Code immer Schritt für Schritt: Welche Schleifen brauche ich, was möchte ich genau abfragen, und noch wichtiger: Macht das, was ich geschrieben habe, auch wirklich genau das, was ich will? Programmieren ist sehr direkt, du sagst dem Computer genau, was er tun soll. Und genau das wird er dann auch tun! Wenn man auch nur kurze Zeit ein wenig unaufmerksam ist, und einfach das hinschreibt, was einem in den Kopf fällt (also so ist das bei mir) kann ich den Code quasi wegwerfen. Ein Logik-Fehler reicht aus, und das Programm tut nicht das was man eigentlich wollte, und man darf viel länger, als das "richtig" schreiben gedauert hätte, nach Fehlern suchen :) .
 
Zuletzt bearbeitet:
AW: [C] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Wenn du das durchspielst, kommst du drauf, dass Spieler1 den letzten Zug macht, also das Unentschieden nach dem letzten Zug von PlayerOne und vor dem (5.) Zug von PlayerTwo festliegt. checkTie() muss also zwischen playerone() und playertwo()
Kann ich mir noch einigermaßen vorstellen.
Du gehst alle 9 Felder durch, und im Falle das:
Spieler1 ein Kreuz gemacht hat
ODER
Spieler2 ein Kreuz gemacht hat

bricht das Spiel ab. Das ist bei jedem Aufruf von checkTie() nach dem ersten Zug der Fall. Verständlich?
Wie genau soll das hier mit den Spielern zusammenhängen? Ich dachte, der Code durchläuft nach jeder Runde die gesamte Matrix und prüft für jedes Feld, ob bereits ein X oder ein O darin gespeichert ist, und wenn ja --> unentschieden (da ja das Spiel im Falle eines Sieges schon vorher durch die jeweilige playerFunktion beendet worden wäre)
Du prüfst nach 2 Zügen das erste Mal die Funktion, also bricht nach 2 Zügen das Spiel auf jeden Fall ab.
[EDIT* ... Erklärung siehe Postingende]
Ok, jetzt funktioniert die Abfrage
Code:
void checkStatus() { [COLOR=seagreen]/* check status of the game after each round */   [COLOR=royalblue][B] int i=0;[/B]    int matrix[ROWS][COLUMNS] = { 0 };
    int newMatrix[ROWS][COLUMNS]= { 0 };

    newMatrix[ROWS][COLUMNS]=printMatrix(matrix, ROWS);

    while (checkWinner(newMatrix, ROWS)!=0) { [COLOR=seagreen]/* continue the game until one player has won ... */        playerOne(newMatrix, ROWS);
       [COLOR=royalblue][B] i++;
        if (i==5) { [/B][COLOR=seagreen]/* Player 1 has the last turn (9th). Afterwards, check for a tie */[B]
            checkTie(newMatrix, ROWS); [/B][COLOR=seagreen]/* ... or the game ends in a tie */[B]
        }[/B]        playerTwo(newMatrix, ROWS);
    }
}
Korrekt wäre: Du prüfst, ob auf allen Feldern bereits ein Stein/Kreuz liegt, und nur in diesem Falle brichst du das Spiel ab. Du könntest zB alle bisher gesetzten
Kreuze zählen, und bei 9 brichst du das Spiel ab. Ich denke, dass das auch dein Ansatz war.
Ja, das hatte ich vor.
Hoffentlich konnte ich dir ein wenig helfen, es sind zwar noch ein paar mehr "Schwachstellen/Logikfehler" drinnen, allerdings betreffen sie dein jetztiges Problem nicht direkt.
Falls du mit "Schwachstellen/Logikfehler" ineffiziente Code-Teile meinst, okay, das weiß ich, dass es die gibt. Aber um sowas kümmere ich mich jetzt noch nicht wirklich. Ich bin immer noch Lerner in C und mein oberstes Ziel ist es ATM, immer schwierigere und längere Codes zu schreiben, die auch genauso funktionieren, wie sie sollen. Sobald ich mich in C wirklich sicher fühle, gehe ich solche Dinge wie Effizienz an ... :)

Eine wirklich Schwachstelle ist wohl die while Schleife in der main, die, so wie ich das verstehe, endlos läuft und damit die Ausgabe der Spielzeit am Ende des Codes verhindert (das Programm gelangt dank der Schleife nie dort hin). Ansonsten wäre mir aber nichts aufgefallen, das jetzt kritisiert werden müsste. Die Profis unter euch wären vielleicht mit ein paar Funktionen weniger ausgekommen, aber das hängt dann auch wieder vom persönlichen Programmierstil ab. Ich zerlege ein großes Problem eben gerne in viele kleine und bearbeite diese möglichst unabhängig voneinander. So tue ich mir einfach leichter. Kann auch sein, dass das noch aus meiner Java-Zeit kommt. :D

Was ich mir aber nicht unterstellen lasse, ist, dass ich einfach hinschreiben würde, was mir so durch den Kopf geht. Ich denke schon sehr intensiv nach beim Programmieren, nur manchmal verlaufe ich mich in eine vermeintliche Sackgasse (v.a. bei für mich neuen Dingen. Es sei erwähnt, dass ich noch nie zuvor mit Matrizen in C gearbeitet habe!). Entweder ich kann den gedanklichen Knoten dann lösen, oder ich versuche, einen Weg um das Problem herum zu finden.

Werde mir die Funktion checkTie() jetzt noch einmal vornehmen. Würde mich wirklich freuen, wenn ich das noch hinbekäme ...

[*EDIT]
Hab's jetzt hinbekommen. Danke für den Hinweis, die Überprüfung zwischen die beiden Spieler-Funktionen zu packen!!! :daumen:

[EDIT2]
So, für ein Unentschieden wird jetzt schon die korrekte Spieldauer angezeigt. In der main musste ich dazu die Schleife komplett entfernen. Schritt für Schritt komme ich nun doch weiter. ;)
Code:
#include <stdio.h>
#include <time.h>

#define ROWS 3
#define COLUMNS 3

int checkWinner(int matrix[][COLUMNS], int rows) { [COLOR=seagreen]/* all possible ways to win the game */    if (matrix[0][0]==79 && matrix[0][1]==79 && matrix[0][2]==79) {
        return 0;
    } else if (matrix[1][0]==79 && matrix[1][1]==79 && matrix[1][2]==79) {
        return 0;
    } else if (matrix[2][0]==79 && matrix[2][1]==79 && matrix[2][2]==79) {
        return 0;
    } else if (matrix[0][0]==79 && matrix[1][0]==79 && matrix[2][0]==79) {
        return 0;
    } else if (matrix[0][1]==79 && matrix[1][1]==79 && matrix[2][1]==79) {
        return 0;
    } else if (matrix[0][2]==79 && matrix[1][2]==79 && matrix[2][2]==79) {
        return 0;
    } else if (matrix[0][0]==79 && matrix[1][1]==79 && matrix[2][2]==79) {
        return 0;
    } else if (matrix[0][2]==79 && matrix[1][1]==79 && matrix[2][0]==79) {
        return 0;
    } else if (matrix[0][0]==88 && matrix[0][1]==88 && matrix[0][2]==88) {
        return 0;
    } else if (matrix[1][0]==88 && matrix[1][1]==88 && matrix[1][2]==88) {
        return 0;
    } else if (matrix[2][0]==88 && matrix[2][1]==88 && matrix[2][2]==88) {
        return 0;
    } else if (matrix[0][0]==88 && matrix[1][0]==88 && matrix[2][0]==88) {
        return 0;
    } else if (matrix[0][1]==88 && matrix[1][1]==88 && matrix[2][1]==88) {
        return 0;
    } else if (matrix[0][2]==88 && matrix[1][2]==88 && matrix[2][2]==88) {
        return 0;
    } else if (matrix[0][0]==88 && matrix[1][1]==88 && matrix[2][2]==88) {
        return 0;
    } else if (matrix[0][2]==88 && matrix[1][1]==88 && matrix[2][0]==88) {
        return 0;
    } else {
        return 1;
    }
}

int checkTie(int matrix[][COLUMNS], int rows) { [COLOR=seagreen]/* check if the game ended in a tie */    int i=0, j=0;
    
    for (i=0; i<ROWS; i++) {
        for (j=0; j<COLUMNS; j++) {
            if (matrix[i][j]==79 || matrix[i][j]==88) {
                printf("Oops, the game ended in a tie!\n");
                return 0;
            }
        }
    }

    return 1;
}

int checkStatus() { [COLOR=seagreen]/* check status of the game after each round */    int i=0;
    int matrix[ROWS][COLUMNS] = { 0 };
    int newMatrix[ROWS][COLUMNS]= { 0 };

    newMatrix[ROWS][COLUMNS]=printMatrix(matrix, ROWS);

    while (checkWinner(newMatrix, ROWS)!=0) { [COLOR=seagreen]/* continue the game until one player has won ... */        playerOne(newMatrix, ROWS);
        i++;
        if (i==5 && (checkTie(newMatrix, ROWS)==0)) { [COLOR=seagreen]/* Player 1 has the last turn (9th). Afterwards, check for a tie */             return 0;  [COLOR=seagreen]/* ... or the game ends in a tie */             }
        }
        playerTwo(newMatrix, ROWS);
    }

    return 1;
}

int playerOne(int matrix[][COLUMNS], int rows) {
    int x1=0, y1=0, error=0;

    printf("Player 1, it's your turn. Please enter coordinates: ");
    scanf("%d %d", &x1, &y1);
    putchar('\n');
    if ((x1 <= 0 || x1 > 3) || (y1 <= 0 || y1 > 3)) { [COLOR=seagreen]/* if Player 1's input is invalid, ask again */        printf("\nINVALID INPUT! Try again ...\n\n");
        playerOne(matrix, ROWS);
        error=1;
    } else if (matrix[x1-1][y1-1]==79 || matrix[x1-1][y1-1]==88) { [COLOR=seagreen]/* if Player 1 chooses a field that is already taken, ask again */        printf("Field already taken! Try again ...\n\n");
        playerOne(matrix, ROWS);
        error=2;
    }

    if (error != 1 && error != 2) { [COLOR=seagreen]/* only print matrix if user input is valid */        matrix[x1-1][y1-1]=88; [COLOR=seagreen]/* ASCII value for 'X' */        printMatrix(matrix, ROWS);
        if (checkWinner(matrix, ROWS)==0) {
            printf("Congratulations, Player 1! You won the game.\n\n");
        } 
    }
    return matrix[ROWS][COLUMNS];
}

int playerTwo(int matrix[][COLUMNS], int rows) {
    int x2=0, y2=0, error=0;

    printf("Player 2, it's your turn. Please enter coordinates: ");
    scanf("%d %d", &x2, &y2);
    putchar('\n');
    if ((x2 <= 0 || x2 > 3) || (y2 <= 0 || y2 > 3)) { [COLOR=seagreen]/* if Player 2's input is invalid, ask again */        printf("\nINVALID INPUT! Try again ...\n\n");
        playerTwo(matrix, ROWS);
        error=1;
    } else if (matrix[x2-1][y2-1]==79 || matrix[x2-1][y2-1]==88) { [COLOR=seagreen]/* if Player 2 chooses a field that is already taken, ask again */        printf("Field already taken! Try again ...\n\n");
        playerTwo(matrix, ROWS);
        error=2;
    }

    if (error != 1 && error != 2) { [COLOR=seagreen]/* only print matrix if user input is valid */        matrix[x2-1][y2-1]=79; [COLOR=seagreen]/* ASCII value for 'O' */        printMatrix(matrix, ROWS);
        if (checkWinner(matrix, ROWS)==0) {
            printf("Congratulations, Player 2! You won the game.\n\n");
        } 
    }
    return matrix[ROWS][COLUMNS];
}

int printMatrix(int matrix[][COLUMNS], int rows) {
    int i=0, j=0;
    int resultMatrix[ROWS][COLUMNS] = { 0 };

    for (i=0; i<ROWS; i++) {
        for (j=0; j<COLUMNS; j++) {
            if (matrix[i][j] == 88 || matrix[i][j] == 79) {
                (j<2) ? (printf(" %c |", matrix[i][j])) : (printf(" %c", matrix[i][j]));
            } else {
                (j<2) ? (printf("   |", matrix[i][j])) : (printf("", matrix[i][j]));
            }
            resultMatrix[i][j]=matrix[i][j];
        }
        printf(i<2 ? "\n---+---+---\n" : "");
     }
     printf("\n\n");

     return resultMatrix[i][j];
}

int main(void) {
    int i=0;
    double time1=0.0, time2=0.0;

    time1=clock();

    printf("TIC TAC TOE\n\n");
    printf("Player 1 ... X\nPlayer 2 ... O\n\n");

   [COLOR=royalblue][B] if (checkStatus()==0) {
        time2=clock()-time1;
        time2=time2/CLOCKS_PER_SEC;
        printf("\nThe game lasted %.2lf minutes.\n\n", time2/60);
    }[/B]
    return 0;
}
Jetzt nur noch eine Zeitmessung für den Siegesfall eines Spielers hinkriegen, dann hätte ich es geschafft ...

[EDIT3]

MADE IT!!! :D

Blau markiert sind jene Änderungen, die notwendig waren, um das gewünschte Ergebnis zu liefern:
Code:
#include <stdio.h>
#include <time.h>

#define ROWS 3
#define COLUMNS 3

int checkWinner(int matrix[][COLUMNS], int rows) { [COLOR=seagreen]/* all possible ways to win the game */    if (matrix[0][0]==79 && matrix[0][1]==79 && matrix[0][2]==79) {
        return 0;
    } else if (matrix[1][0]==79 && matrix[1][1]==79 && matrix[1][2]==79) {
        return 0;
    } else if (matrix[2][0]==79 && matrix[2][1]==79 && matrix[2][2]==79) {
        return 0;
    } else if (matrix[0][0]==79 && matrix[1][0]==79 && matrix[2][0]==79) {
        return 0;
    } else if (matrix[0][1]==79 && matrix[1][1]==79 && matrix[2][1]==79) {
        return 0;
    } else if (matrix[0][2]==79 && matrix[1][2]==79 && matrix[2][2]==79) {
        return 0;
    } else if (matrix[0][0]==79 && matrix[1][1]==79 && matrix[2][2]==79) {
        return 0;
    } else if (matrix[0][2]==79 && matrix[1][1]==79 && matrix[2][0]==79) {
        return 0;
    } else if (matrix[0][0]==88 && matrix[0][1]==88 && matrix[0][2]==88) {
        return 0;
    } else if (matrix[1][0]==88 && matrix[1][1]==88 && matrix[1][2]==88) {
        return 0;
    } else if (matrix[2][0]==88 && matrix[2][1]==88 && matrix[2][2]==88) {
        return 0;
    } else if (matrix[0][0]==88 && matrix[1][0]==88 && matrix[2][0]==88) {
        return 0;
    } else if (matrix[0][1]==88 && matrix[1][1]==88 && matrix[2][1]==88) {
        return 0;
    } else if (matrix[0][2]==88 && matrix[1][2]==88 && matrix[2][2]==88) {
        return 0;
    } else if (matrix[0][0]==88 && matrix[1][1]==88 && matrix[2][2]==88) {
        return 0;
    } else if (matrix[0][2]==88 && matrix[1][1]==88 && matrix[2][0]==88) {
        return 0;
    } else {
        return 1;
    }
}

int checkTie(int matrix[][COLUMNS], int rows) { [COLOR=seagreen]/* check if the game ended in a tie */    int i=0, j=0;
    
    for (i=0; i<ROWS; i++) {
        for (j=0; j<COLUMNS; j++) {
            if (matrix[i][j]==79 || matrix[i][j]==88) {
                printf("Oops, the game ended in a tie!\n");
                return 0;
            }
        }
    }

    return 1;
}

int checkStatus() { [COLOR=seagreen]/* check status of the game after each round */    int i=0;
    int matrix[ROWS][COLUMNS] = { 0 };
    int newMatrix[ROWS][COLUMNS]= { 0 };

    newMatrix[ROWS][COLUMNS]=printMatrix(matrix, ROWS);

    while (checkWinner(newMatrix, ROWS)!=0) { [COLOR=seagreen]/* continue the game until one player has won ... */[COLOR=royalblue][B]        if (playerOne(newMatrix, ROWS)==0) {
            return 0;
        }[/B]        i++;
        if (i==5 && (checkTie(newMatrix, ROWS)==0)) {[COLOR=seagreen] /* Player 1 has the last turn (9th). Afterwards, check for a tie */            return 0; [COLOR=seagreen] /* ... or the game ends in a tie */        }
    [COLOR=royalblue][B]    if (playerTwo(newMatrix, ROWS)==0) {
            return 0;
        }[/B]    }

    return 1;
}

int playerOne(int matrix[][COLUMNS], int rows) {
    int x1=0, y1=0, error=0;

    printf("Player 1, it's your turn. Please enter coordinates: ");
    scanf("%d %d", &x1, &y1);
    putchar('\n');
    if ((x1 <= 0 || x1 > 3) || (y1 <= 0 || y1 > 3)) { [COLOR=seagreen]/* if Player 1's input is invalid, ask again */        printf("\nINVALID INPUT! Try again ...\n\n");
        playerOne(matrix, ROWS);
        error=1;
    } else if (matrix[x1-1][y1-1]==79 || matrix[x1-1][y1-1]==88) { [COLOR=seagreen]/* if Player 1 chooses a field that is already taken, ask again */        printf("Field already taken! Try again ...\n\n");
        playerOne(matrix, ROWS);
        error=2;
    }

    if (error != 1 && error != 2) { [COLOR=seagreen]/* only print matrix if user input is valid */        matrix[x1-1][y1-1]=88;[COLOR=seagreen] /* ASCII value for 'X' */        printMatrix(matrix, ROWS);
        if (checkWinner(matrix, ROWS)==0) {
            printf("Congratulations, Player 1! You won the game.\n");
            [COLOR=royalblue][B]return 0;[/B]        } 
    }
    return matrix[ROWS][COLUMNS];
}

int playerTwo(int matrix[][COLUMNS], int rows) {
    int x2=0, y2=0, error=0;

    printf("Player 2, it's your turn. Please enter coordinates: ");
    scanf("%d %d", &x2, &y2);
    putchar('\n');
    if ((x2 <= 0 || x2 > 3) || (y2 <= 0 || y2 > 3)) { [COLOR=seagreen]/* if Player 2's input is invalid, ask again */        printf("\nINVALID INPUT! Try again ...\n\n");
        playerTwo(matrix, ROWS);
        error=1;
    } else if (matrix[x2-1][y2-1]==79 || matrix[x2-1][y2-1]==88) { [COLOR=seagreen]/* if Player 2 chooses a field that is already taken, ask again */        printf("Field already taken! Try again ...\n\n");
        playerTwo(matrix, ROWS);
        error=2;
    }

    if (error != 1 && error != 2) { [COLOR=seagreen]/* only print matrix if user input is valid */        matrix[x2-1][y2-1]=79; [COLOR=seagreen]/* ASCII value for 'O' */        printMatrix(matrix, ROWS);
        if (checkWinner(matrix, ROWS)==0) {
            printf("Congratulations, Player 2! You won the game.\n");
            [COLOR=royalblue][B]return 0;[/B]        } 
    }
    return matrix[ROWS][COLUMNS];
}

int printMatrix(int matrix[][COLUMNS], int rows) {
    int i=0, j=0;
    int resultMatrix[ROWS][COLUMNS] = { 0 };

    for (i=0; i<ROWS; i++) {
        for (j=0; j<COLUMNS; j++) {
            if (matrix[i][j] == 88 || matrix[i][j] == 79) {
                (j<2) ? (printf(" %c |", matrix[i][j])) : (printf(" %c", matrix[i][j]));
            } else {
                (j<2) ? (printf("   |", matrix[i][j])) : (printf("", matrix[i][j]));
            }
            resultMatrix[i][j]=matrix[i][j];
        }
        printf(i<2 ? "\n---+---+---\n" : "");
     }
     printf("\n\n");

     return resultMatrix[i][j];
}

int main(void) {
    int i=0;
    double time1=0.0, time2=0.0;

    time1=clock();

    printf("TIC TAC TOE\n\n");
    printf("Player 1 ... X\nPlayer 2 ... O\n\n");

    [COLOR=royalblue][B]if (checkStatus()==0) {
        time2=clock()-time1;
        time2=time2/CLOCKS_PER_SEC;
        printf("\nThe game lasted %.2lf minutes.\n\n", time2/60);
    }[/B]
    return 0;
}
Vielen Dank noch einmal, dass du mich aus der gedanklichen Sackgasse geführt hast, Freddycbv! Jetzt können wir über so Dinge, wie Effizienz und "Schwachstellen" im Code reden. Jetzt, wo alles so läuft, wie ich das wollte, habe ich nichts gegen Optimierungen. ;)
 
Zuletzt bearbeitet:
AW: [C] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Super, dass es jetzt funktioniert!

Mit den Logikfehlern meine ich, dass deine Funktionen nicht immer das machen, für das ihr Name eigentlich steht. Das verwirrt ein wenig, und ist nicht ganz so "sauber"

1. checkWinner() prüft nicht, WER gewonnen hat, sondern ob das Spiel zuende ist (weil irgendeiner gewonnen hat). Besser wäre, wenn es direkt prüfen würde, wer gewonnen hat, und entsprechend etwas zurückgibt. Bei deiner jetzigen Implementierung geht es eigentlich auch so wie es bisher ist (Das Spiel funktioniert ja :) ), weil du checkWinner() immer nach dem Zug eines Spielers aufrufst, und beim ersten, wo CheckWinner() "0" zurückgibt, der hat gewonnen.

2. checkStatus() gibt immer 0 zurück.
Ein Spiel kann ja nur in 3 Situationen enden:
1) Niemand gewonnen:
Code:
if (i==5 && (checkTie(newMatrix, ROWS)==0)) 
{[COLOR=seagreen] /* Player 1 has the last turn (9th). Afterwards, check for a tie */    return 0; [COLOR=seagreen] /* ... or the game ends in a tie */}
2) Spieler 1 gewonnen:
Code:
if (playerOne(newMatrix, ROWS)==0) 
{      
     return 0;         
}
3) Spieler 2 gewonnen:
Code:
[COLOR=royalblue][COLOR=black]if (playerTwo(newMatrix, ROWS)==0) 
{       
    return 0;        
}
In allen 3 Fällen wird 0 zurückgegeben.
Wäre es nicht besser, wenn checkStatus() das Ergebniss des Spieles zurüchgibt? ZB. 0 für unentschieden, 1 für Sieg von Spieler1 und 2 für Spieler2?
Wenn du das machst, musst du nur in der main() aufpassen, weil die Zeit (bisher) nur ausgegeben wird, wenn checkStatus() 0 zurückgibt:
Code:
if (checkStatus()==0) 
{     
    time2=clock()-time1;    
    time2=time2/CLOCKS_PER_SEC;    
    printf("\nThe game lasted %.2lf minutes.\n\n", time2/60);  
}
Du kannst hier getrost das if(){} rausnehmen, und die Anweisungen in jedem Fall ausführen:
Code:
checkStatus()        
time2=clock()-time1;         
time2=time2/CLOCKS_PER_SEC;         
printf("\nThe game lasted %.2lf minutes.\n\n", time2/60);
Wenn CheckStatus() dann auch 0, 1 oder 2 zurückgibt (je nach Ausgang des Spieles) kannst du hier dann auch nach dem Gewinner prüfen:
Code:
int GameResult = [COLOR=royalblue][COLOR=black]checkStatus();
if(GameResult == 0 ){...}
else if(GameResult == 1){...}
else if(GameResult == 2){...}
3. checkTie()
Wie genau soll das hier mit den Spielern zusammenhängen? Ich dachte, der Code durchläuft nach jeder Runde die gesamte Matrix und prüft für jedes Feld, ob bereits ein X oder ein O darin gespeichert ist, und wenn ja --> unentschieden (da ja das Spiel im Falle eines Sieges schon vorher durch die jeweilige playerFunktion beendet worden wäre)
Richtig! Es prüft für jedes Feld, ob bereits ein X oder ein O darin gespeichert ist. Es reicht 1 besetztes Feld, und es gibt "Unentschieden" zurück.
Es prüft nicht, ob in allen Feldern bereits ein X oder O gespeichert ist! Verstehst du den Unterschied? Du könntest zB. alle belegten Felder zählen (und nicht schon beim ersten Feld "Unentschieden" zurückgeben), und bei 9 belegten Feldern ein "Unentschieden" zurückgeben.


Hoffentlich bin ich nicht zu kleinlich :) Ich mag strukturierten Aufbau, das hilft vorallem, wenn man seine Projekte später nochmal erweitern will.
 
AW: [C] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Bei deinen Punkten #1 und #2 kann man wohl darüber streiten, was jetzt der "sauberere" Weg ist. Mir persönlich gefällt ehrlich gesagt meine Variante besser. Außerdem macht es ja für den Computer keinen Unterschied, welcher der beiden Spieler gewinnt und die beiden Spieler (die Menschen) werden sich den Code hinter dem Programm wohl nie anschauen. Und nachträgliche Erweiterungen kann man in dem Fall wohl auch ausschließen, weil nie mehr als maximal 2 Personen TIC-TAC-TOE spielen können und für 2 Personen ist der Code ja schon geschrieben. ;)

Wieso ich angeblich das if aus der main rausnehmen kann, kann ich gerade nicht ganz nachvollziehen. Ebenso, wieso checkStatus() immer 0 zurückgeben soll ...

^^ checkStatus() führt seine Überprüfungen so lange durch, bis entweder checkWinner() 0 zurückgibt, oder checkTie() 0 zurückgibt. Das ist ja nicht nach jeder Runde der Fall?!
Richtig! Es prüft für jedes Feld, ob bereits ein X oder ein O darin gespeichert ist. Es reicht 1 besetztes Feld, und es gibt "Unentschieden" zurück.
Für mein Verständnis widersprechen sich deine beiden Sätze hier. Es soll ja auch für jedes Feld überprüft werden, ob ein X oder ein O darin gespeichert ist und wenn das in allen 9 Feldern der Fall ist --> unentschieden.
Es prüft nicht, ob in allen Feldern bereits ein X oder O gespeichert ist!
Warum nicht? Ich glaube schon, dass es das tut. Muss es eigentlich sogar, weil sonst checkTie() nicht richtig funktionieren würde und das tut es aber.

Die Funktion checkTie() wird ja erst verlassen, wenn beide for-Schleifen komplett abgearbeitet sind und was die machen, ist, die gesamte Matrix horizontal und vertikal zu durchlaufen. Damitz sollte also JEDES Feld erwischt werden.
 
Zuletzt bearbeitet:
AW: [C] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Dann beschränken wir uns auf Punkt 3:
Ich behaupte, CheckTie arbeitet inkorrekt! Das Programm läuft nur korrekt wegen folgendem Punkt (in checkStatus):
Code:
if (i==5 && (checkTie(newMatrix, ROWS)==0)) 
{[COLOR=seagreen] /* Player 1 has the last turn (9th). Afterwards, check for a tie */       
     return 0; [COLOR=seagreen] /* ... or the game ends in a tie */         
}
Ich behaupte: checkTie() gibt IMMER 0 zurück, nachdem der erste Stein gesetzt wurde.
d.h. "&& (checkTie(newMatrix, ROWS)==0)" in der If-Abfage kann man weglassen.
Wenn i==5, ist automatisch das Spielbrett voll, dh. es ist unentschieden.
Probiers aus! Du brauchst an dieser Stelle checkTie() nicht, es ist überflüssig, und arbeitet zudem inkorrekt.
Warum inkorrekt?
Code:
int checkTie(int matrix[][COLUMNS], int rows) 
{ [COLOR=seagreen]/* check if the game ended in a tie */      int i=0, j=0;    
      for (i=0; i<ROWS; i++) 
      { 
          for (j=0; j<COLUMNS; j++) 
         {             
              if (matrix[i][j]==79 || matrix[i][j]==88) 
             {
                 printf("Oops, the game ended in a tie!\n");
                 return 0;
             }
         }
     }      
    return 1; 
}
Das ist deine Funktion. Das ist der kritische Teil:
Code:
if (matrix[i][j]==79 || matrix[i][j]==88) {
    printf("Oops, the game ended in a tie!\n");
    return 0;
}
i bewegt sich zwischen 0 und 2, genauso j.
In der If steht: Wenn auf dem Feld[j] ein O oder ein X ist, dann gebe 0 zurück.
Alle 9 Felder werden durchgegangen, und wenn auch nur auf EINEM ein O oder X ist, wird 0 zurückgegeben:
if(Feld[0][0] == 79 || Feld[0][0] == 88) return 0;
if(Feld[0][1] == 79 || Feld[0][1] == 88) return 0;
if(Feld[0][2] == 79 || Feld[0][2] == 88) return 0;
if(Feld[1][0] == 79 || Feld[1][0] == 88) return 0;
if(Feld[1][1] == 79 || Feld[1][1] == 88) return 0;
if(Feld[1][2] == 79 || Feld[1][2] == 88) return 0;
if(Feld[2][0] == 79 || Feld[2][0] == 88) return 0;
if(Feld[2][1] == 79 || Feld[2][1] == 88) return 0;
if(Feld[2][2] == 79 || Feld[2][2] == 88) return 0;

:)
 
AW: [C] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Ich behaupte: checkTie() gibt IMMER 0 zurück, nachdem der erste Stein gesetzt wurde.
d.h. "&& (checkTie(newMatrix, ROWS)==0)" in der If-Abfage kann man weglassen.
Wenn i==5, ist automatisch das Spielbrett voll, dh. es ist unentschieden.
Probiers aus!
Hab's ausprobiert und festgestellt, dass dann "Oops, the game ended in a tie!" bei einem Unentschieden nicht mehr ausgegeben wird. Offensichtlich kann man den zweiten Teil der if-Abfrage nicht löschen. Hast du es ausprobiert?
Du brauchst an dieser Stelle checkTie() nicht, es ist überflüssig, und arbeitet zudem inkorrekt.
Warum inkorrekt?
Das ist der kritische Teil:
Code:
if (matrix[i][j]==79 || matrix[i][j]==88) {
    printf("Oops, the game ended in a tie!\n");
    return 0;
}
i bewegt sich zwischen 0 und 2, genauso j.
In der If steht: Wenn auf dem Feld[j] ein O oder ein X ist, dann gebe 0 zurück.
Alle 9 Felder werden durchgegangen, und wenn auch nur auf EINEM ein O oder X ist, wird 0 zurückgegeben:
if(Feld[0][0] == 79 || Feld[0][0] == 88) return 0;
if(Feld[0][1] == 79 || Feld[0][1] == 88) return 0;
if(Feld[0][2] == 79 || Feld[0][2] == 88) return 0;
if(Feld[1][0] == 79 || Feld[1][0] == 88) return 0;
if(Feld[1][1] == 79 || Feld[1][1] == 88) return 0;
if(Feld[1][2] == 79 || Feld[1][2] == 88) return 0;
if(Feld[2][0] == 79 || Feld[2][0] == 88) return 0;
if(Feld[2][1] == 79 || Feld[2][1] == 88) return 0;
if(Feld[2][2] == 79 || Feld[2][2] == 88) return 0;

Ich habe schon in deinem vorigen Posting verstanden, wie du dir das Verhalten der beiden for-Schleifen vorstellst. Und ich habe auch schon darauf geantwortet ...
Es prüft nicht, ob in allen Feldern bereits ein X oder O gespeichert ist!
Warum nicht? Ich glaube schon, dass es das tut. Muss es eigentlich sogar, weil sonst checkTie() nicht richtig funktionieren würde und das tut es aber.

Die Funktion checkTie() wird ja erst verlassen, wenn beide for-Schleifen komplett abgearbeitet sind und was die machen, ist, die gesamte Matrix horizontal und vertikal zu durchlaufen. Damit sollte also JEDES Feld erwischt werden.
Wenn du recht hast, was schon sein kann, dann verstehe ich aber nicht, wieso der Code in der aktuellen Version wunderbar funktioniert. Auch wenn es tatsächlich nicht so sein sollte, macht es im Spiel den Anschein, als würde die gesamte (!) Matrix auf 79er und 88er durchsucht werden (ob sie voll damit ist).

[EDIT]
Jetzt habe ich verstanden, was du mir sagen willst! :gruebel:

Die ganze Funktion checkTie() ist umsonst, weil das i==5 eh nur passieren kann, wenn es nicht schon zuvor zu einem Sieg eines Spielers gekommen ist. Und wenn es passiert, haben wir automatisch ein Unentschieden. Mein Code hat die Funktion checkTie() nur gebraucht, weil dort eben die Ausgabe von "Oops, the game ended in a tie!" passiert.

Wenn ich also besagte Ausgabe an der richtigen Stelle in checkStatus() reinpacke, kann ich checkTie() komplett löschen:
Code:
#include <stdio.h>
#include <time.h>

#define ROWS 3
#define COLUMNS 3

int checkWinner(int matrix[][COLUMNS], int rows) { /* all possible ways to win the game */
    if (matrix[0][0]==79 && matrix[0][1]==79 && matrix[0][2]==79) {
        return 0;
    } else if (matrix[1][0]==79 && matrix[1][1]==79 && matrix[1][2]==79) {
        return 0;
    } else if (matrix[2][0]==79 && matrix[2][1]==79 && matrix[2][2]==79) {
        return 0;
    } else if (matrix[0][0]==79 && matrix[1][0]==79 && matrix[2][0]==79) {
        return 0;
    } else if (matrix[0][1]==79 && matrix[1][1]==79 && matrix[2][1]==79) {
        return 0;
    } else if (matrix[0][2]==79 && matrix[1][2]==79 && matrix[2][2]==79) {
        return 0;
    } else if (matrix[0][0]==79 && matrix[1][1]==79 && matrix[2][2]==79) {
        return 0;
    } else if (matrix[0][2]==79 && matrix[1][1]==79 && matrix[2][0]==79) {
        return 0;
    } else if (matrix[0][0]==88 && matrix[0][1]==88 && matrix[0][2]==88) {
        return 0;
    } else if (matrix[1][0]==88 && matrix[1][1]==88 && matrix[1][2]==88) {
        return 0;
    } else if (matrix[2][0]==88 && matrix[2][1]==88 && matrix[2][2]==88) {
        return 0;
    } else if (matrix[0][0]==88 && matrix[1][0]==88 && matrix[2][0]==88) {
        return 0;
    } else if (matrix[0][1]==88 && matrix[1][1]==88 && matrix[2][1]==88) {
        return 0;
    } else if (matrix[0][2]==88 && matrix[1][2]==88 && matrix[2][2]==88) {
        return 0;
    } else if (matrix[0][0]==88 && matrix[1][1]==88 && matrix[2][2]==88) {
        return 0;
    } else if (matrix[0][2]==88 && matrix[1][1]==88 && matrix[2][0]==88) {
        return 0;
    } else {
        return 1;
    }
}

int checkStatus() { /* check status of the game after each round */
    int i=0;
    int matrix[ROWS][COLUMNS] = { 0 };
    int newMatrix[ROWS][COLUMNS]= { 0 };

    newMatrix[ROWS][COLUMNS]=printMatrix(matrix, ROWS);

    while (checkWinner(newMatrix, ROWS)!=0) { /* continue the game until one player has won ... */
        if (playerOne(newMatrix, ROWS)==0) {
            return 0;
        }
       [COLOR=royalblue][B] i++;
        if (i==5) { [/B][COLOR=seagreen]/* If neither player has won until the last round (= playerOne's fifth turn), it has to be a tie */[B]
            printf("Oops, the game ended in a tie!\n");
            return 0;  [/B][B]
        }[/B]        if (playerTwo(newMatrix, ROWS)==0) {
            return 0;
        }
    }

    return 1;
}

int playerOne(int matrix[][COLUMNS], int rows) {
    int x1=0, y1=0, error=0;

    printf("Player 1, it's your turn. Please enter coordinates: ");
    scanf("%d %d", &x1, &y1);
    putchar('\n');
    if ((x1 <= 0 || x1 > 3) || (y1 <= 0 || y1 > 3)) { /* if Player 1's input is invalid, ask again */
        printf("INVALID INPUT! Try again ...\n\n");
        playerOne(matrix, ROWS);
        error=1;
    } else if (matrix[x1-1][y1-1]==79 || matrix[x1-1][y1-1]==88) { /* if Player 1 chooses a field that is already taken, ask again */
        printf("Field already taken! Try again ...\n\n");
        playerOne(matrix, ROWS);
        error=2;
    }

    if (error != 1 && error != 2) { /* only print matrix if user input is valid */
        matrix[x1-1][y1-1]=88; /* ASCII value for 'X' */
        printMatrix(matrix, ROWS);
        if (checkWinner(matrix, ROWS)==0) {
            printf("Congratulations, Player 1! You won the game.\n");
            return 0;
        } 
    }
    return matrix[ROWS][COLUMNS];
}

int playerTwo(int matrix[][COLUMNS], int rows) {
    int x2=0, y2=0, error=0;

    printf("Player 2, it's your turn. Please enter coordinates: ");
    scanf("%d %d", &x2, &y2);
    putchar('\n');
    if ((x2 <= 0 || x2 > 3) || (y2 <= 0 || y2 > 3)) { /* if Player 2's input is invalid, ask again */
        printf("INVALID INPUT! Try again ...\n\n");
        playerTwo(matrix, ROWS);
        error=1;
    } else if (matrix[x2-1][y2-1]==79 || matrix[x2-1][y2-1]==88) { /* if Player 2 chooses a field that is already taken, ask again */
        printf("Field already taken! Try again ...\n\n");
        playerTwo(matrix, ROWS);
        error=2;
    }

    if (error != 1 && error != 2) { /* only print matrix if user input is valid */
        matrix[x2-1][y2-1]=79; /* ASCII value for 'O' */
        printMatrix(matrix, ROWS);
        if (checkWinner(matrix, ROWS)==0) {
            printf("Congratulations, Player 2! You won the game.\n");
            return 0;
        } 
    }
    return matrix[ROWS][COLUMNS];
}

int printMatrix(int matrix[][COLUMNS], int rows) {
    int i=0, j=0;
    int resultMatrix[ROWS][COLUMNS] = { 0 };

    for (i=0; i<ROWS; i++) {
        for (j=0; j<COLUMNS; j++) {
            if (matrix[i][j] == 88 || matrix[i][j] == 79) {
                (j<2) ? (printf(" %c |", matrix[i][j])) : (printf(" %c", matrix[i][j]));
            } else {
                (j<2) ? (printf("   |", matrix[i][j])) : (printf("", matrix[i][j]));
            }
            resultMatrix[i][j]=matrix[i][j];
        }
        printf(i<2 ? "\n---+---+---\n" : "");
     }
     printf("\n\n");

     return resultMatrix[i][j];
}

int main(void) {
    int i=0;
    double time1=0.0, time2=0.0;

    time1=clock();

    printf("TIC TAC TOE\n\n");
    printf("Player 1 ... X\nPlayer 2 ... O\n\n");

    if (checkStatus()==0) {
        time2=clock()-time1;
        time2=time2/CLOCKS_PER_SEC;
        printf("\nThe game lasted %.2lf minutes.\n\n", time2/60);
    }

    return 0;
}
Vielen Dank für die Mühe, mir das beizubringen. Aber wie du siehst, sie war nicht umsosnt. ;)
 
Zuletzt bearbeitet:
AW: [C] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

(EDIT)
war nicht ganz einfach, aber bitteschön :D
 
Zuletzt bearbeitet:
AW: [C] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Dein Problem hat mich auf eine Idee gebracht.

Als ich mir deinen Code angeschaut habe fiel mir gleich die if else if Kette auf, die überprüft ob ein Spieler gewonnen hat. Mir hat das nicht so gut gefallen also habe ich mir gedacht wie ein Algorithmus aussehen würde, der

- unabhängig von der Spielfeldgröße
- unabhängig von der Länge einer Gewinnkette

überprüft ob ein Spieler gewonnen hat.

Ich habe mir dazu ein paar Gedanken gemacht und werde dazu in den nächsten Tagen etwas posten. Vielleicht hast du ja auch Lust dich damit auseinanderzusetzen und wir können ein wenig diskutieren und vergleichen ;)
 
AW: [C] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Ja, poste ruhig! Ich schaue mir deine Vorschläge gerne an. :)
 
AW: [C] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

ich finde die überlegung von nay auch sehr interessant.
Habe mir jetzt auch eine Version der Funktion gebastelt, allerdings ist diese auf quadratische Spielfelder beschränkt.
Länge der Gewinnkette als auch Anzahl der Spieler ist dabei egal.
Ich warte allerdings mit dem Posten, da ich mir erstmal ein Testprogramm schreiben muss, um zu prüfen, ob meine Funktion auch richtig läuft :ugly:
 
AW: [C] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Neues Beispiel ... :)

Man schreibe ein Programm, dass eine Matrix horizontal und vertikal nach eingegebenen Wörtern durchsucht. Es soll möglich sein, die gesamte Matrix auszugeben, die Überprüfung durchzuführen und das Programm zu beenden. Bei enthaltenen Wörtern sollen die Koordinaten des Anfangsbuchstaben ausgegeben werden.
(Die Matrix ist gegeben bzw. darf fix definiert werden.)

Den Code hätte ich auch schon komplett fertig, so wie ich mir das vorstelle, nur leider sagt er mir immer, dass das gesuchte Wort nicht in der Matrix enthalten wäre, egal was ich eingebe (also auch bei Wörtern, die enthalten sind!). Daraus schließe ich, dass die ersten beiden if Abfragen in meiner searchMatrix() Funktion, warum auch immer, übersprungen werden und er automatisch im else landet. Die Frage: Warum?
Code:
#include <stdio.h>
#include <stdlib.h>

#define ROWS 12
#define COLUMNS 12

void searchMatrix(char *string, int matrix[][COLUMNS], int rows) {
    int i=0, j=0, k=0, length=0;

    while (*(string+length) != '\0') {
        length++;
    }

[B][COLOR=royalblue]    while (i != ROWS && j != COLUMNS) { [/B][COLOR=seagreen]/* Until the whole matrix is searched ... */[B][COLOR=royalblue]
        if (*(string+i)==matrix[i][j]) {[/B][COLOR=seagreen] /* ... search each row ... */[B][COLOR=royalblue]
            for (k=0; k<length; k++) {
                printf("%c", *(string+k));
            }
            printf(" found horizontally! %d %d\n", i+1, j+1);
        } else if (*(string+j)==matrix[i][j]) { [/B][COLOR=seagreen]/* ... and each column for a match. */[B][COLOR=royalblue]
            for (k=0; k<length; k++) {
                printf("%c", *(string+k));
            }
            printf(" found vertically! %d %d\n", i+1, j+1);
        } else { [/B][COLOR=seagreen]/* If no match is found, say so. */[B][COLOR=royalblue]
            for (k=0; k<length; k++) {
                printf("%c", *(string+k));
            }
            printf(" not found!\n");
            break;
        }
        i++;
        j++;
    }[/B]    
}

void printMatrix(int matrix[][COLUMNS], int rows) {
    int i=0, j=0;

    printf("\n+---+---+---+---+---+---+---+---+---+---+---+---+\n");
    for (i=0; i<ROWS; i++) {
        for (j=0; j<COLUMNS; j++) {
            printf("| %c ", matrix[i][j]);
            if (j==11) {
                printf("|\n+---+---+---+---+---+---+---+---+---+---+---+---+\n");
            }
        }
    }
}

int main(void) {
    int matrix[ROWS][COLUMNS] = {{'X', 'S', 'E', 'C', 'U', 'R', 'I', 'T', 'Y', 'C', 'O', 'T'},
                                 {'M', 'E', 'D', 'I', 'A', 'H', 'E', 'R', 'C', 'S', 'T', 'A'},
                                 {'K', 'C', 'F', 'X', 'J', 'A', 'E', 'S', 'I', 'I', 'L', 'S'},
                                 {'M', 'U', 'I', 'N', 'T', 'R', 'U', 'S', 'I', 'O', 'N', 'K'},
                                 {'A', 'R', 'R', 'Z', 'F', 'W', 'N', 'K', 'I', 'G', 'V', 'Z'},
                                 {'L', 'E', 'E', 'N', 'C', 'R', 'Y', 'P', 'T', 'I', 'O', 'N'},
                                 {'W', 'K', 'W', 'O', 'R', 'M', 'P', 'E', 'U', 'O', 'J', 'X'},
                                 {'A', 'V', 'A', 'M', 'D', 'N', 'D', 'P', 'J', 'H', 'A', 'L'},
                                 {'R', 'L', 'L', 'N', 'V', 'I', 'R', 'U', 'S', 'P', 'E', 'E'},
                                 {'E', 'W', 'L', 'D', 'D', 'E', 'X', 'O', 'L', 'T', 'P', 'U'},
                                 {'X', 'J', 'P', 'R', 'C', 'T', 'C', 'P', 'A', 'P', 'R', 'C'},
                                 {'G', 'K', 'B', 'U', 'F', 'F', 'E', 'R', 'S', 'L', 'T', 'B'}};
    int i=0;
    char string[13];

    printf("Matrix Search - Available commands:\n");
    printf("1 .. Enter a search string\n");
    printf("9 .. Print the matrix\n");
    printf("0 .. Quit the program\n");
    
    for ( ; ; ) { [COLOR=seagreen]/* The program should only end if the user enters 0. */        printf("\nPlease enter your command: ");
        scanf("%d", &i);
        if (i==0) {
            exit(0);
        } else if (i==9) {
            printMatrix(matrix, ROWS);
        } else if (i==1) {
            printf("Please enter search string: ");
            scanf("%s", &string);
            searchMatrix(string, matrix, ROWS);
        }
    }

    return 0;
}
 
Zuletzt bearbeitet:
AW: [C] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

zu der blau markierten while schleife... das kann doch so nix werden ^^ gehs doch mal im kopf stück für stück durch:
du fängst bei 0|0 an und schaust das gelumbe, dann wird i und j erhöht. du bist also plötzlich schon bei 1|1 statt 1|0. den rest der ersten zeile überspringste komplett usw.

und dann der schleifenkopf an sich: solange beide nicht die maximale dimension erreicht haben, mach weiter. selbst wenn du jetzt durch ne änderung zeile für zeile durchgehst, hört er nach der ersten auf - j is ja dann größer wie das maximum geworden.

solche matrizen gehste am besten mit ner doppelten for-schleife durch:
Code:
for(j = 0; j < COLUMNS; j++) {   // erst j durchgehn - spalte für spalte
    for(i = 0; i < ROWS; i++) { // dann i - zeile für zeile in einer spalte -> so wie man nen text liest ^^
        // vergleiche ersten buchstaben des suchwortes mit dem buchstaben an der matrix-position
        // wenn gleich - schau rundherum nach (die 8 angrenzenden felder - achtung ränder und ecken rausfiltern -> bei 0|0 gibts nur 3 bachbarn, bei 0|1 5 usw.), ob der 2. buchstabe des suchwortes gefunden wurde
        // hier am besten ne forschleife wieder bauen, die alle 8 drumherum kontrolliert (for k=0-7 bla) und die nicht existenten skipped
        // sollte hier irgendwo der 2. buchstabe gefunden werden, gehts in die nächste runde -> for(l=2 (die ersten beiden stimmen ja schon) bis suchwortlänge-1) schau, ob die folgenden buchstaben stimmen und brich ab, wenn was nich mehr übereinstimmt
        // is man aus der for-schleife wieder raus, gehts entweder weiter (das wort wurde noch nich gefunden - du bräuchtest irgend ne "flag" variable) bis alle 8 felder durch sin, oder er bricht nach nem fund komplett ab und gibt das ergebnis aus -> aktueller i und j wert is die gesuchte
    }
}

so könnte es prinzipiell funktionieren, denk ich mir. die letzte for schleife könntest vllt auch als while dann machen (while "string noch nich zu ende verglichen" oder "fehlerhafter vergleich") { vergleiche buchstaben } bla blubb.

hoffe, das hilft dir etwas :)
 
AW: [C] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Ich verstehe zwar jetzt, woran es scheitert, aber ich kann deinen Lösungsansatz nicht umsetzen.

Eine "einfachere" Variante (oder vielleicht eh deine, nur anders formuliert) wäre es doch, in der ersten Hälfte des Code-Konstrukts nach dem Anfangsbuchstaben des eingegebenen Wortes zu suchen. Wird dieser gefunden, geht man in der Zeile um ein Feld weiter. So werden alle Zeilen durchgemacht.
Anschließend selbes Spiel in der zweiten Hälfte des Code-Konstrukts, nur hier spaltenweise.
Code:
[COLOR=darkorange]for (i=0; i<ROWS; i++) { 
       [COLOR=darkorchid] for (j=0; j<COLUMNS; j++) {            if (*(string+i)==matrix[i][j]) {
                for (k=0; k<length; k++) {
                    printf("%c", *(string+k));
                }
                printf(" found horizontally! %d %d\n", i+1, j+1);
            [COLOR=darkorchid]} else if (*(string+j)==matrix[i][j]) { 
                for (k=0; k<length; k++) {
                    printf("%c", *(string+k));
                }
                printf(" found vertically! %d %d\n", i+1, j+1);
            }
        }    }
Wozu soll ich denn immer alle Felder rund um den Buchstaben kontrollieren? Schräg fällt sowieso weg und horizontal und vertikal kann ich doch, wie eben erklärt, aufspalten?!

^^ Genau das probiere ich jetzt jedenfalls schon die ganze Zeit, nur ist noch nicht viel dabei rausgekommen (der Code oben stimmt natürlich noch nicht). Werde noch weiterprobieren ...

[EDIT]
Irgendwie so sollte es dann wohl für die Horizontalen ausschauen:
Code:
for (i=0; i<ROWS; i++) { 
        for (j=0; j<COLUMNS; j++) {
            if (*(string+i)==matrix[i][j]) {
                for (l=i; l<COLUMNS; l++) {
                    if (*(string+i)==matrix[i][l]) {
                        for (k=0; k<length; k++) {
                            printf("%c", *(string+k));
                        }
                        printf(" found horizontally! %d %d\n", i+1, j+1);
                    }
                }
            }
        }
    }
Ist noch nicht ganz richtig. ATM erkennt er schon die Position möglicher Startbuchstaben, gibt aber leider dann auch irgendwelche anderen von Buchstaben, die zwar im Wort enthalten, aber in der Matrix nicht direkt hinter dem Startbuchstaben sind, aus. :ugly:

[EDIT2]

Da ich bei dem Problem im Gesamten nicht weiterkomme, habe ich jetzt mal versucht, nur für das Wort "SECURITY" in der ersten Zeile die richtige Ausgabe zu bekommen:
Code:
void searchMatrix(char *string, int matrix[][COLUMNS], int rows) {
    int i=0, j=0, k=0, count=0, length=0;

    while (*(string+length) != '\0') {
        length++;
    }

    for (j=0; j<COLUMNS; j++) {
        if (*(string+j)==matrix[i][j]) {
            count++;
            if (count==length) {
                for (k=0; k<length; k++) {
                    printf("%c", *(string+k));
                }
                printf(" found horizontally! %d %d\n", i+1, j+1);
            }
        }
    }
}
Allerdings gibt der leider mit dem Code gar nichts aus ...
 
Zuletzt bearbeitet:
AW: [C] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Okay, habe mir einen ganz neuen Ansatz ausgedacht ...

Da ich mit der ganzen Matrix überfordert bin, habe ich mir gedacht, ich spalte die Matrix einfach auf, indem ich aus jeder Zeile und jeder Spalte ein Feld mache und dann einfach den Feldinhalt mit dem Inhalt des eingegebenen Wortes vergleiche. Auf diese Weise habe ich zumindest schon mal die richtige Erkennung von Wörtern geschafft. Was noch nicht stimmt, ist die Ausgabe der Position des Startbuchstaben. Hier wäre Hilfe erwünscht. :)
Code:
void searchMatrix(char *string, int matrix[][COLUMNS], int rows) {
    int i=0, j=0, length=0, [B][COLOR=royalblue]searchArrayOne[COLUMNS][/B], [B][COLOR=royalblue]searchArrayTwo[ROWS][/B];

   [B] [COLOR=royalblue]for (i=0; i<COLUMNS; i++) {[/B]
        [B][COLOR=royalblue]searchArrayOne[i]=matrix[0][i];[/B] [COLOR=seagreen]/* mache aus erster Zeile ein Feld */    [B][COLOR=royalblue]}
 [COLOR=royalblue]     for (j=0; j<ROWS; j++) {[/B]
        [B][COLOR=royalblue]searchArrayTwo[j]=matrix[j][0];[/B] [COLOR=seagreen]/* mache aus erster Spalte ein Feld */   [B][COLOR=royalblue] }[/B]

    while (*(string+length) != '\0') {
        length++;
    }

    for (i=0; i<COLUMNS; i++) {
        if (*(string+i)==searchArrayOne[i]) {
            continue;
        } else {
            for (j=0; j<length; j++) {
                printf("%c", *(string+j));
            }
            printf(" found horizontally! %d %d\n", 1, i);
            break;
        }
    }

    [COLOR=seagreen]/*
    for (j=0; j<ROWS; j++) {
        if (*(string+j)==searchArrayTwo[j]) {
            continue;
        } else {
            for (i=0; i<length; i++) {
                printf("%c", *(string+i));
            }
            printf(" found vertically! %d %d\n", 1, j);
            break;
        }
    }
    */}
 
AW: [C] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

asö, diagonalen fallen weg? und is die möglich richtung nur vor/runter oder auch rückwärts/hoch? nuja, verkürzt das ganze nur ebbes, aber bleibt ja im grunde gleich ^^ ich probier mich ma "on the fly" am problem. knifflig isses auf jeden fall nen bissl *g*

Code:
bool checkFind(int x, int y, int xDir, int yDir, char *searchString, int matrix[ROWS][COLUMNS]) { //  <- position des funds, offsets zur richtungsbestimmung und die eigentlichen daten
    bool found = true; // solange true, bis der erste (vergleichs-)fehler auftritt
    // for/while irgendwas hierhin
        if(*searchString+step+1 /* sofern step bei 0 beginnt, muss ich später noch genauer überegen ^^ */ == matrix[x+(xDir*step)][y+(yDir*step)]) { //  stimmt der 2. buchstabe des suchstrings mit dem nächsten (in  entsprechender richtung liegenden) feld-buchstaben der matrix überein
            // bla blubb ^^
        }
    return found;
}

void searchMatrix(char *searchString, int matrix[ROWS][COLUMNS]) { //  <- warum hast du da eigentlich sone seltsame variante? ^^
    int max = 2; // wieviele suchrichtungen soll es geben? atm geh ich mal von nur 2en aus (vorwärts und runter)
     for(y=0; y<COLUMNS; y++) { // <- erst spalten
        for(x=0; x<ROWS; x++) { // dann zeilen ^^ - zumindest find ichs persönlich so leichter nachvollziehbar (von der reihenfolge der abarbeitung her)
            if(*searchString==matrix[x][y]) { // erster buchstabe des suchstrings entspricht dem aktuell betrachteten zeichen in der matrix?
                for(i=0; i<max; i++) {
                    switch(i) { // für jede suchrichtung die fälle bearbeiten - leicht erweiterbar
                    case 0: { // suche nach rechts weiter
                        if(checkFind(x, y, 1, 0, searchString, matrix)) { // überprüfe den fund, ned das es nur zufällig der buchstabe war und der rest nich passt
                            printf("found string '%s' at position %d|%d in direction %d|%d.", searchString, x, y, 1, 0);
                            return; // und raus hier ^^
                        }
                        break;
                    }
                    case 1: { // suche nach unten weiter
                        if(checkFind(x, y, 0, 1, searchString, matrix)) {  // überprüfe den fund, ned das es nur zufällig der buchstabe war und  der rest nich passt
                            printf("found string '%s' at position %d|%d in direction %d|%d.", searchString, x, y, 0, 1);
                            return; // und raus hier ^^
                        }
                        break;
                    }
                    // hier könnte man jetz ganz easy weitere suchrichtungen anfügen...
                }
            }
        }
    }
}
k, will erstma fix mit family los, soweit bin ich jetz erstma gekommen. hab die endgültige suche mal in ne extra funke ausgelagert, so brauch man den kram ned für jede richtung seperat schreiben un brauch bei änderungen nur einmal was umschreiben. bei bis zu 8 möglichen suchrichtungen würde man sich sonst dusslig fixen ^^ denk ma, ich erweiter das später noch nen bissl :)
 
AW: [C] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

^^ Okay, danke für die Mühe erstmal ...

Ich verstehe zwar, was du vor hast, aber die Umsetzung ist mir dann schon etwas zu hoch. Ich hätte es jetzt so probiert:
Code:
#include <stdio.h>
#include <stdlib.h>

#define ROWS 12
#define COLUMNS 12

int checkFind(int i, int j, int dir1, int dir2, char *string, int matrix[ROWS][COLUMNS]) {
    int x=0;

    for (x=1; x<=12; x++) {
        if (*(string+x) == matrix[i+(dir1*x)][j+(dir2*x)]) {
            return 0;
        } else {
            return 1;
        }
    }
}

int searchMatrix(char *string, int matrix[ROWS][COLUMNS]) {
    int i=0, j=0, h=0, k=0, length=0;

    while (*(string+length) != '\0') {
        length++;
    }

    for (i=0; i<COLUMNS; i++) {
        for (j=0; j<ROWS; j++) {
            if (*string==matrix[j][i]) {
                for (h=0; h<12; h++) {
                    switch (h) {
                        case 0: {
                            if (checkFind(i, j, 1, 0, string, matrix)==0) {
                                for (k=0; k<length; k++) {
                                    printf("%c", *(string+k));
                                }
                                printf(" found horizontally! %d %d\n", i+1, j+1);
                                return 0;
                            }
                            break;
                        }
                        case 1: {
                            if (checkFind(i, j, 0, 1, string, matrix)==0) {
                                for (k=0; k<length; k++) {
                                    printf("%c", *(string+k));
                                }
                                printf(" found vertically! %d %d\n", i+1, j+1);
                                return 0;
                            }
                            break;
                        }
                    }
                }
            }
        }
    }
}

void printMatrix(int matrix[ROWS][COLUMNS]) {
    int i=0, j=0;

    printf("\n+---+---+---+---+---+---+---+---+---+---+---+---+\n");
    for (i=0; i<ROWS; i++) {
        for (j=0; j<COLUMNS; j++) {
            printf("| %c ", matrix[i][j]);
            if (j==11) {
                printf("|\n+---+---+---+---+---+---+---+---+---+---+---+---+\n");
            }
        }
    }
}

int main(void) {
    int matrix[ROWS][COLUMNS] = {{'X', 'S', 'E', 'C', 'U', 'R', 'I', 'T', 'Y', 'C', 'O', 'T'},
                                 {'M', 'E', 'D', 'I', 'A', 'H', 'E', 'R', 'C', 'S', 'T', 'A'},
                                 {'K', 'C', 'F', 'X', 'J', 'A', 'E', 'S', 'I', 'I', 'L', 'S'},
                                 {'M', 'U', 'I', 'N', 'T', 'R', 'U', 'S', 'I', 'O', 'N', 'K'},
                                 {'A', 'R', 'R', 'Z', 'F', 'W', 'N', 'K', 'I', 'G', 'V', 'Z'},
                                 {'L', 'E', 'E', 'N', 'C', 'R', 'Y', 'P', 'T', 'I', 'O', 'N'},
                                 {'W', 'K', 'W', 'O', 'R', 'M', 'P', 'E', 'U', 'O', 'J', 'X'},
                                 {'A', 'V', 'A', 'M', 'D', 'N', 'D', 'P', 'J', 'H', 'A', 'L'},
                                 {'R', 'L', 'L', 'N', 'V', 'I', 'R', 'U', 'S', 'P', 'E', 'E'},
                                 {'E', 'W', 'L', 'D', 'D', 'E', 'X', 'O', 'L', 'T', 'P', 'U'},
                                 {'X', 'J', 'P', 'R', 'C', 'T', 'C', 'P', 'A', 'P', 'R', 'C'},
                                 {'G', 'K', 'B', 'U', 'F', 'F', 'E', 'R', 'S', 'L', 'T', 'B'}};
    int i=0;
    char string[13];

    printf("Matrix Search - Available commands:\n");
    printf("1 .. Enter a search string\n");
    printf("9 .. Print the matrix\n");
    printf("0 .. Quit the program\n");
    
    for ( ; ; ) { 
        printf("\nPlease enter your command: ");
        scanf("%d", &i);
        if (i==0) {
            exit(0);
        } else if (i==9) {
            printMatrix(matrix);
        } else if (i==1) {
            printf("Please enter search string: ");
            scanf("%s", &string);
            searchMatrix(string, matrix);
        }
    }

    return 0;
}
Allerdings kommt man damit auf keine vernünftige Ausgabe. Besonders kurios: Egal, was für einen blödsinnigen Code ich auch schreibe, oder in welcher Form ich deinen probiere, "SECURITY" wird immer gefunden (!), wenn auch an der falschen Position. Für sämtliche anderen enthaltenen Wörtern bekomme ich jedoch nicht einmal eine Ausgabe. :ugly: :huh:

[EDIT]

Könnte man das Ganze nicht in auch so realisieren:
Code:
int searchMatrix(char *string, int matrix[ROWS][COLUMNS]) {
    int i=0, j=0, length=0;
    char searchString[]={0}, *coordinate;
    
    for (i=0; i!='\0'; i++) {
        searchString[i]=matrix[0][i]; [COLOR=seagreen]/* char array seachString bekommt Inhalt der ersten Matrix-Zeile */    }

    while (*(string+length)!='\0') {
        length++;
    }

    for (i=0; i<12; i++) {
        if (strstr(searchString, string) != NULL) {
            coordinate=strstr(searchString, string);
            for (j=0; j<length; j++) {
                printf("%c", *(string+j));
            }
            printf(" found horizontally! %d %d\n", *coordinate, i+1);
            break;
        } else {
            for (j=0; j<length; j++) {
                printf("%c", *(string+j));
            }
            printf(" not found!\n");
            break;
        }
    }
}
^^ Da könnte man ja dann auch eine Schleife basteln, die das char array searchString immer dann mit dem Inhalt einer weiteren Zeile/Spalte der Matrix befüllt, wenn in der vorhergehenden nichts gefunden wurde ...
BTW: Wieso gibt mir eigentlich der obige Code "SECURITY not found!" aus?
 
Zuletzt bearbeitet:
AW: [C] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

so, will ich ma versuchen, die erste funktion noch mit leben zu füllen...

Code:
bool checkFind(int x, int y, int xDir, int yDir, char *searchString, int matrix[ROWS][COLUMNS]) { //  <- position des funds, offsets zur richtungsbestimmung und die eigentlichen daten
    bool found = true; // solange true, bis der erste (vergleichs-)fehler auftritt
    int step = 2; // beginnend nach dem 2. buchstaben - der erste war der hauptfund, der 2. war der "richtungsfund"
    int searchX = 0, searchY = 0;
    while(*(searchString+step) != '\0') {
        searchX = x+(xDir*step);
        searchY = y+(yDir*step);
        if(searchX >= ROWS || searchY >= COLUMNS) { // wurde der rand der matrix erreicht, bevor das ganze wort gefunden wurde - abbruch
            found = false;
            break; // raus aus der while
        }
        if(*searchString+step != matrix[searchX][searchY]) { // stimmt der 2. buchstabe des suchstrings NICHT mit dem nächsten (in entsprechender richtung liegenden) feld-buchstaben der matrix überein -> abbrechen
            found = false;
            break; // raus aus der while
        }
        step = step + 1; // is ja kein c++ oder? jedenfalls gehts dann nen buchstaben weiter, wenn bisher alles passt
    }
    return found;
}

void searchMatrix(char *searchString, int matrix[ROWS][COLUMNS]) { //  <- warum hast du da eigentlich sone seltsame variante? ^^
    int max = 2; // wieviele suchrichtungen soll es geben? atm geh ich mal von nur 2en aus (vorwärts und runter)
     for(y=0; y<COLUMNS; y++) { // <- erst spalten
        for(x=0; x<ROWS; x++) { // dann zeilen ^^ - zumindest find ichs persönlich so leichter nachvollziehbar (von der reihenfolge der abarbeitung her)
            if(*searchString==matrix[x][y]) { // erster buchstabe des suchstrings entspricht dem aktuell betrachteten zeichen in der matrix?
                for(i=0; i<max; i++) {
                    switch(i) { // für jede suchrichtung die fälle bearbeiten - leicht erweiterbar
                    case 0: { // suche nach rechts weiter
                        if(checkFind(x, y, 1, 0, searchString, matrix)) { // überprüfe den fund, ned das es nur zufällig der buchstabe war und der rest nich passt
                            printf("found string '%s' at position %d|%d in direction %d|%d.", searchString, x, y, 1, 0);
                            return; // und raus hier ^^
                        }
                        break;
                    }
                    case 1: { // suche nach unten weiter
                        if(checkFind(x, y, 0, 1, searchString, matrix)) {  // überprüfe den fund, ned das es nur zufällig der buchstabe war und  der rest nich passt
                            printf("found string '%s' at position %d|%d in direction %d|%d.", searchString, x, y, 0, 1);
                            return; // und raus hier ^^
                        }
                        break;
                    }
                    // hier könnte man jetz ganz easy weitere suchrichtungen anfügen...
                }
            }
        }
    }
}

so, ok. ich GLAUBE so könnts gehen, wenn mir jetz keine denkfehler unterlaufen sind (oder rechtschreibfehler oder oder ^^). is halt jetz ohne ide oder so nur im textfenster geschrieben :ugly:

die hauptfunktion (unten) geht halt feld für feld der matrix durch (wie man ein buch liest - von links nach rechts und dann in die nächste zeile) und vergleicht den buchstaben darin mit dem ersten buchstaben des strings. findet er also bei "SECURITY" nen S irgendwo, so gehts in die nächste runde: er schaut die umliegenden felder durch (in dem bsp halt nur rechts und drunter, aber lässt sich ja simpel erweitern). findet er dort in einem der felder den 2. buchstaben (also in dem falle das E), so schickt er die position des S an die 2. funktion (die obere) die nun im endeffekt in der einmal gefundenen richtung (also immer weiter nach rechts oder immer weiter nach unten) die buchstaben vergleicht. findet er nun also den 3. buchstaben, is alles ok, findet er den 4. aber nich mehr, bricht er ab und gibt false zurück. dann würde die "äussere" funktion weitersuchen bis zum nächsten S oder eben bis zum ende.

falls die "innere" funktion ALLE buchstaben findet, dann gibts true zurück und er gibt eben den text aus, das ers wie wo was gefunden hat. so zumindest der plan. bei der inneren funktion mit dem step und xDir/yDir is hoffentlich klar, was er da macht. geht man beispielsweise nach rechts weiter, dann übergibt man ja den richtungs"vektor" 1|0 - also je 1 in x richtung und 0 in y richtung. in der checkFind schaut er dann also beim ersten vergleich (sagen wir, er hat bei 3|4 das S gefunden) bei searchX = 3 + (1 * 2) = 5 und searchY = 4 + (0 * 2) -> 5|4 nach dem 3. buchstaben. die 3 is S (der fundort), die 4 is E (die richtung) und die 5 is dann hoffentlich C. danach wird step um 1 erhöht, und er sucht bei searchX = 3 + (1 * 3) = 6 und searchY = 4 + (0 * 3) -> 6|4 nach dem 4. buchstaben. gut, ich hoffe, ich konnts dir verdeutlichen. is die matrix aber nur bis zur 6 (ROWS = 6) breit, dann würde er dann aber abbrechen, da 5 der maximale X-wert sein kann.

probiers mal aus, hoffe es funzt ^^
 
Zurück