马上五一了,带大家玩一下五子棋——C语言

news2024/11/26 17:31:41

五一祝福

因为这篇博文实在五一这天完成的,所以呢,在介绍五子棋之前,先祝各位支持小白的大佬都五一快乐!
花了点时间下了个“五一快乐”的五子棋,哈哈哈哈哈哈,还不太熟练,所以写的有点丑,勉强过的去就行,不知道佬们看不看得出来,还是说实在一点都不像,不过没关系,佬们阅读了之后希望可以给我修正一下,去玩玩。那个’乐‘字确实没整好,哈哈哈,看起来超别扭
如下图所示:
在这里插入图片描述
祝福送给打架了之后就让我们来说一说正文吧。

五子棋的实现

五子棋的实现分为一下几个功能的实现:

  1. 首先是先构建棋盘,我们这里用了一个二维数组chessboard来对我们的棋盘进行初始化和放置棋子
  2. 实现展示棋盘的函数void ShowChessBoard(int board[ROW][COL])
  3. 玩家1下棋,我们用函数void PlayerMove(int board[ROW][COL], int who)来实现,后面那个参数who 传的是谁就是到谁下棋
  4. 玩家1下棋之后棋盘会有变化,我们要对棋局进行判断是否达成了五子连珠,或者说整个棋盘的棋子都放满了还没结束,那就是平局,否则就是继续进行棋局,我们用函数int IsOver(int board[ROW][COL])来进行判断,其中这个函数的判断方法是通过调用函数int ChessCount(int board[ROW][COL], enum Dir d)来判断每下一步棋之后该位置的八个方向都进行判断,看是否达成其中至少有一个方向满足五子连珠来判断当前棋局的情况
  5. 玩家2下棋,将第3 ,4中的玩家1变成玩家2重复上述第3 , 4步。

1 菜单

代码实现:

void menu()
{
    printf("****************************\n");
    printf("******1. 开始   0.退出******\n");
    printf("****************************\n");
    printf("请选择 :> ");

}

2.展示棋盘

代码实现:

void ShowChessBoard(int board[ROW][COL])
{
    printf("\033c");
    printf("玩家1——●\n");
    printf("玩家2——○\n");
    printf("\n\n  ");
    //打印y坐标轴
    for (int i = 0; i < COL; i++) {
        printf("%3d", i);
    }
    printf("\n");
    for (int i = 0; i < ROW; i++) {
        printf("%3d", i);//打印x坐标轴
        for (int j = 0; j < COL; j++) {
            if (board[i][j] == Player1) {
                //player1
                printf(" ●");//用黑棋表示玩家1的棋子
            }
            else if (board[i][j] == Player2) {
                //player2
                printf(" ○");//用白棋表示玩家2的棋子
            } 
            else {
                //Space
                printf(" + ");//空余部分默认为'+'
            }
        }
        printf("\n");
    }
}

3.玩家下棋

代码实现:

void PlayerMove(int board[ROW][COL], int who)
{
    while (1) {
        printf("\n玩家[%d] 请输入你需要下棋的位置:> ", who);
        scanf("%d %d", &x, &y);//输入一个下棋的坐标
        if (x<0 || y > COL) {
            printf("非法坐标,重新输入!\n");
        }
        else if (board[x][y] != 0) {
            printf("该位置已被占用!\n");
        }
        else {
            board[x][y] = who;//把下棋的玩家对应的常量值赋值给该位置对应的值
            break;
        }
    }
}

4.统计下棋位置所对应的同种棋子的个数

代码实现:

int ChessCount(int board[ROW][COL], enum Dir d)
{
    int _x = x;
    int _y = y;

    int count = 0;
    while (1) {
        switch (d) {
        case LEFT:
            _y--;
            break;
        case RIGHT:
            _y++;
            break;
        case UP:
            _x--;
            break;
        case DOWN:
            _x++;
            break;
        case LEFT_UP:
            _x--, _y--;
            break;
        case RIGHT_DOWN:
            _x++, _y++;
            break;
        case RIGHT_UP:
            _x--, _y++;
            break;
        case LEFT_DOWN:
            _x++, _y--;
            break;
        }
        if (_x < 0 || _x > ROW - 1 || _y < 0 || _y > COL - 1) {
            break;
        }//对下的棋子位置进行八个方向位置的连续的同种棋子个数进行统计
        if (board[x][y] == board[_x][_y]) {
            count++;
        }
        else {
            break;
        }
    }
    return count;
}

