C语言实现三子棋游戏

news2024/11/16 23:38:00

test.c源文件 - 三子棋游戏测试

game.h头文件 - 三子棋游戏函数的声明

game.c源文件 - 三子棋游戏函数的实现

主函数源文件: 

#define _CRT_SECURE_NO_WARNINGS 1

#include"game.h"  //自己定义的用""
void menu()
{
	printf("****************************************\n");
	printf("*******        三子棋          *********\n");
	printf("*******   author:小凡同学     *********\n");
	printf("*******        1.play          *********\n");
	printf("*******        0.exit          *********\n");
	printf("****************************************\n");
}
void game()
{
	//存储数据 - 二位数组
	char board[ROW][COL];
	//初始化棋盘 - 初始化空格
	InitBoard(board, ROW, COL);
	//打印一下棋盘 - 本质上是打印数组内容
	DisplayBoard(board, ROW, COL);
	char ret = 0;//接受游戏状态
	while (1)
	{
		//玩家下棋
		PlayerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//判断玩家是否赢得游戏
		ret=IsWin(board, ROW, COL);
		if (ret != 'C')
			break;
		//电脑下棋
		ComputerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//判断电脑是否赢得游戏
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
			break;
	}
	if (ret == '*')
	{
		printf("玩家赢了\n");

	}
	else if (ret == '#')
	{
		printf("电脑赢了\n");
	}
	else
	{
		printf("平局\n");
	}
	
}
int main()
{
	int input=0;
	srand((unsigned int)time(NULL));
	do 
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			/*printf("三子棋游戏\n");*/
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,重新选择\n");
			break;
		}
	} while (input);  //当input=0是while条件判断为假,跳出循环,非零即为真,do while循环继续
	return 0;
}

头文件封装:

#pragma once

//头文件的包含

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
//符号定义
#define ROW 10
#define COL 10

//函数声明

