ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

连连看(源码及图片素材)

2020-12-29 16:58:17  阅读:204  来源: 互联网

标签:y2 short 连连看 img 图片素材 源码 grid y1 x1


@连连看(源码及图片素材)

连连看(源码及图片素材)

首先声明一下,我不是计算机专业的人,这是我大二上程设课的大作业,第一次做游戏,当时会的东西不多很焦虑,不知道该怎么开始第一步。开始前搜了很多东西,什么“图形界面编程”“面向对象编程”等等,结果其实根本用不上。easyx也是现学的(好在并不难)。在CSDN上找到了好些前辈的文章,非常感谢他们(对了,如果是和我一样非常小白的小白,完全不知道要干啥,可以先去知乎看看童晶老师的文章,感受一下一个小游戏是怎么写的,缓解一下焦虑)。

为了把这份帮助传递下去,决定把自己写的连连看上传上来。第一次写这么长的代码,很大的工作量,写的时候思路不够清晰,有些混乱,所以,我也知道我代码写的不好,仅仅是抱着贡献一点绵薄之力的心态,希望读者可以自行甄别(也不知道有没有bug哈哈哈)。再次感谢CSDN上分享知识的前辈们。

可以转载,请务必注明出处。禁止商用。

将源码、图片素材(freeillustrations.xyz)、删减版实验报告和用到的字体文件上传到了百度网盘上(虽然我真的很讨厌百度网盘。。。),方便大家下载,希望能帮到大家。永久有效。
链接: https://pan.baidu.com/s/1bqBNjDoM14ohiJzBc-VEiA 密码: fhoq

图形库用的是easyx,头文件graphics.h

对了,放上最终游戏界面的部分截图(很用心地做了界面设计,不喜勿喷)
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

头文件

#pragma once
#include<graphics.h>
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<string>
#include<atlstr.h>	//CString头文件atlstr.h
#include<algorithm>
#include<time.h>
#include<process.h>
#include<algorithm>
using namespace std;

定义

#pragma once
#define column 16
#define row 12
#define grid_size 40
#define x0 5
#define y0 5
#define gap 0
const short windows_width = 2 * x0 + grid_size * column + gap * (row - 1) + 250;
const short windows_lenth = 2 * y0 + grid_size * row + gap * (row - 1);

//img[13] 开始菜单背景, img[14] 游戏界面背景, img[15] 排行榜、设置界面的“退出”按钮
IMAGE img[16];
LOGFONT textstyle;
//为真则进入菜单界面
bool flg = true;		
short nhint = 2;
short nshuffle = 1;
int combo = 2;
int score = 0;
long t_start;
short resttime = 360;
short t_limit = 360;
//t代表游戏开始到上一次消除成功多久了,t初始化为-5是为了防止第一次消除被误判为combo
short t = -5;
short n_img = (column - 2) * (row - 2);
short level = 1;
//在设置界面记录之前是否已经选择过一个关卡
short prechoice = 0;			
char fl_name[20] = "rank_list1.txt";

class labels
{
public:
	labels() : x(0), y(0), w(200), h(60), n(13) {}
	labels(short _x, short _y, short _w, short _h, short _n) : x(_x), y(_y), w(_w), h(_h), n(_n) {}
	//判断是否点击了该按钮
	bool init(MOUSEMSG m)
	{
		if (m.x >= x && m.x <= x + w && m.y >= y && m.y <= y + h)
			return true;
		else
			return false;
	}
private:
	short x, y, w, h, n;
};
labels lstart_game(250, 270, 400, 80, 13);
labels lrank_list(380, 5, 140, 40, 14);
labels lexit_game(760, 460, 120, 40, 15);
labels lsetting(855, 5, 40, 40, 16);
labels lshuffle(646, 287, 79, 46, 17);
labels lhint(646, 207, 79, 46, 18);
labels lbk_to_menu(720, 392, 79, 46, 19);
labels lclose_rank(410, 440, 79, 46, 20);

RECT rthint = { 631, 200, 870, 260 };
RECT rtshuffle = { 631, 280, 870, 340 };
RECT rlhint = { 646, 207, 725, 253 };
RECT rlshuffle = { 646, 287, 725, 333 };
RECT rbk_to_menu = { 720, 392, 799, 438 };
RECT rscores = { 650, 85, 870, 175 };
//输出“排行榜”三个字的矩形,“设置”两个字也是这个区域
RECT rrank_name = { 235, 25, 665, 120 };
RECT rrank1 = { 235, 25, 665, 120 };
RECT rrank2 = { 235, 125, 665, 425 };
RECT R = { 0, 5, windows_width, 45 };

