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

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

首先声明一下,我不是计算机专业的人,这是我大二上程设课的大作业,第一次做游戏,当时会的东西不多很焦虑,不知道该怎么开始第一步。开始前搜了很多东西,什么“图形界面编程”“面向对象编程”等等,结果其实根本用不上。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;elsereturn 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;elsecombo = 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);elsedrawtext(_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;}//其实一定会有解的,这条语句可以删除elsereturn;
}//设置界面
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;elseclk_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;elsereturn -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]);elsedrawsolidrectangle(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;
}

连连看(源码及图片素材)相关推荐

  1. Scratch开发的双人格斗游戏,包含游戏源码,图片素材分享!

    链接: https://pan.baidu.com/s/1yx3mB2mR61aWAl_12Js27w 提取码: b4if 复制这段内容后打开百度网盘手机App,操作更方便哦 2018干货合集: ▷S ...

  2. 狂神Spring Boot 员工管理系统 【源码 + 笔记 + web素材】 超详细整理

    目录 员工管理系统 1.准备工作 1.1.导入资源 1.2.编写pojo层 1.3.编写dao层 2.首页实现 2.1.引入Thymeleaf 2.2.编写MyMvcConfig 2.3.测试首页 3 ...

  3. 用html语言编写美食栏目 源码,仿美食网首页html+css 完全源码和图片

    [实例简介] 用了一个多星期仿的美食网的首页,html和css分离,完整的源码及图片: [实例截图] [核心代码] kikibingo_6821075 └── 仿美食网首页html+css 完全源码和 ...

  4. html5连连看源码解析,JS连连看源码完美注释版(推荐)

    JS连连看源码完美注释版 table{ border-collapse: collapse; } td{ border: solid #ccc 1px; height: 36px; width: 36 ...

  5. 小程序源码:强大的多功能图片处理器微信小程序源码下载图片画框合成-多玩法安装简单

    大家好这是以开以图片为主题的一款小程序 里面拥有了多种的图片处理功能,也算是比较强大的一款 另外小编最喜欢的就是里面的图片画框合成这个功能 该功能里面有N种画框模板,然后画框的尺寸根据您的图片自适应处 ...

  6. php读取图片文件流,详解php文件包含原理(读取文件源码、图片马、各种协议、远程getshell等)...

    详解php文件包含原理(读取文件源码.图片马.各种协议.远程getshell等) 作者是namezz (看完图相当于做了一轮实验系列) 现有文件代码如下 1.png (21.16 KB, 下载次数: ...

  7. include详解 shell_详解php文件包含原理(读取文件源码、图片马、各种协议、远程getshell等) ......

    详解php文件包含原理(读取文件源码.图片马.各种协议.远程getshell等) 作者是namezz (看完图相当于做了一轮实验系列) 现有文件代码如下 include和include_once.re ...

  8. 小程序源码:图片拼图微信小程序源码下载

    该款小程序支持多种流量主 另外支持多种图形模板制作切割 另外也支持长图合成等功能 安装简单,新手容易上手,具体就不多说了大家自行研究吧! 小程序源码下载地址: 小程序源码:图片拼图微信小程序源码下载- ...

  9. 小程序源码:图片拼图微信小程序源码-多玩法安装简单

    该款小程序支持多种流量主 另外支持多种图形模板制作切割 另外也支持长图合成等功能 安装简单,新手容易上手,具体就不多说了大家自行研究吧! 小程序源码下载地址: 小程序源码:图片拼图微信小程序源码-多玩 ...

最新文章

  1. Delphi的单元文件详解
  2. Kubernetes从懵圈到熟练:认证与调度
  3. java 复写_课程5.4之函数的复写(override)
  4. 「PDF Expert」macOS 全能型 PDF 工具,几大能力务必了解下
  5. 原创 | 一文了解那些和Spring Bean有关的那些注解!
  6. 【uva 1395】Slim Span(图论--最小生成树+结构体快速赋值 模版题)
  7. PHP 开发邀请功能,使用 larainvite 为 Laravel 5.3 应用添加邀请注册功能
  8. C#设计模式之十六观察者模式(Observer Pattern)【行为型】
  9. 有人公开了Avast、McAfee 等杀软中的 8 个 0day
  10. 机器学习代码实战——SVM(支持向量机)(使用不同核函数)
  11. node 多进程 vs java_如何理解node的多进程
  12. 未来的人工智能和 AR/VR 会从哪些方面影响教育?有什么机会?
  13. 飞行计算机配置,微软飞行模拟器配置要求一览 最低/最高PC配置详情
  14. Ubuntu16.04 微信网页版安装
  15. 手机当台式电脑摄像头
  16. java微信公众号上传永久素材_微信开放平台永久素材视频文件上传
  17. 短视频搬运神器,二次剪辑神器,涨粉热门必备软件,黑科技----效果杠杠的
  18. JAVASE、JAVAEE(J2EE)、
  19. 金融IT应小心陷入单纯追求技术目标的误区
  20. 微信小程序 —— 瀑布流简单写法(css3属性加wx:if判断轻松实现)

热门文章

  1. Topographic Laser Ranging and Scanning_Principles and Processing——第一章 1.7
  2. windows下如何进行linux编程,生产者-消费者问题编程简单实现--windows和linux下
  3. 《原则》——RAY #160;DALIO
  4. 揭秘:贵州交警“六合一”系统,零故障运行500天的背后
  5. python微信昵称乱码
  6. PS如何给人物照片添加烟雾效果
  7. 拿小本本记下的Linux Shell常用技巧(一)
  8. java 10进制 和16进制相互转换
  9. 大数据企业,主要需要什么类型的人才?
  10. 从国内外网站发展格局看秒杀竞拍网