C语言实现简易n子棋小游戏(代码含注解)

news2024/9/23 5:24:43

利用C语言简单实现一个n子棋小游戏,棋盘大小由自己定义

将源文件分为   执行游戏的测试文件(test.c)和保存游戏运行逻辑的相关函数的文件(game.c)

头文件中声明符号和函数的定义(game.h)

游戏执行主要依靠二维数组实现,电脑走棋采用随机值的方法简易地实现而非采用高级的算法

头文件 game.h

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <math.h>
#include<stdlib.h>
#include<windows.h>
#include<time.h>
//符号的定义(定义几子棋)
#define ROW 3
#define COL 3

//函数的定义
void InitBoard(char board[ROW][COL], int row, int col);//初始化棋盘
void PrintBoard(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);//电脑下棋
char IsWin(char board[ROW][COL], int row, int col);//判断游戏结果

源文件 test.c

#include "game.h"            //引用头文件
void game() {
	char ret;
	char board[ROW][COL];  //二维数组存储游戏数据,ROW、COL为行和列,在头文件game.h中定义
	InitBoard(board,ROW,COL);//初始化棋盘为空格
	PrintBoard(board, ROW, COL);//打印棋盘
	while (1) {
		printf("玩家走\n\n");
		PlayerMove(board, ROW, COL);  //玩家下棋
		Sleep(500);
		PrintBoard(board, ROW, COL);  
		//判断玩家是否赢得游戏
		ret=IsWin(board, ROW, COL);		//返回值为*代表玩家获胜、#代表电脑获胜、D代表平局、C代表未出结果,游戏继续
		if (ret != 'C') {
			break;
		}
		printf("电脑走\n\n");
		ComputerMove(board, ROW, COL);//玩家下棋
		Sleep(1300);
		PrintBoard(board, ROW, COL);
		//判断电脑是否赢得游戏
		ret = IsWin(board, ROW, COL);
		if (ret != 'C') {
			break;
		}

	}
	if (ret == '*') {
		printf("玩家获胜\n\n");
	}
	else if (ret =='#') {
		printf("电脑获胜\n\n");

	}
	else if (ret == 'D') {
		printf("平局\n\n");
	}
	PrintBoard(board, ROW, COL);//打印游戏结果

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

}
int main() {
	int n;
	srand((unsigned int)time(NULL));//设置随机数种子
	do
	{
		menu();
		printf("请选择:\n");
		scanf("%d", &n);
		switch (n)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,重新选择\n");
			break;
		}
	} while (n);
	return 0;
}

源文件 game.c

#include "game.h"                        //引用头文件
void InitBoard(char board[ROW][COL], int row, int col) {
	for (int i = 0; i < ROW; i++) {
		for (int j = 0; j < COL; j++) {
			board[i][j] = ' ';
		}
	}
}
void PrintBoard(char board[ROW][COL], int row, int col) {          //打印棋盘
	for (int j = 0; j < col; j++) {
		printf(" ___");
	}
	printf(" \n");
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			printf("| %c ",board[i][j]);
		}
		printf("|\n");
		if (i < row ) {
			for (int j = 0; j < col; j++) {
				printf("|___");
			}
			printf("|\n");
		}

	}
	printf("\n");
}
void PlayerMove(char board[ROW][COL], int row, int col) {
	while (1) {                            //若输入错误则一直循环
		int x, y;
		printf("请输入坐标:\n");
		scanf("%d %d", &x, &y);
        if (x <= row && x >= 1 && y <= col && y >= 1) {         //判断坐标是否合法
			if (board[x - 1][y - 1] == ' ')                     //玩家输入的坐标需要减1,因为数组从0开始,同时判断坐标是否被占用过
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("坐标被占用,请重新输入:\n");
			}
		}
		else
		{
			printf("坐标不合法,请重新输入:\n");
		}


	}
}
void ComputerMove(char board[ROW][COL], int row, int col) {
	while (1) {
		int x = rand() % row;  //生成合法的行坐标
		int y = rand() % col;  //生成合法的列坐标
		if (board[x][y]==' ') {
			board[x][y] = '#';
			break;
		}
	}
}

