C语言实现三子棋游戏

 

目录

一.三子棋游戏分析和设计

二.文件结构设计

 三.代码实现

1.先打印菜单,定义menu函数。

2.棋盘初始化

3.下棋

玩家下棋:

电脑下棋:

4判断输赢

判断平局:

四、完整代码

test.c

game.h

game.c


《三子棋》是一款古老的民间传统游戏,又被称为黑白棋、圈圈叉叉棋、井字棋、一条龙、九宫棋等。游戏分为双方对战,双方依次在9宫格棋盘上摆放棋子,率先将自己的三个棋子连成一条线的一方则视为胜利者。

那么应如何使用C语言实现呢?

一.三子棋游戏分析和设计

  • 使⽤控制台实现经典的三子棋游戏
  • 游戏可以通过菜单实现继续玩或者退出游戏
  • 三子棋的棋盘是3*3的格⼦

游戏界面:

菜单:

 

 

二.文件结构设计

设计成三个文件实现这个游戏。

test.c // ⽂件中写游戏的测试逻辑

game.c // ⽂件中写游戏中函数的实现等

game.h // ⽂件中写游戏需要的数据类型和函数声明等

 三.代码实现

1.先打印菜单,定义menu函数。

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

2.棋盘初始化

创建二维数组board存放棋盘信息,定义qipan函数,初始化二维数组,使3*3的每个位置全部置为空

void qipan(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] = ' ';
		}
	}
} 

打印棋盘,定义dayinqipan函数,使用 “-” 与“|”符号打印出棋盘

void dayinqipan(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)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}
	}
}

3.下棋

玩家下棋:

void wanjia(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("玩家:*  电脑:#\n");
	printf("玩家走\n");
	while (1)
	{
		printf("请输入要下的坐标:>");
		scanf("%d%d", &x,&y);
		//判断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 diannao(char board[ROW][COL], int row, int col)
{
	printf("电脑走:>\n");
	printf("...\n");
	int x = 0;
	int y = 0;
	while (1)
	{
	    x = rand() % row;
	    y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
	Sleep(1000);
}

4判断输赢

每次下完棋,有四种游戏的状态,玩家赢,电脑赢,平局,继续

设定:
玩家赢--'*'
电脑赢--'#'
平局--‘q’
继续--'c'

 定义panduan函数判断输赢,只需判断同一行/同一竖/两个对角线的字符是否一样,就能判断出输赢

int panduan(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];
		}
	}
	//竖三列
	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[2][0] == board[1][1] && board[1][1] == board[0][2] && board[2][0] != ' ')
			return board[1][1];
	//平局
	int ret = pingju(board, row, col);
	if (ret==1)
	{
		return'q';
	}
	return'c';
}

判断平局:

棋盘满了就代表了游戏平局

//返回1表示棋盘满了
//返回0表示棋盘没满
int pingju(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;
}

四、完整代码

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include"game.h"
void menu()
{
	printf("******************************\n");
	printf("****   1. play  0. exit  *****\n");
	printf("******************************\n");
}
void game()
{
	int ret = 0;
	//数组-存放走出的棋盘信息
	char board[ROW][COL] = { 0 }; 
		//初始化棋盘
	qipan(board, ROW, COL);
	//打印棋盘
	dayinqipan( board, ROW, COL);
	//下棋
	while (1)
	{
		//玩家下棋
		wanjia(board, ROW, COL);
		dayinqipan(board, ROW, COL);
		//判断玩家是否赢
		ret = panduan(board, ROW, COL);
		if (ret != 'c')
		{
			break;
		}
		//电脑下棋
		diannao(board, ROW, COL);
		dayinqipan(board, ROW, COL);
		//判断电脑是否赢
		ret = panduan(board, ROW, COL);
		if (ret != 'c')
		{
			break;
		}
	}
	system("cls");
	if (ret == '*')
	{
		printf("玩家赢\n");
	}
	else if (ret == '#')
	{
		printf("电脑赢\n");
	}
	else
	{
		printf("平局\n");
	}
	
}
void test()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择:》");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 2:
			printf("退出\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}
	} while (input);
}
int main()
{
	test();
	return 0;
}

game.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#define ROW 3
#define COL 3
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
//棋盘初始化
void qipan(char board[ROW][COL], int row, int col);

//打印棋盘
void dayinqipan(char board[ROW][COL],int row,int col);

//玩家下棋
void wanjia(char board[ROW][COL], int row, int col);

//电脑下棋
void diannao(char board[ROW][COL], int row, int col);

//四种游戏的状态
//玩家赢-'*'
//电脑赢-'#'
// 平局-‘q’
//继续--'c'
// 
//判断输赢
int panduan(char board[ROW][COL], int row, int col);

