三子棋判断输赢问题,该如何解决?

问题遇到的现象和发生背景

在自学井字棋 三子棋,于是自己试着写了些,在判定输赢有问题

遇到的现象和发生背景,请写出第一个错误信息

游戏里斜着的棋被能判断输赢,横竖的棋不能被判断输赢
如图斜着可以判断输赢

img

横竖不能判断输赢,而且如果继续下完所有棋子,游戏什么也不提示直接开始下一局。

img

img

用代码块功能插入代码,请勿粘贴截图。 不用代码块回答率下降 50%

1.test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"


void game()
{
    char board[ROW][COL];
    //给一个棋盘

    InitBoard(board,ROW,COL);
    //初始化棋盘    
    DisplayBoard(board,ROW,COL);
    //打印棋盘
    while (1)
    {
        PlayerMove(board, ROW, COL);    
        DisplayBoard(board, ROW, COL);
        if (TicTTWin(board, ROW, COL) != 1)
        {
            break;
        }        
        Tmp();//清理缓冲区
        //判断
        ComputerMove(board, ROW, COL);
        DisplayBoard(board, ROW, COL);
        if (TicTTWin(board, ROW, COL) != 1)
        {
            break;
        }
        //判断
    }
}

int main()
{
    int input = 1;
    srand((unsigned)time(NULL));
    while (input)
    {    
        menu();
        printf("请输入您的选项:>");
        scanf("%d", &input);
        switch (input)
        {
        case 1:
            printf("开始游戏\nPS游戏规则:输入数字进行下棋,例如1 2(包括空格),您的棋子将会下载[1][2]的位置\n棋盘顺序:左上角为原点,横轴为第一个数字,纵轴为第二个数字。\n");
            Tmp();
            game(); break;
        case 0:
            printf("退出游戏\n");
            return 0;
        default:
            printf("输入错误,请重新输入\n");
            Tmp();
        }
    }
}


2.game.h

#pragma once
#include 
#include 
#include 
#define ROW 3//行数
#define COL 3//列数

void menu();
//打印菜单

void InitBoard(char board[ROW][COL], int row, int col);
//初始化棋盘的调用

void DisplayBoard(char board[ROW][COL], int row, int col);
//打印棋盘

void PlayerMove(char board[ROW][COL], int row, int col);
//玩家走
void ComputerMove(char board[ROW][COL], int row, int col);
//电脑走

void Tmp();
//清理缓冲区


int TicTTWin(char board[ROW][COL], int row, int col);
//判断三子棋游戏进行情况

int IsFull(char board[ROW][COL], int row, int col);
//判断棋盘满没满

3.game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"

//菜单
void menu()
{

    printf("****************************\n");
    printf("****************************\n");
    printf("******    ————    ******\n");
    printf("******   | 三子棋 |   ******\n");
    printf("******    ————    ******\n");
    printf("******     1.Play     ******\n");
    printf("******     0.exit     ******\n");
    printf("******                ******\n");
    printf("****************************\n");
    printf("****************************\n");
}

//棋盘初始化
void InitBoard(char board[ROW][COL], int row, int col)
{
    int i, j = 0;
    for (i = 0; i < ROW; i++)
    {
        for (j = 0; j < COL; j++)
            board[i][j] = ' ';
    }
}

//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col)
{
    int i, j = 0;
    for (i = 0; i < ROW; i++)
    {
        for (j = 0; j < COL; j++)
        {
            printf(" %c ", board[i][j]);
            if (j < COL - 1)
            printf("|");
        }
        printf("\n");
        for (j = 0; j < COL; j++)
        {
            if (i < COL - 1)
            {
                printf("---");
                if (j < ROW-1)
                {
                    printf("|");
                }
            }                
        }
        
        printf("\n");
    }
}

//玩家走
void PlayerMove(char board[ROW][COL], int row, int col)
{
    int x, y = 0;
    while (1)//循环到玩家下好棋,跳出循环
    {    
        printf("玩家走:>");
        scanf("%d %d", &x, &y);
        if (x - 1 < ROW && y - 1 < COL)
        {
            if (board[x - 1][y - 1] == ' ')
            {
                board[x - 1][y - 1] = '*';
                break;//下好,跳出循环
            }                
            else
            {
                printf("此地已被占用\n");
            }
        }
        else
        {
            printf("下棋位置不合法\n");
        }
    }
}

