当前位置: 首页 > news >正文

五子棋(C语言实现)

目录

构思

1、主程序

2、初始化

3、游戏菜单

4、打印棋盘

6、玩家下棋

7、判断输赢

 8、功能整合

人机下棋

完整版: 

game.h

game.c

text.c

 测试功能代码


构思

五子棋不必多介绍了,大家小时候都玩过哈。

我们要通过程序实现这个小游戏,大体上的构思得有:

游戏流程:运行游戏>>打印棋盘>>下棋>>判断输赢

由此,我们声明如下函数、棋盘数组和回合数 (用于双人下棋时下不同棋子的判断)。

将这些都放在我创建的头文件game.h中方便其他文件使用: 

#include <stdio.h>
#include <Windows.h>int map[19][19];//棋盘
int flag;//回合数//初始化棋盘
void init();//游戏菜单
void menuView();//打印棋盘
void gameView_ShowMap();//玩家下棋
int playerMove(int x, int y);//判断输赢
int isWin(int x, int y);//判断输赢
void winView();

1、主程序

先进行游戏下棋,后进行判断输赢,比较符合do—while的特点。 

int main()
{int input = 0;do{menuView();printf("请选择:");scanf("%d", &input);switch (input) {case 1:gameView();break;case 0:printf("退出游戏\n");break;default:printf("输入错误,请重新选择.\n");break;}} while (input);return 0;
}
  • 首先打印菜单,提示玩家进行选择开始游戏。
  • 通过输入变量input的值,判断是否进行游戏,
  • 值为1则调用gameView函数进行游戏,0则结束游戏。
  • gameView函数对各种功能函数进行整合。

在此之前先将各种功能函数进行实现,最后将它们放入gameView整合。 

2、初始化

void init() {for (int i = 0; i < 19; i++) {for (int j = 0; j < 19; j++) {map[i][j] = 0;}}flag = 0;
}
  • 将棋盘每个格子初始化为0。
  • 回合数初始化为0。

3、游戏菜单

void menuView() {printf("*************************\n");printf("*****   1. play    ******\n");printf("*****   0. exit    ******\n");printf("*************************\n");
}

4、打印棋盘

这里我选择设计了棋盘格和横纵坐标,我们可以根据需要自行设计。 