char IsWin(char board[ROW][COL], int row, int col) {
	int x = 0;                   //计数器判断一行或一列是否遍历结束
	int sum1 = 0;                //判断*的数量
	int sum2 = 0;                //判断#的数量

	for (int i = 0; i < col; i++) {
		for (int j = 0; j < row; j++) {               //判断每行上是否有连续三个相等的符号
			if (board[i][j] == '*') {
				sum1 += 1;
			}
			if (board[i][j] == '#') {
				sum2 +=1;
			}
			x++;
			if(x==row){                                 //一行统计完时
				if (sum1 == row) {                        //一行全是*
					return '*';
				}
				else if (sum2 == row) {
					return '#';                         //一行全是#
				}
				else {                                  //一行中未分胜负则计数器清零统计下一行
					sum1 = 0;                         
					sum2 = 0;
					x = 0;
				}
			}

		}
	}
	for (int j = 0; j < row; j++) {
		for (int i = 0; i < col; i++) {                //行未分出胜负,则开始统计列
			if (board[i][j] == '*') {
				sum1 += 1;
				
			}
			if (board[i][j] == '#') {
				sum2 += 1;
			
			}
			x++;
			if (x == row) {                             //一列统计完时
				if (sum1 == row) {                        //一列全是*
					return '*';
				}
				else if (sum2 == row) {
					return '#';                         //一列连全是#
				}
				else {                                  //一列中未分胜负则计数器清零统计下一列
					sum1 = 0;
					sum2 = 0;
					x = 0;
				}
			}
		}
	}
	for (int i = 0; i < col; i++) {
		for (int j = 0; j < row; j++) {                 //行列都为分出胜负统计主对角线元素
			if (i == j) {
				if (board[i][j] == '*') {
					sum1 += 1;
				}
				else if (board[i][j] == '#') {
					sum2 += 1;
				}
			}
		}
	}
	if (sum1 == row) {
		return '*';                                     //主对角线上元素都为*
	}
	else if (sum2 == row) {
		return '#';                                     //主对角线上元素都为#
	}
	else {
		sum1 = 0;
		sum2 = 0;                                       //计数器清零统计副对角线
	}
	//查看副对角线上的元素,可以先复制一个横向翻转的临时棋盘board1,查看主对角线上的元素
	char board1[ROW][COL];
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			board1[i][j] = board[i][col-j-1];
		}
	}
	//判断临时棋盘的主对角线元素
	for (int i = 0; i < col; i++) {
		for (int j = 0; j < row; j++) {                 
			if (i == j) {
				if (board1[i][j] == '*') {
					sum1 += 1;
				}
				else if (board1[i][j] == '#') {
					sum2 += 1;
				}
			}
		}
	}
	if (sum1 == row) {
		return '*';                                     //主对角线上元素都为*
	}
	else if (sum2 == row) {
		return '#';                                     //主对角线上元素都为#
	}
	else {
		sum1 = 0;
		sum2 = 0;                                       //计数器清零
	}
	//查看是否为平局,则是以上都判断完后,棋盘是否满了,满了则返回‘D’,不满则继续
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			if (board[i][j] == ' ') {
				return 'C';                     //有地方是空的,游戏还未出结果
			}
		}
	}
	return 'D';                                 //棋盘满了且没分出胜负,则为平局
}

运行结果(以3子为例):

以上为C语言简易实现n子棋的内容

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

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

相关文章

【NI-DAQmx入门】LabVIEW中DAQmx同步

1.同步解释 1.1 同步基础概念 触发器&#xff1a;触发器是控制采集的命令。您可以使用触发器来启动、停止或暂停采集。触发信号可以源自软件或硬件源。 时钟&#xff1a;时钟是用于对数据采集计时的周期性数字信号。根据具体情况&#xff0c;您可以使用时钟信号直接控制数据采…

ElasticSearch概述+SpringBoot 集成 ES

ES概述 开源的、高扩展的、分布式全文检索引擎【站内搜索】 解决问题 1.搜索词是一个整体时&#xff0c;不能拆分&#xff08;mysql整体连续&#xff09; 2.效率会低&#xff0c;不会用到索引&#xff08;mysql索引失效&#xff09; 解决方式 进行数据的存储&#xff08;只存储…

ssm基于Javaweb的物流信息管理系统的设计与实现论文

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统物流信息管理难度大&#xff0c;容错率低&#xff0c;管理…

基于OpenCV的谷物颗粒识别

基于OpenCV的谷物颗粒识别 一、程序整体功能介绍1.1 导入库与函数定义1.2 颜色分割与灰度处理1.3 二值化与轮廓检测1.4 绘制与计数1.5 主程序与结果展示 二、算法原理与实现流程2.1算法原理&#xff08;1&#xff09;颜色分割&#xff08;2&#xff09;灰度处理与二值化&#x…

mysql进阶 - 存储过程

目录 1. 用途&#xff1a; 2. 相关语法 2.1 创建 2.1.1 语法 2.1.2 示例 2.2 查看存储过程 2.3 调用 2.4 修改存储过程 2.5 删除存储过程 1. 用途&#xff1a; 存储过程广泛存在于一些遗留系统&#xff0c;可以减少代码的编写。而近些年&#xff0c;存储过程很少再用…

【期末不挂科-C++考前速过系列P4】大二C++实验作业-继承和派生(3道代码题)【解析,注释】

前言 大家好吖&#xff0c;欢迎来到 YY 滴C考前速过系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的《…

试用统信服务器操作系统UOS 20

作者&#xff1a;田逸&#xff08;formyz&#xff09; 试用统信Linux操作系统UOS&#xff0c;想了解一下用已有的Linux经验能否轻松驾驭它。以便在某些场景下&#xff0c;可以多一种选择。本次试验在Proxmox VE 8&#xff08;以下简称PVE 8&#xff09;平台下进行&#xff0c;采…

杨中科 .NETCORE ENTITY FRAMEWORK CORE-1 EFCORE 第一部分