5.判断棋局是否结束

代码实现:

int IsOver(int board[ROW][COL])
{
    //将八个方向对应的同种棋子转变为统计四条直线上对应的同种棋子总数
    int count1 = ChessCount(board, LEFT) + ChessCount(board, RIGHT) + 1;
    int count2 = ChessCount(board, UP) + ChessCount(board, DOWN) + 1;
    int count3 = ChessCount(board, LEFT_UP) + ChessCount(board, RIGHT_DOWN) + 1;
    int count4 = ChessCount(board, LEFT_DOWN) + ChessCount(board, RIGHT_UP) + 1;
    //只要有一个方向连续的同种棋子数满足大于等于5个,那么相对应的玩家获得胜利
    if (count1 >= 5 || count2 >= 5 || count3 >= 5 || count4 >= 5) {
        if (board[x][y] == Player1) {
            return PLAYER1_WIN;
        }
        else {
            return PLAYER2_WIN;
        }
    }
    //否则如果棋盘还没下满,也就是只要还有位置没放棋子,则对局继续
    for (int i = 0; i < ROW; i++) {
        for (int j = 0; j < COL; j++) {
            if (board[i][j] == 0) {
                return CONTINUE;
            }
        }
    }
    //以上情况都不符合那就是平局
    return DROW;
}

6.将以上函数功能进行结合的game 函数

代码实现:

void game()
{
	 //初始化
    int chessboard[ROW][COL];
    memset(chessboard, '\0', sizeof(chessboard));
    //判断结果的变量,默认初始化为对局继续
    int result = CONTINUE;
    do {
        ShowChessBoard(chessboard);
        PlayerMove(chessboard, Player1);
        result = IsOver(chessboard);
        if (CONTINUE != result) {
            break;
        }
        ShowChessBoard(chessboard);
        PlayerMove(chessboard, Player2);
        result = IsOver(chessboard);
        if (CONTINUE != result) {
            break;
        }
    } while (1);

    ShowChessBoard(chessboard);
    switch (result) {
    case PLAYER1_WIN:
        printf("恭喜玩家1获胜!\n");
        break;
    case PLAYER2_WIN:
        printf("恭喜玩家2获胜了!\n");
        break;
    case DROW:
        printf("平局,不服可以再战!\n");
        break;
    }
}

完整代码

game.h
#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ROW 30               
#define COL 30
#define Player1 1
#define Player2 2
#define CONTINUE 0
#define PLAYER1_WIN 1
#define PLAYER2_WIN 2
#define DROW   3

enum dir
{
	LEFT,
	RIGHT,
	UP,
	DOWN,
	LEFT_UP,
	RIGHT_UP,
	LEFT_DOWN,
	RIGHT_DOWN
};


void menu();

void game();

void ShowChessBoard(int chessboard[ROW][COL]);

int IsOver(int chessboard[ROW][COL]);

void PlayerMove(int chessboard[ROW][COL], int who);

int ChessCount(int chessboard[ROW][COL], enum dir d);




game.c
#include "game.h"

int x = 0;
int y = 0;

void menu()
{
    printf("****************************\n");
    printf("******1. 开始   0.退出******\n");
    printf("****************************\n");
    printf("请选择 :> ");

}

void ShowChessBoard(int board[ROW][COL])
{
    printf("\033c");
    printf("玩家1——●\n");
    printf("玩家2——○\n");
    printf("\n\n  ");
    //打印y坐标轴
    for (int i = 0; i < COL; i++) {
        printf("%3d", i);
    }
    printf("\n");
    for (int i = 0; i < ROW; i++) {
        printf("%3d", i);//打印x坐标轴
        for (int j = 0; j < COL; j++) {
            if (board[i][j] == Player1) {
                //player1
                printf(" ●");//用黑棋表示玩家1的棋子
            }
            else if (board[i][j] == Player2) {
                //player2
                printf(" ○");//用白棋表示玩家2的棋子
            } 
            else {
                //Space
                printf(" + ");//空余部分默认为'+'
            }
        }
        printf("\n");
    }
}
void PlayerMove(int board[ROW][COL], int who)
{
    while (1) {
        printf("\n玩家[%d] 请输入你需要下棋的位置:> ", who);
        scanf("%d %d", &x, &y);//输入一个下棋的坐标
        if (x<0 || y > COL) {
            printf("非法坐标,重新输入!\n");
        }
        else if (board[x][y] != 0) {
            printf("该位置已被占用!\n");
        }
        else {
            board[x][y] = who;//把下棋的玩家对应的常量值赋值给该位置对应的值
            break;
        }
    }
}

