Tic Tac Toe AI错误

时间:2016-01-14 22:56:57

标签: c

char checkwinner(char ttt[][3]) {
    char winner = 0;

    for (int p = 0; winner == 0 && p < 2; p++) {
        char XO = p == 0 ? 'x' : 'o';
        for (int i = 0; winner == 0 && i < 3; i++) {
            if (ttt[i][0] == XO && ttt[i][1] == XO && ttt[i][2] == XO)
                winner = XO;
            else
            if (ttt[0][i] == XO && ttt[1][i] == XO && ttt[2][i] == XO)
                winner = XO;
        }

        if (winner == 0 && ttt[0][0] == XO && ttt[1][1] == XO && ttt[2][2] == XO)
            winner = XO;
        else
        if (winner == 0 && ttt[0][2] == XO && ttt[1][1] == XO && ttt[2][0] == XO)
            winner = XO;
    }
    return winner;
}


int main (void) {
    char b[3][3] = {{'1', '2', '3'},
                    {'4', '5', '6'},
                    {'7', '8', '9'}};
    int turn = 0, i, j, loc, type, counter = 0;
    char XO, AL;
    char theChar = 'A';
    char junk ='A';

    printf("Type in 1 to play with AL, or 2 to play with another human\n");
    scanf("%d", &type);

    while (turn <= 9) {
        char winner = checkwinner(b);
        if (winner == 'x' || winner == 'o') {
            printf("%c has  won! You get 100 million DOGECOINS! Just enter your debt card information to our website, as well as your checking account and social security number. Go to www.THIS_IS_NOT_A_SCAM.com to get your dogecoins today!\n", winner);
            return (0);
        } else
        if (((b[0][0] == 'x') || (b[0][0] == 'o')) 
        &&  ((b[0][1] == 'x') || (b[0][1] == 'o')) 
        &&  ((b[0][2] == 'x') || (b[0][2] == 'o'))
        &&  ((b[1][0] == 'x') || (b[1][0] == 'o'))
        &&  ((b[1][1] == 'x') || (b[1][1] == 'o'))
        &&  ((b[1][2] == 'x') || (b[1][2] == 'o'))
        &&  ((b[2][0] == 'x') || (b[2][0] == 'o'))
        &&  ((b[2][1] == 'x') || (b[2][1] == 'o'))
        &&  ((b[2][2] == 'x') || (b[2][2] == 'o'))) {
            printf("This is a tie.\n");
            return (0);

        }  //<---- missing brace!

        if (type == 1) {
            counter = counter + 1;

            if (counter == 1) { XO = 'x'; }
            if (counter == 2) { XO = 'o'; }
            if (counter == 3) { XO = 'x'; }
            if (counter == 4) { XO = 'o'; }
            if (counter == 5) { XO = 'x'; }
            if (counter == 6) { XO = 'o'; }
            if (counter == 7) { XO = 'x'; }
            if (counter == 8) { XO = 'o'; }
            if (counter == 9) { XO = 'x'; }
        }

        if (type == 2) {
            XO = 'x';
            AL = 'o';

            for (i = 0; i < 3; i++) {
                for (j = 0; j < 3; j++) {
                    b[i][j] = AL;
                    printArray(b);
                }
            }
        }

        theChar = getchar();
        putchar(theChar);
        printf("Enter number: ");
        scanf("%d", &loc);

        j = (loc - 1) % 3;
        i = (loc - 1) / 3;

        if ((b[i][j] == 'x') || (b[i][j] == 'o')) {
            printf("That spot has been taken!\n");
            return (0);
        }
        putchar('\n');
        junk = getchar();
        b[i][j] = XO;
        printArray(b);
    }
}

void printArray(char thearray[3][3]) {
    int i, j;
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 3; j++) {
            printf("%c ", thearray[i][j]);
        }
        printf("\n");
    }
}

现在我正试图完成AI模式。而不仅仅是找到第一个空白空间并打印单个“空白”。我的游戏打印出9个这样的板子:

o 2 3
4 5 6
7 8 9
o o 3
4 5 6
7 8 9
o o o
4 5 6
7 8 9
o o o
o 5 6
7 8 9
o o o
o o 6
7 8 9
o o o
o o o
7 8 9
o o o
o o o
o 8 9
o o o
o o o
o o 9
o o o
o o o
o o o

如何在打印一个&#39; o后让游戏停止,然后让&#39; x&#39;选择一招?感谢所有帮助。

1 个答案:

答案 0 :(得分:0)

找到AL播放位置的代码不正确:

    if (type == 2) {
        XO = 'x';
        AL = 'o';

        for (i = 0; i < 3; i++) {
            for (j = 0; j < 3; j++) {
                b[i][j] = AL;
                printArray(b);
            }
        }
    }

您只需在网格上播放每个位置并进行打印!

请改为尝试:

    if (type == 2) {
        XO = 'x';
        AL = 'o';

        for (i = 0; i < 3; i++) {
            for (j = 0; j < 3; j++) {
                if (b[i][j] != 'x' && b[i][j] != 'o') {
                    b[i][j] = AL;
                    i = j = 2;  /* ugly way to exit the nested loops */
                }
            }
        }
        printArray(b);
    }

但这种游戏策略很容易被击败!

此外,您忘记增加turn,但如果您这样做,则可以使用简单的if (turn == 9)替换繁琐的测试。

编辑:退出此嵌套循环需要更多逻辑...最好将AL游戏播放移动到单独的功能。此外,您的逻辑存在缺陷:如果type2而不是1,则让AL播放...

这是一个可以兼顾双方的简化版本:

#include <stdio.h>

char checkwinner(char b[3][3]) {
    for (int i = 0; i < 3; i++) {
        if (b[i][0] == b[i][1] && b[i][1] == b[i][2])
            return b[i][0];
        if (b[0][i] == b[1][i] && b[1][i] == b[2][i])
            return b[0][i];
    }
    if ((b[0][0] == b[1][1] && b[1][1] == b[2][2])
    ||  (b[0][2] == b[1][1] && b[1][1] == b[2][0])) {
        return b[1][1];
    }
    return 0;
}

void printArray(char b[3][3]) {
    for (int i = 0; i < 3; i++) {
        printf("%c %c %c\n", b[i][0], b[i][1], b[i][2]);
    }
    printf("\n");
}

void playAl(char b[3][3], char AL) {
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            if (b[i][j] != 'x' && b[i][j] != 'o') {
                b[i][j] = AL;
                return;
            }
        }
    }
}

int main (void) {
    char board[3][3] = {{'1', '2', '3'},
                        {'4', '5', '6'},
                        {'7', '8', '9'}};
    int turn, i, j, loc, type;

    printf("What does AL play? (0:none, 1:x, 2:o, 3:both) ");
    scanf("%d", &type);

    for (turn = 0;; turn++) {
        printArray(board);
        char winner = checkwinner(board);
        if (winner == 'x' || winner == 'o') {
            printf("%c has won! Game over\n", winner);
            return 0;
        }
        if (turn == 9) {
            printf("This is a tie.\n");
            return 0;
        }

        char XO = "xo"[turn % 2];
        if (type & (1 << (turn % 2))) {
            /* AL's turn to play */
            playAl(board, XO);
            continue;
        }

        for (;;) {
            printf("Enter number: ");
            if (scanf("%d", &loc) != 1)
                return 1;

            j = (loc - 1) % 3;
            i = (loc - 1) / 3 % 3;
            if (board[i][j] != 'x' && board[i][j] != 'o')
                break;

            printf("This spot is already taken!, try again\n");
        }
        board[i][j] = XO;
    }
}