struct grids
{
	short x = 0;
	short y = 0;
	//编号 -1 表示没有图片
	short img_num = -1;				
}grid[row][column];

struct levels
{
	char fl_name[20];
	short n_img;
	short t_limit;
};
struct levels level1 = { "rank_list1.txt", 140, 360 };
struct levels level2 = { "rank_list2.txt", 140, 150 };
struct levels level3 = { "rank_list3.txt",  80, 150 };
struct levels level4 = { "rank_list4.txt", 110, 200 };
struct levels level5 = { "rank_list5.txt", 110, 150 };

int Rand(int i)
{
	return rand() % i;
}

void initgridxy();
void initimg();
void initmap1();
void initmap2();
void initmap3();
void draw_start_menu();
void draw_game_window();

void rank_list();
void setting();
void hint();
void shuffle();
bool ten_solutions();

bool start_menu();
void start_game();
void game_window();
void game_over();
bool judge();
void save_memory();

void draw_map();
void drawline(short x1, short y1, short x2, short y2);
void drawrectangle(short x, short y);
void drawsolidrectangle(short x, short y);
void print_score(int scores);

bool is_solution(short &solution_x1, short &solution_y1, short &solution_x2, short &solution_y2);
bool x_no_dots_between(short x1, short x2, short y);
bool y_no_dots_between(short y1, short y2, short x);
bool is_connected(short x1, short y1, short x2, short y2, short &x3, short &y3, short &x4, short &y4);
bool no_turn(short x1, short y1, short x2, short y2);
bool one_turn(short x1, short y1, short x2, short y2, short &x3, short &y3);
bool two_turns(short x1, short y1, short x2, short y2, short &x3, short &y3, short &x4, short &y4);

bool cmp(short a, short b)
{
	return a > b;
}

/*返回label序号,label序号即为对应的img[]序号;
	false代表在开始菜单界面,true代表在游戏界面 */
short clk_labels(MOUSEMSG m, bool flg);
//选择哪个关卡
void clk_levels(MOUSEMSG m);

函数们

#include"headers.h"
#include"definitions.h"
//#include<iostream>
int main()
{
	initgraph(windows_width, windows_lenth + 30);
	setbkcolor(WHITE);				//背景色
	setfillcolor(WHITE);
	setbkmode(OPAQUE);

	gettextstyle(&textstyle);
	textstyle.lfHeight = 50;
	textstyle.lfWidth = 30;
	textstyle.lfQuality = ANTIALIASED_QUALITY;
	textstyle.lfWeight = 700;
	_tcscpy(textstyle.lfFaceName, _T("Aa方萌 (非商业使用)"));
	settextstyle(&textstyle);

	LINESTYLE linestyle;
	linestyle.thickness = 2;
	setlinestyle(&linestyle);
	initimg();
	initgridxy();

	while (1)
	{
		//返回false代表用户点击了“退出游戏”
		if (!start_menu())			
		{
			closegraph();
			return 0;
		}
		start_game();
		while (!flg);
	}

	_getch();
	closegraph();
}

//开始菜单界面
bool start_menu()
{
	level = 1;
	prechoice = 0;
	flg = true;
	cleardevice();
	draw_start_menu();
	FlushMouseMsgBuffer();
	while (1)
	{
		MOUSEMSG m;
		m = GetMouseMsg();
		if (m.mkLButton)
		{
			if (clk_labels(m, false) == 13)		//开始游戏
			{
				flg = false;
				return true;
			}
			else if (clk_labels(m, false) == 14)
			{
				rank_list();
				draw_start_menu();
			}

			else if (clk_labels(m, false) == 15)
			{
				return false;		//用户点击了“退出游戏”
			}
			else if (clk_labels(m, false) == 16)
			{
				setting();
				draw_start_menu();
			}
		}
	}
}

//进入哪一关
void start_game()
{
	while (!flg)
	{
		switch (level)
		{
		case 1:
			strcpy(fl_name, level1.fl_name);
			resttime = level1.t_limit;
			t_limit = resttime;
			n_img = level1.n_img;

			draw_game_window();
			initmap1();
			game_window();

			break;
		case 2:
			strcpy(fl_name, level2.fl_name);
			resttime = level2.t_limit;
			t_limit = resttime;
			n_img = level2.n_img;

			draw_game_window();
			initmap1();
			game_window();
			break;
		case 3:
			strcpy(fl_name, level3.fl_name);
			resttime = level3.t_limit;
			t_limit = resttime;
			n_img = level3.n_img;

			draw_game_window();
			initmap2();
			game_window();
			break;
		case 4:
			strcpy(fl_name, level4.fl_name);
			resttime = level4.t_limit;
			t_limit = resttime;
			n_img = level4.n_img;

			draw_game_window();
			initmap3();
			game_window();
			break;
		case 5:
			strcpy(fl_name, level5.fl_name);
			resttime = level5.t_limit;
			t_limit = resttime;
			n_img = level5.n_img;

			draw_game_window();
			initmap3();
			game_window();
			flg = true;//无论如何都要返回主菜单了
			return;
		}
	}
	//循环结束,说明flg为true了,返回菜单界面
	return;
}