一 、什么是EF Core 什么是ORM 1、说明: 本课程需要你有数据库、SOL等基础知识。 2、ORM: ObjectRelational Mapping。让开发者用对象操作的形式操作关系数据库 比如插入: User user new User(Name"admin"Password"123”; orm.Save(user);比如查询: Book b…

串行Nor Flash的结构和参数特性

文章目录 引言1、Nor Flash的结构2、Nor Flash的类别3.标准Serial Nor Flash的特征属性1.Wide Range VCC Flash2.Permanent Lock3.Default Lock Protection4.Standard Serial Interface5.Multi-I/O6.Multi-I/O Duplex (DTR)7.XIP&#xff08;片上执行&#xff09; 4.标准Serial…

【LabVIEW FPGA入门】LabVIEW FPGA 实现SPI通信协议

该实现由两个组件组成&#xff1a;在 LabVIEW FPGA 中实现的 SPI 协议以及用于从主机 PC 或实时控制器与 FPGA 进行通信的 LabVIEW 主机接口。该架构允许从单个主机程序控制多个 SPI 端口&#xff0c;同时仍然允许定制 FPGA VI 以进行其他数据采集和处理。该实现不使用任何DMA&…

运算电路(1)——加法器

一、引言 微处理器是由一片或少数几片大规模集成电路组成的中央处理器。这些电路执行控制部件和算术逻辑部件的功能。微处理器能完成取指令、执行指令&#xff0c;以及与外界存储器和逻辑部件交换信息等操作&#xff0c;是微型计算机的运算控制部分。它可与存储器和外围电路芯片…

FasterNet(CVPR 2023)论文解读

paper&#xff1a;Run, Dont Walk: Chasing Higher FLOPS for Faster Neural Networks official implementation&#xff1a;https://github.com/jierunchen/fasternet 存在的问题 为了设计轻量、速度快的网络&#xff0c;许多工作都专注于减少floating-point operations (F…

点餐新体验:老板自研扫码点餐小程序的成果

为了提高餐厅的效率和顾客的用餐体验&#xff0c;餐饮店老板们纷纷开始探索新的技术手段。其中&#xff0c;扫码点餐小程序就是一种非常受欢迎的解决方案。 扫码点餐小程序是一种基于微信小程序开发的餐饮点餐系统&#xff0c;它通过扫描桌码或菜品二维码&#xff0c;实现快速点…

图神经网络|图注意网络Graph Attention Network

图注意网络Graph Attention Network Leaky ReLU 有利于压低负数对结局的影响。 图注意网络Graph Attention Network的流程 输入向量 h i h_i hi​乘上权重矩阵W得到对应的向量 h i ∗ h_i^* hi∗​,并将 h i ∗ h_i^* hi∗​计算出对应的 a i a_i ai​,从而得到最终对结果向量…

2023年第十四届中国数据库技术大会(DTCC2023):核心内容与学习收获(附大会核心PPT下载)

随着信息化时代的深入发展&#xff0c;数据库技术作为支撑信息化应用的核心技术&#xff0c;其重要性日益凸显。本次大会以“数据价值&#xff0c;驱动未来”为主题&#xff0c;聚焦数据库领域的前沿技术与最新动态&#xff0c;吸引了数千名业界专家、企业代表和数据库技术爱好…

STL篇一:string

文章目录 前言1. STL的简单理解1.1 什么是STL1.2 STL的版本1.3 STL的六大组件1.4 STL的重要性1.5 STL的缺陷 2. string类2.1 为什么学习string类&#xff1f;2.1.1 C语言中的字符串2.1.2 两个面试题 2.2 标准库中的string类2.2.1 string类(了解)2.2.2 string类的常用接口说明 2…

Selenium 测试 Electron 应用

Electron 介绍 Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个 JavaScript代码代码库并创建 在Windows、macOS和Linux上运行的跨平台应用。 • 有哪些应用 有许多我们常见的桌面应用&am…

SpringBoot+SSM项目实战 苍穹外卖(09) day9作业

继续上一节的内容&#xff0c;本节是作业课&#xff0c;要求独立完成&#xff1a;用户端历史订单模块、商家端订单管理模块相关业务新功能开发和已有功能优化。 目录 作业要求用户端历史订单模块查询历史订单查询订单详情取消订单再来一单 商家端订单管理模块订单搜索各个状态的…

数据库练习题

素材&#xff1a; 表名&#xff1a;worker-- 表中字段均为中文&#xff0c;比如 部门号 工资 职工号 参加工作 等 CREATE TABLE worker ( 部门号 int(11) NOT NULL, 职工号 int(11) NOT NULL, 工作时间 date NOT NULL, 工资 float(8,2) NOT NULL, 政治面貌 varchar(10) NO…

Django教程|数据统计图表(echarts、highchart)

前言 highchart&#xff0c;国外。 echarts&#xff0c;国内。 本项目集成 hightchart和echarts图表库实现数据统计功能。 包括&#xff1a;折线图&#xff0c;柱状图&#xff0c;饼图和数据集图。 效果图 echats Highcharts 源代码 编写模板&#xff08;Template&#x…