三子棋小游戏(简单详细)

news2024/12/23 20:09:21

设计总体思路

实现游戏可以一直玩,先打印棋盘,玩家和电脑下棋,最后分出胜负。

如果编写较大的程序,我们可以分不同模块

例如这个三子棋,我们可以创建三个文件

分别为:

  1. game.h     函数的声明
  2. game.c     函数的实现
  3. test.c        测试游戏逻辑

一、打印游戏菜单界面

首先要有开始界面并且有选项选择,开始你的游戏,代码以及效果图如下:

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

int main()
{
	srand((unsigned int)time(NULL));   //随机数  无符号整型  时间戳   
                                       //头文件:stdlib.h  time.h
	int input = 0;
	do 
	{
		menu();                        //先打印菜单
		printf("请选择>:");            //选项选择
		scanf("%d", &input);
		switch(input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,重新选择\n");
			break;
		}
	} while (input);
	return 0;
}

二、打印棋盘

创建并初始化数组,再打印棋盘,代码以及效果图如下:

game.h

#pragma once

//头文件的包含
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>      //我们可以将头文件都包含在game.h,
                      //其余使用只需包含一下game.h即可,无需重复写头文件
                    

#define ROW 3         //定义一下行和列,未来所有使用行和列直接使用ROW和COL,
#define COL 3         //如果要更改行和列即可全篇修改

                      
//函数的声明
// 
//初始化棋盘
void InitBoard(char board[ROW][COL],int row,int col);

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

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

void InitBoard(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++)
		{
			board[i][j] = ' ';
		}
	}
	//初始化   地址   初始化的内容  字节大小   头文件:string.h
	//memset(&board[0][0],' ',row*col*sizeof(board[0][0]));  //这个也是初始化棋盘
}

void DisplayBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 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");
	}
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

void game()
{
	//存放数据需要一个3*3的二维数组
	char board[ROW ][COL] = {0};
	//初始化棋盘
	InitBoard(board, ROW, COL);
	//显示棋盘
	DisplayBoard(board, ROW, COL);
}

三、玩家下棋

 '*' 代表玩家下的棋子

代码思路,第一步创建玩家下棋的函数PlayerMove()并输入坐标,代码图如下:

game.c

void PlayerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;

	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] == ' ')    //因为数组下标是从0开始
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("坐标被占用,重新输入\n");
			}
		}
		else
		{
			printf("坐标非法,请重新输入\n");
		}
	}
}

四、电脑下棋

 '#' 代表电脑下的棋子

代码思路,第一步创建电脑下棋的函数ComputerMove()并输入坐标,代码图如下:

game.c

//电脑随机下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
	while (1)
	{
		int x = 0;
		int y = 0;
		printf("电脑下棋>:\n");

		x = rand() % row;
		y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

五、判断输赢

创建判断输赢的IsWin()函数,while()循环实现玩家和电脑可以轮流下直到一方胜利,

如果有三个 '*' 符号连成一条线,代表玩家获胜,

如果有三个 '#' 符号连成一条线,代表电脑获胜,

如果九个格子填满,但无三个相同符号连成一条线,则平局。

IsWin()函数中:

  1. 玩家赢返回'*'
  2. 电脑赢返回'#'
  3. 平局返回'Q'
  4. 继续游戏返回'C'

game.c

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;

}

//判断输赢
//玩家赢 - '*'
//电脑赢 - '#'
//平局 - 'Q'
//继续 - 'C'
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][0] != ' ')
		{
			return board[i][0];
		}
	}
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
		{
			return board[0][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];
	}
    //判断是否平局
	if (IsFull(board,row,col))
	{
		return 'Q';
	}
	//游戏继续
	return 'C';
}

test.c

void game()
{
	//存放数据需要一个3*3的二维数组
	char board[ROW ][COL] = {0};
	//初始化棋盘
	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");
	}
	if ('#' == ret)
	{
		printf("电脑赢\n");
	}
	if ('Q' == ret)
	{
		printf("平局\n");
	}
}

 六、最后整理代码(完整代码)

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

void InitBoard(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++)
		{
			board[i][j] = ' ';
		}
	}
	//初始化   地址   初始化的内容  字节大小   头文件:string.h
	//memset(&board[0][0],' ',row*col*sizeof(board[0][0]));
}


void DisplayBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 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 PlayerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;

	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)
{
	while (1)
	{
		int x = 0;
		int y = 0;
		printf("电脑下棋>:\n");

		x = rand() % row;
		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;

}

//判断输赢
//玩家赢 - '*'
//电脑赢 - '#'
//平局 - 'Q'
//继续 - 'C'
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][0] != ' ')
		{
			return board[i][0];
		}
	}
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
		{
			return board[0][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];
	}
    //判断是否平局
	if (IsFull(board,row,col))
	{
		return 'Q';
	}
	//游戏继续
	return 'C';
}

game.h

#pragma once

//头文件的包含
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>


#define ROW 3
#define COL 3

//函数的声明
// 
//初始化棋盘
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);

//判断输赢
char IsWin(char board[ROW][COL], int row, int col);

test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include"game.h"

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

}

void game()
{
	//存放数据需要一个3*3的二维数组
	char board[ROW ][COL] = {0};
	//初始化棋盘
	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");
	}
	if ('#' == ret)
	{
		printf("电脑赢\n");
	}
	if ('Q' == ret)
	{
		printf("平局\n");
	}
}

int main()
{
	srand((unsigned int)time(NULL));   //随机数  无符号整型  时间戳   
                                       //头文件:stdlib.h  time.h
	int input = 0;
	do 
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch(input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,重新选择\n");
			break;
		}
	} while (input);
	return 0;
}

七、游戏展示

如果各位玩了之后会发现(因为电脑是随机下的,所以可能要被电脑气死)

  1. 赢是特别简单
  2. 电脑赢有点难度
  3. 平局究极难

所以我们可以把平局作为目标去尝试,你会发现还是有点意思的!

最后希望对你们有帮助

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

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

相关文章

求臻医学:乳腺癌治疗与基因检测 探索个性化医疗的未来

乳腺癌是全球女性最常见的恶性肿瘤&#xff0c;2020年全球新发乳腺癌病例约为230万&#xff0c;发病率超过肺癌&#xff0c;位居全部恶性肿瘤首位&#xff01;本文将为您总结乳腺癌的治疗策略与基因检测&#xff0c;揭示个性化医疗的重要意义。 乳腺癌的诊疗 早期乳腺癌通常不…

小程序echarts折线图去除圆圈

如图&#xff0c;默认的折线图上面是有圆圈的&#xff0c;鼠标放上去或者手指触摸的话会有对应的文字出现&#xff0c;但很多时候我们不需要这个圆圈&#xff0c;怎么办呢&#xff0c;其实很简单&#xff0c;只要在 series 中设置属性 showSymbol 为false 就好啦 symbol: none,…

SpringCloud Gateway--Predicate/断言(详细介绍)下

&#x1f600;前言 本篇博文是关于SpringCloud Gateway–Predicate/断言&#xff08;详细介绍&#xff09;下&#xff0c;希望你能够喜欢 &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以…

(三)Python变量类型和运算符

所有的编程语言都支持变量&#xff0c;Python 也不例外。变量是编程的起点&#xff0c;程序需要将数据存储到变量中。 变量在 Python 内部是有类型的&#xff0c;比如 int、float 等&#xff0c;但是我们在编程时无需关注变量类型&#xff0c;所有的变量都无需提前声明&#x…

从C语言到C++:C++入门知识(2)

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家解读一下有关C的基础知识点&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通 数据结…

云原生之使用Docker部署PDF多功能工具Stirling-PDF

云原生之使用Docker部署PDF多功能工具Stirling-PDF 一、Stirling-PDF介绍1.1 Stirling-PDF简介1.2 Stirling-PDF功能 二、本次实践规划2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、下载Stirli…

全网最全面最精华的设计模式讲解,从程序员转变为工程师的第一步

前言 现代社会&#xff0c;技术日新月异&#xff0c;要想跟上技术的更新就必须不断学习&#xff0c;而学习技术最有效方式就是阅读优秀的源码&#xff0c;而优秀的源码都不是简单的逻辑堆积&#xff0c;而是有很灵活的设计模式应用其中&#xff0c;如果我们不懂设计模式&#…

移动机器人运动规划 --- 基于图搜索的A*算法

移动机器人运动规划 --- 基于图搜索的A*算法 A*算法A*算法伪代码A* 算法步骤示例A*算法分析启发函数设计 A*应用的更好方式 A*算法 A算法与Dijkstra算法的框架是完全一样的&#xff0c;**A算法就是有启发性的Dijkstra算法** 代价函数&#xff1a;g(n) 表示的是从开始节点到当…

