C语言---五子棋游戏之我的大一课程设计

本文详细介绍了使用C语言开发的五子棋游戏,包括需求分析、总体设计、详细设计和调试测试。游戏支持人机对战和双人对战模式,具有悔棋、投降和排行榜功能。在人机对战中,电脑采用特定算法判断并下棋。游戏的排行榜以文件形式保存,玩家可以查看历史最佳步数。开发过程中使用了VisualStudio2022、EasyX图形库和Windows11平台。

一、 需求分析

1.1 设计意义

五子棋是全国智力运动会竞技项目之一,起源于中国古代的传统黑白棋种之一,日文亦有连五子、五子连、串珠、五目、五目碰、五格、五石、五法、五联、京棋等多种称谓;英文则称之为FIR(Five In A Row的缩写)、Gomoku(日语“五目”的罗马拼音)、Gobang、connect 5、mo-rphion等;捷克文piskvorky,韩文omok等等。五子棋是一种两人对弈的纯策略型棋类游戏。双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成五子连珠者获胜。五子棋容易上手,老少皆宜,而且趣味横生,引人入胜。它不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。是一种训练人逻辑思维严密性的好游戏,本程序将用c语言实现一个简单的五子棋,旨在讲述五子棋开发的原理。

1.2 设计要求

1、问题描述
请用所学的C语言知识实现一个命令行下的五子棋游戏。要求有棋盘界面,并实现人与人、人与计算机两种对弈模式。
2、功能要求
(1)要求有棋盘界面,并实现人与人、人与计算机两种对弈模式。
(2)游戏初始选择是否可以悔棋。
(3)查看游戏排行榜前五名,排行榜以文件形式保存。
(4)游戏进行过程中可以投降。
1.3 开发工具及应用平台

Visual Studio2022,EasyX 和 Windows11

二、 总体设计

2.1系统流程模块

2.2 数据结构设计

定义一个结构体类型inf,其中包括姓名和步数两个变量。

typedef struct inf
{
   
   
	char name[20];
	int score;
}info;

2.3 函数功能设计

函数功能设计的表格,如表1所示:

								表1 函数功能设计表
函数名 功能介绍
void hello() 欢迎界面
void load() 等待界面
void start() 游戏初始化
void ret() 排行界面
void board() 绘画棋局
void behind() 玩家对战
int success(int[15][15]) 胜利条件判断
void regret(int[15][15], int[15][15]) 悔棋功能
void machine() 人机对战
int robot(int[15][15], int[15][15], int[15][15]) 电脑执棋
void win(int) 胜利界面
void over() 游戏结束

2.4 磁盘文件

本系统使用一个磁盘文件:
存放玩家排行榜的文件(paihang.txt)

三、详细设计

3.1 主函数

主函数主要是 播放音乐 以及 显示菜单的一个过程。
此模块主函数main()代码如下:

int main()
{
   
   
	hello();//播放游戏背景音乐+等待游戏打开
	start();//显示游戏主菜单 让玩家选择
	return 0;
}

3.2 主界面

主要由三大模块组成:人机对战模式;双人对站模式;排行榜显示;主界面显示函数如下:

