投骰子小游戏easyx原创实现(中南大学C语言课程设计)

一、题目

1.1 要求

运用C语言数学运算库函数及easyx图形编程库函数编写一个掷色子游戏程序。

1.2 知识

掌握C语言的语法、语义、基础数据类型、数字、指针、结构体、联合体、文件等的基本概念;掌握ANSI C标准库的字符串、文件、数学运算、标准输入输出、日期时间、资源管理等基本库函数并能熟练运用。建立程序设计开发和算法设计的基本思维方式,充分利用网络开源资源,逐步掌握C语言的高级编程技巧。

1.3 能力

熟练运用当前流行的C/C++开发工具如Visual C++进行程序设计;熟练掌握并运用ANSI C的标准库解决相关问题;建立算法和程序设计的基本思维模式,熟练运用搜索工具和开源资源解决程序设计过程中存在的问题,培养解决复杂工程问题的能力,针对具体问题提出有效的解决方案,增强高级程序设计的能力;在交叉知识的讨论中培养创新意识,提高分析、发现、研究和解决问题的能力。

1.4 素质

以熟练使用相关开发工具、运用标准及扩展库为基础,具备从问题到算法抽象建模的独立思维素质;具备抽取问题核心本质,利用搜索引擎,从互联网获取相关开发资源的素质;通过课程中的分析讨论,培养沟通交流及相互协作的素质;通过课外导学的模式,提升自主学习和终身学习的意识,形成不断学习和适应发展素质。

二、 设计思路

2.1 需求分析
  1. 基本原理
    运用随机数对六取余再加一的算法模拟掷色子的过程,运用电脑产生的随机数模拟现实生活中投掷色子的过程。
  2. 基本功能
    首先玩家选择 Big or Small(押大小)并输入赌注金额,完成后电脑摇三个骰子(产生三个随机数)并计算总值,总值大于等于11小于等于18为“大”,总值大于等于3小于等于10为“小”。告诉玩家押对或是押错,玩家初始金额是 1000 元,赔率为1倍。玩家可以模拟现实生活中摇色子的过程。
  3. 数据流图
    数据流图
2.2 总体设计
  1. 总体结构
    a) 开始界面:主要由“开始游戏”按钮和“规则介绍”按钮两部分构成,还可以选择背景音乐是否播放,为游戏的开始界面
    b) 游戏界面:主要由三个骰子构成主界面,右侧四分之一为玩家余额以及系统提示语
    c) 规则介绍界面:主要介绍游戏规则,点开即弹出
  2. 模块关系
    玩家点开游戏后进入开始界面,开始界面下设游戏界面以及规则介绍界面,游戏界面与规则介绍界面并列,均可返回开始界面。
  3. 总体流程
    先进入开始游戏界面,玩家先点击“规则介绍”按钮了解游戏流程,再返回开始界面,点击“开始游戏”按钮开始游戏。开始游戏后,玩家先选择big或者small,并输入赌注金额,之后界面显示三个骰子的大小以及总和,系统提示赌局结果,并重新显示玩家余额。

2.3 详细设计
  1. 开始界面
    运用图形库函数,鼠标可点击区域有三个,分别为“开始游戏”按键区域,“游戏规则”按键区域,以及音乐播放图标区域。三个区域点击后对应的操作分别为,打开游戏界面,打开规则介绍界面,控制音乐停止与播放。
  2. 游戏界面
    左边为三个骰子的图片,图片下方先不显示数字,右上角为玩家余额显示,每进行一轮游戏更新显示一次,右下角为系统提示语:“你赢了xx金币!太机智了!”或者“你输了xx金币!太笨了!”。玩家进入后先在提示框中选择大小,再输入赌注金额,系统进行随机数抽取,后在骰子图片下方显示骰子大小及总数,在右侧显示系统提示语,并实现金额变更。界面右上角有关闭按键,返回开始游戏界面
  3. 规则介绍界面
    为开始游戏界面上方的一个悬浮框,右上角有关闭游戏按键,可关闭此悬浮框。此悬浮框主要显示内容为“游戏规则——玩家首先选择 Big or Small(押大小),选择完成后玩家输入赌注金额;之后系统开始摇三个骰子并计算总值,总值大于等于11小于等于18为“大”,总值大于等于3小于等于10为“小”;玩家初始金额是 1000 元,赔率为1倍。”