int ChessCount(int board[ROW][COL], enum Dir d)
{
    int _x = x;
    int _y = y;

    int count = 0;
    while (1) {
        switch (d) {
        case LEFT:
            _y--;
            break;
        case RIGHT:
            _y++;
            break;
        case UP:
            _x--;
            break;
        case DOWN:
            _x++;
            break;
        case LEFT_UP:
            _x--, _y--;
            break;
        case RIGHT_DOWN:
            _x++, _y++;
            break;
        case RIGHT_UP:
            _x--, _y++;
            break;
        case LEFT_DOWN:
            _x++, _y--;
            break;
        }
        if (_x < 0 || _x > ROW - 1 || _y < 0 || _y > COL - 1) {
            break;
        }//对下的棋子位置进行八个方向位置的连续的同种棋子个数进行统计
        if (board[x][y] == board[_x][_y]) {
            count++;
        }
        else {
            break;
        }
    }
    return count;
}

int IsOver(int board[ROW][COL])
{
    //将八个方向对应的同种棋子转变为统计四条直线上对应的同种棋子总数
    int count1 = ChessCount(board, LEFT) + ChessCount(board, RIGHT) + 1;
    int count2 = ChessCount(board, UP) + ChessCount(board, DOWN) + 1;
    int count3 = ChessCount(board, LEFT_UP) + ChessCount(board, RIGHT_DOWN) + 1;
    int count4 = ChessCount(board, LEFT_DOWN) + ChessCount(board, RIGHT_UP) + 1;
    //只要有一个方向连续的同种棋子数满足大于等于5个,那么相对应的玩家获得胜利
    if (count1 >= 5 || count2 >= 5 || count3 >= 5 || count4 >= 5) {
        if (board[x][y] == Player1) {
            return PLAYER1_WIN;
        }
        else {
            return PLAYER2_WIN;
        }
    }
    //否则如果棋盘还没下满,也就是只要还有位置没放棋子,则对局继续
    for (int i = 0; i < ROW; i++) {
        for (int j = 0; j < COL; j++) {
            if (board[i][j] == 0) {
                return CONTINUE;
            }
        }
    }
    //以上情况都不符合那就是平局
    return DROW;
}

void game()
{
	 //初始化
    int chessboard[ROW][COL];
    memset(chessboard, '\0', sizeof(chessboard));
    //判断结果的变量,默认初始化为对局继续
    int result = CONTINUE;
    do {
        ShowChessBoard(chessboard);
        PlayerMove(chessboard, Player1);
        result = IsOver(chessboard);
        if (CONTINUE != result) {
            break;
        }
        ShowChessBoard(chessboard);
        PlayerMove(chessboard, Player2);
        result = IsOver(chessboard);
        if (CONTINUE != result) {
            break;
        }
    } while (1);

    ShowChessBoard(chessboard);
    switch (result) {
    case PLAYER1_WIN:
        printf("恭喜玩家1获胜!\n");
        break;
    case PLAYER2_WIN:
        printf("恭喜玩家2获胜了!\n");
        break;
    case DROW:
        printf("平局,不服可以再战!\n");
        break;
    }
}
test.c
#include "game.h"


int main()
{
    int input = 0;
    do
    {
        menu();
        scanf("%d", &input);
        switch (input)
        {
        case 1:
            printf("欢迎来到五子棋---玩家1vs玩家2\n");
            printf("祝您游戏愉快\n");
            game();
            break;
        case 0:
            printf("游戏已退出\n");
            break;
        default:
            printf("选择错误,请重新输入!\n");
            break;
        }
    } while (input);
    return 0;
}