//初始化棋盘
void InitBoard(char board[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);

//判断输赢
/*
游戏状态:
1.玩家赢了 - *
2.电脑赢了 - #
3.平局  - Q -棋盘下满了
 返回 * # Q 游戏结束
4.游戏继续 - C

IsWin() 用来判断游戏的状态
*/
//判断游戏是否有输赢
char IsWin(char board[ROW][COL], int row, int col);

//判断平局

游戏函数实现源文件: 

#define _CRT_SECURE_NO_WARNINGS 1
#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++)
//	{
//		printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
//		if(i<row-1)
//			printf("---|---|---\n");
//	}
//}

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, y;
	printf("玩家走:>\n");
	while (1) 
	{
		printf("请输入下棋的坐标:>");
		scanf("%d %d", &x, &y);
		//判断坐标合法性
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			//下棋
			//坐标是否被占用
			if (board[x - 1][y - 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");
	while (1) 
	{
		int x = rand() % row;
		int y = rand() % col;
		//判断占用
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

int 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;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			//判断三行
			if (board[i][j] == board[i][j+1] && board[i][j+1] == board[i][j+2] && board[i][j+1] != ' ')
			{
				return board[i][j+1];
			}
			//判断三列
			if (board[i][j] == board[i+1][j] && board[i+1][j] == board[i+2][j] && board[i+1][j] != ' ')
			{
				return board[i + 1][j];
			}
			//主对角线
			if (board[i][j] == board[i+1][j+1] && board[i + 1][j + 1] == board[i + 2][j + 2] && board[i+1][j+1] != ' ')
			{
				return board[i+1][j+1];
			}
			//副对角线
			if (board[i][j] == board[i+1][j-1] && board[i+1][j-1] == board[i+2][j-2] && board[i+1][j-1] != ' ')
			{
				return board[i + 1][j - 1];
			}
		}
	}
	判断三行
	//	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];
	//		}
	//	}
	判断三列
	//	for (i = 0; i < col; i++)
	//	{
	//		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
	//		{
	//			return board[1][i];
	//		}
	//	}
	判断对角线
	//	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];
	//	}

	//判断平局
		//如果棋盘满了返回1,不满返回0
		int ret=IsFull(board, row, col);
		if (ret == 1)
		{
			return 'Q';//平局
		}
		//继续
		return 'C';
			
}

运行结果:

 

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

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

相关文章

代码随想录算法训练营day43

文章目录 Day43 最后一块石头的重量II题目思路代码 目标和题目思路代码 一和零题目思路代码 Day43 最后一块石头的重量II 1049. 最后一块石头的重量 II - 力扣&#xff08;LeetCode&#xff09; 题目 有一堆石头&#xff0c;每块石头的重量都是正整数。 每一回合&#xff0…

2023-07-30 LeetCode每日一题(环形链表 II)

2023-07-30每日一题 一、题目编号 142. 环形链表 II二、题目链接 点击跳转到题目位置 三、题目描述 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 n…

【探索C++中的顺序表】手动实现vector容器

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a;初阶数据结构 &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0c;是对…

Fourier变换及其应用(Brad G. Osgood)——第2章——Fourier变换

第2章 Fourier变换 2.1 初识Fourier变换(A First Look at the Fourier Transform) 我们即将从Fourier级数过渡到Fourier变换。“过渡(transition)”是合适的词&#xff0c;因为我们选择了Fourier变换从周期函数到非周期函数的引出路径。 为了完成这一旅程&#xff0c;我们将把…

【优选算法题练习】day10

文章目录 一、137. 只出现一次的数字 II1.题目简介2.解题思路3.代码4.运行结果 二、剑指 Offer 53 - II. 0&#xff5e;n-1中缺失的数字1.题目简介2.解题思路3.代码4.运行结果 三、153. 寻找旋转排序数组中的最小值1.题目简介2.解题思路3.代码4.运行结果 总结 一、137. 只出现一…

登录报错 “msg“:“Request method ‘GET‘ not supported“,“code“:500

1. 登录失败 2. 排查原因, 把 PostMapping请求注释掉, 或改成GetMapping请求就不会报错 3. 找到SecurityConfig.java , 新增 .antMatchers("/**/**").permitAll() //匹配允许所有路径 4. 登录成功

【算法基础:动态规划】5.4 状态压缩DP

文章目录 例题列表291. 蒙德里安的梦想⭐⭐⭐⭐⭐91. 最短Hamilton路径⭐⭐⭐ 相关链接 例题列表 291. 蒙德里安的梦想⭐⭐⭐⭐⭐ https://www.acwing.com/problem/content/293/ 当横向方格摆放完成后&#xff0c;纵向方格的拜访方式就已经确定了。&#xff08;因为我们只要求…

井字棋(TicTacToe)

目录 三种游戏 习题 1. 传统设置 2. 中间的网格 三种游戏 “选15”、“井字棋”、“魔幻15”游戏本质上是同一个游戏。 function tictactoe(job) % TICTACTOE Pick15, TicTacToe, and Magic3. % % Pick15. Pick single digit numbers. Each digit can be chosen % on…

蓝海卓越计费管理系统远程命令执行

活着&#xff0c;就要时刻准备承受磨难&#xff01; 漏洞描述 蓝海卓越计费管理系统存在命令调试页面&#xff0c;导致攻击者可以远程命令执行 漏洞复现 访问 debug.php页面 远程调试命令执行 /debug.php漏洞证明 文笔生疏&#xff0c;措辞浅薄&#xff0c;望各位大佬不吝…

GIS基础制图之地形图

数据:地理空间数据云(http://www.gscloud.cn/)下一张北京地区DEM(30m),统一用这一张来做。 晶格 工具运行窗口不贴了,因为参数设置基本上都是默认没有什么要改的 1、「3D Analyst」—「转换」—「由栅格转出」—「栅格转TIN」 2、「3D Analyst」—「转换」—「由TIN转出」—…

【Rust教程 | 基础系列 | Cargo工具】Cargo介绍及使用

文章目录 前言一&#xff0c;Cargo介绍1&#xff0c;Cargo安装2&#xff0c;创建Rust项目2&#xff0c;编译项目&#xff1a;3&#xff0c;运行项目&#xff1a;4&#xff0c;测试项目&#xff1a;5&#xff0c;更新项目的依赖&#xff1a;6&#xff0c;生成项目的文档&#xf…

MP的开发流程

MP的开发流程 1、添加依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.ap…

微服务04 分布式搜索引擎 elasticsearch DSL数据聚合 自动补全 数据同步 集群 微服务保护 Sentinel

微服务03 分布式搜索引擎 elasticsearch ELK kibana RestAPI 索引库 DSL查询 RestClient 黑马旅游 分布式搜索引擎03 1.数据聚合 聚合&#xff08;aggregations&#xff09;可以让我们极其方便的实现对数据的统计、分析、运算。例如&#xff1a; 什么品牌的手机最受欢迎&…

无涯教程-jQuery - Transfer方法函数

Transfer 效果可以与effect()方法一起使用。这会将元素的轮廓转移到另一个元素。尝试可视化两个元素之间的交互时非常有用。 Transfer - 语法 selector.effect( "transfer", {arguments}, speed ); 这是所有参数的描述- className - 传输元素将收到的可选类名。…

Doris安装部署入门

文章目录 一 Doris 介绍1.1 使用场景1.1.2 Doris架构 二 Doris单机部署2.1 下载 Doris2.2 配置 Doris2.2.1 配置 FE2.2.2 启动 FE2.2.3 查看 FE 运行状态2.2.4 连接 FE2.2.5 停止 FE 节点2.2.6 配置 BE2.2.7 启动 BE2.2.8 添加 BE 节点到集群2.2.9 查看 BE 运行状态2.2.10 停止…

基于springboot+mybatis+thymeleaf+html产品销售与分析系统

基于springbootmybatisthymeleafhtml产品销售与分析系统 一、系统介绍二、功能展示1.下单(批发商)2.订单管理&#xff08;批发商&#xff09;3.首页(厂家管理员)4.订单管理&#xff08;厂家管理员&#xff09;5.商品管理&#xff08;厂家管理员&#xff09;6.统计分析&#xff…

SpringBoot集成RocketMQ

SpringBoot整合RocketMQ使用非常简单&#xff0c;下面是一个简单的例子&#xff0c;作为备忘&#xff1a; 完整项目代码&#xff1a; https://github.com/dccmmtop/springBootRocketMQ 项目目录结构 依赖 <dependencies><dependency><groupId>org.apache.…

Linux下进程特性总结:工作目录,环境变量,标准输出转命令行参数,O_CLOEXEC标志作用,读写锁控制进程互斥

进程是运行中的程序&#xff0c;是资源分配的最小单位&#xff0c;其有一些特性对于实际开发很有帮助&#xff0c;本篇博客将进程的相关特性进行梳理总结&#xff0c;包含工作目录&#xff0c;环境变量&#xff0c;标准输出转命令行参数&#xff0c;读写锁控制进程互斥。 目录…

vo 2 输出helloworld

vo 2 输出helloworld 目录概述需求&#xff1a; 设计思路实现思路分析1.code 拓展实现性能参数测试&#xff1a; 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better r…

HCIP重发布实验

目录 实验要求&#xff1a; 步骤一&#xff1a;拓扑设计IP地址规划 拓扑设计 R1 R2 R3 R4 发布路由 R1 R2 R3 R4 双向重发布 在R2和R4 上进行 R2 R4 检查R1 修改开销值选路 择优选择去4.0网段的路径 测试&#xff1a;​编辑 择优选择去32网段的路径 测试&…