三、实现代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>		//使用srand((unsigned int) time(NULL)) 和 rand() 产生随机数
#include <easyx.h>		//使用图形库函数(包含windows.h的头文件)
#include <conio.h>		//使用_getch()函数
#include <mmsystem.h>	//包含多媒体设备接口头文件(播放音乐)
#include <graphics.h>
#pragma comment(lib,"winmm.lib")//加载静态库(播放音乐)
#define win_width 900
#define win_height 500 
char money[10] = "1000";	//玩家初始余额

int begin(void)
{
	//设置一个背景色并以背景色清屏
	setbkcolor(RGB(191, 181, 227));
	cleardevice();
	int botton[2][4] = { {600,250,150,50} , {600,330,150,50} };//界面上两个按钮的位置
	//输入并加载背景图片
	IMAGE img;
	loadimage(&img, "./背景.jpg", win_width, win_height);//or窗口适应图片大小:int width = img.getwidth();
	putimage(0, 0, &img);

	//在背景图片上显示“开始游戏”的botton、“游戏规则”的botton
	setlinecolor(BLACK);				//线条颜色
	setfillcolor(RGB(81, 191, 219));	//填充颜色
	setlinestyle(PS_SOLID, 2);			//线条样式
	fillroundrect(botton[0][0], botton[0][1], botton[0][0] + botton[0][2], botton[0][1] + botton[0][3], 10, 10);
	fillroundrect(botton[1][0], botton[1][1], botton[1][0] + botton[1][2], botton[1][1] + botton[1][3], 10, 10);

	//将文字在botton里居中显示
	settextcolor(RGB(40,62,89));
	setbkmode(TRANSPARENT);
	settextstyle(35, 0, "华文行楷");
	char s1[] = "开始游戏";
	int width1 = botton[0][0] + botton[0][2] / 2 - textwidth(s1) / 2;
	int height1 = botton[0][1] + botton[0][3] / 2 - textheight(s1) / 2;
	outtextxy(width1, height1, s1);
	char s2[] = "游戏规则";
	int width2 = botton[1][0] + botton[1][2] / 2 - textwidth(s2) / 2;
	int height2 = botton[1][1] + botton[1][3] / 2 - textheight(s2) / 2;
	outtextxy(width2, height2, s2);

	//鼠标点击操作
	ExMessage msg;
	int ret = 0;
	while (true) {
		if (peekmessage(&msg, EM_MOUSE)) {
			if (msg.x >= width1 && msg.x <= width1 + 150 && msg.y >= height1 && msg.y <= height1 + 50) 
			{
				//消息分发
				if (msg.message == WM_LBUTTONDOWN) {
					printf("开始游戏被左击了");
					ret = 2;
					break;
				}
			}
			if (msg.x >= width2 && msg.x <= width2 + 150 && msg.y >= height2 && msg.y <= height2 + 50)
			{
				//消息分发
				if (msg.message == WM_LBUTTONDOWN) {
					printf("游戏规则被左击了");
					ret = 1;
					break;
				}
			}

		}

	}

	return ret;
}

