三子棋小游戏

news2024/9/24 21:40:41

使用C语言编写代码,实现一个简单小游戏---三子棋

这里创建1个game.h文件,用来声明函数、宏的文件,一个game.c文件用来实现函数game(),一个play.h文件用来作为该游戏的源文件。

具体代码如下:

1.game.h文件

#pragma once

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

#define ROW 3
#define COL 3  //这是一个宏定义。宏定义用于在程序中指定一个常量或表达式的标识符,
/*并且在编译时将其替换为指定的值。在这个例子中,它定义了一个常量ROW和COL。
在程序中,可以使用ROW来代替数字3,使得程序更易于理解和维护*/

//初始化棋盘
void InitBoard(char borad[ROW][COL], int row, int col);

//打印棋盘
void DisplayBoard(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);

//判断输赢:
//玩家赢---*
//电脑赢---#
//平局---Q
//继续---C

char IsWin(char board[ROW][COL], int row, int col);

2.game.c文件

#include"game.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;
	for (i = 0;i < row;i++)
	{
		int j = 0;
		for (j = 0;j < col;j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
			{
				printf("|");
			}
		}
		printf("\n");
		if (i < row - 1)
		{
			int j = 0;
			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;
	printf("玩家请下棋->\n");

	while (1)
	{
		printf("请输入坐标->:");
		scanf_s("%d %d", &x, &y);
		//坐标范围合法的判断
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (board[x - 1][y - 1] == ' ')//x,y减1,是因为这里代表行和列,例如有3行,那么x的取值范围为1-3,但是数组下标为0-2,所以要减去1
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("坐标被占用,不能下棋,请选择其他位置\n");
			}
		}
		else
		{
			printf("坐标非法,请重新输入\n");
		}
	}
}

void ComputerMove(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋->\n");

	int x = 0;
	int y = 0;

	while (1)
	{
		x = rand() % row;//注意这里x的是取余数,所以范围是0到row-1,与上面的取值范围不同
		y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	
	}
}

//判断棋盘是否满了
//满了---返回1
//不满---返回0
IsFull(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++)
		{
			if (board[i][j] == ' ')
			{
				return 0;
			}
		}
	}
	return 1;
}

char IsWin(char board[ROW][COL], int row, int col)
{
	//行
	int i = 0;
	for (i = 0;i < row;i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')
		{
			return board[i][1];
		}
	}
	//列
	int j = 0;
	for (j = 0;j < row;j++)
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ')
		{
			return board[1][j];
		}
	}
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
		return board[1][1];
	}

	//没有人赢,平局,返回Q
	if (IsFull(board, row, col))
	{
		return 'Q';
	}

	//继续
	return 'C';
}

下面是部分函数解释:

game.h文件中包括了初始化棋盘、打印棋盘、玩家下棋、电脑下棋、判断棋盘是否满了、判断输赢等函数的实现。

1. InitBoard()函数用于初始化棋盘。遍历二维数组board,将每个元素初始化为空格。

2. DisplayBoard()函数用于打印棋盘。通过循环遍历二维数组board,在每个位置输出当前棋盘上的棋子,并在棋子之间输出分隔线。

3. PlayerMove()函数用于玩家下棋。通过提示玩家输入坐标,然后判断坐标的合法性。合法的坐标范围为1到行数和列数,若坐标合法并且对应位置为空,则将该位置标记为玩家的棋子。

4. ComputerMove()函数用于电脑下棋。通过随机生成坐标,然后判断坐标对应位置是否为空,若为空,则将该位置标记为电脑的棋子。

5. IsFull()函数用于判断棋盘是否满了。遍历棋盘上的每个位置,若存在空格,则返回0表示棋盘未满,否则返回1表示棋盘已满。

6. IsWin()函数用于判断是否有人获胜。首先检查每行是否有连续相同的棋子,然后检查每列是否有连续相同的棋子,最后检查对角线是否有连续相同的棋子。若存在连续相同的棋子,则返回对应的棋子标记。若棋盘已满但没有人获胜,则返回Q表示平局。若棋盘未满且没有人获胜,则返回C表示继续。

 3.play.c文件

#include"game.h"
#include<stdio.h>

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

