说明:本文的代码参考了网络上下载的源代码:《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,否则返回false bool 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(); }