好了,我们的五子棋实现就到这了,五一快乐哦~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/480001.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

常用 Composition API【VUE3】

二、常用 Composition API 7. 计算属性与监视 7.1 computed函数 与Vue2.x中computed配置功能一致写法 <template><h1>一个人的信息</h1>姓&#xff1a;<input type"text" v-model"person.firstName"><br><br>名&a…

【ROS 开发神器 Visual Studio Code 的安装和设置】

【ROS 开发神器 Visual Studio Code 的安装和设置】 1. Visual Studio Code的安装1.1 点击deb文件下载1.2 安装VScode1.3 启动软件1.4 添加收藏夹 2. 导入工作空间2.1 熟悉Vscode基本界面2.2 添加工作空间 3. 安装简体中文语言4. 安装ROS插件5. 安装CMake插件6. 安装括号颜色插…

SpringBoot 中的加密模块

Spring Boot 是一款流行的 Java 开发框架&#xff0c;它提供了多种加密模块&#xff0c;用于保护数据的安全性。本文将介绍 Spring Boot 中的加密模块&#xff0c;包括对称加密、非对称加密和哈希加密等&#xff0c;同时还会提供相应的代码示例。 一、对称加密 对称加密是一种…

改进YOLOv8 | 即插即用篇 | 全维动态卷积 |《 OMNI-DIMENSIONAL DYNAMIC CONVOLUTION》

单个静态卷积核是现代卷积神经网络(CNNs)的常见训练范式。然而,最近的动态卷积研究表明,学习加权为其输入依赖注意力的n个卷积核的线性组合可以显著提高轻量级CNNs的准确性,同时保持高效的推理。然而,我们观察到现有的作品通过卷积核空间的一个维度(关于卷积核数量)赋予…

关于密码学的进一步答疑:SSL和TLS的区别、CA和CT的关系

《密码学&#xff1a;一文读懂常用加密技术原理及其逻辑与应用方法》一文一经发布后&#xff0c;后台收到了许多私信&#xff0c;承蒙喜爱&#xff0c;这篇文章将主要对后台收到的高频问题予以统一回应。 问题一: 在讨论加密解密的过程中&#xff0c;常常在同一语境下同时出现S…

设计模式之原型模式(深拷贝浅拷贝)

目录 1、什么是原型模式 2、前置知识&#xff08;深拷贝&浅拷贝&#xff09; 2.1 浅拷贝 2.2 深拷贝 3、代码实现 3.1 通过Object中的clone方法实现浅拷贝 3.2 通过对象流来实现深拷贝 4、原型模式总结 4.1 优缺点 4.2 使用场景 4.3 对比直接new对象有何不同 1、…

如何使用递归函数实现Excel列号转换列标

在Excel中&#xff0c;列标与列号转换是VBA开发过程中经常用到的功能&#xff0c;下面这篇博客为大家解释了多种方法。 【Excel列标与列号转换】 那么这篇博文的核心是“递归过程”&#xff0c;实现这个功能并不是必须使用递归过程&#xff0c;但是这也不失为一种实现方法&am…

【Android入门到项目实战-- 8.2】—— 使用HTTP协议访问网络

目录 一、使用HttpURLConnection 1、使用Android的HttpURLConnection步骤 1&#xff09;获取HttpURLConnection实例 2)设置HTTP请求使用的方法 3)定制HTTP请求&#xff0c;如连接超时、读取超时的毫秒数 4)调用getInputStream()方法获取返回的输入流 5)关闭HTTP连接 2、…

NXP - LPC1769与LPC1768的区别

文章目录 NXP - LPC1769与LPC1768的区别概述笔记General description验证结论END NXP - LPC1769与LPC1768的区别 概述 openpnp设备用到了冰沙主板. 冰沙主板的主控MCU用到了LPC1769, 想着研究一下. 订了OM13085UL, 遥遥无期… 买了LPC MCU的书, 里面提到了书的作者的网店, 居…

python+vue精品课程建设制作django服务网站系统