//机器人走
void ComputerMove(char board[ROW][COL], int row, int col)
{
    printf("电脑走\n");


    while (1)
    {
        int a = rand()%row;
        int b = rand()%col;    //不断给随机位置
        if (board[a][b] == ' ')//判断是否有空位
        {
            board[a][b] = '#';
            break;
        }        
    }
    
}

//清理缓冲区
void Tmp()
{
    while (getchar() != '\n');
}

//判断棋盘满没满
int IsFull(char board[ROW][COL], int row, int col)
{
    int i, j = 0;
    for (i = 0; i < ROW; i++)
    {
        for (j = 0; j < COL; j++)
        {
            if (board[i][j] == ' ')
                return 0;//没满 返回0
        }
    }
                return 1;//满了 返回1
}


//三子棋游戏情况判断
int TicTTWin(char board[ROW][COL], int row, int col)
{
    int i, j = 0;        
    for (i = 0; i < ROW; i++)
    {
        for (j = 0; j < COL; j++)
        {
            if ((board[i][j] == board[i + 1][j + 1] && board[i][j] == board[i + 2][j + 2] && board[i][j] != ' ')/*( \  赢)*/ ||
                (board[i][j] == board[i - 1][j + 1] && board[i][j] == board[i - 2][j + 2] && board[i][j] != ' ')/*( /  赢)*/ ||
                (board[i][j] == board[i + 1][  j  ] && board[i][j] == board[i - 1][  j  ] && board[i][j] != ' ')/*( 竖 赢)*/ ||
                (board[i][j] == board[  i  ][j + 1] && board[i][j] == board[  i  ][j - 1] && board[i][j] != ' ')/*( 横 赢)*/)
            {
                if (board[i][j] == '*')
                {
                    printf("你赢了!\n");
                    return 0;//返回* 玩家赢
                }

                if (board[i][j] == '#')
                {
                    printf("电脑赢了 T-T 你输了!\n");
                    return 0;//返回# 电脑赢
                }

            }
            else if(IsFull(board, row, col))
                {
                    return 0;//棋盘满了
                    printf("平局!\n");
                }
                else
                {
                    return 1;//棋盘没满
                }
        }
    }
}



运行结果及详细报错内容

判定输赢的函数是game.c里最后一个函数

//三子棋游戏情况判断
int TicTTWin(char board[ROW][COL], int row, int col)
{
    int i, j = 0;        
    for (i = 0; i < ROW; i++)
    {
        for (j = 0; j < COL; j++)
        {
            if ((board[i][j] == board[i + 1][j + 1] && board[i][j] == board[i + 2][j + 2] && board[i][j] != ' ')/*( \  赢)*/ ||
                (board[i][j] == board[i - 1][j + 1] && board[i][j] == board[i - 2][j + 2] && board[i][j] != ' ')/*( /  赢)*/ ||
                (board[i][j] == board[i + 1][  j  ] && board[i][j] == board[i - 1][  j  ] && board[i][j] != ' ')/*( 竖 赢)*/ ||
                (board[i][j] == board[  i  ][j + 1] && board[i][j] == board[  i  ][j - 1] && board[i][j] != ' ')/*( 横 赢)*/)
            {
                if (board[i][j] == '*')
                {
                    printf("你赢了!\n");
                    return 0;//返回* 玩家赢
                }

                if (board[i][j] == '#')
                {
                    printf("电脑赢了 T-T 你输了!\n");
                    return 0;//返回# 电脑赢
                }

            }
            else if(IsFull(board, row, col))
                {
                    return 0;//棋盘满了
                    printf("平局!\n");
                }
                else
                {
                    return 1;//棋盘没满
                }
        }
    }
}


我的解答思路和尝试过的方法,不写自己思路的,回答率下降 60%

因为一点头绪都没有.不知道是不是我写的代码有坑(初学者的痛)
求各位帮助!

修改下 TicTTWin函数,应该把IsFull和棋盘没满移出来,不然的话,假设我是下的最后一个竖行,第一次循环其实就走到棋盘没满那边去了,就无法走到赢了的条件里面,独立出去后,两层for就可以把所有的条件都判断到了。