void game()
{
	char ret = 0;
	char board[ROW][COL] = { 0 };
	InitBoard(board, ROW,COL);//初始化棋盘
	DisplayBoard(board, ROW, COL);//打印棋盘
	while (1)
	{
		PlayerMove(board, ROW, COL);
		//判断输赢
		ret=IsWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		DisplayBoard(board, ROW, COL);
		ComputerMove(board, ROW, COL);
		//判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		DisplayBoard(board, ROW, COL);
	}
	if (ret == '*')
	{
		printf("玩家赢\n");
	}
	else if (ret == '#')
	{
		printf("电脑赢\n");
	}
	else
	{
		printf("平局\n");
	}

	DisplayBoard(board, ROW, COL);
}

int main()
{
	srand((unsigned int)time(NULL));
	//设置随机数的生成起点

	int input = 0;

	do
	{
		menu();
		printf("是否开始游戏->:");
		scanf_s("%d", &input);
		
		switch(input)
		{
		case 1:
			game();
			break;
			
		case 0:
			printf("退出游戏\n");
			break;

		default:
			printf("输入错误,请重新输入->:\n");
			break;
		}
	} while (input);

	return 0;
}

运行结果如下: 

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

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

相关文章

利用大型语言模型轻松打造浪漫时刻

当情人节年年如约而至&#xff0c;每每都需费尽心思为对方营造一场令人难忘的仪式&#xff0c;却因缺乏创意与思路而倍感困扰。今天&#xff0c;我决定让大型语言模型为我们提供一些灵感和建议&#xff0c;让我们能够轻松实现这一目标。让我们开始行动吧&#xff01;此前&#…

问卷是否要做信效度分析,5类信度与4类效度常用指标及评价标准

论文问卷进行分析时&#xff0c;大家是否有这样的疑惑—— 我收集的问卷是否需要进行信效度分析呢&#xff1f; 下面一文给大家梳理问卷信效度分析的相关内容&#xff0c;包括什么样的题目需要进行信效度分析、5类信度分析与4类效度分析常用指标及评价标准。 一、问卷是否需…

JW01二氧化碳传感器(串行通信 STM32)

目录 一、介绍 二、传感器原理 1.工作原理介绍 2.串口数据流格式 三、程序设计 main.c文件 usart3.h文件 usart3.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 JW01-CO2检测模块是一种用于检测空气中二氧化碳浓度的传感器模块。它可以广泛应用于室内空气质量…

java算法OJ(1)位运算

目录 1.前言 2.正文 2.1位运算符号 2.1俩数相除 2.1.1题目 2.1.2示例 2.1.3题解 2.2二进制求和 2.2.1题目 2.2.2示例 2.2.3题解 2.3只出现一次的数字 2.3.1题目 2.3.2示例 2.3.3题解 2.4只出现一次的数字&#xff08;进阶版&#xff09; 2.4.1题目 2.4.2示例…

glb数据格式

glb数据格式 glb 文件格式只包含一个glb 文件&#xff0c;文件按照二进制存储&#xff0c;占空间小 浏览 浏览glb工具的很多&#xff0c;ccs&#xff0c;3D查看器等都可以&#xff0c;不安装软件的话用下面网页加载就可以&#xff0c;免费 glTF Viewer (donmccurdy.com) glb…

uniapp小程序中通过uni.setClipboardData实现复制功能无效的原因和解决方案

// 复制下载链接const shareFile (filePath) > {const pdfUrl 复制内容uni.showModal({title: 下载提示,content: 请复制链接到浏览器中下载,confirmColor: #eb2444,confirmText: 复制链接,success(res) {if (res.confirm) {uni.setClipboardData({data: pdfUrl, // url地…

C++: unordered系列关联式容器

目录 1. unordered系列关联式容器1.1 unordered_map1.2 unordered_set 2. 哈希概念3. 哈希冲突4. 闭散列5. 开散列 博客主页: 酷酷学 感谢关注!!! 正文开始 1. unordered系列关联式容器 在C98中&#xff0c;STL提供了底层为红黑树结构的一系列关联式容器&#xff0c;在查询时…

【笔记】自动驾驶预测与决策规划_Part4_时空联合规划

文章目录 0. 前言1. 时空联合规划的基本概念1.1 时空分离方法1.2 时空联合方法 2.基于搜索的时空联合规划 &#xff08;Hybrid A* &#xff09;2.1 基于Hybrid A* 的时空联合规划建模2.2 构建三维时空联合地图2.3 基于Hybrid A*的时空节点扩展2.4 Hybrid A* &#xff1a;时空节…