功能介绍通篇文章的撰写基础是实际的应用需要&#xff0c;然后在架构系统之前全面复习大学所修习的相关知识以及网络提供的技术应用教程&#xff0c;以视频建设制作服务的实际应用需要出发&#xff0c;架构系统来改善现视频建设制作服务工作流程繁琐等问题。不仅如此以操作者的…

kotlin在鸿蒙开发中的实践

先说一说kotlin 我们知道&#xff1a; kotlin目前是安卓首选的编程语言。 安卓逐渐抛弃java&#xff0c;拥抱kotlin这是大的趋势。 kotlin的最大优点就是与java的互操作性。 kotlin编译的产物和java一样是bytecode(不抬杠&#xff0c;本文只说面向jvm的kotlin)。 kotlin是一…

Cadence基础操作:Schematic编辑

本文转载自B站up主:_WithB&#xff0c;原文链接如下&#xff1a;https://www.bilibili.com/read/cv20414466 鼠标 左键单击 –> 选中或确定操作 按住左键 –> 选中区域内所有组件 左键双击&#xff0c;可以选择以特定操作模式和窗口类型进入对应组件的下一层一般我是ed…

Winform从入门到精通(36)—ColorDialog(史上最全)更新中

前言 当我们需要设置某个控件的颜色时,并且需要弹出一个可以选择颜色的对话框时,这时候就需要使用ColorDialog 一、属性 1、AllowFullOpen 该属性用于启用或者禁用“自定义颜色按钮”,该属性为true时,可以自定义颜色 2、AnyColor 实际测试该属性没什么作用 3、Colo…

请求与相应

从容器到Servlet 前面我们介绍了JSP的内置对象和Servlet的相关知识&#xff0c; 以及如何部署和开发一个Servlet。但是&#xff0c; 并没有详细介绍如何将Servlet与JSP结合起来使用。Web容器是JSP唯一可以识别的HTTP服务器&#xff0c; 所以必须了解Web容器如何生成请求和响应…

来上海一个月的记录、思考和感悟

作者 | gongyouliu 编辑 | gongyouliu 从4月3号早上来上海&#xff0c;到今天差不多整整一个月了&#xff0c;也是自己正式从杭州离职创业&#xff08;我更愿意称之为自由职业者&#xff0c;毕竟我没有招聘全职员工&#xff0c;有两个朋友业余时间在帮我&#xff09;的第一个月…

SAP UI5 之Bootstrap(引导)笔记二

文章目录 Setting up Visual Studio Code for UI5 development1.0 官网 Walkthrough学习-Bootstrap 引导加载1.0.1 在 index.html中新增script标签1.0.2 在webapp 下面新增index.js文件1.0.3启动UI5的服务 Setting up Visual Studio Code for UI5 development 学习链接 Setti…

如何正确部署Redisearch和Rejson(附*.so文件免费下载)

1 缘起 项目需要。 最近的一个项目需要做文本搜索,技术选型:Redis的两个组件Redisearch和ReJSON。 Redisearch和ReJSON是Redis的两个组件: RediSearch为Redis提供查询、二次索引和全文搜索。使用RediSearch,首先要在Redis数据上声明索引。然后使用RediSearch查询语言来查…

【电子通识】颜色的困惑:什么是国际通用Panone(潘通)

Pantone 是世界知名的色彩权威机构&#xff0c;也是色彩系统的供应商&#xff0c;为许多行业提供专业色彩选择。在 Pantone 之前&#xff0c;每个印刷公司都有自己的色彩指南。比如都是“黄色”&#xff0c;但由于印刷方式有所不同&#xff08;具体取决于每个油墨公司如何解释该…

学习之-Mysql Sql 优化之 Explain

在开发中&#xff0c;往往遇到一些慢查询语句&#xff0c; 我们需要对慢查询进行优化。Explain工具就是用来分析某个慢查询执行情况的工具。通过在select 语句前加上explain 关键字&#xff0c;然后执行就会得到某个sql 执行计划信息&#xff0c;通过分析执行计划&#xff0c;我…

vue相关知识导学

学习资料 Vue 相关源码地址&#xff1a; vue2.0 GitHub - vuejs/vue: This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/coreVue3.0 GitHub - vuejs/core: &#x1f596; Vue.js is a progressive, incrementally-adoptable JavaScri…