C项目2:实现五子棋功能

功能说明:

 

黑棋与白棋进行博弈,先连满5个与自己颜色相同的棋子获胜。

函数要求:

1.棋子能够正常输入到棋盘中

2.能够正确判断棋子成功嬴棋:

(1)横向连满5个与自己颜色相同的棋子为获胜

(2)纵向连满5个与自己颜色相同的棋子为获胜

(3)正斜向连满5个与自己颜色相同的棋子为获胜

(4)负斜向连满5个与自己颜色相同的棋子为获胜

3.嬴棋了还可以再开一局

4.双方都输了(棋盘满了)可以再开一局

函数声明:

void initchessboard(PBoard pboard);//初始化

void start(PBoard pboarrd);//开始下棋

bool success(PBoard pboarrd, int cur_xpos, int cur_ypos, const char* chess_type);//判断赢局

//cur_xpos是x坐标,cur_ypos是y坐标, chess_type是当前棋子颜色

bool success_hx_position(PBoard pboarrd, int cur_xpos, int cur_ypos, const char* chess_type);//横向位置判断赢局

bool success_zx_position(PBoard pboarrd, int cur_xpos, int cur_ypos, const char* chess_type);//纵向位置判断赢局

bool success_zxx_position(PBoard pboarrd, int cur_xpos, int cur_ypos, const char* chess_type);//左斜向位置判断赢局

bool success_yxx_position(PBoard pboarrd, int cur_xpos, int cur_ypos, const char* chess_type);//右斜向位置判断赢局

bool isfull(PBoard pboard);//判断期盼是否为满

void show_board(PBoard pboard);//展示棋盘

写在前面:

一个汉字占2字节

英文+一个字节//这个就是普通字符

汉字+两个字节//键盘输“加”选择的加号

因为黑白棋符号的缘故,我们棋盘初始化界面的‘+’为汉字‘+’,这样在进行数组更换符号时才能一一对应上

//获取如下两个图标,键盘输入“圆圈”即可找到

//有的找的⭕找的是图标,也是1字节的,可以找个别的字符替代一下,比如□

所以下面的代码我就用□表示白棋,●表示黑棋

代码实现

chess.h

#pragma once
#include<stdio.h>
#define ROW 5//行
#define COLUMN 5//列
#define N 5//设置5个旗子连着为赢

typedef struct ChessBoard {
    const char* chess_board[ROW][COLUMN];
    int size;//记录当前棋盘有效棋子个数
}ChessBoard, * PBoard;

//功能函数
void initchessboard(PBoard pboard);//初始化
void start(PBoard pboarrd);//开始下棋
bool success(PBoard pboarrd, int cur_xpos, int cur_ypos, const char* chess_type);//判断赢局:横纵对角
//cur_xpos是x坐标,cur_ypos是y坐标, chess_type是当前棋子颜色
bool success_hx_position(PBoard pboarrd, int cur_xpos, int cur_ypos, const char* chess_type);//横向位置
bool success_zx_position(PBoard pboarrd, int cur_xpos, int cur_ypos, const char* chess_type);//纵向位置
bool success_zxx_position(PBoard pboarrd, int cur_xpos, int cur_ypos, const char* chess_type);//左斜向位置
bool success_yxx_position(PBoard pboarrd, int cur_xpos, int cur_ypos, const char* chess_type);//右斜向位置
bool isfull(PBoard pboard);//判断下满
void show_board(PBoard pboard);//展示棋盘

.cpp

//主程序
#include"chess.h"
int main()
{
    ChessBoard chessboard;
    start(&chessboard);
    return 0;
}

.cpp

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
#include"chess.h"
#include<string.h>
void initchessboard(PBoard pboard)//初始化
{
    pboard->size = 0;
    for (int i = 0; i < ROW; i++)
    {
        for (int j = 0; j < COLUMN; j++)
        {
            pboard->chess_board[i][j] = { "+" };
        }
    }
}
bool success(PBoard pboarrd, int cur_xpos, int cur_ypos, const char* chess_type)//判断赢局:横纵对角
{
    return(success_hx_position(pboarrd, cur_xpos, cur_ypos, chess_type)
        || success_zx_position(pboarrd, cur_xpos, cur_ypos, chess_type)
        || success_zxx_position(pboarrd, cur_xpos, cur_ypos, chess_type)
        || success_yxx_position(pboarrd, cur_xpos, cur_ypos, chess_type));
}