多线程——“死锁”

目录 前言 一、一个线程&#xff0c;一把锁 1.问题介绍 2.可重入锁 二、两个线程&#xff0c;两把锁 1.问题介绍 2.解决方式 三、N个线程&#xff0c;M把锁 1.哲学家就餐问题 2.解决方式 结尾 前言 “死锁”是多线程代码中一类常见的问题&#xff0c;加锁是能解决线…

plt的简单使用

目录 介绍示例 介绍 plt 是 Python 中 Matplotlib 库的一个常用别名&#xff0c;它表示 pyplot&#xff0c;这是一个用于创建图形和图形的可视化表示的工具。下面是一些 plt 函数的详解和示例&#xff0c;以帮助大家理解和使用。 示例 示例1&#xff1a; import matplotlib…

AV1 Bitstream Decoding Process Specification--[9]:语法结构语义-5

原文地址&#xff1a;https://aomediacodec.github.io/av1-spec/av1-spec.pdf 没有梯子的下载地址&#xff1a;AV1 Bitstream & Decoding Process Specification摘要&#xff1a;这份文档定义了开放媒体联盟&#xff08;Alliance for Open Media&#xff09;AV1视频编解码…

loadrunner个人笔记

创建场景配置&#xff1a; 两个同时 去四&#xff1a;日志、时间、模拟、其他自动事务 加一&#xff1a;首选项 1、写脚本&#xff0c;沟通官方、文件打印扫描 MFI-sw.support.gsd.imsc.sda.globalopentext.com support.casemicrofocus.com 支持资源 | Micro Focus | OpenT…

【毕业论文+源码】基于ASP的课程指导平台的开发

引 言 随着全球信息化技术的兴起&#xff0c;特别是Internet的日益普及&#xff0c;解决了信息Internet上传递的问题&#xff0c;建立了一个组织得很好的信息结构框架&#xff0c;使得Internet用户能够在Internet上的任何一个终端&#xff0c;以一种简单、统一的方式来访问超…

Leetcode Hot 100刷题记录 -Day18(反转链表)

反转链表&#xff1a; 问题描述&#xff1a; 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&a…

视频监控相关笔记

一、QT 之 QTreeWidget 树形控件 Qt编程指南&#xff0c;Qt新手教程&#xff0c;Qt Programming Guide 一个树形结构的节点中的图表文本 、附带数据的添加&#xff1a; QTreeWidgetItem* TourTreeWnd::InsertNode(NetNodeInfo node, QTreeWidgetItem* parent_item) { // …

回文子串通用做法

647. 回文子串 先引出力扣链接 给定一个字符串&#xff0c;你的任务是计算这个字符串中有多少个回文子串。 具有不同开始位置或结束位置的子串&#xff0c;即使是由相同的字符组成&#xff0c;也会被视作不同的子串。示例 1&#xff1a; 输入&#xff1a;"abc" 输出…

for循环的应用

正三角 for (int i 0; i < 8; i) { for (int j 0; j < 15; j) { int kong 8 - i - 1; int star 2 * i 1; if (j < kong) { Console.Write(" "); } else if (j < kong star)…

【LLM学习之路】9月23日24日 第十、十一天 Attention代码解读

【LLM学习之路】9月23日24日 第十、十一天 Attention代码解读 Transformer模型大致分为三类 纯 Encoder 模型&#xff08;例如 BERT&#xff09;&#xff0c;又称自编码 (auto-encoding) Transformer 模型&#xff1b;纯 Decoder 模型&#xff08;例如 GPT&#xff09;&#…

多颜色绘制语义分割/变化检测结果图

在论文绘图时&#xff0c;传统的二元语义分割结果图颜色单一&#xff08;下图左&#xff09;&#xff0c;所以论文中常根据混淆矩阵类别使用多颜色进行绘制&#xff08;下图右&#xff09;&#xff0c;可以看到&#xff0c;结果的可视化效果更好。 以下是绘制代码&#xff1a; …

同等学力申硕英语网课如何选择

很多考生想知道同等学力申硕英语网课如何选择&#xff0c;小编告诉大家&#xff0c;首先明确自己的学习目标和需求是为了提高口语、阅读、写作还是听力能力? 只有明确了自己的学习目标和需求&#xff0c;才能更好地选择适合自己的课程和平台。 二、选择知名品牌和口碑良好的平…