//判断平局
int pingju(char board[ROW][COL], int row, int col);

game.c

#include"game.h"
void qipan(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 dayinqipan(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)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}
	}
}

void wanjia(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("玩家:*  电脑:#\n");
	printf("玩家走\n");
	while (1)
	{
		printf("请输入要下的坐标:>");
		scanf("%d%d", &x,&y);
		//判断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 diannao(char board[ROW][COL], int row, int col)
{
	printf("电脑走:>\n");
	printf("...\n");
	int x = 0;
	int y = 0;
	while (1)
	{
	    x = rand() % row;
	    y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
	Sleep(1000);
}

//返回1表示棋盘满了
//返回0表示棋盘没满
int pingju(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;
}

int panduan(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];
		}
	}
	//竖三列
	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[2][0] == board[1][1] && board[1][1] == board[0][2] && board[2][0] != ' ')
			return board[1][1];
	//平局
	int ret = pingju(board, row, col);
	if (ret==1)
	{
		return'q';
	}
	return'c';
}

感谢

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【找出满足差值条件的下标 I】python

目录 暴力题解 优化&#xff1a;滑动窗口维护大小值 暴力题解 class Solution:def findIndices(self, nums: List[int], indexDifference: int, valueDifference: int) -> List[int]:nlen(nums)for i in range(n):for j in range(n-1,-1,-1):if abs(i-j)>indexDiffere…

python使用base加密解密

原理 base编码是一种加密解密措施&#xff0c;目前常用的有base16、base32和base64。其大致原理比较简单。 以base64为例&#xff0c;base64加密后共有64中字符。其加密过程是编码后将每3个字节作为一组&#xff0c;这样每组就有3*824位。将每6位作为一个单位进行编码&#xf…

Windows平台C#版RTSP转RTMP直播推送定制版

技术背景 前几年我们发布了C版的多路RTMP/RTSP转RTMP转发官方定制版。在秉承低延迟、灵活稳定、低资源占用的前提下&#xff0c;客户无需关注开发细节&#xff0c;只需图形化配置转发等各类参数&#xff0c;实现产品快速上线目的。 如监控类摄像机、NVR等&#xff0c;通过厂商…

经典链表题-链表回文结构

&#x1f389;&#x1f389;&#x1f389;欢迎莅临我的博客空间&#xff0c;我是池央&#xff0c;一个对C和数据结构怀有无限热忱的探索者。&#x1f64c; &#x1f338;&#x1f338;&#x1f338;这里是我分享C/C编程、数据结构应用的乐园✨ &#x1f388;&#x1f388;&…

C#基础语言

​​​​ 目录 一个c# 程序主要包括以下部分&#xff1a;​​​​​​​ 标识符 C# 关键字 C# 数据类型 值类型&#xff08;Value types&#xff09; 引用类型&#xff08;Reference types&#xff09; 对象&#xff08;Object&#xff09;类型 动态&#xff08;Dynam…

迅睿 CMS 中开启【ionCube 扩展】的方法

有时候我们想要某种功能时会到迅睿 CMS 插件市场中找现有的插件&#xff0c;但会有些担心插件是否适合自己的需求。于是迅睿 CMS 考虑到这一层推出了【申请试用】&#xff0c;可以让用户申请试用 30 天&#xff0c;不过试用是有条件的&#xff0c;条件如下&#xff1a; php 版…

03. Spring 事务管理

文章目录 1. Spring 事务管理简介2. Transactional 注解属性信息3. Transactional 简单使用4. Transactional 使用注意事项4.1 正确指定事务回滚的异常类型4.1.1 Java 异常继承体系 4.2 Transactional 注解应用在 public 方法或类上才有效4.3 正确设置 Transactional 的 propag…

解决vue3项目vite打包忽略.vue扩展名

项目打包时报could not relolve “...”&#xff0c;因为vite已不再默认忽略.vue扩展名。 解决方法如下&#xff1a; 在vite.config.js中配置vite使其忽略 .vue 扩展名&#xff08;不建议忽略&#xff09; 注意&#xff1a;即使忽略了.vue文件&#xff0c;在实际写的时候也要加…

【CTF Web】CTFShow web7 Writeup(SQL注入+PHP+进制转换)

web7 1 阿呆得到最高指示&#xff0c;如果还出问题&#xff0c;就卷铺盖滚蛋&#xff0c;阿呆心在流血。 解法 注意到&#xff1a; <!-- flag in id 1000 -->拦截很多种字符&#xff0c;连 select 也不给用了。 if(preg_match("/\|\"|or|\||\-|\\\|\/|\\*|\…

