C语言基础知识巩固--会打字就能学会的推箱子

C语言知识巩固–会打字就能学会的推箱子

临近期末了,不知道大家复习的怎么样(头大)。

学C语言也将近一个学期了,最近发现了一个推箱子的小游戏可以巩固一下C语言知识,涉及到基本的输入输出、循环、函数、数组,跟大家一起分享复习。

代码在200行左右,简单易学,不仅能积累代码量,对数组复习也是挺有帮助的

  1. 找到相关的特殊符号

    为了方便起见,相关的符号我已经帮大家找好了,当然大家也可以找自己喜欢的符号

    找到对应的符号之后,我们还要确定符号对应的数字,因为操作数组还是要回归到数字的嘛(数字也是任意的)

    人  ♀  5
    箱子 ★  4
    障碍 ■  1
    目的地 ☆  3
    箱子推到目的地:7
    空地   0
    
  2. 设计窗口

    控制太黑黑的窗口真的不太好看,所以我专门写了个函数设计了一下窗口(设计了还是不好看[捂脸])

    void designWin()
    {
    	system("title 推箱子(控制台版本)");
    	system("color E0");
    	system("mode con cols=24 lines=12");
    }
    
  3. 设计地图

    现在开始就要开始复习我们的数组知识啦

    首先我们先定义一个数组

    int map[3][8][8];//3:游戏的总关卡数
    			   //8:游戏地图的长宽
    

    地图设计:

    int map[3][8][8] ={
    	1,1,1,1,1,1,1,1,
    	1,3,4,0,0,4,3,1,
    	1,1,1,1,0,1,1,1,
    	1,1,1,1,5,1,1,1,
    	1,1,1,1,0,1,1,1,
    	1,1,1,1,0,1,1,1,
    	1,3,4,0,0,4,3,1,
    	1,1,1,1,1,1,1,1,
    
    	1,1,1,1,1,1,1,1,
    	1,1,1,1,1,1,1,1,
    	1,1,1,1,1,1,1,1,
    	1,1,1,1,1,1,1,1,
    	1,3,4,0,0,1,1,1,
    	1,1,4,1,5,1,1,1,
    	1,3,0,0,0,1,1,1,
    	1,1,1,1,1,1,1,1,
    
    	1,1,1,1,1,1,1,1,
    	1,1,0,5,0,1,1,1,
    	1,1,0,1,4,0,0,1,
    	1,1,0,3,0,3,0,1,
    	1,0,0,4,4,0,0,1,
    	1,0,0,0,1,3,0,1,
    	1,1,1,0,0,0,1,1,
    	1,1,1,1,1,1,1,1
    };
    
  4. 画地图

    接下来,我们将设计好的地图画在控制台窗口上,也就是输出出来

    这里就用到数组的遍历知识啦

    这里我用的是switch,大家也可以用if-else

    void drawMap()
    {
    	for (int i = 0; i < 8; i++)
    	{
    		for (int j = 0; j < 8; j++)
    		{
    			switch (map[GuanKa][i][j])
    			{
    			case 0:
    				printf("  ");
    				break;
    			case 1:
    				printf("■");
    				break;
    			case 3:
    				printf("☆");
    				break;
    			case 4:
    				printf("★");
    				break;
    			case 5:
    			case 8:
    				printf("♀");
    				break;
    			case 7:
    				printf("●");
    				break;
    			}
    		}
    		printf("\n");
    	}
    }
    
  5. 确定人物的坐标

    想要对人物进行操控,我们需要确定人物的坐标,所以我封装了两个函数来确定任务的x坐标以及y坐标,因为写数组习惯了,所以用i、j来表示横纵坐标

    //寻找人物的i坐标
    int findMen_i()
    {
    	int i, j;
    	for (i = 0; i < 8; i++)
    	{
    		for (j = 0; j < 8; j++)
    		{
    			if (map[GuanKa][i][j] == 5 || map[GuanKa][i][j] == 8)
    				return i;
    		}
    	}
    }
    //寻找人物的j坐标
    int findMen_j()
    {
    	int i, j;
    	for (i = 0; i < 8; i++)
    	{
    		for (j = 0; j < 8; j++)
    		{
    			if (map[GuanKa][i][j] == 5 || map[GuanKa][i][j] == 8)
    				return j;
    		}
    	}
    }
    
  6. 游戏交互

    接下来就是本次项目的难点,所谓的移动,就是将数组中的数字进行该表,例如0变成5,就意味着人往前走了一格(因为0表示空地,5表示人)

    为了接下来的方便讲解,我给大家加上了宏替换

    #define ♀ 5
    #define ★ 4
    #define ■ 1
    #define ☆ 3
    #define ● 7
    #define 空地 0
    

    接下来我们要分类讨论:

    1. 如果前方是空地或者☆,那我们就可以顺利走过去

      if (map[GuanKa][i - 1][j] == 空地 || map[GuanKa][i - 1][j] ==)
      {
      	map[GuanKa][i - 1][j] +=;
      	map[GuanKa][i][j] -=;
      }
      
    2. 如果人前方是●,那就要判断箱子前方的东西

      1. 如果箱子前方是空地或☆,那就直接走过去,并将箱子送到目的地

        if (map[GuanKa][i - 1][j] ==|| map[GuanKa][i - 1][j] ==)
        {
        	if (map[GuanKa][i - 2][j] == 空地 || map[GuanKa][i - 2][j] ==)
        	{
        		map[GuanKa][i][j] -=;
        		map[GuanKa][i - 1][j] +=;
        		map[GuanKa][i - 2][j] +=;
        	}
        }
        

    接下来的下、左、右也是相对应的操作,考验的就是大家对数组的熟练程度,交互函数如下:

    void GameCtrl()
    {
    	int i = findMen_i();
    	int j = findMen_j();
    	int UserInt =_getch();//隐式输入,用到头文件#include<conio.h>
    	switch (UserInt)
    	{
    	case 'w':
    	case 'W':
    	case 72:
    		if (map[GuanKa][i - 1][j] == 空地 || map[GuanKa][i - 1][j] ==)
    		{
    			map[GuanKa][i - 1][j] +=;
    			map[GuanKa][i][j] -=;
    		}
    		if (map[GuanKa][i - 1][j] ==|| map[GuanKa][i - 1][j] ==)
    		{
    			if (map[GuanKa][i - 2][j] == 空地 || map[GuanKa][i - 2][j] ==)
    			{
    				map[GuanKa][i][j] -=;
    				map[GuanKa][i - 1][j] +=;
    				map[GuanKa][i - 2][j] +=;
    			}
    		}
    		break;
    	case 's':
    	case 'S':
    	case 80:
    		if (map[GuanKa][i + 1][j] == 空地 || map[GuanKa][i + 1][j] ==)
    		{
    			map[GuanKa][i + 1][j] +=;
    			map[GuanKa][i][j] -=;
    		}
    		if (map[GuanKa][i + 1][j] ==|| map[GuanKa][i + 1][j] ==)
    		{
    			if (map[GuanKa][i + 2][j] == 空地 || map[GuanKa][i + 2][j] ==)
    			{
    				map[GuanKa][i][j] -=;
    				map[GuanKa][i + 1][j] +=;
    				map[GuanKa][i + 2][j] +=;
    			}
    		}
    		break;
    	case 'a':
    	case 'A':
    	case 75:
    		if (map[GuanKa][i][j - 1] == 空地 || map[GuanKa][i][j - 1] ==)
    		{
    			map[GuanKa][i][j - 1] +=;
    			map[GuanKa][i][j] -=;
    		}
    		if (map[GuanKa][i][j - 1] ==|| map[GuanKa][i][j - 1] ==)
    		{
    			if (map[GuanKa][i][j - 2] == 空地 || map[GuanKa][i][j - 2] ==)
    			{
    				map[GuanKa][i][j] -=;
    				map[GuanKa][i][j - 1] +=;
    				map[GuanKa][i][j - 2] +=;
    			}
    		}
    		break;
    	case 'd':
    	case 'D':
    	case 77:
    		if (map[GuanKa][i][j + 1] == 空地 || map[GuanKa][i][j + 1] ==)
    		{
    			map[GuanKa][i][j + 1] +=;
    			map[GuanKa][i][j] -=;
    		}
    		if (map[GuanKa][i][j + 1] ==|| map[GuanKa][i][j + 1] ==)
    		{
    			if (map[GuanKa][i][j + 2] == 空地 || map[GuanKa][i][j + 2] ==)
    			{
    				map[GuanKa][i][j] -=;
    				map[GuanKa][i][j + 1] +=;
    				map[GuanKa][i][j + 2] +=;
    			}
    		}
    		break;
    	}
    

    PS:上面的数字则是上、下、左、右健所对应的数字编码

  7. 判断关卡

    最后呢就是简单的判断游戏关卡啦,也是简单的数组遍历

    int Gamenum()
    {
    	int flag = 1;
    	for (int i = 0; i < 8; i++)
    	{
    		for (int j = 0; j < 8; j++)
    		{
    			if (map[GuanKa][i][j] == 4)
    			{
    				flag = 0;
    				return flag;
    			}
    		}
    	}
    }
    

    最后只要把个个函数都写到main()函数中

    int main()
    {
        designWin();
        while (1)
        {
            drawMap();
            if (Gamenum())
            {
                GuanKa++;
                if (GuanKa == 3)
                {
                    printf("恭喜通关\n");
                    system("pause");
                    break;
                }
                else
                {
                    printf("按任意键进入下一关!\n");
                }
            }
            GameCtrl();
        }
        return 0;
    }
    

    这就是所有流程啦,希望大家能点点赞,更希望对大家的复习有用。
    完整的源码我会写在后面,方便大家复制使用,编译的游戏我也会上传到我的资源上提供大家下载
    PS:最后我发现宏定义的字符是不能用的,所以还是要老老实实的改成数字吧

    #include<stdio.h>
    #include<conio.h>
    #include<stdlib.h>
    //关卡
    int GuanKa = 0;
    //地图
    int map[3][8][8] ={
    	1,1,1,1,1,1,1,1,
    	1,3,4,0,0,4,3,1,
    	1,1,1,1,0,1,1,1,
    	1,1,1,1,5,1,1,1,
    	1,1,1,1,0,1,1,1,
    	1,1,1,1,0,1,1,1,
    	1,3,4,0,0,4,3,1,
    	1,1,1,1,1,1,1,1,
    
    	1,1,1,1,1,1,1,1,
    	1,1,1,1,1,1,1,1,
    	1,1,1,1,1,1,1,1,
    	1,1,1,1,1,1,1,1,
    	1,3,4,0,0,1,1,1,
    	1,1,4,1,5,1,1,1,
    	1,3,0,0,0,1,1,1,
    	1,1,1,1,1,1,1,1,
    
    	1,1,1,1,1,1,1,1,
    	1,1,0,5,0,1,1,1,
    	1,1,0,1,4,0,0,1,
    	1,1,0,3,0,3,0,1,
    	1,0,0,4,4,0,0,1,
    	1,0,0,0,1,3,0,1,
    	1,1,1,0,0,0,1,1,
    	1,1,1,1,1,1,1,1
    };
    //窗口设计
    void designWin()
    {
    	system("title 推箱子(控制台版本)");
    	system("color E0");
    	system("mode con cols=24 lines=12");
    }
    //画地图
    void drawMap()
    {
    	for (int i = 0; i < 8; i++)
    	{
    		for (int j = 0; j < 8; j++)
    		{
    			switch (map[GuanKa][i][j])
    			{
    			case 0:
    				printf("  ");
    				break;
    			case 1:
    				printf("■");
    				break;
    			case 3:
    				printf("☆");
    				break;
    			case 4:
    				printf("★");
    				break;
    			case 5:
    			case 8:
    				printf("♀");
    				break;
    			case 7:
    				printf("●");
    				break;
    			}
    		}
    		printf("\n");
    	}
    }
    //寻找人的i坐标
    int findMen_i()
    {
    	int i, j;
    	for (i = 0; i < 8; i++)
    	{
    		for (j = 0; j < 8; j++)
    		{
    			if (map[GuanKa][i][j] == 5 || map[GuanKa][i][j] == 8)
    				return i;
    		}
    	}
    }
    //寻找人的y坐标
    int findMen_j()
    {
    	int i, j;
    	for (i = 0; i < 8; i++)
    	{
    		for (j = 0; j < 8; j++)
    		{
    			if (map[GuanKa][i][j] == 5 || map[GuanKa][i][j] == 8)
    				return j;
    		}
    	}
    }
    //判断游戏关卡
    int Gamenum()
    {
    	int flag = 1;
    	for (int i = 0; i < 8; i++)
    	{
    		for (int j = 0; j < 8; j++)
    		{
    			if (map[GuanKa][i][j] == 4)
    			{
    				flag = 0;
    				return flag;
    			}
    		}
    	}
    }
    //游戏的控制操作
    void GameCtrl()
    {
    	int i = findMen_i();
    	int j = findMen_j();
    	int UserInt =_getch();
    	switch (UserInt)
    	{
    	case 'w':
    	case 'W':
    	case 72:
    		if (map[GuanKa][i - 1][j] == 0 || map[GuanKa][i - 1][j] == 3)
    		{
    			map[GuanKa][i - 1][j] += 5;
    			map[GuanKa][i][j] -= 5;
    		}
    		if (map[GuanKa][i - 1][j] == 4 || map[GuanKa][i - 1][j] == 7)
    		{
    			if (map[GuanKa][i - 2][j] == 0 || map[GuanKa][i - 2][j] == 3)
    			{
    				map[GuanKa][i][j] -= 5;
    				map[GuanKa][i - 1][j] += 1;
    				map[GuanKa][i - 2][j] += 4;
    			}
    		}
    		break;
    	case 's':
    	case 'S':
    	case 80:
    		if (map[GuanKa][i + 1][j] == 0 || map[GuanKa][i + 1][j] == 3)
    		{
    			map[GuanKa][i + 1][j] += 5;
    			map[GuanKa][i][j] -= 5;
    		}
    		if (map[GuanKa][i + 1][j] == 4 || map[GuanKa][i + 1][j] == 7)
    		{
    			if (map[GuanKa][i + 2][j] == 0 || map[GuanKa][i + 2][j] == 3)
    			{
    				map[GuanKa][i][j] -= 5;
    				map[GuanKa][i + 1][j] += 1;
    				map[GuanKa][i + 2][j] += 4;
    			}
    		}
    		break;
    	case 'a':
    	case 'A':
    	case 75:
    		if (map[GuanKa][i][j - 1] == 0 || map[GuanKa][i][j - 1] == 3)
    		{
    			map[GuanKa][i][j - 1] += 5;
    			map[GuanKa][i][j] -= 5;
    		}
    		if (map[GuanKa][i][j - 1] == 4 || map[GuanKa][i][j - 1] == 7)
    		{
    			if (map[GuanKa][i][j - 2] == 0 || map[GuanKa][i][j - 2] == 3)
    			{
    				map[GuanKa][i][j] -= 5;
    				map[GuanKa][i][j - 1] += 1;
    				map[GuanKa][i][j - 2] += 4;
    			}
    		}
    		break;
    	case 'd':
    	case 'D':
    	case 77:
    		if (map[GuanKa][i][j + 1] == 0 || map[GuanKa][i][j + 1] == 3)
    		{
    			map[GuanKa][i][j + 1] += 5;
    			map[GuanKa][i][j] -= 5;
    		}
    		if (map[GuanKa][i][j + 1] == 4 || map[GuanKa][i][j + 1] == 7)
    		{
    			if (map[GuanKa][i][j + 2] == 0 || map[GuanKa][i][j + 2] == 3)
    			{
    				map[GuanKa][i][j] -= 5;
    				map[GuanKa][i][j + 1] += 1;
    				map[GuanKa][i][j + 2] += 4;
    			}
    		}
    		break;
    	}
    	system("cls");
    }
    int main()
    {
        designWin();
        while (1)
        {
            drawMap();
            if (Gamenum())
            {
                GuanKa++;
                if (GuanKa == 3)
                {
                    printf("恭喜通关\n");
                    system("pause");
                    break;
                }
                else
                {
                    printf("按任意键进入下一关!\n");
                }
            }
            GameCtrl();
        }
        return 0;
    }
    
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值