啊哈C语言:第8章 《游戏时间到了》-----2020/4/10

从2月底开始直到前天,当我学完二维字符数组、字典序后,翻到这一章的页面时,心情是欢喜的,我想一件坚持了很久的事情做到了最后关头,都是付出的时间、精力的成果!开心心!

而一个多月坚持独立思考的成果终于要检验了!相对于之前写过的程序,一个具有可操作性可玩性的游戏,是一种更加具象化的成果体现,也更加有成就感!!

下面就是正文啦!

快速抵达

  • @[TOC](快速抵达)
  • 推 箱 子
  • ***以上是推动单个O!!***

第一个游戏:走迷宫!

使用井号‘#’制作迷宫的宫墙,将大写字母‘O’当作小球,作为玩家操作的对象,右侧宫墙有一处缺口是终点,通过W S A D四个按键分别控制小球进行上、下、左、右的移动。

玩法是进入游戏操作小球从起始位置移动到终点即为游戏胜利。

迷宫主体全部使用 ‘ # ’组成,井号在C语言中属于字符,这让我们联想到使用一行行的字符串打印迷宫。那就是多行字符,所以应该要用上一章刚学的二维字符数组来打印这个地图!

观察地图的行列,一共有20行30列,每行字符串末尾有一个结束标记,所以定义二维字符数组a为:char a[20][31] ……后面按照迷宫的结构,初始化迷宫,每行无 # 处用空格键隔开,注意每行细节不能错。
效果如下:

    char a[50][50]={"##############################","#O         #   ##   # ### ####","# ###### # # #    # # ### ####","# #   ## #   # #### # ###   ##","#   # ##  ###    #  #  ## ####","##### #     # ##### ##    ####","#   # ##### #   #   # # #    #","# # #    ## # #### ## # # ####","# # # ##      ##      # # ####","# # # ####### ## ###### #   ##","# #   ##   # ## ###### ###   #","# ###### # #####  #        # #","#        # #     ##### ### #  ","# ######## ##### # ### ### # #","#     # ## ##### ###       ###","##### # ## #      ######## # #","#     # ## ## ###        #   #","# # ###       ###### ####### #","# #    ### ##      #         #","##############################"};

注意字符串从0开始计数。之所以定义51行49列,因为方便。

而地图本身的20行30列准确定义为 a [19] [30] 中 20是行X表示20行,30是
列Y表示30列。

故理解行列为XY后,我们利用a [x] [y] 可以通过x、y来表示地图中任意位置。

故小球O 的位置是a[1][1],终点出口的位置是a[12][30]
故我们使用x=1;y=1存储小球起始位置,p=12;g=30存储终点位置

提前定义完xypg的值,还需要一个 i 来控制输出地图的for循环。

 int i,x,y,p,q;char ch;x=1;y=1;p=12;q=30;

主要操作是控制小球移动,WASD四个按键,本质其实是输入字符WASD,所以每个循环最开始都是使用输入语句getch获取输入的字符。故应当定义一个字符变量ch来存储输入的字符。

先清屏,然后输出地图。紧接着进while循环,循环条件为1死循环。

