【问题标题】:Tic-Tac-Toe Game Function To Check For Winner井字游戏功能检查获胜者
【发布时间】:2015-11-29 05:15:08
【问题描述】:

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

#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;
        }
}

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

【问题讨论】:

  • 您没有在wincheck 中检查-。也就是说,您错误地将三个相邻的 - 条目匹配为胜利。
  • 感谢您的快速响应!我现在看到了问题,非常感谢您的帮助!
  • 记住在 tac-tac-toe 中只有 8 种获胜方式,可以大大缩短/清理代码。所以可以定义一个静态/常量表,然后代码简单地遍历表,遍历每个表行,并比较相关的位置(该表包含游戏板的行/列坐标)以查看特定玩家是否有每个游戏板坐标处的匹配条目。

标签: c


【解决方案1】:

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

因此,进行相等性检查是不够的,您还必须确保这些单元中的至少 一个 已设置为真实玩家。 p>

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

// 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);

但我更喜欢(有点强迫症)保持原样以保持一致性:-)

它们还都返回实际获胜者,而不仅仅是表示有获胜者。您可能不需要该信息,因为它显然是最后一个移动的玩家,但返回额外信息可能没有实质性的危害。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多