void gameView_ShowMap() {int i, j;printf("   ");for (i = 0; i < 19; i++) {//打印横坐标printf("%3d ",i);}printf("\n   ");for (i = 0; i < 19; i++) {printf("+---");}printf("+\n");for (i = 0; i < 19; i++) {printf("%2d |", i);//每行输出前都先打印纵坐标for (j = 0; j < 19; j++) {printf(" %d ", map[i][j]);//打印棋子if (j < 18)printf("|");}printf("|\n");if(i<18)printf("   |");if(i==18)printf("   +");for (j = 0; j < 19; j++) {printf("---");if (j < 18)printf("+");}printf("+\n");}
}

效果如下: 

6、玩家下棋

int playerMove(int x, int y) {if (x >= 0 && x < 19 && y >= 0 && y < 19) {if (map[x][y] == 0) {if (flag % 2 == 0)map[x][y] = 1;//下黑子elsemap[x][y] = 2;//下白子//落子成功return 1;}else {//该位置已有棋子return 0;}}else {//坐标不合法return -1;}
}
  • 首先判断下棋位置是否在棋盘0到18的横纵坐标内,如果不在函数返回值-1,
  • 如果在棋盘内,则进行下棋。
  • 棋盘每个格子初始值为0,判断当前格子的值为0才可以下棋,否则返回值为0。
  • 回合数flag初始值为0,当flag为偶数下黑子>>1,奇数下白子>>2,成功下棋返回值为1。

7、判断输赢

int isWin(int x, int y) {int i, j;for (i = 0; i < 19; i++) {for (j = 0; j < 19; j++) {if (map[i][j] == 0) {continue;}//横着连成五子if (j < 15)if (map[i][j] == map[i][j + 1] && map[i][j] == map[i][j + 2]&& map[i][j] == map[i][j + 3] && map[i][j] == map[i][j + 4])return map[i][j];//竖着连成五子if (i < 15)if (map[i][j] == map[i + 1][j] && map[i][j] == map[i + 2][j]&& map[i][j] == map[i + 3][j] && map[i][j] == map[i + 4][j])return map[i][j];//左斜着连成五子-> " \ "if (i < 15 && j < 15)if (map[i][j] == map[i + 1][j + 1] && map[i][j] == map[i + 2][j + 2]&& map[i][j] == map[i + 3][j + 3] && map[i][j] == map[i + 4][j + 4])return map[i][j];//右斜着连成五子-> " / "if (i < 15 && j > 4)if (map[i][j] == map[i + 1][j - 1] && map[i][j] == map[i + 2][j - 2]&& map[i][j] == map[i + 3][j - 3] && map[i][j] == map[i + 4][j - 4])return map[i][j];}}return 0;
}
  • i < 15 用于确保在检查垂直和左斜方向的连续五子时,起始位置 (i, j) 之后至少还有4个位置。因为五子连成一线需要五个连续的位置,所以确保从当前位置开始往下检查的时候不会超出数组的边界。

  • j < 15 用于确保在检查水平和左斜方向的连续五子时,起始位置 (i, j) 之后至少还有4个位置。同样,这是为了确保从当前位置开始往右检查的时候不会超出数组的边界。

  • j > 4 用于确保在检查右斜方向的连续五子时,起始位置 (i, j) 之前至少还有4个位置。这是为了确保从当前位置开始往左检查的时候不会超出数组的边界。

 8、功能整合

void gameView()
{init();int x = 0, y = 0;int ret = 0;//辅助判断坐标是否合法while (1) {gameView_ShowMap();printf("请输入要下棋的坐标:");scanf("%d %d", &x, &y);if (playerMove(x, y) == 0) {printf("\n!!!该坐标已被占用!!!\n");Sleep(2000);continue;}else if (playerMove(x, y) == -1) {printf("\n!!!请输入合法坐标!!!\n");Sleep(2000);continue;}else {flag++;//切换回合}if (isWin(x, y) == 0) {continue;}else if (isWin(x, y) == 1) {printf("黑子获胜\n");break;}else if (isWin(x, y) == 2) {printf("白子获胜\n");break;}}}
  •  这里的Sleep函数需要头文件#include <Windows.h>,使用该函数暂停两秒,防止continue后下次循环打印的棋盘将提示信息挡住。
  • 下棋坐标不合法打印提示信息后,进入下次循环重新输入。
  • 成功下棋则flag自增,切换回合。
  • 每次下棋后都要判断输赢,有人赢了则停止循环,否则继续下棋。
  • (其实应该从下棋次数第五次开始判断输赢更合理,读者可以自行添加判断)

人机下棋

想要实现人机下棋可以看看我这篇文章《三子棋》 ,里面实现了人机下棋,读者可以自行模仿改进,实现其功能的重要函数可以在这篇文章中学习 rand&srand函数 。 

完整版: 

game.h

#include <stdio.h>
#include <Windows.h>
int map[19][19];//棋盘
int flag;//回合数//初始化
void init();//游戏菜单
void menuView();//打印棋盘
void gameView_ShowMap();//玩家下棋
int playerMove(int x, int y);//判断输赢
int isWin(int x, int y);

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"void init() {for (int i = 0; i < 19; i++) {for (int j = 0; j < 19; j++) {map[i][j] = 0;}}flag = 1;
}int isWin(int x, int y) {int i, j;for (i = 0; i < 19; i++) {for (j = 0; j < 19; j++) {if (map[i][j] == 0) {continue;}//横着连成五子if (j < 15)if (map[i][j] == map[i][j + 1] && map[i][j] == map[i][j + 2]&& map[i][j] == map[i][j + 3] && map[i][j] == map[i][j + 4])return map[i][j];//竖着连成五子if (i < 15)if (map[i][j] == map[i + 1][j] && map[i][j] == map[i + 2][j]&& map[i][j] == map[i + 3][j] && map[i][j] == map[i + 4][j])return map[i][j];//左斜着连成五子-> " \ "if (i < 15 && j < 15)if (map[i][j] == map[i + 1][j + 1] && map[i][j] == map[i + 2][j + 2]&& map[i][j] == map[i + 3][j + 3] && map[i][j] == map[i + 4][j + 4])return map[i][j];//右斜着连成五子-> " / "if (i < 15 && j > 4)if (map[i][j] == map[i + 1][j - 1] && map[i][j] == map[i + 2][j - 2]&& map[i][j] == map[i + 3][j - 3] && map[i][j] == map[i + 4][j - 4])return map[i][j];}}return 0;
}int playerMove(int x, int y) {if (x >= 0 && x < 19 && y >= 0 && y < 19) {if (map[x][y] == 0) {if (flag % 2 == 0)map[x][y] = 1;//下黑子elsemap[x][y] = 2;//下白子//落子成功return 1;}else {//该位置已有棋子return 0;}}else {//坐标不合法return -1;}
}void menuView() {printf("*************************\n");printf("*****   1. play    ******\n");printf("*****   0. exit    ******\n");printf("*************************\n");
}void gameView_ShowMap() {int i, j;printf("   ");for (i = 0; i < 19; i++) {//打印横坐标printf("%3d ",i);}printf("\n   ");for (i = 0; i < 19; i++) {printf("+---");}printf("+\n");for (i = 0; i < 19; i++) {printf("%2d |", i);//每行输出前先都打印纵坐标for (j = 0; j < 19; j++) {printf(" %d ", map[i][j]);if (j < 18)printf("|");}printf("|\n");if(i<18)printf("   |");if(i==18)printf("   +");for (j = 0; j < 19; j++) {printf("---");if (j < 18)printf("+");}printf("+\n");}
}

text.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"void gameView()
{init();int x = 0, y = 0;int ret = 0;//辅助判断坐标是否合法while (1) {gameView_ShowMap();printf("请输入要下棋的坐标:");scanf("%d %d", &x, &y);if (playerMove(x, y) == 0) {printf("\n!!!该坐标已被占用!!!\n");Sleep(2000);continue;}else if (playerMove(x, y) == -1) {printf("\n!!!请输入合法坐标!!!\n");Sleep(2000);continue;}else {flag++;//切换回合}if (isWin(x, y) == 0) {continue;}else if (isWin(x, y) == 1) {printf("黑子获胜\n");break;}else if (isWin(x, y) == 2) {printf("白子获胜\n");break;}}}int main()
{int input = 0;do{menuView();printf("请选择:");scanf("%d", &input);switch (input) {case 1:gameView();break;case 0:printf("退出游戏\n");break;default:printf("输入错误,请重新选择.\n");break;}} while (input);return 0;
}

 测试功能代码

此代码可以替换int main主函数,用于测试函数功能是否正确,可以减少自行下棋测试时间 

成功运行输出如下:

int main()
{int testflag = 0;//init测试代码init();if (flag != 0) {printf("init()错误");exit(0);}for (int i = 0; i < 19; i++) {for (int j = 0; j < 19; j++) {if (map[i][j]) {printf("init()错误");exit(0);}}}printf("init()测试成功\n");testflag++;//playerMove测试代码int result = 1;result &= playerMove(2, 2);result &= playerMove(2, 3);result &= playerMove(2, 4);result &= playerMove(2, 5);if (result != 1 || (map[2][2] && map[2][3] && map[2][4] && map[2][5]) != 1) {printf("playerMove()错误");exit(0);}flag = 1;result &= playerMove(2, 5);if (result != 0 || map[2][5] != 1) {printf("playerMove()错误");exit(0);}printf("playerMove()测试成功\n");testflag++;//isWin测试代码playerMove(2, 1);if (isWin(2, 1)) {printf("isWin()错误");exit(0);}playerMove(1, 0);playerMove(3, 2);playerMove(4, 3);playerMove(5, 4);if (isWin(1, 0) != 2) {printf("isWin()错误");exit(0);}printf("isWin()测试成功\n");testflag++;if (testflag == 3) {printf("service代码测试成功\n");}return 0;
}

相关文章:

五子棋(C语言实现)

目录 构思 1、主程序 2、初始化 3、游戏菜单 4、打印棋盘 6、玩家下棋 7、判断输赢 8、功能整合 人机下棋 完整版&#xff1a; game.h game.c text.c 测试功能代码 构思 五子棋不必多介绍了&#xff0c;大家小时候都玩过哈。 我们要通过程序实现这个小游戏&…...

thymeleaf,bootstrap-fileinput 多文件上传

组件遍历上传 一、前端 <!DOCTYPE html> <html lang"zh" xmlns:th"http://www.thymeleaf.org" > <head><th:block th:include"include :: header(修改固定资产信息)" /><th:block th:include"include :: date…...

爬虫 | 基础模块了解

文章目录 &#x1f4da;http协议&#x1f4da;requests模块&#x1f4da;re模块&#x1f407; re.I 或 re.IGNORECASE&#x1f407;re.M或 re.MULTILINE&#x1f407;re.S 或 re.DOTALL&#x1f407; re.A 或 re.ASCII&#x1f407; re.X 或 re.VERBOSE&#x1f407;特殊字符类…...

CSS复习笔记

CSS 文章目录 CSS1.概念2.CSS 引入方式3.选择器基础选择器:标签选择器类选择器id 选择器通配符选择器 复合选择器:**后代选择器****子代选择器****并集选择器****交集选择器-了解****伪类选择器** 结构伪类选择器&#xff1a;**:nth-child&#xff08;公式&#xff09;**伪元素…...

编译linux的设备树

使用make dtbs命令时 在arch/arm 的目录Makefile文件中有 boot : arch/arm/boot prepare 和scripts是空的 在文件scripts/Kbuild.include中 变量build : -f $(srctree)/scripts/Makefile.build obj build变量虽然没有在arch/arm 的目录Makefile文件中定义&#xff0c;但…...

⛳ MyBatis 中 Mapper 接口工作原理实例解析

&#x1f38d;目录 ⛳ MyBatis 中 Mapper 接口工作原理实例解析&#x1f3a8; 一、Mapper 接口是怎么找到实现类的&#xff1f;&#x1f43e; 二、从一段代码看起&#x1f69c; 三、Mapper 接口&#x1f3ed; 四、Mapper 接口的动态代理类的生成&#x1f381; 五、总结 ⛳ MyBa…...

Android 音频可视化

Android音频可视化&#xff0c;指的是将音频的频率绘制到屏幕上&#xff0c;达到一种视觉效果&#xff0c;使播放或录制过程更加生动形象。 在Android进行视频可视化涉及的三个主要知识点,其中比较难以理解的傅里叶变换公式。 Android原生的Visualizer使用&#xff08;获取频…...

刷机与救砖避坑指南

提示&#xff1a;快速进行刷机和救砖学习理解 文章目录 一、刷机1.什么是刷机&#xff0c;需要进行那些准备&#xff1f;2.刷机1.解开bl&#xff08;bootloader&#xff09;锁2.刷入TWRP和Magsik3.刷入第三方ROM 二、救砖&#xff08;9008&#xff09;1.手机售后一键线刷包&…...

软件建模知识点

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 例如&#xff1a;…...

WSL 配置 Linux

WSL 配置 Linux Windows 启动 Linux 子系统 控制面板 -> 程序和功能&#xff0c; 将 适用于 Linux 的 Windows 子系统 勾选。 安装 Terminal 在 Microsoft Store 市场上搜索 Terminal 安装 Windows Terminal。 安装 编译工具链 sudo apt update # 更新软件包 sudo apt i…...

VS Code:CMake配置

概述 在VSCode和编译器MinGW安装完毕后&#xff0c;要更高效率的进行C/C开发&#xff0c;采用CMake。CMake是一个开源、跨平台的编译、测试和打包工具&#xff0c;它使用比较简单的语言描述编译&#xff0c;安装的过程&#xff0c;输出Makefile或者project文件&#xff0c;再去…...

Flex 词法分析实验实现(电子科技大学编译技术Icoding实验)

Flex 词法分析 此为电子科技大学编译技术 实验1&#xff1a;词法分析 将具体实现中的三个文件和自己的实验报告一起上传才能通过 根据词法分析实验中给定的文法&#xff0c;利用 flex 设计一词法分析器&#xff0c;该分析器从标准输入读入源代码后&#xff0c;输出单词的类别编…...

设计模式——20. 解释器模式

1. 说明 解释器模式(Interpreter Pattern)是一种行为型设计模式,它用于定义一门语言的语法解析,并为该语言创建解释器。该模式将一个问题或领域表达成一个语言,然后提供一个解释器来解释这种语言中的表达式,以执行特定操作。 要点和组成部分: 抽象表达式(Abstract Ex…...

多输入多输出 | MATLAB实现CNN-BiLSTM-Attention卷积神经网络-双向长短期记忆网络结合SE注意力机制的多输入多输出预测

MATLAB实现CNN-BiLSTM-Attention卷积神经网络-双向长短期记忆网络结合SE注意力机制的多输入多输出预测 目录 MATLAB实现CNN-BiLSTM-Attention卷积神经网络-双向长短期记忆网络结合SE注意力机制的多输入多输出预测预测效果基本介绍程序设计往期精彩参考资料 预测效果 基本介绍 C…...

一文让你玩转Linux多进程开发

Linux多进程开发 主要介绍多进程开发时的要点 进程状态转换 进程反应了进程执行的变化。 进程的状态分为三种 ,运行态,阻塞态,就绪态 在五态模型中分为以下几种,新建态&#xff0c;就绪态&#xff0c;运行态&#xff0c;阻塞态,终止态。 运行态&#xff1a;进程占用处理器正在运…...

Linux线程同步实例

线程同步实例 1. 生产消费者模型基本概念2. 基于BlockingQueue的生产者消费者模型3. 基于环形队列的生产消费模型4. 线程池 1. 生产消费者模型基本概念 生产者消费者模型是一种常用的并发设计模式&#xff0c;它可以解决生产者和消费者之间的速度不匹配、解耦、异步等问题。生…...

LuatOS-SOC接口文档(air780E)-- iconv - iconv操作

iconv.open(tocode, fromcode)# 打开相应字符编码转换函数 参数 传入值类型 解释 string 释义&#xff1a;目标编码格式 取值&#xff1a;gb2312/ucs2/ucs2be/utf8 string 释义&#xff1a;源编码格式 取值&#xff1a;gb2312/ucs2/ucs2be/utf8 返回值 返回值类型 解…...

matlab第三方硬件支持包下载和安装

1、在使用matlab内部的附加功能安装时&#xff0c;由于matlab会验证是否正版无法打开 2、在matlab官网直接找到对应的硬件支持包下载&#xff0c;但是是下图的安装程序 可以直接在matlab中跳转到该程序所在的文件夹双击安装&#xff0c;但是安装到最后出错了 3.根据出错时mala…...

docker compose和consul(服务注册与发现)

一、Docker-compose 简介 Docker-Compose项目是基于Python开发的Docker官方开源项目&#xff0c;负责实现对Docker容器集群的快速编排。 Docker-Compose将所管理的容器分为三层&#xff0c;分别是 工程&#xff08;project&#xff09;&#xff0c;服务&#xff08;service&a…...

使用Python进行钻石价格分析

钻石是最昂贵的宝石之一。钻石的质量通常以其重量&#xff08;克拉&#xff09;、净度、颜色和切工来评估。重量越大、净度越高、色彩纯净、切工精细的钻石价格也越高。其中&#xff0c;4C标准是衡量钻石质量的国际标准&#xff0c;即克拉&#xff08;Carat&#xff09;、净度&…...

AI选型与配置:让快马智能推荐npm包并生成个人博客系统前端代码

最近在尝试用AI辅助开发个人博客系统&#xff0c;发现整个过程比想象中顺畅很多。特别是依赖管理和技术选型这个环节&#xff0c;AI能帮我们省去大量查文档和试错的时间。下面记录下我的实践过程&#xff0c;或许对同样想快速搭建博客的朋友有帮助。 需求明确化阶段 首先需要…...

Android端集成MiniCPM-V-2_6轻量化版本:移动端图像风格迁移App开发

Android端集成MiniCPM-V-2_6轻量化版本&#xff1a;移动端图像风格迁移App开发 1. 引言 你有没有想过&#xff0c;用自己的手机摄像头&#xff0c;就能实时看到眼前的世界变成梵高的《星空》或者莫奈的《睡莲》&#xff1f;这听起来像是科幻电影里的场景&#xff0c;但现在&a…...

Qwen3.5-4B模型Python零基础入门:从环境搭建到第一个AI对话程序

Qwen3.5-4B模型Python零基础入门&#xff1a;从环境搭建到第一个AI对话程序 1. 前言&#xff1a;为什么选择Qwen3.5-4B入门AI开发 如果你对AI感兴趣但不知道从何开始&#xff0c;这篇教程就是为你准备的。Qwen3.5-4B是一个非常适合入门的中文大语言模型&#xff0c;它体积适中…...

思源宋体TTF:开源中文字体的技术突破与商业价值重构

思源宋体TTF&#xff1a;开源中文字体的技术突破与商业价值重构 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 在数字化内容爆炸的今天&#xff0c;中文字体的选择直接影响信息传递的…...

腾讯地图API实战:5分钟搞定经纬度录入与地图选点功能(Vue版)

腾讯地图API实战&#xff1a;5分钟搞定经纬度录入与地图选点功能&#xff08;Vue版&#xff09; 在当今的Web开发中&#xff0c;地图功能已成为许多应用的标配需求。无论是电商平台的店铺定位&#xff0c;还是社交应用的位置分享&#xff0c;甚至是企业内部系统的区域管理&…...

Zotero插件市场:变革学术研究工具管理的创新解决方案

Zotero插件市场&#xff1a;变革学术研究工具管理的创新解决方案 【免费下载链接】zotero-addons Zotero add-on to list and install add-ons in Zotero 项目地址: https://gitcode.com/gh_mirrors/zo/zotero-addons 在数字化学术研究的进程中&#xff0c;文献管理工具…...

Qwen3-0.6B-FP8部署详解:如何用16GB显存跑通FP8量化版Qwen3轻量推理

Qwen3-0.6B-FP8部署详解&#xff1a;如何用16GB显存跑通FP8量化版Qwen3轻量推理 想体验最新的大语言模型&#xff0c;但被动辄几十GB的显存需求劝退&#xff1f;今天&#xff0c;我们来解决这个痛点。 Qwen3系列模型以其强大的推理和对话能力备受关注&#xff0c;但其标准版本…...

避坑指南:解决Livox Mid-360双雷达点云融合时坐标系错乱与IMU数据混杂问题

Livox Mid-360双雷达点云融合实战&#xff1a;坐标系校准与IMU数据分离全解析 当你在RViz中看到两个Livox Mid-360雷达的点云像醉酒的水母一样随机飘动&#xff0c;而IMU数据又像被搅拌机混合过的果汁——恭喜你&#xff0c;遇到了多传感器融合的经典难题。这不是简单的参数调整…...

Qwen2.5-VL半监督学习效果展示:有限标注下的性能提升

Qwen2.5-VL半监督学习效果展示&#xff1a;有限标注下的性能提升 1. 引言 在AI视觉领域&#xff0c;标注数据一直是制约模型性能的关键因素。传统监督学习需要大量人工标注&#xff0c;成本高、周期长&#xff0c;让很多企业和研究者望而却步。但今天&#xff0c;随着半监督学…...

【计算机组成原理】1 计算机组成原理学习路线:从晶体管到云架构的知识图谱

1 为什么你需要一张知识图谱 计算机组成原理是计算机科学的核心基石&#xff0c;它研究计算机硬件系统的基本组成原理、逻辑实现及工作机制。对于计算机专业学生或软件开发者而言&#xff0c;理解"代码如何在硬件上运行"不仅是应试需要&#xff0c;更是性能优化、系统…...