python tempfile模块:生成临时文件和临时目录

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 tempfile 模块专门用于创建临时文件和临时目录&#xff0c;它既可以在 UNIX 平台上运行良好&#xff0c;也可以在 Windows 平台上运行良好。 tempfile 模块中常用…

蓝牙技术|蓝牙在物联网产品上的功能,特别是苹果Find My中的应用

蓝牙技术经历了不同的迭代&#xff0c;引入了新功能和改进。最初的蓝牙版本于1999年推出。低功耗蓝牙(BLE)&#xff0c;也称为蓝牙4.0或蓝牙智能&#xff0c;于2010年发明&#xff0c;旨在最大限度地降低功耗。这使得它非常适合使用电池供电的物联网设备&#xff0c;从而延长电…

私有继承和虚函数私有化能用么?

源起 以前就知道private私有化声明关键字&#xff0c;和virtual虚函数关键字两者并不冲突&#xff0c;可以同时使用。 但是&#xff0c;它所表示的场景没有那么明晰&#xff0c;也觉得难以理解&#xff0c;直到近段时间遇到一个具体场景。 场景 借助ACE遇到的问题进行展示 …

深眸科技入局AI视觉行业,以深度学习赋能视觉应用推进智造升级

随着科技的飞速发展&#xff0c;人工智能技术已经成为改变我们生活的重要力量&#xff0c;而深度学习作为人工智能的一个重要分支&#xff0c;近年来随着卷积神经网络的突破和推广&#xff0c;取得了显著进展&#xff0c;并呈现爆发式增长势头。 目前AI技术已经被迅速引入到机…

数据集笔记:上海摩拜共享单车

2017年8月上海地区摩拜单车的数据&#xff0c;已脱敏处理 订单id、自行车id、用户id、起始时间、起始经纬度、终止时间、终止经纬度、路径 数据地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1LqL_VtCfgm3vv-NrVCoTkw 提取码&#xff1a;3d3y

各种不同情景的现场急救方法,正确急救的动作要领与操作步骤

一、教程描述 生活中的现场急救&#xff0c;应该是每个人必备的生活技能&#xff0c;可以成功挽救很多人的生命。本套教程为你讲解在各种不同情景下&#xff0c;针对宝宝、儿童与成人等不同群体&#xff0c;现场急救的操作步骤&#xff0c;正确急救的动作要领&#xff0c;以及…

docker安装MySQL 5.7

1.安装 Mysql 5.7 docker镜像 拉取官方镜像 docker pull mysql:5.7查看镜像库 docker images2.创建mysql容器 在本地创建mysql的映射目录 mkdir -p /root/mysql/data /root/mysql/logs /root/mysql/conf在/root/mysql/conf中创建 *.cnf 文件(叫什么都行) touch my.cnf创建…

【51单片机】10-蜂鸣器

1.蜂鸣器的原理 这里的“源”不是指电源。而是指震荡源。 也就是说&#xff0c;有源蜂鸣器内部带震荡源&#xff0c;所以只要一通电就会叫。 而无源内部不带震荡源&#xff0c;所以如果用直流信号无法令其鸣叫。必须用2K~5K的方波去驱动它。 有源蜂鸣器往往比无源的贵&#xff…

mysql双主互从

在主从配置的基础上&#xff0c;反向配置

zblog插件大全-zblog免费插件

在当今数字化时代&#xff0c;拥有一个精彩的博客或网站已经成为许多人追求的目标。通过博客&#xff0c;我们可以分享知识、表达观点&#xff0c;甚至创造收入。然而&#xff0c;维持一个充满新鲜内容的博客却不是一件容易的事情。 ZBlog自动采集插件 什么是ZBlog自动采集插件…

八、3d场景的区域光墙

在遇到区域展示的时候我们就能看到炫酷的区域选中效果&#xff0c;那么代码是怎么编辑的呢&#xff0c;今天咱们就好好说说&#xff0c;下面看实现效果。 思路&#xff1a; 首先&#xff0c;光墙肯定有多个&#xff0c;那么必须要创建一个新的js文件来作为他的原型对象。这个光…

IDEA的Maven换源

前言 IDEA是个好东西&#xff0c;但是使用maven项目时可能会让人很难受&#xff0c;要么是非常慢&#xff0c;要么直接下载不了。所以我们需要给IDEA自带maven换源&#xff0c;保证我们的下载速度。 具体操作 打开IDEA安装路径&#xff0c;然后打开下面的文件夹 plugins\m…