Tic-Tac-Toe游戏功能检查获胜者

时间:2015-11-29 05:15:08

标签: c

我已经为自己的井字游戏编写了以下代码:

#include <stdio.h>
#include <math.h>

void instructions();
void printboard(char board[3][3]);
int wincheck(char board[3][3]);

int main(){
        char tictac[3][3] = {{'-', '-', '-'}, {'-', '-', '-'}, {'-', '-', '-'}};
        int player = 0;
        int win = 0;
        int player_choice = 0;
        int row = 0;
        int col = 0;

        instructions();
        for(int i=0; i<9 && win==0; i++){
                printboard(tictac);
                player = i%2 + 1;
                do{
                        printf("\nPlayer #%d, enter your spot choice:\n", player);
                        scanf("%d", &player_choice);
                        if(player_choice == 1){
                                row = 0;
                                col = 0;
                        }
                        else if(player_choice == 2){
                                row = 0;
                                col = 1;
                        }
                        else if(player_choice == 3){
                                row = 0;
                                col = 2;
                        }
                        else if(player_choice == 4){
                                row = 1;
                                col = 0;
                        }
                        else if(player_choice == 5){
                                row = 1;
                                col = 1;
                        }
                        else if(player_choice == 6){
                                row = 1;
                                col = 2;
                        }
                        else if(player_choice == 7){
                                row = 2;
                                col = 0;
                        }
                        else if(player_choice == 8){
                                row = 2;
                                col = 1;
                        }
                        else if(player_choice == 9){
                                row = 2;
                                col = 2;
                        }
                        else{
                                printf("Not a valid choice, please choose again.");
                        }

                }while(player_choice<0 || player_choice>9 || tictac[row][col]!='-');
                if(player == 1){
                        tictac[row][col] = 'X';
                }
                else if(player == 2){
                        tictac[row][col] = 'O';
                }
                if(wincheck(tictac)!=0){
                        win = player;
                }
        }
        printboard(tictac);
        if(!win){
                printf("\n\nTHE GAME IS A DRAW!\n");
        }
        else{
                printf("\n\nCONGRATULAIONS PLAYER #%d, YOU WON!\n", win);
        }
}

void instructions(){
        printf("\n\t\t\t  WELCOME TO TIC TAC TOE!\n");
        printf("\nGame Rules:\n");
        printf("\nThe program will ask the player to enter which spot they would like to place their X or O.\nPlease use spot numbers as shown below:\n\n");
        printf("\t\t\t\t 1 | 2 | 3 \n");
        printf("\t\t\t\t---+---+---\n");
        printf("\t\t\t\t 4 | 5 | 6 \n");
        printf("\t\t\t\t---+---+---\n");
        printf("\t\t\t\t 7 | 8 | 9 \n");
        printf("\n\t------------------------LET'S BEGIN!------------------------\n\n\n");
}

void printboard(char board[3][3]){
        printf("\t\t\t\t %c | %c | %c \n", board[0][0], board[0][1], board[0][2]);
        printf("\t\t\t\t---+---+---\n");
        printf("\t\t\t\t %c | %c | %c \n", board[1][0], board[1][1], board[1][2]);
        printf("\t\t\t\t---+---+---\n");
        printf("\t\t\t\t %c | %c | %c \n", board[2][0], board[2][1], board[2][2]);
}

int wincheck(char board[3][3]){
        if((board[0][0]==board[0][1] && board[0][0]==board[0][2]) || (board[1][0]==board[1][1] && board[1][0]==board[1][2]) || (board[2][0]==board[2][1] && board[2][0]==board[2][2])){
                return 1;/*Checks to see if player has won across any of the rows.*/
        }
        else if((board[0][0]==board[1][0] && board[0][0]==board[2][0]) || (board[0][1]==board[1][1] && board[0][1]==board[2][1]) || (board[0][2]==board[1][2] && board[0][2]==board[2][2])){
                return 1;/*Checks to see if player has won down any columns.*/
        }
        else if((board[0][0]==board[1][1] && board[0][0]==board[2][2]) || (board[0][2]==board[1][1] && board[0][2]==board[2][0])){
                return 1;/*Checks to see if player has won in a diagonal.*/
        }
        else{
                return 0;
        }
}

我尝试玩游戏时遇到了问题。在第一个玩家选择&#34;游戏点后#34;它认为他们已经赢了。因此我认为这个问题很可能是由于wincheck函数出错,但我无法弄清楚究竟是什么导致了这个问题。我是一名初学程序员,所以如果这是一个愚蠢的问题我会道歉。非常感谢您提供的任何帮助!

1 个答案:

答案 0 :(得分:0)

问题是确实与您的wincheck函数有关。它正确地检查了三个候选单元是否相等,但是检查了那些单元是否已被填充。这意味着即使在采取任何行动之前,该游戏也将被检测为获胜(由于 all 所有单元格都设置为-,因此将通过简单的相等性检查)。

因此,仅进行 相等性检查还不够,还必须确保至少有 个这样的单元已被设置为真实玩家。

您还可以通过一些重构使代码更具可读性,例如:

// Returns the actual winner, or '-' if none. Needs x/y start cell
// and x/y deltas (direction, basically).

int checkOneWinPossibility(char board[3][3], int x, int y, int xd, int yd) {
    // Check all no-winner scenarios, return winner only if they all fail.

    if (board[x][y] == '-') return '-';
    if (board[x][y] != board[x+xd][y+yd]) return '-';
    if (board[x][y] != board[x+xd*2][y+yd*2]) return '-';

    return board[x][y];
}

int checkAllWinPossibilities(char board[3][3]){
    int winner;

    // Horizontals.

    if ((winner = checkOneWinner(board, 0, 0, 0, 1)) != '-') return winner;
    if ((winner = checkOneWinner(board, 1, 0, 0, 1)) != '-') return winner;
    if ((winner = checkOneWinner(board, 2, 0, 0, 1)) != '-') return winner;

    // Verticals.

    if ((winner = checkOneWinner(board, 0, 0, 1, 0)) != '-') return winner;
    if ((winner = checkOneWinner(board, 0, 1, 1, 0)) != '-') return winner;
    if ((winner = checkOneWinner(board, 0, 2, 1, 0)) != '-') return winner;

    // Diagonals.

    if ((winner = checkOneWinner(board, 0, 0, 1, 1)) != '-') return winner;
    if ((winner = checkOneWinner(board, 2, 0, -1, 1)) != '-') return winner;

    return '-';
}

只需执行以下操作即可将最后一个对角线检查 return语句组合在一起:

return checkOneWinner(board, 2, 0, -1, 1);

但是我更喜欢(稍微强迫症)将其保持不变:-)

他们都返回了 actual 赢家,而不仅仅是表明有赢家。您可能不需要该信息,因为它显然是最后移动的玩家,但是返回额外信息可能并没有实质性危害。