int introduce(void)
{
	//画一个圆角矩形装说明文字
	setlinecolor(BLACK);		
	setfillcolor(RGB(112,142,190));		
	setlinestyle(PS_SOLID, 3);  
	fillroundrect(100,100,800,400,20,20);	
	//关闭按钮
	settextcolor(BLACK);
	setbkmode(TRANSPARENT);
	settextstyle(50, 40, "黑体");
	outtextxy(760, 100, "X");
	//说明文字
	settextcolor(RED);
	setbkmode(TRANSPARENT);
	settextstyle(40, 0, "幼圆");
	char title[] = "游戏规则";
	outtextxy(450 - textwidth(title) / 2, 120, title);
	char line1[] = "         玩家首先选择 Big or Small(押大小),选";
	char line2[] = "择完成后玩家输入赌注金额;之后系统开始摇三";
	char line3[] = "个骰子并计算总值,总值大于等于11小于等于18";
	char line4[] = "为“大”,总值大于等于3小于等于10为“小”;";
	char line5[] = "玩家初始金额是 1000 元,赔率为1倍。";
	settextcolor(RGB(40, 62, 89));
	setbkmode(TRANSPARENT);
	settextstyle(30, 0, "华文新魏");
	outtextxy(140 , 180, line1);
	outtextxy(140 , 220, line2);
	outtextxy(140 , 260, line3);
	outtextxy(140 , 300, line4);
	outtextxy(140 , 340, line5);

	//鼠标点击操作
	ExMessage msg;
	int ret = 0;
	while (true) {
		if (peekmessage(&msg, EM_MOUSE)) {

			if (msg.x >= 750 && msg.x <= 800 && msg.y >= 100 && msg.y <=150)
			{
				//消息分发
				if (msg.message == WM_LBUTTONDOWN) {
					printf("关闭按钮被左击了");
					break;
				}
			}

		}

	}
	return ret;
}

