用C语言做点小游戏:走迷宫和推箱子

  • Post author:
  • Post category:其他

首先

在一切之前,因为需要用到方向键,而获取方向键的函数在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++;
			}
		}
	}	
}

版权声明:本文为Glanic原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。