感谢解答 2022-01-09 21:42 采纳率: 70.6%
浏览 27
已结题

c语言写个三子棋,遇到个小问题

第一个问题:为啥我的scanf里没有空格,但我输入的时候输入11没反应,非得输入1空格1才行
第二个问题:我把第一行输满,为啥显示平局,我知道这么多if有点麻烦,我也知道有更简便的方法,但我就是想知道哪里错了

#include "自定义函数声明.h"//引用库函数用的是<>,引用自建的头文件用的是""

void menu()//三子棋登录页面
{
    printf("**************************\n");
    printf("**********三子棋**********\n");
    printf("**************************\n");
    printf("***  1.play    0.exit  ***\n");
    printf("**************************\n");
}

void game()//三子棋游戏//%3意思是取余0-2,因为3%3=1
{
    char board[ROW][COL] = {0};//设定一个二维数组
    char comeback = 0;
    InitBoard(board, ROW, COL);//初始化函数,清空面板
    Displayboard(board, ROW, COL);//打印棋盘函数,使棋盘可视化
    while (1)//永远为真,一直下,直到一方赢了break
    {
        PlayerMove(board,ROW,COL);//玩家走
        Displayboard(board, ROW, COL);//打印棋盘
        comeback = IsWin(board, ROW, COL);
        if (comeback != 'C')
        {
            break;
        }
        ComputerMove(board, ROW, COL);//电脑走
        Displayboard(board, ROW, COL);//打印棋盘
        comeback = IsWin(board, ROW, COL);
        if (comeback != 'C')
        {
            break;
        }
    }
    if (comeback == '*')
    {
        printf("玩家获胜!");
    }
    else if (comeback == '#')
    {
        printf("电脑获胜!");
    }
    else
    {
        printf("平局!");
    }
}

void test()//三子棋登录程序
{
    int input = 0;//接收输出内容
    srand((unsigned int)time(NULL));
    do//游戏至少要先进来,所以do while
    {
        menu();//一进来是登录页面
        printf("choice>>>");
        scanf("%d", &input);
        switch (input)//根据输入内容来确定分支
        {
        case 1:
            game();//1的话进入游戏,game程序结束后直接跳出循环,退出游戏
            break;
        case 0:
            printf("退出游戏!\n");
            break;//0的话直接就是退出游戏
        default:
            printf("输入有误,请重新输入!\n");//1和0以外的,提示重新输入
            break;
        }
    } 
    while (input);//一进来输入1的话进入游戏,输入0的话退出游戏,输入非0,也就是真,再循环一次
}//这样每个输入得数都有正确的路

int main()//三子棋游戏,设立主程序,里面的没个子程序都单独拿出来写,为了好区分
{
    test();
    return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include <string.h>
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

#ifndef __自定义函数声明_H_//n是not,意思是如果没有引用这个文件的话,就将下列的函数包含进去,如果引用过了,就不包含
#define __自定义函数声明_H_
#define ROW 3//控制棋盘的行
#define COL 3//控制棋盘的列
void InitBoard(char board[ROW][COL],int row,int col);
void Displayboard(char board[ROW][COL], int row, int col);
int SuM(int x, int y);
void PlayerMove(char board[ROW][COL], int row, int col);
void ComputerMove(char board[ROW][COL], int row, int col);
char IsWin(char board[ROW][COL],int row, int col);

#endif//函数声明结束
#define _CRT_SECURE_NO_WARNINGS 1//这个文件里写函数的内容
#include "自定义函数声明.h"

void InitBoard(char board[ROW][COL], int row, int col)//初始化函数,每次游戏之后清空面板//三子棋
{
    int i = 0;
    int 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 = 0;
    int j = 0;
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)//先打印一行
        {
            printf(" %c ", board[i][j]);
            if (j < col - 1)//-1是为了避免最后多一次打印
            {
                printf("|");
            }
        }
        printf("\n");
        if (i < row - 1)
        {
            for (j = 0; j < col; j++)
            {
                printf("---");
                if (j < col - 1)
                {
                    printf("|");
                }
            }
            printf("\n");
        }
    }
}

