weiqi7777

STM32实现2048游戏(一) C实现

0
阅读(5030)

先在PC上,用c语言实现2048游戏。用的软件是vc6.0,比较老的软件了。

2048游戏用c语言实现,其实也还是比较容易的,本质上就是一个二维数组,每次通过输入的值,判断是上移,下移,左移,右移后,再去改变这个二维数组的值,然后将二维数组的值显示出来就行了。

int b[4][4] = { 16,8,0,8, 16,1024,0,8, 4,32,0,8, 2,0,0,8}; void zuoyi(int a[4]); void youyi(int a[4]); void shangyi(int row); void xiayi(int row); int iswin(); int isfailure(); void display(); void gennew_pane();

定义的b[4][4]就是所需要的二维数组,可以预先往数组里面写入值。然后就是几个函数:

zuoyi(int a[4]) :左移

youyi(int a[4]):右移

shangyi(int row)上移

xiayi(int row)下移

iswin()判断是否胜利

isfailure():判断是否失败

display() :对二位数组显示

gennew_pane():产生新的值

有了这几个函数,然后在主函数中,就通过输入的值,调用这些函数即可了。

int main(int argc, char* argv[]) { char c; display(); while(1) { scanf("%c",&c); fflush(stdin); if( c == 'a' ) { zuoyi(b[0]); zuoyi(b[1]); zuoyi(b[2]); zuoyi(b[3]); gennew_pane(); system("cls"); display(); if(isfailure()) { printf("游戏失败\n"); break; } } else if( c== 'd') { youyi(b[0]); youyi(b[1]); youyi(b[2]); youyi(b[3]); gennew_pane(); system("cls"); display(); if(isfailure()) { printf("游戏失败\n"); break; } } else if( c== 'w') { shangyi(0); shangyi(1); shangyi(2); shangyi(3); gennew_pane(); system("cls"); display(); if(isfailure()) { printf("游戏失败\n"); break; } } else if( c=='s') { xiayi(0); xiayi(1); xiayi(2); xiayi(3); gennew_pane(); system("cls"); display(); if(isfailure()) { printf("游戏失败\n"); break; } } else { printf("输入错误,请重新输入\n"); } if(iswin()) { printf("游戏胜利!!!、n"); break; } } return 0; }

主函数其实做的事很简单,就是读取输入的值,判断是往那一边移位,然后再对数组进行操作,再将二维数组给打印出来,判断是否游戏胜利或者失败,胜利就打印出胜利,失败就打印失败,如果没有胜利或失败,就在等待输入,进行下一轮。

下面就是实现各个函数

1、左移,参数是行数组,先对值一样的合并,再往左边移动,保证非零的值永远在左边。

void zuoyi(int a[4]) { int i; int j; //merge for(i=0; i<3; i++) { if(a[i] == a[i+1]) { a[i] = a[i] + a[i+1]; a[i+1] = 0; } } //zuoyiwei for(i=0; i<3; i++) { if(a[i] == 0) { for(j=i; j<3; j++) a[j] = a[j+1]; a[j] = 0; } } }

2、右移,参数是行数组,先对值一样的合并,再往右边移动,保证非零的值永远在右边。

void youyi(int a[4]) { int i; int j; //merge for(i=3; i>0; i--) { if(a[i] == a[i-1]) { a[i] = a[i] + a[i-1]; a[i-1] = 0; } } //youyiwei for(i=3; i>0; i--) { if(a[i] == 0) { for(j=i; j>0; j--) a[j] = a[j-1]; a[j] = 0; } } }

3、上移,输入参数是第几列。将列的值一样的合并,在往上移,保证非零的数永远在上

void shangyi(int column) { int i; int j; //merge for(i=0; i<3; i++) { if(b[i][column] == b[i+1][column]) { b[i][column] = b[i][column] + b[i+1][column]; b[i+1][column] = 0; } } //shangyiwei for(i=0; i<3; i++) { if(b[i][ column] == 0) { for(j=i; j<3; j++) b[j][column] = b[j+1][column]; b[j][column] = 0; } } }

4、下移,输入参数是第几列。将列的值一样的合并,在往下移,保证非零的数永远在下

void xiayi(int column) { int i; int j; //merge for(i=3; i>0; i--) { if(b[i][column] == b[i-1][column]) { b[i][column] = b[i][column] + b[i-1][column]; b[i-1][column] = 0; } } //xiayiwei for(i=3; i>0; i--) { if(b[i][ column] == 0) { for(j=i; j>0; j--) b[j][column] = b[j-1][column]; b[j][column] = 0; } } }

5、判断赢,这个就依次检查二维数组是否有一个值是2048就行了。

int iswin() { int i; int j; for(i=0; i<4; i++) for(j=0; j<4; j++) if(b[i][j] == 2048) return 1; return 0; }

6、判断输,这个要相对麻烦点。要输的话,首先数组中,没有一个值是0,其次,没有一个值和他的上下左右是一样的,也就是下一次不能移动了,这就输了。在这里,是这样判断的,遍历前三行前三列的每一个元素,如果以该元素为左上角的4方块数据有一个为0,说明还可以移动,游戏还没有结束。如果该元素和右边的数据,或者下边的数据一样的话,说明可以移动,游戏也还没有结束。如果该元素的下边数据和该元素的右下角数据一样的话,或者该元素的右边数据和该元素的有下家数据一样的话,说明可以移动,游戏也还没有结束。除了上面的所有情况下,说明移动不了,认定游戏失败

int isfailure() { int i; int j; //three row for(i=0; i<3; i++) { for(j=0; j<3; j++) { if(b[i][j] == 0 || b[i][j+1] == 0 || b[i+1][j] == 0 || b[i+1][j+1] == 0) return 0; if(b[i][j] == b[i][j+1]) return 0; if(b[i][j] == b[i+1][j]) return 0; if(b[i+1][j] == b[i+1][j+1]) return 0; if(b[i][j+1] == b[i+1][j+1]) return 0; } } return 1; }

7、产生新的值。在每次移动后,要随机产生一个新的2值。这个就比较容易了,使用随机函数,得到坐标,判断坐标处值是否为0,为0,说明可以在该地方产生。

void gennew_pane() { int i; int j; int k=0; srand(time(0)); while(1) { i=rand()%4; j=rand()%4; if(b[i][j] == 0) { b[i][j] = 2; break; } k++; if(k>200) break; } }

8、打印,就是将二维数组给打印出来,打印出来的效果和2048游戏是一样的,只是没有图形化界面而已

void display() { int i; int j; printf(" 欢迎来到2048游戏\n"); printf(" w/s/a/d 上/下/左/右\n"); for(i=0; i<4; i++) { for(j=0; j<4; j++) printf("%4d ",b[i][j]); printf("\n"); } printf("\n"); }

这样,就完成了2048C设计了。

以下是游戏截图。这是游戏开始界面,初始值和定义的二维数组的初始值一样。

clip_image002

按下d后,就变成以下界面了,然后就发现有一个小bug了,第一行的两个8竟然没有合并。原来程序设计,只是考虑了相邻两个一样的值才合并的。所以就有以下bug了。

clip_image004

在多移几次,就胜利了。

clip_image006

以上,就用c语言实现了2048游戏了。后面要将这个游戏给移植到STM32上面去,用TFT屏显示界面。

关于上面所说的bug,各位神仙大神,可是有什么好的方法解决吗?

Baidu
map