泡沫奇诺 2023-01-23 13:44 采纳率: 50%
浏览 83
已结题

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

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

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

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

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

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 <stdio.h>
#include <time.h>
#include <stdlib.h>
#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%

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

  • 写回答

2条回答 默认 最新

  • 有一只小精灵 2023-01-23 15:39
    关注

    修改下 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;//棋盘没满
        }
    }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 1月31日
  • 已采纳回答 1月23日
  • 创建了问题 1月23日

悬赏问题

  • ¥15 想问一下树莓派接上显示屏后出现如图所示画面,是什么问题导致的
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号