void PlayerMove(char board[ROW][COL], int row, int col)
{
    int x = 0;
    int y = 0;
    while (1)
    {
        printf("玩家走,请输入坐标>>\n");
        scanf("%d%d", &x, &y);
        if (x >= 1 && x <= ROW && y >= 1 && y <= 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)
{
    int x = 0;
    int y = 0;
    printf("电脑走\n");
    while (1)
    {
        x = rand() % 3;
        y = rand() % 3;
        if (x >= 1 && x <= ROW && y >= 1 && y <= COL)
        {
            if (board[x][y] == ' ')
            {
                board[x][y] = '#';
                break;
            }
        }

    }
}

int IsFull(char board[ROW][COL], int row, int col)//返回1表示棋盘满了,返回0表示棋盘没满
{
    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
        {
            if (board[i][j] == ' ')//只要有一个空格,就表示没满,直接返回0
            {
                return 0;
            }
        }
    }
    return 1;//循环完了没有返回0就来到这返回1,表示满了,平局
}

char IsWin(char board[ROW][COL], int row, int col)//自写判断输赢条件,缺点是数量大时不能一个一个写,先验证一下
{
    char x = 0;
    //if (board[row][col] != ' ' && board[0][0] == board[0][1] == board[0][2] == '*' || board[1][0] == board[1][1] == board[1][2] == '*' || board[2][0] == board[2][1] == board[2][2] == '*' || board[0][0] == board[1][0] == board[2][0] == '*' || board[1][0] == board[1][1] == board[1][2] == '*' || board[2][0] == board[2][1] == board[2][2] == '*' || board[0][0] == board[1][1] == board[2][2] == '*' || board[0][2] == board[2][1] == board[2][0] == '*')
    //{//不等于 空格 是因为一开始肯定有三个相等的空格,此时不能判断谁输谁赢
    //    return board[row][col];//这里直接返回值,接收值在game函数里
    //}
    if (board[0][0] != ' ' && board[0][1] != ' ' && board[0][2] != ' ' && board[0][0] == board[0][1] && board[0][1] == board[0][2])//行1
    {
        x=board[row][col];
        return x;
    }
    if (board[1][0] != ' ' && board[1][1] != ' ' && board[1][2] != ' ' && board[1][0] == board[1][1] && board[1][1] == board[1][2])//行2
    {
        return board[row][col];
    }
    if (board[2][0] != ' ' && board[2][1] != ' ' && board[2][2] != ' ' && board[2][0] == board[2][1] && board[2][1] == board[2][2])//行3
    {
        return board[row][col];
    }
    if (board[0][0] != ' ' && board[1][0] != ' ' && board[2][0] != ' ' && board[0][0] == board[1][0] && board[1][0] == board[2][0])//列1
    {
        return board[row][col];
    }
    if (board[0][1] != ' ' && board[1][1] != ' ' && board[2][1] != ' ' && board[0][1] == board[1][1] && board[1][1] == board[2][1])//列2
    {
        return board[row][col];
    }
    if (board[0][2] != ' ' && board[1][2] != ' ' && board[2][2] != ' ' && board[0][2] == board[1][2] && board[1][2] == board[2][2])//列3
    {
        return board[row][col];
    }
    if (board[0][0] != ' ' && board[1][1] != ' ' && board[2][2] != ' ' && board[0][0] == board[1][1] && board[1][1] == board[2][2])//    \    //
    {
        return board[row][col];
    }
    if (board[2][0] != ' ' && board[1][1] != ' ' && board[0][2] != ' ' && board[2][0] == board[1][1] && board[1][1] == board[0][2])//    /    //
    {
        return board[row][col];
    }
    if (1 == IsFull(board,ROW,COL))
    {
        return 'Q';
    }
    return 'C';
}

img

  • 写回答

1条回答 默认 最新

  • 感谢解答 2022-01-10 21:35
    关注

    我自己找到了,原因是判断输赢条件里,return board没有设置具体坐标,导致返回值不知道返回了些啥,所以最后判断该打印什么的时候都是else平局

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 1月18日
  • 已采纳回答 1月10日
  • 创建了问题 1月9日

悬赏问题

  • ¥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 支付宝网页转账系统不识别账号