广度优先搜索算法的典型应用——消灭小星星游戏的核心代码实现与解析

来源:互联网 发布:acm编程大赛题目 编辑:程序博客网 时间:2024/05/17 09:23

        说明:本文的代码参考了网络上下载的源代码:《2013.3.25 游戏开发基地——孙广东 消灭小星星》,在此对原作者表示衷心感谢!

        这几天在看算法导论里面的BFS和DFS,于是发现消灭小星星这个游戏就用到了BFS算法,就自己试着写了一下消灭小星星游戏的主要代码。现在与大家分享,欢迎批评指正!

#include <stdlib.h>//小星星的坐标class point{public:int x;int y;point():x(0),y(0){}};//存储小星星的链表class starListNode{public:point p;starListNode *next;starListNode(){p.x = 0;p.y = 0;next = NULL;}};//链表队列class listQueue{public:starListNode *head;starListNode *tail;listQueue():head(NULL),tail(NULL){}};listQueue lq;//初始化队列bool initListQueue(){lq.head = new starListNode();lq.tail = lq.head;if(lq.head == NULL)return false;lq.head->next == NULL;return true;}//入队bool enQueue(point tp){starListNode *np = new starListNode();if(np == NULL)return false;np->p.x = tp.x;np->p.y = tp.y;np->next = NULL;lq.tail->next = np;lq.tail = np;return true;}//出队bool deQueue(point &tq){if(lq.head == lq.tail)return false;starListNode *slnp;slnp = lq.head->next;tq.x = slnp->p.x;tq.y = slnp->p.y;lq.head->next = slnp->next;if(slnp == lq.tail)lq.tail = lq.head;delete slnp;return true;}//小星星类class star{public:int x;//横坐标int y;//纵坐标int type;//取值为1到5,6表示背景色int state;//0表示未被选中,1表示被选中};star st[10][10];//初始化所有星星void initStar(){for(int i = 0;i < 10;i++)for(int j = 0;j < 10;j++){st[i][j].x = j;st[i][j].y = i;st[i][j].type = rand()%5 + 1;st[i][j].state = 0;}}//判断某一个星星的上方是否还有未消去的星星,如果还有未消去的星星则返回true,否则返回falsebool upExistStar(star s){int j = s.x;int i = s.y;for(;i > 0;--i){if(st[i-1][j].type != 6)return true;}return false;}//处理空格,使星星下落void dealBlank(){int i,j,m;for(j = 0;j < 10;++j){for(i = 9;i > 0;--i){if(st[i][j].type == 6 && upExistStar(st[i][j]) == true){for(m = i;m > 0;--m)st[m][j].type = st[m-1][j].type;st[m][j].type = 6;}}}}//判断某一列是否为空白bool isBlankColumn(int j){for(int i = 0;i < 10;i++){if(st[i][j].type != 6)return false;}return true;}//消去出现的空白列void dealBlankColumn(){for(int j = 0;j < 10;j++){if(isBlankColumn(j)){for(int m = j;m < 9;m++)for(int i = 0;i < 10;i++)st[i][m].type = st[i][m+1].type;}}}//当选中一颗小星星时,找到与它相邻的所有相同星星void findAllSameStar(int sx,int sy){if(st[sx][sy].type == 6)return;st[sx][sy].state = 1;int starType = st[sx][sy].type;point tepo;tepo.x = st[sx][sy].x;tepo.y = st[sx][sy].y;initListQueue();enQueue(tepo);point tp;//用BFS算法,找到与选中的小星星相同的所有相邻小星星while(deQueue(tp)){if(tp.x > 0 && st[tp.x - 1][tp.y].type == starType && st[tp.x - 1][tp.y].state != 1){st[tp.x - 1][tp.y].state = 1;tepo.x = tp.x - 1;tepo.y = tp.y;enQueue(tepo);}if(tp.x < 9 && st[tp.x + 1][tp.y].type == starType && st[tp.x + 1][tp.y].state != 1){st[tp.x + 1][tp.y].state = 1;tepo.x = tp.x + 1;tepo.y = tp.y;enQueue(tepo);}if(tp.y > 0 && st[tp.x][tp.y - 1].type == starType && st[tp.x][tp.y - 1].state != 1){st[tp.x][tp.y - 1].state = 1;tepo.x = tp.x;tepo.y = tp.y - 1;enQueue(tepo);}if(tp.y < 9 && st[tp.x][tp.y + 1].type == starType && st[tp.x][tp.y + 1].state != 1){st[tp.x][tp.y + 1].state = 1;tepo.x = tp.x;tepo.y = tp.y + 1;enQueue(tepo);}}}int score = 0;//当鼠标再次点击选中的小星星时,与它相邻的所有相同小星星均消失,并且悬空的小星星下降,空白列被消除void wipeAllStar(){for(int i = 0;i < 10;i++){for(int j = 0;j < 10;j++){if(st[i][j].state == 1 && st[i][j].type != 6){st[i][j].type = 6;score += 200;//每消去一个星星得200分st[i][j].state = 0;//消去后状态改为未选中}}}//处理悬空的小星星,在这里要调用3次dealBlank()是因为如果第一行的一个小星星最大可能向下滑9格,但是在这种情况下调用一次dealBlank()后距离底部的单元格数是4,需要再调用两次dealBlank()才能使小星星坠落到底部dealBlank();dealBlank();dealBlank();//处理空白列dealBlankColumn();}


0 0