//游戏界面
void game_window()
{
	flg = false;
	t = -5;
	nhint = 2;
	nshuffle = 1;
	score = 0;
	combo = 2;
	t_start = time(0);
	long t_now = t_start;
	//	_beginthread(&draw_timer, 0, NULL);
	BeginBatchDraw();
	textstyle.lfHeight = 50;
	textstyle.lfWidth = 30;
	settextstyle(&textstyle);
	char level_name[10];
	sprintf(level_name, "第%d关得分", level);
	RECT rr = { 650, 35, 870, 120 };
	drawtext(CString(level_name), &rr, DT_VCENTER | DT_CENTER | DT_SINGLELINE);

	setfillcolor(BGR(0xF7E085));
	solidroundrect(17, windows_lenth - 3, windows_width - 17, windows_lenth + 23, 6, 6);
	setfillcolor(BGR(0xAD4560));
	solidroundrect(20, windows_lenth, windows_width - 20, windows_lenth + 20, 6, 6);
	setfillcolor(WHITE);
	EndBatchDraw();
	setlinecolor(BGR(0xF7E085));

	FlushMouseMsgBuffer();
	settextcolor(BLACK);

	bool clked = false;						//记录是否已经选中了一张图片
	short x1 = 0, y1 = 0, x2 = 0, y2 = 0;
	short lenth;
	while (1)
	{
		if (t_now != time(0))
		{
			BeginBatchDraw();
			setfillcolor(BGR(0xF7E085));
			solidroundrect(17, windows_lenth - 3, windows_width - 17, windows_lenth + 23, 6, 6);
			setfillcolor(BGR(0xAD4560));
			lenth = resttime * (windows_width - 40) / t_limit;
			solidroundrect(20, windows_lenth, 20 + lenth, windows_lenth + 20, 6, 6);
			setfillcolor(WHITE);
			EndBatchDraw();
			resttime--;
			t_now = time(0);
		}
		//时间到
		if (!resttime)
		{

			game_over();
			flg = true;
			Sleep(2 * 1000);
			return;
		}
		short tmpx1 = 0, tmpy1 = 0, tmpx2 = 0, tmpy2 = 0;
		if (MouseHit())
		{
			MOUSEMSG m;
			m = GetMouseMsg();
			if (m.mkLButton)
			{
				if (clk_labels(m, true) == 17 && nshuffle)
				{
					nshuffle--;
					char s[10];
					sprintf(s, "%c / 1 次", nshuffle + '0');
					settextcolor(BLACK);
					drawtext(CString(s), &rtshuffle, DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
					srand((unsigned)time(0));
					shuffle();
					draw_map();
					continue;
				}
				else if (clk_labels(m, true) == 18 && nhint)
				{
					nhint--;
					char s[10];
					sprintf(s, "%c / 2 次", nhint + '0');
					settextcolor(BLACK);
					drawtext(CString(s), &rthint, DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
					hint();
					continue;
				}
				else if (clk_labels(m, true) == 19)
				{
					flg = true;
					return;					//bk_to_menu
				}
				else if (clk_labels(m, true) == 0)		//点击格子区域
				{
					if (clked)
					{
						x2 = (m.x - x0) / grid_size;
						y2 = (m.y - y0) / grid_size;

						short x3 = x1;
						short y3 = y1;
						short x4 = x2;
						short y4 = y2;
						if (x1 == x2 && y1 == y2)
						{
							clked = false;
							combo = 2;
							putimage(grid[y1][x1].x, grid[y1][x1].y, &img[grid[y1][x1].img_num]);

						}
						//能够消除
						else if (is_connected(x1, y1, x2, y2, x3, y3, x4, y4))
						{
							n_img -= 2;
							short tmpt = (short)(time(0) - t_start);
							if (tmpt - t < 2)
								combo = combo * 2;
							else
								combo = 2;
							t = tmpt;
							score += combo;
							print_score(score);
							setlinecolor(BGR(0xF7E085));

							drawrectangle(x1, y1);
							drawrectangle(x2, y2);
							drawline(x1, y1, x3, y3);
							drawline(x3, y3, x4, y4);
							drawline(x4, y4, x2, y2);

							Sleep(300);

							BeginBatchDraw();

							setlinecolor(WHITE);
							drawrectangle(x1, y1);
							drawrectangle(x2, y2);
							drawsolidrectangle(x1, y1);
							drawsolidrectangle(x2, y2);
							drawline(x1, y1, x3, y3);
							drawline(x3, y3, x4, y4);
							drawline(x4, y4, x2, y2);

							EndBatchDraw();

							setlinecolor(BGR(0xF7E085));

							grid[y1][x1].img_num = -1;
							grid[y2][x2].img_num = -1;
							if (judge())
							{
								return;
							}
							clked = false;
						}
						//不能消除
						else
						{
							putimage(grid[y1][x1].x, grid[y1][x1].y, &img[grid[y1][x1].img_num]);
							x1 = x2;
							y1 = y2;
							combo = 2;
							drawrectangle(x1, y1);
						}
					}
					else
					{
						x1 = (m.x - x0) / grid_size;
						y1 = (m.y - y0) / grid_size;
						drawrectangle(x1, y1);
						clked = true;
					}
				}
				else if (clk_labels(m, true) == -1)		//既没有点击labels也没有点击格子区域,包括已被消除的区域!!!					
				{
					continue;
				}
			}
		}
	}
}

//游戏界面的“判断”模块
//返回true就是游戏成功,false就是残局
bool judge()			
{

	//判断是否在规定时间内全部消除(即是否成功过关)
	if (!n_img && resttime)
	{
		save_memory();
		
		setbkmode(TRANSPARENT);

		BeginBatchDraw();
		if (level != 5)
			drawtext(_T("游戏成功!2s后进入下一关..."), &R, DT_VCENTER | DT_CENTER | DT_SINGLELINE);
		else
			drawtext(_T("恭喜您已经通关!2s后返回菜单界面..."), &R, DT_VCENTER | DT_CENTER | DT_SINGLELINE);
		EndBatchDraw();

		setbkmode(OPAQUE);

		flg = false;
		Sleep(2 * 1000);
		level++;
		return true;
	}

	//残局
	short tmpx1, tmpy1, tmpx2, tmpy2;
	if (!is_solution(tmpx1, tmpy1, tmpx2, tmpy2))
	{

		shuffle();
		flg = false;
		return false;
	}
	return false;
}

//游戏失败,输出提示文字
void game_over()
{

	setfillcolor(WHITE);
	settextcolor(BGR(0xAD4560));

	setbkmode(TRANSPARENT);

	BeginBatchDraw();
	drawtext(_T("时间到,游戏失败!2s后返回菜单界面..."), &R, DT_VCENTER | DT_CENTER | DT_SINGLELINE);
	EndBatchDraw();

	setbkmode(OPAQUE);
}

//游戏界面
//绘制游戏界面基本形状及文字
void draw_game_window()
{
	setbkcolor(WHITE);				//背景色
	setfillcolor(WHITE);
	textstyle.lfHeight = 50;
	textstyle.lfWidth = 30;
	settextstyle(&textstyle);

	BeginBatchDraw();

	putimage(0, 0, &img[14]);
	setfillcolor(WHITE);
	solidroundrect(22, 22, 628, 468, 15, 15);
	print_score(0);
	settextcolor(BLACK);
	drawtext(_T("2 / 2 次"), &rthint, DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
	drawtext(_T("1 / 1 次"), &rtshuffle, DT_RIGHT | DT_VCENTER | DT_SINGLELINE);

	EndBatchDraw();
}

//显示得分
void print_score(int score)
{
	char sscore[10];
	itoa(score, sscore, 10);
	settextcolor(BGR(0xAD4560));
	drawtext(CString(sscore), &rscores, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}

//游戏界面,提示
void hint()
{
	short s_x1 = 1, s_y1 = 1, s_x2 = 1, s_y2 = 1;
	setlinecolor(BGR(0x41BFDA));

	if (is_solution(s_x1, s_y1, s_x2, s_y2))
	{
		BeginBatchDraw();

		drawrectangle(s_x1, s_y1);
		drawrectangle(s_x2, s_y2);

		EndBatchDraw();

		Sleep(5 * 100);

		BeginBatchDraw();

		putimage(grid[s_y1][s_x1].x, grid[s_y1][s_x1].y, &img[grid[s_y1][s_x1].img_num]);
		putimage(grid[s_y2][s_x2].x, grid[s_y2][s_x2].y, &img[grid[s_y2][s_x2].img_num]);

		EndBatchDraw();

		setlinecolor(BGR(0xF7E085));
		return;
	}
	//其实一定会有解的,这条语句可以删除
	else
		return;
}

//设置界面
void setting()
{
	BeginBatchDraw();

	setfillcolor(WHITE);
	solidroundrect(225, 20, 675, 500, 20, 20);

	textstyle.lfHeight = 70;
	textstyle.lfWidth = 50;
	settextstyle(&textstyle);
	settextcolor(BGR(0xfed9db));
	setbkcolor(WHITE);
	drawtext(_T("设置"), &rrank1, DT_VCENTER | DT_CENTER | DT_SINGLELINE);
	putimage(410, 440, &img[15]);

	settextcolor(BGR(0x94b7bd));
	textstyle.lfHeight = 45;
	textstyle.lfWidth = 28;
	settextstyle(&textstyle);
	for (short i = 0; i < 5; i++)
	{
		setfillcolor(BGR(0xf9f0e8));
		setbkcolor(BGR(0xf9f0e8));

		solidroundrect(330, 180 + (i - 1) * 60, 570, 180 + (i - 1) * 60 + 50, 10, 10);

		RECT tmpr = { 330, 180 + (i - 1) * 60, 570, 180 + (i - 1) * 60 + 50 };

		char sscr[10], clevel[10];

		sprintf(clevel, "第%d关", i + 1);
		drawtext(CString(clevel), &tmpr, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
	}
	setlinecolor(BGR(0xF7E085));
	roundrect(330 + 1, 180 + (prechoice - 1) * 60 - 1, 570 + 1, 180 + (prechoice - 1) * 60 + 50 - 1, 10, 10);
	
	EndBatchDraw();

	MOUSEMSG m;
	while (1)
	{
		m = GetMouseMsg();
		if (m.mkLButton)
		{
			if (m.mkLButton && lclose_rank.init(m))
				return;
			else
				clk_levels(m);
		}
	}
}

//设置界面,判断选择的是哪一关
void clk_levels(MOUSEMSG m)
{
	for (short i = 0; i < 5; i++)
	{
		if (m.x > 330 && m.x < 570
			&& m.y < 180 + (i - 1) * 60 + 50 && m.y > 180 + (i - 1) * 60)
		{
			setlinecolor(BGR(0xf9f0e8));
			roundrect(330 + 1, 180 + (prechoice - 1) * 60 - 1, 570 + 1, 180 + (prechoice - 1) * 60 + 50 - 1, 10, 10);
			prechoice = i;
			level = i + 1;
			setlinecolor(BGR(0xF7E085));
			roundrect(330 + 1, 180 + (i - 1) * 60 - 1, 570 + 1, 180 + (i - 1) * 60 + 50 - 1, 10, 10);
		}
	}
	return;
}

//排行榜界面
void rank_list()
{
	FILE *fp;
	short scr;

	setfillcolor(WHITE);
	solidroundrect(225, 20, 675, 500, 20, 20);

	textstyle.lfHeight = 70;
	textstyle.lfWidth = 50;
	settextstyle(&textstyle);
	settextcolor(BGR(0xfed9db));
	setbkcolor(WHITE);
	drawtext(_T("排行榜"), &rrank1, DT_VCENTER | DT_CENTER | DT_SINGLELINE);
	putimage(410, 440, &img[15]);

	settextcolor(BGR(0x94b7bd));
	textstyle.lfHeight = 50;
	textstyle.lfWidth = 30;
	settextstyle(&textstyle);

	BeginBatchDraw();

	for (short i = 0; i < 5; i++)
	{
		sprintf(fl_name, "rank_list%d.txt", i + 1);
		setfillcolor(WHITE);
		setbkcolor(WHITE);
		if (!(i % 2))
		{
			setfillcolor(BGR(0xf9f0e8));
			setbkcolor(BGR(0xf9f0e8));
		}

		solidroundrect(240, 180 + (i - 1) * 60, 360, 180 + i * 60, 10, 10);
		solidroundrect(380, 180 + (i - 1) * 60, 665, 180 + i * 60, 10, 10);

		RECT tmpr1 = { 240, 180 + (i - 1) * 60, 360, 180 + i * 60 };
		RECT tmpr2 = { 380, 180 + (i - 1) * 60, 665, 180 + i * 60 };

		char sscr[10], clevel[10];

		sprintf(clevel, "第%d关", i + 1);
		drawtext(CString(clevel), &tmpr1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
		if (!(fp = fopen(fl_name, "r")))
			drawtext(_T("无人上榜"), &tmpr2, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
		else
		{
			fread(&scr, sizeof(scr), 1, fp);
			itoa(scr, sscr, 10);
			drawtext(CString(sscr), &tmpr2, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
			fclose(fp);
		}
	}
	EndBatchDraw();

	MOUSEMSG m;

	while (1)
	{
		m = GetMouseMsg();
		if (m.mkLButton && lclose_rank.init(m))
			return;
	}
}

//过关后存档
void save_memory()
{
	FILE *fp;
	short i = 0;
	short scr;
	sprintf(fl_name, "rank_list%d.txt", level);
	if (fp = fopen(fl_name, "r"))
	{
		fread(&scr, sizeof(scr), 1, fp);
		if (scr < score)
			scr = score;
		fclose(fp);
		remove(fl_name);
	}
	else
	{
		scr = score;
	}
	fp = fopen(fl_name, "w+");
	fwrite(&scr, sizeof(scr), 1, fp);
	fclose(fp);
}

//绘制形状
void drawsolidrectangle(short  x, short y)
{
	setfillcolor(WHITE);
	solidrectangle(grid[y][x].x, grid[y][x].y, grid[y][x].x + grid_size, grid[y][x].y + grid_size);
}

void drawrectangle(short x, short y)
{
	rectangle(grid[y][x].x + 1, grid[y][x].y + 1, grid[y][x].x + grid_size - 2, grid[y][x].y + grid_size - 2);
}

void drawline(short x1, short y1, short x2, short y2)
{

	LINESTYLE linestyle;
	linestyle.thickness = 3;
	setlinestyle(&linestyle);

	line(grid[y1][x1].x + grid_size / 2, grid[y1][x1].y + grid_size / 2, grid[y2][x2].x + grid_size / 2, grid[y2][x2].y + grid_size / 2);
}

//画开始菜单
void draw_start_menu()
{
	putimage(0, 0, &img[13]);
}

short clk_labels(MOUSEMSG m, bool _flg)
{
	short x = (m.x - x0) / grid_size;
	short y = (m.y - y0) / grid_size;

	if (!_flg)
	{
		if (lstart_game.init(m))
			return 13;
		else if (lrank_list.init(m))
			return 14;
		else if (lexit_game.init(m))
			return 15;
		else if (lsetting.init(m))
			return 16;
	}
	else if (_flg)
	{
		if (lshuffle.init(m))
			return 17;
		else if (lhint.init(m))
			return 18;
		else if (lbk_to_menu.init(m))
			return 19;
		else if (x > -1 && y > -1 && x < column && y < row && grid[y][x].img_num != -1)
			return 0;
		else
			return -1;
	}
}

//初始化grid[][].img_num
//第一、二关地图
void initmap1()
{
	for (int i = 0; i < column; i++)
	{
		grid[0][i].img_num = -1;
		grid[row - 1][i].img_num = -1;
	}
	for (int j = 0; j < row; j++)
	{
		grid[j][0].img_num = -1;
		grid[j][column - 1].img_num = -1;
	}
	srand(unsigned(time(0)));
	for (int j = 1; j < row / 2; j++)
		for (int i = 1; i < column - 1; i++)
		{
			grid[j][i].img_num = rand() % 13;
			grid[j + row / 2 - 1][i].img_num = grid[j][i].img_num;
		}

	do
	{
		srand((unsigned)time(0));
		for (int i = 1; i < level1.n_img + 1; i++)
		{
			shuffle();
		}
	} while (!ten_solutions());

	draw_map();
}

//第三关地图,呈十字形
void initmap2()
{
	for (int i = 0; i < column; i++)
	{
		grid[0][i].img_num = -1;
		grid[row - 1][i].img_num = -1;
	}
	for (int j = 0; j < row; j++)
	{
		grid[j][0].img_num = -1;
		grid[j][column - 1].img_num = -1;
	}
	for (short j = 1; j < 4; j++)
		for (short i = 1; i < 6; i++)
		{
			grid[j][i].img_num = -1;

		}
	for (short j = 1; j < 4; j++)
		for (short i = 10; i < 15; i++)
		{
			grid[j][i].img_num = -1;

		}
	for (short j = 8; j < 11; j++)
		for (short i = 10; i < 15; i++)
		{
			grid[j][i].img_num = -1;

		}
	for (short j = 8; j < 11; j++)
		for (short i = 1; i < 6; i++)
		{
			grid[j][i].img_num = -1;

		}

	srand(unsigned(time(0)));
	for (int j = 4; j < 6; j++)
		for (int i = 1; i < column - 1; i++)
		{
			grid[j][i].img_num = rand() % 13;
			grid[j + 2][i].img_num = grid[j][i].img_num;
		}
	for (int j = 1; j < 4; j++)
		for (int i = 6; i < 10; i++)
		{
			grid[j][i].img_num = rand() % 13;
			grid[j + 7][i].img_num = grid[j][i].img_num;

		}

	do
	{
		srand((unsigned)time(0));
		for (int i = 1; i < level2.n_img + 1; i++)
		{
			shuffle();
		}
	} while (!ten_solutions());

	draw_map();
}

//第四、五关地图,主对角线附近为空
void initmap3()
{
	for (short k = 12; k < 15; k++)
		for (short j = 1; j < row - 1; j++)
		{
			short i = k - j;
			grid[j][i].img_num = -1;
		}
	for (int i = 0; i < column; i++)
	{
		grid[0][i].img_num = -1;
		grid[row - 1][i].img_num = -1;
	}
	for (int j = 0; j < row; j++)
	{
		grid[j][0].img_num = -1;
		grid[j][column - 1].img_num = -1;
	}

	srand(unsigned(time(0)));
	for (short k = 2; k < 12; k++)
		for (short j = 1; j < k; j++)
		{
			grid[j][k - j].img_num = rand() % 13;
			grid[11 - j][15 - k + j].img_num = grid[j][k - j].img_num;

		}

	do
	{
		srand((unsigned)time(0));
		for (int i = 1; i < level3.n_img + 1; i++)
		{
			shuffle();
		}
	} while (!ten_solutions());

	draw_map();
}

//把图片输出
void draw_map()
{
	BeginBatchDraw();

	setfillcolor(WHITE);
	for (short j = 1; j < row - 1; j++)
		for (short i = 1; i < column - 1; i++)
		{
			if (grid[j][i].img_num != -1)
				putimage(grid[j][i].x, grid[j][i].y, &img[grid[j][i].img_num]);
			else
				drawsolidrectangle(i, j);
		}

	EndBatchDraw();
}

//初始化保证至少有十对图案可以消除
bool ten_solutions()
{
	short tmpx1, tmpy1, tmpx2, tmpy2, nsolution = 0, tmpx3, tmpy3, tmpx4, tmpy4;
	for (tmpy1 = 1; tmpy1 < row - 1; tmpy1++)
		for (tmpx1 = 1; tmpx1 < column - 1; tmpx1++)
			for (tmpy2 = tmpy1; tmpy2 < row - 1; tmpy2++)
				for (tmpx2 = 1; tmpx2 < column - 1; tmpx2++)
				{
					if (grid[tmpy1][tmpx1].img_num != -1 && grid[tmpy2][tmpx2].img_num != -1
						&& is_connected(tmpx1, tmpy1, tmpx2, tmpy2, tmpx3, tmpy3, tmpx4, tmpy4))
					{
						nsolution++;
						if (nsolution >= 10)
							return true;
					}
				}
	return false;
}

//洗牌,直到有解
void shuffle()
{
	short tmpx1 = 0, tmpy1 = 0, tmpx2 = 0, tmpy2 = 0, tmp_imgn = -1;

	do
	{
		do
		{
			tmpx1 = rand() % column;
			tmpy1 = rand() % row;
		} while (grid[tmpy1][tmpx1].img_num == -1);
		do
		{
			tmpx2 = rand() % column;
			tmpy2 = rand() % row;
		} while (grid[tmpy2][tmpx2].img_num == -1);
		tmp_imgn = grid[tmpy1][tmpx1].img_num;
		grid[tmpy1][tmpx1].img_num = grid[tmpy2][tmpx2].img_num;
		grid[tmpy2][tmpx2].img_num = tmp_imgn;
	} while (grid[tmpy1][tmpx1].img_num == grid[tmpy2][tmpx2].img_num
		|| !is_solution(tmpx1, tmpy1, tmpx2, tmpy2));
}

//初始化grid[][].x, grid[][].y
void initgridxy()
{
	for (int j = 0; j < row; j++)
		for (int i = 0; i < column; i++)
		{
			grid[j][i].x = x0 + i*(grid_size + gap);
			grid[j][i].y = y0 + j*(grid_size + gap);
		}
}

//载入图像
void initimg()
{
	char img_name[16];
	for (int i = 0; i < 10; i++)
	{
		sprintf(img_name, "imag\\%c.png", i + '0');
		loadimage(&img[i], CString(img_name), grid_size, grid_size);
	}
	for (int i = 0; i < 3; i++)
	{
		sprintf(img_name, "imag\\1%c.png", i + '0');
		loadimage(&img[i + 10], CString(img_name), grid_size, grid_size);
	}
	loadimage(&img[13], _T("imag\\13.png"));
	loadimage(&img[14], _T("imag\\14.png"));
	loadimage(&img[15], _T("imag\\15.jpg"), 79, 46);
}

//中间是否有其他点,保证l < r
bool x_no_dots_between(short x1, short x2, short y)
{
	short l = x1 < x2 ? x1 : x2, r = x1 > x2 ? x1 : x2;
	for (int i = l + 1; i < r; i++)
	{
		if (grid[y][i].img_num != -1)
			return false;
	}
	return true;
}

//中间是否有其他点,保证t < b
bool y_no_dots_between(short y1, short y2, short x)
{
	short t = y1 < y2 ? y1 : y2, b = y1 > y2 ? y1 : y2;
	for (int i = t + 1; i < b; i++)
	{
		if (grid[i][x].img_num != -1)
			return false;
	}
	return true;
}

//判断连通情况
bool is_connected(short x1, short y1, short x2, short y2, short &x3, short &y3, short &x4, short &y4)
{
	if (grid[y1][x1].img_num == grid[y2][x2].img_num && grid[y1][x1].img_num != -1)
	{
		if (x1 == x2 && y1 == y2)
			return false;
		if (x1 == x2 || y1 == y2)
		{
			if (no_turn(x1, y1, x2, y2))
			{
				return true;
			}
			if (two_turns(x1, y1, x2, y2, x3, y3, x4, y4))
			{
				return true;
			}
		}
		else
		{
			if (one_turn(x1, y1, x2, y2, x3, y3))
			{
				return true;
			}
			if (two_turns(x1, y1, x2, y2, x3, y3, x4, y4))
			{
				return true;
			}
		}
	}
	return false;
}

//不经过拐点直接连通
bool no_turn(short x1, short y1, short x2, short y2)
{
	if (y1 == y2)
	{
		if (x_no_dots_between(x1, x2, y1))
			return true;
	}
	else
	{
		if (y_no_dots_between(y1, y2, x1))
			return true;
	}
	return false;
}

//经过一个拐点
bool one_turn(short x1, short y1, short x2, short y2, short &x3, short &y3)
{
	if (grid[y1][x2].img_num == -1 && no_turn(x1, y1, x2, y1) && no_turn(x2, y1, x2, y2))
	{
		x3 = x2;
		y3 = y1;
		return true;
	}
	if (grid[y2][x1].img_num == -1 && no_turn(x1, y1, x1, y2) && no_turn(x1, y2, x2, y2))
	{
		x3 = x1;
		y3 = y2;
		return true;
	}
	return false;
}

//经过两个拐点
bool two_turns(short x1, short y1, short x2, short y2, short &x3, short &y3, short &x4, short &y4)
{
	for (int i = 0; i < column; i++)
		if (i != x1 && i != x2 && grid[y1][i].img_num == -1 && grid[y2][i].img_num == -1)
			//不写成no_turn && one_turn是为了避免与ont_turn 两种情况之一重复
			if (no_turn(x1, y1, i, y1) && no_turn(i, y1, i, y2) && no_turn(i, y2, x2, y2))
			{
				x3 = i;
				y3 = y1;
				x4 = i;
				y4 = y2;
				return true;
			}

	for (int i = 0; i < row; i++)
		if (i != y1 && i != y2 && grid[i][x1].img_num == -1 && grid[i][x2].img_num == -1)
			if (no_turn(x1, y1, x1, i) && no_turn(x1, i, x2, i) && no_turn(x2, i, x2, y2))
			{
				x3 = x1;
				y3 = i;
				x4 = x2;
				y4 = i;
				return true;
			}
	return false;
}

//有无解
bool is_solution(short &x1, short &y1, short &x2, short &y2)
{
	short tmpx3, tmpy3, tmpx4, tmpy4;
	for (y1 = 1; y1 < row - 1; y1++)
		for (x1 = 1; x1 < column - 1; x1++)
			for (y2 = y1; y2 < row - 1; y2++)
				for (x2 = 1; x2 < column - 1; x2++)
				{
					if (grid[y1][x1].img_num != -1)
						if (grid[y2][x2].img_num != -1)
							if (grid[y1][x1].img_num == grid[y2][x2].img_num)
								if (is_connected(x1, y1, x2, y2, tmpx3, tmpy3, tmpx4, tmpy4))
									return true;
				}
	return false;
}

标签:y2,short,连连看,img,图片素材,源码,grid,y1,x1
来源: https://blog.csdn.net/qq_40930634/article/details/111923895

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有