Spring MVC+mybatis 项目入门:旅游网(一)项目创建与准备

个人博客&#xff1a;Spring MVCmybatis 项目入门:旅游网&#xff08;一&#xff09;项目创建与准备 | iwtss blog 先看这个&#xff01; 这是18年的文章&#xff0c;回收站里恢复的&#xff0c;现阶段看基本是没有参考意义的&#xff0c;技术老旧脱离时代&#xff08;2024年辣…

使用不同的编译器编译 Skia,性能差距居然这么大

Skia 是一个开源的 2D 图形库&#xff0c;提供路径、文本、图像和渲染等图形处理功能。它最初由 Skia Inc. 开发&#xff0c;后来被 Google 收购&#xff0c;并用在多个 Google 的产品中&#xff0c;包括 Chrome 浏览器和 Android 操作系统中。从事 Android 系统开发的同学应该…

Science 基于尖峰时序编码的模拟神经触觉系统,可实现动态对象分类

快速处理和有效利用手与物体交互过程中产生的动态触觉信号&#xff08;例如触摸和抓握&#xff09;对于触觉探索和灵巧的物体操作至关重要。将电子皮肤&#xff08;e-skins&#xff09;推进到模仿自然触觉的水平&#xff0c;是恢复截肢者和瘫痪患者丧失的功能的可行解决方案&am…

北核论文完美复现:自适应t分布与动态边界策略改进的算术优化算法

声明&#xff1a;文章是从本人公众号中复制而来&#xff0c;因此&#xff0c;想最新最快了解各类智能优化算法及其改进的朋友&#xff0c;可关注我的公众号&#xff1a;强盛机器学习&#xff0c;不定期会有很多免费代码分享~ 目录 原始算术优化算法 改进点1&#xff1a;引入…

深入探索MySQL SELECT查询:从基础到高级,解锁数据宝藏的密钥

系列文章目录 更新ing... MySQL操作全攻略&#xff1a;库、表、数据、事务全面指南深入探索MySQL SELECT查询&#xff1a;从基础到高级&#xff0c;解锁数据宝藏的密钥MySQL SELECT查询实战&#xff1a;练习题精选&#xff0c;提升你的数据库查询技能PyMySQL&#xff1a;连接P…

【电路笔记】-巴特沃斯滤波器设计

巴特沃斯滤波器设计 文章目录 巴特沃斯滤波器设计1、概述2、Decades和Octaves3、低通巴特沃斯滤波器设计4、滤波器设计 – 巴特沃斯低通5、三阶巴特沃斯低通滤波器在之前的滤波器教程中,我们研究了简单的一阶型低通和高通滤波器,这些滤波器的 RC 滤波器电路设计中仅包含一个电…

Ant design vue的表格双击编辑功能(即双击开始编辑并自动获得焦点,失去焦点时完成编辑)

本文基于Ant Design Vue官方网站的表格&#xff08;可编辑单元格&#xff09;&#xff08;表格 Table - Ant Design Vue (antdv.com))中的样板代码获得双击编辑且获得焦点、失去焦点时完成编辑的功能。 要点&#xff1a; &#xff08;1&#xff09;双击时候实现编辑&#xff…

spark实战:实现分区内求最大值,分区间求和以及获取日志文件固定日期的请求路径

spark实战&#xff1a;实现分区内求最大值&#xff0c;分区间求和以及获取日志文件固定日期的请求路径 Apache Spark是一个广泛使用的开源大数据处理框架&#xff0c;以其快速、易用和灵活的特点而受到开发者的青睐。在本文中&#xff0c;我们将通过两个具体的编程任务来展示S…

在CentOS7上安装Oracle11

一、概述 Oracle有两种安装方式&#xff0c;桌面安装和静默安装。这里我采用桌面安装的方式。 不得不说&#xff0c;Oracle真的是我目前为止安装过的最麻烦的软件没有之一&#xff0c;比K8S还麻烦&#xff0c;Oracle&#xff0c;真有你的&#xff01;废话不多说&#xff0c;臭…

重学java 45.多线程 下 总结 定时器_Timer

人开始反向思考 —— 24.5.26 定时器_Timer 1.概述:定时器 2.构造: Timer() 3.方法: void schedule(TimerTask task, Date firstTime, long period) task:抽象类,是Runnable的实现类 firstTime:从什么时间开始执行 period:每隔多长时间执行一次…

Java | Leetcode Java题解之第100题相同的树

题目&#xff1a; 题解&#xff1a; class Solution {public boolean isSameTree(TreeNode p, TreeNode q) {if (p null && q null) {return true;} else if (p null || q null) {return false;}Queue<TreeNode> queue1 new LinkedList<TreeNode>();…