学习心得之——c++用类实现基于控制台的推箱子小游戏

这篇博客分享了作者使用面向对象编程思想设计推箱子小游戏的心得。通过设立Board和Object两个类,详细阐述了游戏逻辑的实现,包括对象的状态标记、移动规则以及胜利条件的判断。文章最后提供了部分代码,并期待读者的交流和指正。
摘要由CSDN通过智能技术生成

第一次发表博客有点紧张啦!那么今天我们就来讨论一下面向对象中对推箱子小游戏的一个思考。

以下来源于自己的一个作业,可能想法和分析不够完善,如果您有其他想法,欢迎批评交流。

    在推箱子的小游戏中,我设置了两个类Board类和Object类。Board类用提供生成游戏界面和进行游戏的方法,而Object类则是地图上的不同物品。

    在写这个游戏的时候,我发现这个游戏清晰的由两部分组成,第一是由棋盘,第二是由物品(包括人,箱子,墙,空白),而棋盘上包含了这些东西。因此,我可以暂且设计两个类BoardObject。再考虑棋盘,游戏中只需要一个棋盘就行了,每局地图的不同我们可以用指针指向不同的物品来形成。然后考虑Object类,看能否派生出子类。由于该游戏只需要控制人的移动(箱子的移动是由于人的移动产生的),所以我们只需要一个移动以及判断移动的函数。再加上这些Object除了名字以外并没有区别,所以并不需要派生出子类,我们仅仅需要在类中添加一个flag标记Object的种类即可。然后考虑如何进行移动,由于棋盘上Object的种类和数量是既定的,所以我们只需要固定数量的对象,然后每次改变棋盘每个位置指向的对象即可。

    然后我们再来找Object有没有其他共性。我们可以发现,由于空白(space)和目的地都是可以走人(以及箱子的),则我们可以再用一个bool变量state标记来区别他们,将目的地看成是一个特殊的space(或者是object,后面你会发现为什么这样说)。若为true,则它为目的地。到了这一步以后,我们很自然的发现,我们同样可以用state来区分箱子是否已经在目的地里了,因此判断方法变得更为简洁。

    在前面说到了,我们可以交换两个pointer指向的对象来实现移动,那么如果人与目的地发生交换或者箱子与目的地发生交换时,指针指向改变,那不是目的地的位置也移动了吗?和前面提到的一样,由于棋盘上的object是既定的,那么state标记为trueobject的数量也是固定的,我们可以每次成功移动都先交换objectstate,在进行指针的交换,那么目的地的位置就是固定的。到了这里,你会发现目的地其实就是statetrueobject(因为墙不发生移动,所以不参与到state的交换),我们每次交换state的过程也就是保证目的地固定的过程(即棋盘上某点指向的对象的state总为true)。

    思考完怎么移动后,我们来考虑移动的规则(因为你只有知道方式,才能去思考该方式对应的规则)。人的每次移动,无非就是三种情况:遇到space(空白),wall(墙)和box(箱子)(按照上述的思路,我们已经认为目的地是特殊的Object,所以不考虑在内),遇到空白很简单,直接按上述移动方式交换;遇到墙不移动;遇到箱子时,因为箱子可以移动(但不可以自发移动),那么此时我们可以将箱子视为人再用人的判断规则去判断(唯一的区别就是如果此时前面也为箱子那么不移动)。我们先判断箱子,若箱子可移动则说明人也可移动,那么先移动箱子再移动人。

    解决了移动方法和移动规则后,只剩下判断是否胜利或者是否失败。这就很简单了:若每个箱子都在目的地上(及每个箱子的state均为true)则胜利;若任意一个箱子的任意两边都是墙,则肯定失败。


    下面附上代码。

 
/****************************Author:wangyiheng*************************/
/****************************tuixiangzi***********************************/
/*****************************2018.7.6***********************************/

#include <algorithm>
#include <conio.h>
#include <iostream>
#include <vector>
#include <Windows.h>
#include <cstdlib>
#include <cstdio>
#define KEY_UP 72
#define KEY_DOWN 80
#define KEY_LEFT 75
#define KEY_RIGHT 77
#define MIN_LEVEL 1
#define MAX_LEVEL 4
using namespace std ;
void   SelectColor ( int iColor){                  //颜色函数
    HANDLE  hConsole =
         GetStdHandle ((STD_OUTPUT_HANDLE)); //得到控制台输出设备的句柄
     SetConsoleTextAttribute (hConsole, iColor); //设置控制台设备的属性
}
int aiMap1[ 14 ][ 16 ] = {
    { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{ 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 },
{ 0 , 0 , 0 , 0 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 1 , 0 , 0 , 0 , 0 },
{ 0 , 0 , 0 , 1 , 1 , 3 , 4 , 2 , 1 , 1 , 2 , 1 , 1 , 0 , 0 , 0 },
{ 0 , 0 , 0 , 1 , 2 , 3 , 4 , 5 , 4 , 2 , 2 , 3 , 1 , 0 , 0 , 0 },
{ 0 , 0 , 0 , 1 , 2 , 3 , 2 , 4 , 2 , 4 , 3 , 1 , 1 , 0 , 0 , 0 },
{ 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 2 , 2 , 1 , 0 , 0 , 0 , 0 },
{ 0 , 0
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值