bool success_hx_position(PBoard pboarrd, int cur_xpos, int cur_ypos, const char* chess_type)//横向位置
{
    //当前棋子的左边位置和右边位置遍历查找
    int count = 0;//记录与当前棋子相同颜色的棋子个数
    int i = cur_xpos;
    for (int j = cur_ypos-1; j >= 0; j--)//左边
    {
        if (pboarrd->chess_board[i][j] == chess_type)
            count++;
        else
            break;
    }
    //上面的for函数可以简化成
    //for (int j = cur_ypos - 1&& pboarrd->chess_board[i][j] == chess_type; j >= 0; j--)//左边
    //{
    //        count++;
    //}
    for (int j = cur_ypos ; j < COLUMN; j++)//右边
    {
        if (pboarrd->chess_board[i][j] == chess_type)
            count++;
        else
            break;
    }
    if (count >= N)
    {
        printf("%s赢了!\n", chess_type);
        return true;
    }
    else
        return false;
}
bool success_zx_position(PBoard pboarrd, int cur_xpos, int cur_ypos,const char* chess_type)//纵向位置
{
    //当前棋子的上边位置和下边位置遍历查找
    int count = 0;//记录与当前棋子相同颜色的棋子个数
    int j = cur_ypos;
    for (int i = cur_xpos - 1; i >= 0; i--)//上边
    {
        if (pboarrd->chess_board[i][j] == chess_type)
            count++;
        else
            break;
    }
    for (int i = cur_xpos; i < ROW; i++)//下边
    {
        if (pboarrd->chess_board[i][j] == chess_type)
            count++;
        else
            break;
    }
    if (count >= N)
    {
        printf("%s赢了!\n", chess_type);
        return true;
    }
    else
        return false;
}
bool success_zxx_position(PBoard pboarrd, int cur_xpos, int cur_ypos, const char* chess_type)//左斜向位置
{
    //当前棋子的左上位置和左下位置遍历查找
    int count = 0;//记录与当前棋子相同颜色的棋子个数
    int j = cur_ypos;
    int i = cur_xpos;
    //
    for (; i >= 0 && j >=0 && pboarrd->chess_board[i][j] == chess_type; i--,j--)//左上
    {  count++;
    }

    for (j = cur_ypos+1,i = cur_xpos+1; i <ROW  && j <COLUMN && pboarrd->chess_board[i][j] == chess_type; i++, j++)//左下
    { count++;
    }
    if (count >= N)
    {
        printf("%s赢了!\n", chess_type);
        return true;
    }
    else
        return false;
}
bool success_yxx_position(PBoard pboarrd, int cur_xpos, int cur_ypos, const char* chess_type)//右斜向位置
{
        //当前棋子的右上位置和右下位置遍历查找
        int count = 0;//记录与当前棋子相同颜色的棋子个数
        int j = cur_ypos;
        int i = cur_xpos;
        for (; i >=0 && j < COLUMN && pboarrd->chess_board[i][j] == chess_type; i--, j++)//右上
        {
            count++;
        }
        for (i = cur_xpos+1, j = cur_ypos -1; i < ROW && j >=0 && pboarrd->chess_board[i][j] == chess_type; i++, j--)//左下
        {
            count++;
        }
        if (count >= N)
        {
            printf("%s赢了!\n", chess_type);
            return true;
        }
        else
            return false;
}
void show_board(PBoard pboard)//展示棋盘
{
    for (int i = 0; i < ROW; i++)
    {
        for (int j = 0; j < COLUMN; j++)
            printf("%s",pboard->chess_board[i][j]);
        printf("\n");
    }
}

bool isfull(PBoard pboard)//判断满
{
    return pboard->size == ROW * COLUMN ? true: false;
}

