今天我来分享一道对于初学C语言的同学非常有启发作用的编程例题,是用C语言实现单张地图推箱子的小游戏。
这个游戏是基于Linux环境下编程的,所用工具为ubuntu、和gcc编译器。
首先推箱子的地图,我们根据经典游戏推箱子中的其中一幅地图来自做,图片如下。
用图片形式实现这张图片对于初学编程的同学来说,难以实现,所以我们选择用字符代替的形式来实现这张地图。
我们采用2为数组的方式来存储这张地图,具体的数字与字符含义转换如下:
0 printf(" "); 路
2 printf("@"); 人
3 printf("#"); 墙
4 printf("$"); 箱子
5 printf("O"); 目标点
7 printf("@"); 人
9 printf("$"); 箱子
代码如下:
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <getch.h> int mx = 0; int my = 0; int step = 0; char map[8][8] = { {0,0,3,3,3,3,0,0}, {0,0,3,5,5,3,0,0}, {0,3,3,0,5,3,3,0}, {0,3,0,0,4,5,3,0}, {3,3,0,4,0,0,3,3}, {3,0,0,3,4,4,0,3}, {3,0,0,2,0,0,0,3}, {3,3,3,3,3,3,3,3} }; void show_map(void) { for(int i=0;i<8;i++) { for(int j=0;j<8;j++) { if(0 == map[i][j]) { printf(" "); } else if(2 == map[i][j]) { printf("@ "); } else if(3 == map[i][j]) { printf("# "); } else if(4 == map[i][j]) { printf("$ "); } else if(5 == map[i][j]) { printf("O "); } else if(7 == map[i][j]) { printf("@ "); } else if(9 == map[i][j]) { printf("$ "); } } printf("\n"); } } void up(void) { for(int i=0; i<8;i++) { for(int j=0; j<8;j++) { if(2 == map[i][j] || 7 == map[i][j]) { mx =i; my =j; } } } if(3 == map[mx-1][my]) { return; } else if(0 == map[mx-1][my] || 5 == map[mx-1][my]) { map[mx-1][my] += 2; map[mx][my] -= 2; step++; } else if(4 == map[mx-1][my] || 9 == map[mx-1][my]) { if(0 == map[mx-2][my]) { map[mx-2][my] += 4; map[mx-1][my] -= 2; map[mx][my] -= 2; step++; } else if(5 == map[mx-2][my]) { map[mx-2][my] += 4; map[mx-1][my] -= 2; map[mx][my] -= 2; step++; } else { return; } } } void down(void) { for(int i=0; i<8;i++) { for(int j=0; j<8;j++) { if(2 == map[i][j] || 7 == map[i][j]) { mx =i; my =j; } } } if(3 == map[mx+1][my]) { return; } else if(0 == map[mx+1][my] || 5 == map[mx+1][my]) { map[mx+1][my] += 2; map[mx][my] -= 2; step++; } else if(4 == map[mx+1][my] || 9 == map[mx+1][my]) { if(0 == map[mx+2][my]) { map[mx+2][my] += 4; map[mx+1][my] -= 2; map[mx][my] -= 2; step++; } else if(5 == map[mx+2][my]) { map[mx+2][my] += 4; map[mx+1][my] -= 2; map[mx][my] -= 2; step++; } else { return; } } } void left(void) { for(int i=0; i<8;i++) { for(int j=0; j<8;j++) { if(2 == map[i][j] || 7 == map[i][j]) { mx =i; my =j; } } } if(3 == map[mx][my-1]) { return; } else if(0 == map[mx][my-1] || 5 == map[mx][my-1]) { map[mx][my-1] += 2; map[mx][my] -= 2; step++; } else if(4 == map[mx][my-1] || 9 == map[mx][my-1]) { if(0 == map[mx][my-2]) { map[mx][my-2] += 4; map[mx][my-1] -= 2; map[mx][my] -= 2; step++; } else if(5 == map[mx][my-2]) { map[mx][my-2] += 4; map[mx][my-1] -= 2; map[mx][my] -= 2; step++; } else { return; } } } void right(void) { for(int i=0; i<8;i++) { for(int j=0; j<8;j++) { if(2 == map[i][j] || 7 == map[i][j]) { mx =i; my =j; } } } if(3 == map[mx][my+1]) { return; } else if(0 == map[mx][my+1] || 5 == map[mx][my+1]) { map[mx][my+1] += 2; map[mx][my] -= 2; step++; } else if(4 == map[mx][my+1] || 9 == map[mx][my+1]) { if(0 == map[mx][my+2]) { map[mx][my+2] += 4; map[mx][my+1] -= 2; map[mx][my] -= 2; step++; } else if(5 == map[mx][my+2]) { map[mx][my+2] += 4; map[mx][my+1] -= 2; map[mx][my] -= 2; step++; } else { return; } } } void start_soko(void) { FILE* frp = fopen("soko.bin","r"); if(NULL == frp) { printf("数据加载错误!\n"); return; } fread(map,1,64,frp); fclose(frp); } void exit_soko(void) { FILE* fwp = fopen("soko.bin","w"); printf("____"); if(NULL == fwp) { printf("数据保存错误!\n"); } fwrite(map,1,64,fwp); fclose(fwp); } int main() { start_soko(); while(true) { system("clear"); //显示地图 show_map(); //判定是否游戏结束 int cnt = 0; for(int i=0; i<8; i++) { for(int j=0; j<8;j++) { if(9 == map[i][j]) { cnt++; } } } if(4 == cnt) { printf("游戏结束,共使用%d步!\n",step); return 0; } printf("%d\n",cnt); //获取方向键 switch(getch()) { case 'w':up();break; case 's':down();break; case 'a':left();break; case 'd':right();break; case 'q':exit_soko();return 0; default: puts("输入指令有误!"); } } exit_soko(); }