void start()
{
   
   
	int cont = 0;

	initgraph(600, 800);
	cleardevice();
	settextcolor(RED);					//设置文字颜色
	setbkmode(TRANSPARENT);				//设置窗口透明
	settextstyle(128, 0, "微软雅黑");    //设置字体大小、宽度、字体
	outtextxy(100, 100, "五子棋");       
	setlinecolor(RED);                  
	rectangle(150, 300, 450, 650);		//绘制矩形
	rectangle(160, 310, 440, 640);
	line(160, 420, 440, 420);			//画一条线
	line(160, 530, 440, 530);
	settextstyle(65, 0, "微软雅黑");
	outtextxy(170, 340, "人机大战");
	outtextxy(170, 450, "双人对战");
	outtextxy(170, 560, "玩家排行");
	setlinecolor(WHITE);
	settextcolor(WHITE);
	settextstyle(23, 0, "微软雅黑");
	outtextxy(527, 37, "音乐");
	circle(550, 50, 25);

	IMAGE gc;//定义鼠标信息变量
	loadimage(&gc, "image//jjkk.png");
	putimage(220, 660, &gc);

	while (true)
	{
   
   
		MOUSEMSG m;
		m = GetMouseMsg();//鼠标信息
		if (m.uMsg == WM_LBUTTONDOWN)//鼠标左键
		{
   
   
			if (m.x <= 440 && m.x >= 160 && m.y < 640 && m.y > 530)
				ret();//排名界面
			if (m.x <= 440 && m.x >= 160 && m.y < 530 && m.y > 420)
				behind();//玩家对战
			if (m.x <= 440 && m.x >= 160 && m.y < 420 && m.y > 310)
				machine();//人机对战
			if (m.x <= 575 && m.x >= 528 && m.y < 75 && m.y > 25)
			{
   
   
				if (cont % 2 == 0)
				{
   
   
					mciSendString(TEXT("pause mysong"), NULL, 0, NULL);
					cont++;
				}
				else
				{
   
   
					mciSendString(TEXT("resume mysong"), NULL, 0, NULL);
					cont++;
				}
			}
		}
	}
}

各个模块显示信息如下:

人机对战模式:

玩家可以与电脑进行PK,同时如果成绩高超可以将分数记入排行榜之中,来和别人横向比较一下与他人的实力差距。

此模块查找函数search_record()代码如下:


void machine()
{
   
   
	board();
	setlinecolor(WHITE);

	MOUSEMSG m; // 定义鼠标消息
	int i = 0, x, y, q = 0, p = 0;
	int red[15][15], white[15][15], stick[15][15], whtie1[15][15];

	while (true)
	{
   
   

		m = GetMouseMsg();
		x = m.x % 50;
		y = m.y % 50;
		setrop2(R2_COPYPEN);	//二元光栅操作码:R2_COPYPEN当前颜色
		if (m.uMsg == WM_LBUTTONDOWN)		// 使用鼠标左键进行操作
		{
   
   
			if (m.x <= 1130 && m.y < 680 && m.x >= 860 && m.y > 590)				 //投降
				win(1);
			if (m.x <= 1130 && m.y < 590 && m.x >= 860 && m.y > 500)					//重开
				machine();
			if (m.x <= 1130 && m.y < 500 && m.x >= 860 && m.y > 410)
			{
   
   
				for (int x1 = 0; x1 < 15; x1++) 
				{
   
   
					for (int y1 = 0; y1 < 15; y1++) 
					{
   
   
						if (whtie1[x1][y1] != white[x1][y1]) 
						{
   
   
							white[x1][y1] = 0;
							stick[x1][y1] = 0;
						}

					}
				}
				red[p][q] = 0;
				stick[p][q] = 0;
				regret(red, whtie1);
				continue;
			}

			if (x >= 25)
				m.x = m.x - x + 50;
			else
				m.x = m.x - x;
			if (y >= 25)
				m.y = m.y - y + 50;
			else
				m.y = m.y - y;
			p = m.x / 50 - 1;
			q = m.y / 50 - 1;
			if (p < 15 && q < 15)
			{
   
   
				if (stick[p][q] == 1)
					break;
				if (m.x <= 750 && m.y <= 750 && m.x >= 50 && m.y >= 50)
				{
   
   
					setfillcolor(RED);
					fillcircle(m.x, m.y, 20);
					red[p][q] = 1;
					if (success(red) == 1)win(2);
					stick[p][q] = 1;
				}
				for (int x1 = 0; x1 < 15; x1++) {
   
   
					for (int y1 = 0; y1 < 15; y1++) {
   
   
						whtie1[x1][y1] = white[x1][y1];
					}
				}
				robot(red, white, stick);
			}
		}
	
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏目浅石.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值