void start(PBoard pboard) //开始下棋
{
    
    int choice;
    const char* chess_type;
    int xpos, ypos;
    printf("五子棋游戏开始了!\n");
    while(true){
        initchessboard(pboard);//初始化棋盘
         printf("请选择输入的棋子类型:\n1.白棋□,2.黑棋●,3.退出游戏\n");
         scanf("%d", &choice);
         if (choice == 3)
         {
             printf("游戏结束\n");
             return;
         }
            //if(choice==1)
              //  chess_type = "□";
          //  else
             //   chess_type = "●";
         chess_type = choice == 1 ? "□" : "●";
         while (true)
        {
            show_board(pboard);
            printf("请输入%s棋子的坐标(空格符间隔):\n", chess_type);
            scanf("%d%d", &xpos, &ypos);
            //对当前位置进行判断,若有棋子在就不能再下
            //1.棋盘满  2,棋盘未满但该位置有棋子
            //while (true)
            {
                if (pboard->chess_board[xpos][ypos] == "+")
                {
                    pboard->chess_board[xpos][ypos] = chess_type;
                    pboard->size++;
                    //break;
                }
                else
                {
                    //判满
                    if (isfull(pboard))
                    {
                        printf("棋盘已满\n是否需要重开一局,y or n?\n");
                        char num;
                        getchar();
                        scanf("%c", &num);
                        getchar();
                        //printf("%c", num);
                        if (num == 'y')
                            break;//跳出一层循环
                        else
                        {
                            printf("游戏结束\n");
                            return;
                        }
                    }
                    else
                    {
                        printf("该位置已有棋子,请重新输入:\n");
                        scanf("%d%d", &xpos, &ypos);
                        pboard->size++;
                    }
                    pboard->chess_board[xpos][ypos] = chess_type;
                }
            }
            //判断该棋子是否为赢剧
            if (success(pboard, xpos, ypos, chess_type))
            {
                show_board(pboard);
                printf("%s棋子获胜\n是否需要重开一局,y or n?\n", chess_type);
                char num;
                getchar();
                scanf("%c",&num);
                getchar();
                //printf("%c", num);
                if (num == 'y')
                    break;//跳出一层循环
                else
                {
                    printf("游戏结束\n");
                    return;
                }
            }
            else
                chess_type = chess_type == "●"?"□":"●";

          }
      }
}

结果:

初始化界面调试:

 检验已有棋子位置是否可以重复下棋:

 检查横向位置成功情况:

 检查纵向位置成功情况:

检查左斜向位置获胜情况:

 

检查右斜向位置获胜情况:

重开局测验:

 判断棋盘为满:

 代码解析:

除了在代码内部“//”出来的,还有一些需要解释的地方

1.键盘对于字符的获取:

本来scanf("%c",&num);就可以,但是在输入的时候缓冲区有\n输入只有也有\n的存在,会导致,实际输入的内容为:

        \n 

        y

        \n,因而对于num与'y'比较时也出错,因此用getchar();函数捕捉掉“\n”,即为如下代码所示。

                               

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言五子棋双人对战项目的架构可以分为以下几个模块: 1. 用户界面模块:负责显示游戏界面和接收用户输入。可以使用图形库或者命令行界面来实现。 2. 游戏逻辑模块:负责处理游戏规则和逻辑。包括判断胜负、落子、切换玩家等功能。 3. AI模块(可选):如果需要实现人机对战,可以添加一个AI模块,负责计算机玩家的落子策略。 4. 存储模块(可选):如果需要保存游戏进度或者记录游戏历史,可以添加一个存储模块,负责读写游戏数据。 5. 辅助函数模块:包含一些辅助函数,用于判断棋盘状态、检查落子是否合法等。 下面是一个简单的示例代码,展示了一个基本的五子棋双人对战项目的架构: ```c // 用户界面模块 void drawBoard(); void getUserInput(); // 游戏逻辑模块 void initGame(); void playGame(); int checkWin(); void switchPlayer(); // AI模块 void makeMove(); // 存储模块 void saveGame(); void loadGame(); // 辅助函数模块 int isValidMove(); int isBoardFull(); int main() { initGame(); playGame(); return 0; } void initGame() { // 初始化游戏数据 } void playGame() { while (!checkWin() && !isBoardFull()) { drawBoard(); getUserInput(); switchPlayer(); } // 游戏结束,显示结果 } int checkWin() { // 判断是否有玩家获胜 } void switchPlayer() { // 切换玩家 } void drawBoard() { // 绘制游戏界面 } void getUserInput() { // 获取用户输入 } void makeMove() { // AI计算落子位置 } void saveGame() { // 保存游戏进度 } void loadGame() { // 加载游戏进度 } int isValidMove() { // 检查落子是否合法 } int isBoardFull() { // 检查棋盘是否已满 } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值