int play(void)
{
	//设置一个背景色并以背景色清屏
	setbkcolor(WHITE);
	cleardevice();

	//将白色背景分区
	setlinecolor(RGB(40, 62, 89));		//线条颜色
	setlinestyle(PS_SOLID, 5);			//线条样式
	line(675, 0, 675, 500);				//竖分割线
	line(675, 200, 900, 200);			//横分割线

	//输入并加载骰子图片
	IMAGE dice;
	loadimage(&dice, "./骰子.jpg", 150, 150);
	putimage(50, 150, &dice);
	putimage(225, 150, &dice);
	putimage(400, 150, &dice);
	
	//显示关闭按钮
	settextcolor(RGB(40, 62, 89));
	setbkmode(TRANSPARENT);
	settextstyle(50, 40, "黑体");
	outtextxy(625, 0, "X");

	//显示继续游戏按钮
	settextcolor(RED);
	setbkmode(TRANSPARENT);
	settextstyle(25, 0, "楷体");
	outtextxy(680, 450, "继续游戏");

	//显示重新游戏按钮
	settextcolor(RGB(40, 62, 89));
	setbkmode(TRANSPARENT);
	settextstyle(25, 0, "楷体");
	outtextxy(790, 450, "重新游戏");

	//右上角显示"当前余额"
	settextcolor(RED);
	setbkmode(TRANSPARENT);
	settextstyle(30, 0, "楷体");
	outtextxy(730, 50, "当前余额");
	
	//右上角显示余额数值
	setlinecolor(BLACK);					//线条颜色
	setfillcolor(RGB(112, 142, 190));		//填充颜色
	setlinestyle(PS_SOLID, 3);				//线条样式
	fillroundrect(685, 120, 890, 180, 10, 10);//宽205,高60
	settextcolor(BLACK);
	setbkmode(TRANSPARENT);
	settextstyle(50, 0, "黑体");
	int width = 685 + 205 / 2 - textwidth(money) / 2;
	int height = 120 + 60 / 2 - textheight(money) / 2;
	outtextxy(width, height, money);


	//弹出消息框,让玩家选择押大押小
	int flag = 1;					//默认玩家选择押大,压小则为0
	HWND m_hWnd = GetHWnd();
	if (MessageBox(m_hWnd, ("是否选择押大?"), ("押大小"), MB_ICONQUESTION | MB_YESNO) == IDNO) { flag = 0;}

	//弹出消息框,让玩家输入赌注金额
	char s[10];
	InputBox(s,30,"请输入赌注金额(不超过一千万)");
	Sleep(1000);

	//显示三个骰子的随机结果
	char show[3];
	int outcome[3] = { 0 }, sum = 0;
	int i = 0;
	srand((unsigned int)time(NULL));
	for (i = 0; i < 3; i++) {
		outcome[i] = rand() % 6 + 1;
		sum += outcome[i];
		show[i] = outcome[i] + '0';
	}
	
	IMAGE dice1, dice2, dice3, dice4, dice5, dice6;
	loadimage(&dice1, "./一点.jpg", 150, 150);
	loadimage(&dice2, "./二点.jpg", 150, 150);
	loadimage(&dice3, "./三点.jpg", 150, 150);
	loadimage(&dice4, "./四点.jpg", 150, 150);
	loadimage(&dice5, "./五点.jpg", 150, 150);
	loadimage(&dice6, "./六点.jpg", 150, 150);

	settextcolor(RGB(40, 62, 89));
	setbkmode(TRANSPARENT);
	settextstyle(50, 0, "幼圆");
	switch (outcome[0]) {
		case 1:	putimage(50, 150, &dice1); break;
		case 2: putimage(50, 150, &dice2); break;
		case 3: putimage(50, 150, &dice3); break;
		case 4: putimage(50, 150, &dice4); break;
		case 5: putimage(50, 150, &dice5); break;
		case 6: putimage(50, 150, &dice6); break;
	}
	outtextxy(125 - textwidth(show[0]) / 2, 400, show[0]);
	Sleep(1000);
	switch (outcome[1]) {
		case 1:	putimage(225, 150, &dice1); break;
		case 2: putimage(225, 150, &dice2); break;
		case 3: putimage(225, 150, &dice3); break;
		case 4: putimage(225, 150, &dice4); break;
		case 5: putimage(225, 150, &dice5); break;
		case 6: putimage(225, 150, &dice6); break;
	}
	outtextxy(300 - textwidth(show[1]) / 2, 400, show[1]);
	Sleep(1000);
	switch (outcome[2]) {
		case 1:	putimage(400, 150, &dice1); break;
		case 2: putimage(400, 150, &dice2); break;
		case 3: putimage(400, 150, &dice3); break;
		case 4: putimage(400, 150, &dice4); break;
		case 5: putimage(400, 150, &dice5); break;
		case 6: putimage(400, 150, &dice6); break;
	}
	outtextxy(475 - textwidth(show[2]) / 2, 400, show[2]);
	Sleep(1000);
	
	//在右下角显示提示语
	if (flag == 1 && sum >= 11 || flag == 0 && sum <= 10)
	{
		settextcolor(RGB(128, 0, 0));
		setbkmode(TRANSPARENT);
		settextstyle(40, 0, "华文行楷");
		outtextxy(720, 250, "你赢了!");
		outtextxy(700, 310, "太机智了!");
	}
	else
	{
		settextcolor(RGB(128, 0, 0));
		setbkmode(TRANSPARENT);
		settextstyle(40, 0, "华文行楷");
		outtextxy(720, 250, "你输了!");
		outtextxy(720, 310, "太笨了!");
	}



	//******************************************************************
	//更新余额(将字符串转化为数字)
	Sleep(1000);
	int money_s = 0;//整形的现有余额
	int s_s = 0;	//整形的赌注金额
	int t = 1;
	int n = strlen(money);
	for (i = n - 1; i >= 0; i--) {			//将字符串转化成整形的原有余额
		money_s += (money[i] - '0') * t;
		t *= 10;
	}
	n = strlen(s);
	t = 1;
	for (i = n - 1; i >= 0; i--) {			//将字符串转化成整形的赌注金额
		s_s += (s[i] - '0') * t;
		t *= 10;
	}
	//更新余额(计算新的余额)
	if (flag == 1 && sum >= 11 || flag == 0 && sum <= 10) money_s += s_s;
	else money_s -= s_s;
	//更行余额(将新余额转化为字符串)
	if(money_s==0) strcpy_s(money, sizeof(money) / sizeof(money[0]), "0");
	else 
	{
		if (money_s > 0) flag = 0;
		else {
			flag = 1;
			money[0] = '-';
			money_s = -money_s;
		}
		for (i = flag; money_s > 0; i++) {
			money[i] = money_s % 10 + '0';
			money_s /= 10;
		}
		money[i] = '\0';
	}
		//倒序字符串
	char tmp;
	n = strlen(money);
	if (flag == 0) {
		for (i = 0; i < n / 2; i++) {
			tmp = money[i];
			money[i] = money[n - i - 1];
			money[n - i - 1] = tmp;
		}
	}
	else {
		for (i = 1; i <= n / 2; i++) {
			tmp = money[i];
			money[i] = money[n - i ];
			money[n - i ] = tmp;
		}
	}
	//更行余额(显示新余额)
	setlinecolor(BLACK);						//线条颜色
	setfillcolor(RGB(112, 142, 190));			//填充颜色
	setlinestyle(PS_SOLID, 3);					//线条样式
	fillroundrect(685, 120, 890, 180, 10, 10);	//宽205,高60
	settextcolor(BLACK);
	setbkmode(TRANSPARENT);
	settextstyle(50, 0, "黑体");
	width = 685 + 205 / 2 - textwidth(money) / 2;
	height = 120 + 60 / 2 - textheight(money) / 2;
	outtextxy(width, height, money);
	//*************************************************************



	//如果余额不足
	if (flag == 1)
	{
		//显示你负债了
		setlinecolor(BLACK);						//线条颜色
		setfillcolor(RGB(112, 142, 190));			//填充颜色
		setlinestyle(PS_SOLID, 3);					//线条样式
		fillroundrect(250, 150, 650, 350, 10, 10);	//宽400,高200
		settextcolor(RED);
		setbkmode(TRANSPARENT);
		settextstyle(50, 0, "华文行楷");
		width = 450 - textwidth("你负债了!") / 2;
		height = 200 - textheight("你负债了!") / 2;
		outtextxy(width, height, "你负债了!");
		width = 450 - textwidth("请及时止损!!") / 2;
		height = 300 - textheight("请及时止损!!") / 2;
		outtextxy(width, height, "请及时止损!!");
		//退出游戏
		Sleep(3000);
		strcpy_s(money, sizeof(money) / sizeof(money[0]), "1000");
		return 0;
	}
	//鼠标点击操作
	ExMessage msg;
	int ret = 0;
	while (true) {
		if (peekmessage(&msg, EM_MOUSE)) {
			//玩家选择退出
			if (msg.x >= 625 && msg.x <= 675 && msg.y >= 0 && msg.y <= 50 && msg.message == WM_LBUTTONDOWN)
			{
				printf("关闭按钮被左击了");
				strcpy_s(money, sizeof(money) / sizeof(money[0]), "1000");
				ret = 0;
				break;
			}
			//玩家选择继续游戏
			if (msg.x >= 680 && msg.x <= 790 && msg.y >= 450 && msg.y <= 500 && msg.message == WM_LBUTTONDOWN)
			{
				printf("继续游戏按钮被左击了");
				ret = 2;
				break;
			}
			//玩家鼠标选择重新游戏
			if (msg.x >= 790 && msg.x <= 900 && msg.y >= 450 && msg.y <= 500 && msg.message == WM_LBUTTONDOWN)
			{
				printf("重新游戏按钮被左击了");
				strcpy_s(money, sizeof(money) / sizeof(money[0]), "1000");
				ret = 2;
				break;
			}

		}

	}
	return ret;
}

void BGM()
{
	//打开音乐,播放音乐 
	//alias 取别名
	//repeat 重复播放 
	mciSendString("open ./背景音乐.mp3 alias BGM", 0, 0, 0);
	mciSendString("play BGM repeat", 0, 0, 0);
	if (false)
	{
		mciSendString("close BGM", 0, 0, 0);
	}

}

int main()
{
	//打开一个图像窗口并显示命令行窗口
	//EW_SHOWCONSOLE显示命令行窗口
	initgraph(win_width, win_height);
	//播放背景音乐
	BGM();
	//获取窗口句柄并设置窗口标题
	HWND hnd = GetHWnd();
	SetWindowText(hnd, "掷色子小游戏");

	int screen = begin();
	while (true)
	{
		if (screen == 1) screen = introduce();
		else if (screen == 2) screen = play();
		else screen = begin();
	}

	//按任意键关闭
	char c = getchar();
	//关闭图像窗口
	closegraph();
	return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Forest_Lamb

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

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

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

打赏作者

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

抵扣说明:

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

余额充值