首先
在一切之前,因为需要用到方向键,而获取方向键的函数在getch.h头文件中,所以需要导入getch.h到系统库中
1、在windows中把getch.h头文件放入共享文件夹 //路径由于自己设置因人而异
2、终端进入共享文件夹:
cd /media/sf_share/
3、复制头文件到标准库:
sudo cp getch.h /usr/include/
4、加读权限:
sudo chmod +r /usr/include/getch.h //加入读取权限就够了
走迷宫
题目:设计如图迷宫,通过方向键上下左右控制目标走到终点,然后打印通关时长
思维导图
代码实现
#include <stdio.h>
#include <getch.h>
#include <time.h>
#include <stdlib.h>
int main(int argc,const char* argv[])
{
//定义一个二维数组存放迷宫
char arr[10][10] = {
{'#','#','#','#','#','#','#','#','#','#'},
{'#','#','#','#','#','#','#',' ',' ',' '},
{'#',' ','#','#','#','#','#',' ','#','#'},
{'#','@','#','#','#','#','#',' ','#','#'},
{'#',' ','#',' ',' ',' ','#',' ','#','#'},
{'#',' ','#',' ','#',' ','#',' ','#','#'},
{'#',' ','#',' ','#',' ',' ',' ','#','#'},
{'#',' ',' ',' ','#','#','#','#','#','#'},
{'#',' ','#','#','#','#','#','#','#','#'},
{'#','#','#','#','#','#','#','#','#','#'},
};
//存放起始时间
int seconds = time((time_t*)NULL);
//玩家的坐标
int lx = 3,ly = 1;
//开始死循环
for(;;)
{
system("clear"); //清屏
printf("\n");
for(int i = 0; i<10; i++) //打印地图
{
for(int j = 0; j<10; j++)
{
printf("%c ",arr[i][j]);
}
printf("\n");
}
if(1 == lx && 9 == ly) //判断玩家坐标是否正在终点,同时将判断延后,以打印出最后一遍地图
{
printf("结束!,用时%d秒",time((time_t*)NULL)-seconds); //打印时间并结束程序
return 0;
}
switch(getch()) //获取方向键并为其设置switch开关
{
case 186: //方向左
{
if('#' != arr[lx][ly-1])
{
arr[lx][ly-1] = '@';
arr[lx][ly] = ' ';
ly -= 1; //更新地图和玩家坐标
}
break;
}
case 185: //方向右
{
if('#' != arr[lx][ly+1])
{
arr[lx][ly+1] = '@';
arr[lx][ly] = ' ';
ly += 1;
}
break;
}
case 184: //方向下
{
if('#' != arr[lx+1][ly])
{
arr[lx+1][ly] = '@';
arr[lx][ly] = ' ';
lx += 1;
}
break;
}
case 183: //方向上
{
if('#' != arr[lx-1][ly])
{
arr[lx-1][ly] = '@';
arr[lx][ly] = ' ';
lx -= 1;
}
break;
}
}
}
}
推箱子
题目:做出如图地图,推箱子玩法为常规玩法,要求打印步数
此关玩法百度“推箱子第十三关”
思维导图
代码实现(初稿)
#include <stdio.h>
#include <getch.h>
#include <stdlib.h>
int main(int argc,const char* argv[])
{
//定义地图
char map[8][8] = {
{0,0,1,1,1,1,0,0},
{0,0,1,4,4,1,0,0},
{0,1,1,0,4,1,1,0},
{0,1,0,0,3,4,1,0},
{1,1,0,3,0,0,1,1},
{1,0,0,1,3,3,0,1},
{1,0,0,2,0,0,0,1},
{1,1,1,1,1,1,1,1}
};
//定义人的坐标
char m_x = 6, m_y = 3;
//记录步数
int step = 0;
//死循环
for(;;)
{
int cnt = 0; //记录目标点上的箱子的数量
system("clear"); //清屏
for(int i=0; i<8; i++)
{
for(int j=0; j<8; j++)
{
switch(map[i][j]) //打印地图
{
case 0: printf(" ");break; //路
case 1: printf("# ");break; //墙
case 2: printf("@ ");break; //人
case 3: printf("$ ");break; //箱子
case 4: printf("O ");break; //目标点
case 6: printf("@ ");break; //目标点为O,人为@,2+4得6,也就是人@,这样记录方便之后直接进行加减
case 7: printf("$ "); //3+4=7 $+O=$
cnt++; //记录箱子和目标点的重合数
break;
}
}
printf("\n");
}
if(4 == cnt) //本地图有四个目标点,如果全部与箱子重合则判断胜利,打印步数结束程序
{
printf("游戏结束,共走了%d步\n",step);
return 0;
}
switch(getch()) //获取方向
{
case 183: //上
if(0 == map[m_x-1][m_y] ||
4 == map[m_x-1][m_y])
{ //可移动情况1:不用推箱子,方向上为路或目标点
map[m_x-1][m_y] += 2; //刷新地图
map[m_x][m_y] -= 2;
m_x--; //更新坐标
step++; //记录步数
}
else if(3 == map[m_x-1][m_y] ||
7 == map[m_x-1][m_y])
{ //可移动情况2:要推箱子,判断箱子后是否有箱子或者墙,有就无法推动
if(0 == map[m_x-2][m_y] ||
4 == map[m_x-2][m_y])
{
map[m_x-2][m_y] += 3;
map[m_x-1][m_y] -= 1;
map[m_x][m_y] -= 2;
m_x--;
step++;
}
}
break;
case 184: //下
if(0 == map[m_x+1][m_y] ||
4 == map[m_x+1][m_y])
{
map[m_x+1][m_y] += 2;
map[m_x][m_y] -= 2;
m_x++;
step++;
}
else if(3 == map[m_x+1][m_y] ||
7 == map[m_x+1][m_y])
{
if(0 == map[m_x+2][m_y] ||
4 == map[m_x+2][m_y])
{
map[m_x+2][m_y] += 3;
map[m_x+1][m_y] -= 1;
map[m_x][m_y] -= 2;
m_x++;
step++;
}
}
break;
case 185: //右
if(0 == map[m_x][m_y+1] ||
4 == map[m_x][m_y+1])
{
map[m_x][m_y+1] += 2;
map[m_x][m_y] -= 2;
m_y++;
step++;
}
else if(3 == map[m_x][m_y+1] ||
7 == map[m_x][m_y+1])
{
if(0 == map[m_x][m_y+2] ||
4 == map[m_x][m_y+2])
{
map[m_x][m_y+2] += 3;
map[m_x][m_y+1] -= 1;
map[m_x][m_y] -= 2;
m_y++;
step++;
}
}
break;
case 186: //左
if(0 == map[m_x][m_y-1] ||
4 == map[m_x][m_y-1])
{
map[m_x][m_y-1] += 2;
map[m_x][m_y] -= 2;
m_y--;
step++;
}
else if(3 == map[m_x][m_y-1] ||
7 == map[m_x][m_y-1])
{
if(0 == map[m_x][m_y-2] ||
4 == map[m_x][m_y-2])
{
map[m_x][m_y-2] += 3;
map[m_x][m_y-1] -= 1;
map[m_x][m_y] -= 2;
m_y--;
step++;
}
}
break;
}
}
}
在写出初稿后发现,判断方向并处理的代码有冗余,可以设置一个变量用来存储偏移值,做整合优化后,可得:
代码实现(优化)
#include <stdio.h>
#include <getch.h>
#include <stdlib.h>
int main(int argc,const char* argv[])
{
char map[8][8] = {
{0,0,1,1,1,1,0,0},
{0,0,1,4,4,1,0,0},
{0,1,1,0,4,1,1,0},
{0,1,0,0,3,4,1,0},
{1,1,0,3,0,0,1,1},
{1,0,0,1,3,3,0,1},
{1,0,0,2,0,0,0,1},
{1,1,1,1,1,1,1,1}
};
char m_x = 6, m_y = 3;
int step = 0;
for(;;)
{
int cnt = 0;
system("clear");
for(int i=0; i<8; i++)
{
for(int j=0; j<8; j++)
{
switch(map[i][j])
{
case 0: printf(" ");break;
case 1: printf("# ");break;
case 2: printf("@ ");break;
case 3: printf("$ ");break;
case 4: printf("O ");break;
case 6: printf("@ ");break;
case 7: printf("$ ");
cnt++;
break;
}
}
printf("\n");
}
if(4 == cnt)
{
printf("游戏结束,共走了%d步\n",step);
return 0;
}
int ox = 0, oy = 0; //设置x和y轴的偏移值
switch(getch()) //switch不再有大量重复代码,改为设置偏移值
{
case 183: ox--; break;
case 184: ox++; break;
case 185: oy++; break;
case 186: oy--; break;
}
//统一整合后,xy的变化都用偏移值代替,地图更新由于对地图元素的定义可以用偏移值轻松完成
if(0 == map[m_x+ox][m_y+oy] ||
4 == map[m_x+ox][m_y+oy])
{
map[m_x+ox][m_y+oy] += 2;
map[m_x][m_y] -= 2;
m_x += ox;
m_y += oy;
step++;
}
else if(3 == map[m_x+ox][m_y+oy] ||
7 == map[m_x+ox][m_y+oy])
{
if(0 == map[m_x+ox*2][m_y+oy*2] ||
4 == map[m_x+ox*2][m_y+oy*2])
{
map[m_x+ox*2][m_y+oy*2] += 3;
map[m_x+ox][m_y+oy] -= 1;
map[m_x][m_y] -= 2;
m_x += ox;
m_y += oy;
step++;
}
}
}
}