int TicTTWin(char board[ROW][COL], int row, int col)
{
    int i, j = 0;
    for (i = 0; i < ROW; i++)
    {
        for (j = 0; j < COL; j++)
        {
            if ((board[i][j] == board[i + 1][j + 1] && board[i][j] == board[i + 2][j + 2] && board[i][j] != ' ')/*( \  赢)*/ ||
                (board[i][j] == board[i - 1][j + 1] && board[i][j] == board[i - 2][j + 2] && board[i][j] != ' ')/*( /  赢)*/ ||
                (board[i][j] == board[i + 1][  j  ] && board[i][j] == board[i + 2][  j  ] && board[i][j] != ' ')/*( 竖 赢)*/ ||
                (board[i][j] == board[  i  ][j + 1] && board[i][j] == board[  i  ][j + 2] && board[i][j] != ' ')/*( 横 赢)*/)
            {
                if (board[i][j] == '*')
                {
                    printf("你赢了!\n");
                    return 0;//返回* 玩家赢
                }

                if (board[i][j] == '#')
                {
                    printf("电脑赢了 T-T 你输了!\n");
                    return 0;//返回# 电脑赢
                }

            }
        }
    }
    if (IsFull(board, row, col))
    {
        return 0;//棋盘满了
        printf("平局!\n");
    }
    else
    {
        return 1;//棋盘没满
    }
}

判断输赢函数修改如下,供参考:

//三子棋游戏情况判断
int TicTTWin(char board[ROW][COL], int row, int col)
{
    int i, j, result = -1, numX = 0, numO = 0, numX1 = 0, numO1 = 0;
    for (i = 0; i < row; i++)
    {

        for (j = 0, numX = 0, numO = 0; j < col; j++) //行遍历
        {
            if (board[i][j] == '*')
                numX++;
            else if (board[i][j] == '#')
                numO++;
        }
        if (numX == 3) {
            printf("你赢了!\n");
            result = 1;
            return 0;
        }
        else if (numO == 3) {
            printf("电脑赢了 T-T 你输了!\n");
            result = 0;
            return 0;
        }

        for (j = 0, numX = 0, numO = 0; j < row; j++) //列遍历
        {
            if (board[j][i] == '*')
                numX++;
            else if (board[j][i] == '#')
                numO++;
        }
        if (numX == 3) {
            printf("你赢了!\n");
            result = 1;
            return 0;
        }
        else if (numO == 3) {
            printf("电脑赢了 T-T 你输了!\n");
            result = 0;
            return 0;
        }
    }
    numX = 0, numO = 0, numX1 = 0, numO1 = 0;
    for (i = 0; i < row; i++)          //对角线
    {

        for (j = 0; j < col; j++)
        {
            if (i == j) {
                if (board[i][j] == '*')
                    numX++;
                else if (board[i][j] == '#')
                    numO++;
            }
            if (i + j == col - 1) {
                if (board[i][j] == '*')
                    numX1++;
                else if (board[i][j] == '#')
                    numO1++;
            }
        }
    }
    if (numX == 3 || numX1 == 3) {
        printf("你赢了!\n");
        result = 1;
        return 0;
    }
    else if (numO == 3 || numO1 == 3) {
        printf("电脑赢了 T-T 你输了!\n");
        result = 0;
        return 0;
    }
    if (result == -1 && IsFull(board, row, col)) {

        printf("平局!\n");
        return 0;
    }
    return 1;//棋盘没满
}

#if 0
        for (j = 0; j < COL; j++)
        {
            if ((board[i][j] == board[i + 1][j + 1] && board[i][j] == board[i + 2][j + 2] && board[i][j] != ' ')/*( \  赢)*/ ||
                (board[i][j] == board[i - 1][j + 1] && board[i][j] == board[i - 2][j + 2] && board[i][j] != ' ')/*( /  赢)*/ ||
                (board[i][j] == board[i + 1][j] && board[i][j] == board[i - 1][j] && board[i][j] != ' ')/*( 竖 赢)*/ ||
                (board[i][j] == board[i][j + 1] && board[i][j] == board[i][j - 1] && board[i][j] != ' ')/*( 横 赢)*/)
            {
                if (board[i][j] == '*')
                {
                    printf("你赢了!\n");
                    return 0;//返回* 玩家赢
                }

                if (board[i][j] == '#')
                {
                    printf("电脑赢了 T-T 你输了!\n");
                    return 0;//返回# 电脑赢
                }

            }
            else if (IsFull(board, row, col))
            {
                return 0;//棋盘满了
                printf("平局!\n");
            }
            else
            {
                return 1;//棋盘没满
            }
        }
    }
#endif