获取字符后,用if语句判断输入的是什么字符。

    for(i=0;i<=20;i++)puts(a[i]);while(1){ch=getch();//【输入语句】if(ch=='s')//【判断输入的字符是什么】

下面是最关键的两个内容,如何控制小球O规避宫墙 # ?以及小球O是怎么移动的呢?

我们之前理解过X和Y了,所以我们明白x+1,实际上就是增进一行!而y+1则是增进1列!xy代表着小球的位置,小球位于x行y列,故小球向左走,是
y-1,向右走是y+1,向上是x-1,向下是x+1!

一:检测用户输入了什么字符,进入了哪个if语句后,立刻开始检测“前方”是否为宫墙 # 若是则中断接下来的语句直接进入下个循环。该输入无效。

二:小球的移动过程是:原位置赋为空格——x或y值加1或减1——新位置赋为小球O

if(ch=='s'){if(a[x+1][y]!='#'){a[x][y]=' ';x++;  //想想为什么不是a[x+1][y]呢?a[x][y]='O';}}

知晓了一个方向的操作,那么其他方向的操作都是相通的。

if(ch=='s'){if(a[x+1][y]!='#'){a[x][y]=' ';x++;a[x][y]='O';}}if(ch=='w'){if(a[x-1][y]!='#'){a[x][y]=' ';x--;a[x][y]='O';}}if(ch=='a'){if(a[x][y-1]!='#'){a[x][y]=' ';y--;a[x][y]='O';}}if(ch=='d'){if(a[x][y+1]!='#'){a[x][y]=' ';y++;a[x][y]='O';}}

重点基本就结束啦,是不是还缺了点什么?

最后还要检测小球是否到了终点,如果是,就跳出循环并庆祝用户游戏通关!

如果不是,就重新清屏并输出一遍地图,对于已经变动过的xy值,这相当于刷新。

     system("cls");for(i=0;i<=20;i++)puts(a[i]);if(x==p&&y==q)break;while(1)printf("%s牛逼!",u);Sleep(3000);return 0;

游戏结束,开头让用户输入个名字,储存起来庆祝的时候用就好啦!
效果可喜庆了!

其实这个游戏十分简单,只要理解了二维字符数组有关位置的概念就什么都知道了。


推 箱 子


本章的第二个游戏,也是最后一个游戏,亦是本书最后一个程序

如果说走迷宫游戏是一瓶矿泉水,那么推箱子游戏就是一瓶果粒橙橙汁!

它建立在走迷宫的基础之上,所以我在详述完走迷宫后,关于推箱子的部分,就仅剖析最关键最重要的部分!

如上图所示,推箱子游戏的玩法和走迷宫相似,WASD控制小人S上下左右移动。不同的是,增加了小人S推动箱子O的节目。

char u[11];gets(u);char a[7][11]={"##########","##     ###","##O###   #","# S O  O #","# !!# O ##","##!!#   ##","##########",};

以上是地图

控制S推动O,直至四个箱子O都被推至四个感叹号处,游戏通关!

这个游戏最核心最关键的重点在于:

  1. 如何用WASD控制S上下左右移动
  2. S如何规避宫墙(S前方为墙时,推动无效)
  3. S如何推动1个箱子O
  4. S如何推动多个箱子O
  5. S推动一个或多个箱子O时,如何让箱子O规避宫墙(也就是O前方为墙时S的推动无效)

1和2在走迷宫里已经解读过了

规避的宫墙

if(nb=='w'){if(a[x-1][y]!='#')

S向上移动

                 a[x][y]=' ';x--;a[x][y]='O';

O也是字符,让S动起来的原理也是让O动起来的原理。

关键在于O和S如何协同移动!

当S移动的方向上没有O时,S仅移动自己;当S移动的方向上有O时,推动O并移动自己!

这是一个分支选项,可以用 if 分支来判断这个问题。

输入某个按键,进入某个按键的 if 的循环时,首先应当判断前方是否为宫墙。紧接着就是判断前方是否有O!

当我们单单移动S时,我们是:原位置赋空格—朝方向进1或退1—新位置赋S

我们先回顾一下规避宫墙:倘若S前方为宫墙#,S如此操作的话,宫墙 # 会被S吞掉!

这就是当我按下W后,为什么使用if(a[x-1][y]!='#')作为最外的 if 嵌套。来规避宫墙

故当我们对箱子O也是一个心思时,我们不想要S吞掉O,故操作S的步骤要放到【判断前方不是箱子O】这个语句内。

 if(a[x-1][y]!='O')

故S前方不是O才能移动,那么S和O之间进行协同移动时,应当是O先动,S再动!

所以操作顺序明确了,先O后S。

按下某个键,进入某个if内,先判断宫墙,然后进入O的操作:
1.判断O前方是否是宫墙#
2. 如果不是就操作O向前!

以上是推动单个O!!

但是多个O呢?如何推动多个箱子?

箱子数量是未知的!故我们应当要计数

我们利用for循环,统计前方是否有O,控制for循环的整型变量 j 初始值是0,当确认前方有O时为1,进入for循环,倘若前方还有O则 j+1 并继续循环,直至前方不为O时跳出循环

此时 j 的值便是S前方的小球O的数量

我们要判断最后一个小球前方是不是宫墙 # 如果是,就不能执行推动O了

if(a[x-(j+1)][y]!='#')//【最后一个球的下一位是否是墙】

以下就是完整的一段:如何操作S推动1个或多个小球

      if(nb=='w'){if(a[x-1][y]!='#'){if(a[x-1][y]=='O'){j++;while(1){if(a[x-(j+1)][y]=='O')//【统计有多少个球】j++;elsebreak;}if(a[x-(j+1)][y]!='#')//【最后一个球的下一位是否是墙】{while(j>=1)//【从后往前,逐步操作小球直到最后一个小球】{a[x-j][y]=' ';a[x-(j+1)][y]='O';j--;}}}if(a[x-1][y]!='O')//【验证了前方无小球后,移动S】{a[x][y]=' ';x--;a[x][y]='O';}}}

本章是《啊哈C语言》的最终章,其实走迷宫这个例子用的非常好,推箱子这个游戏用的更妙。做完这俩游戏,学生也算是出炉了!

走迷宫游戏,作者在书中从头到尾讲了一遍。

而对于推箱子游戏,作者在介绍完游戏玩法后,便宣布本书内容的结束!

这是最骚的!

纪磊老师将这最后的程序交给了读者,他引导读者依靠自己的实力完成这个游戏,只有依靠独立思考解决的问题,才是最有成就感的!也才能激起对编程的兴趣!

全书中纪磊老师一直在引导读者培养独立思考的意识!直到最后,也映射着编程之路都是独立思考为先!

。。。码了两个小时有点累,感谢纪磊老师贡献的这本书!纪念我在这本书中,每一个逻辑挑战中,成功运行程序时,所收获的纯粹的快乐!

解析《啊哈C》--最终章:用C语言制作走迷宫和推箱子的小游戏相关推荐

  1. C语言学习:简单的小游戏 走迷宫、推箱子

    目录 一.走迷宫分析: 走迷宫代码展示 二.推箱子分析: 推箱子代码展示 一.走迷宫分析: 数据分析:         1.定义二维字符数组作为迷宫地图         2.定义变量记录角色的位置 x ...

  2. 使用Dart/Flutter语言开发的命令行文字RPG类型小游戏

    使用Dart/Flutter语言开发的命令行文字RPG类型小游戏 项目源码:https://gitee.com/FantasyWind/word_game 介绍 项目背景 本项目为使用Dart/Flu ...

  3. C语言100行代码实现推箱子

    1 C语言100行代码实现推箱子 1.1 概述  C语言是很好入门编程的一个语言,它拥有着很好的移植性,基本上所有的平台都支持C语言编程.有些C语言基础的你,是不是也很想做一个项目来检验一下自己的学习 ...

  4. c语言 老鼠乘法,c语言-老鼠走迷宫逐步理解

    c语言实现老鼠走迷宫 在没有智能手机的时代,不少人玩游戏会玩老鼠走迷宫这样的闯关游戏.每一关有着不同的地图场景,可能还会充斥着各种障碍. 老鼠走迷宫是经典的递回求解的算法题 我们用二维数组表示迷宫场景 ...

  5. 【c语言】 我使用c语言基础做了一个老少皆宜的”国民小游戏(三字棋)“

    C语言实现三字棋小游戏 前言 游戏效果 游戏实现 前言 本三字棋小游戏是依靠二维数组为核心来实现的,可以更加好理解掌握c语言数组的概念知识,依靠做小游戏项目,把学到了知识在输出出来加已巩固,最后有源代 ...

  6. C语言--实现(三)井子棋小游戏(基础版)

    相信大家在生活中肯定知道和了解五子棋的玩法,三子棋的玩法和五子棋一样,当有三个一样的"棋子"连成一条线,不管是横竖斜,谁先完成这个条件,谁就获胜. 那大家有没有想过用编码的形式怎么 ...

  7. C语言实现《别碰白块》小游戏!全部代码+思路注释

    今天我们将用C语言实现一个小球跳跃躲避方块的游戏. 就像闯关游戏一样,小球闯关类游戏是休闲游戏的一种,玩家在游戏中需要控制各种不同的小球展开不同的挑战,尽情的闯过重重的关卡,努力的操作小球躲避障碍物以 ...

  8. C语言-老鼠走迷宫(深度寻路算法)

    老鼠走迷宫-c语言(基于深度优先的寻路算法) 这个是学校的课设,刚开始有点头疼,但是感觉越做越有意思了,于是就有如下代码,可能相较于大佬还有差距,但是这是我目前所能做的最优的程序了吧! 话不多说,说一 ...

  9. C语言老鼠走迷宫(单路径)算法详细讲解

    最近在学习C语言的一些经典算法,其中遇到了一点困难,导致卡进度了.琢磨了很久,在绘制流程图时,突然灵感大开理解了,老鼠走迷宫算法的奇妙.所以写了这个,一来是方便以后右和我类似的同学自学时,遇到这个问题 ...

  10. C语言 老鼠走迷宫详解6,算法: Mazing-老鼠走迷宫

    说明 老鼠走迷宫是递回求解的基本题型.我们在二维阵列中使用 2 表示迷宫墙壁,使用 1 来表示老鼠的行走路径,尝试以程式求由入口至出口的路径. 解法 老鼠可走上,下,左,右四个方向.入口一般在左上,出 ...

最新文章

  1. 前滴滴出行产品经理刘飞:写给产品经理的说明书(上)
  2. C++Odd Even Sort奇偶排序的实现算法(附完整源码)
  3. iOS如何判断当前网络的运营商
  4. [Sharepoint2007对象模型]第三回:Web应用程序(SPWebApplication)
  5. 360天擎默认卸载密码_用好360(四)
  6. structs 1.x 学习
  7. 数据可视化:CSV格式,JSON格式
  8. caxa计算机编程,CAXA软件编程实例1
  9. 泰勒公式推导及多元泰勒展开式
  10. 51单片机学习入门(三):串口
  11. Android中的英文翻译
  12. 年度案例大数据盘点之Spark篇
  13. java mc和java jdk_JDK、JRE、JVM三者间的关系
  14. Java自定义变换产生摘要数据
  15. OpenCV开发笔记(四十九):红胖子8分钟带你深入了解轮廓识别(图文并茂+浅显易懂+程序源码)
  16. 计算机网络与通信课程感想3000字,计算机网络与通信技术课程学习心得.doc
  17. 深夜聊聊Bufferbloat以及TCP BBR
  18. 专访 | wuhan2020拾柴者王欣:开源的世界里没有老师
  19. Linux工具学习之【git】
  20. 按键精灵入门指引——应用导向学习

热门文章

  1. 2124. OIBH杯第三次模拟赛(普及组)Problem 1 : tictac 立体井字棋
  2. Java调用WebService接口
  3. 求助:Flash Builder 4.7早上开机后提示“未能创建视图: 插件“com.adobe.flexbuilder.as.editor”无法实例化
  4. 简单好用的每日任务管理小工具-sticker桌面便签
  5. 全球及中国企业级硬盘行业消费量调研及投资战略研究报告2022-2028年
  6. FL Studio 20.9水果编曲软件中文汉化补丁包
  7. 这些年的项目管理心得
  8. 【java毕业设计】基于javaEE+Mybatis的WEB仓库管理系统设计与实现(毕业论文+程序源码)——仓库管理系统
  9. 基于 SpringBoot + Mybatis 的个人在线音乐平台
  10. 消息中间件RabbitMQ 初探