这篇文章是用C语言做了一个推箱子小游戏,实现起来比较简单,和大家一起回味一下童年捧着按键机玩推箱子的日子!文末附带万字源码!

目录

一、写在前面

二、设计思路

1.主界面函数介绍

2.选择界面函数

3.选择函数

4.游戏步骤重播函数

5.键盘键位设置函数

6.游戏界面函数

7.向左函数

8.向右函数

9.向下函数

10.向上函数

11.通关函数

12.最佳记录函数

13.入队列函数

14.出队列函数

三、最后总结

四、完整源码


Hello,你好呀,我是灰小猿!一个超会写bug的程序猿!

还记得我们曾经的那个推箱子吗,记得小时候家里只有按键的诺基亚的时候,推箱子、贪吃蛇都是我天天最经常玩的游戏,然后最近正好有小伙伴问我有没有做过相关的开发,所以今天在这里跟大家一个用C语言实现的简单推箱子的小游戏,带着大家一起回味一下童年呀!【点赞收藏,上车坐好!】

一、写在前面

推箱子游戏程序的设计为分别设置各类型函数类,设定推箱子房子布局的数据结构二维数组,以及记录最短步骤数目以及最好成绩的二维数组,通过函数对房子进行布局,定义数据结构队列类,并设置公有成员函数和私有成员函数。

与此同时,我运用C++中的派生类相关知识设定相同类名以及不同类名的对象,用于构造推箱子游戏的分布函数,设定数据结构出队和入队函数,同时设计以箱子为对象,依据于人的横纵坐标位置的函数,设计基于游戏数据界面的,开始界面通关提示、游戏时选项提示、玩游戏时界面显示地图左右上下方向通关提示以及排行榜等。

同时,根据游戏要求设定输出游戏主界面和游戏关卡选择界面,用于我们的操作,构造将游戏步骤进行重新播放的函数,根据以上以及各类型详细函数设定主函数并进行操作运行游戏,以此来达到使游戏平稳运行的要求。除上述内容之外,在制作游戏时,我还运用了多元分组的构造模式,使得程序内容简单易懂,任何有程序基础的人都可以进行交流学习。接下来我跟大家分享一下主要的模块设计,最后附上完整源码供大家参考!小伙伴们别忘了三连支持,收藏学习呀!

二、设计思路

在程序中我利用类与对象完成了对游戏地图的设计,以及对于关卡的选择等众多功能。并且利用数据结构中的理念,实现了对人与箱子的定位和时间步数等功能的实现。总体来说,该程序涵盖了我们所学习的相关知识,虽然游戏有点简单,但是其中内容却涉猎甚广,

推箱子游戏的设计目的,在于合理有效运用数据结构栈与队列,以及C++中的类与对象以及派生类的相关知识,将游戏中的各个环节拆分开来,运用派生类将各个环节串联起来,达到实现程序稳定运行的目的。以下是总体设计图:

1.主界面函数介绍

在box下的begin派生类中,我们的主要功能是输出游戏界面,在该函数中,我们对游戏内部功能进行了详细介绍,其中包括游戏玩法和操作指令,与此同时,对游戏主界面进行了详细优化,在该函数中,在游戏功能的介绍上,我们分别使用星星,圆圈和特殊符号代表箱子,目标位置和推箱子的小人物,我们调用进行观察,选择的函数来完成游戏,玩家对游戏关卡的选择,并且在操作指令上对进行撤销选择和退出游戏进行了详细介绍,方便玩家更好的游戏体验,

2.选择界面函数

在游戏选择界面中,我们采用双五角星的界面图形动画,在中间设定关卡选项,选择选项中有1到4个关卡可供选择,在用户进行关卡选择以后,可将选择关卡的序号进行返回到函数之中,函数对玩家选择的序号进行识别,一次对1到4个关卡进行选择判断,然后在程序中跳转到相应的函数界面,供玩家进行游戏,倘若玩家输入的序号不在1到4之间,则系统会自动提示输入错误,请重新输入的字样。

3.选择函数

在派生类选择函数中,我们设定了重播,主界面,最好记录,退出四个选项,当玩家游戏无法通关时,可按键盘上的c键来跳转出选择界面进行玩家的选择,和选择关卡的设定一样,我们在玩家反馈过来的1到4四个序号进行判断,然后依次作出重播放,返回主界面,跳转出最好记录,退出系统四个功能。

4.游戏步骤重播函数

在游戏玩一下通关以后,我们会设定一个游戏步骤重播函数,在该函数执行以后,玩家可以观看由程序对玩家步骤进行记录而设定好的游戏步骤重播,在该函数中,我们主要是依据玩家进行上下左右方向键操作,对其方向的使用进行存储到数组之中,当玩家选择进行游戏步骤重播时,我们可将该二维数组中的数据释放出来,达到将游戏步骤进行重新播放的效果。

5.键盘键位设置函数

在游戏开始以后,有玩家可通过上下左右方向键来进行游戏中小人的控制操作,而游戏中小人控制操作的方向键,我们所依据的是Ascii码键盘键位,其中左键为75号,右键为77号上键为72号,下键为80号,在开始游戏以后,玩家对按键进行操作,与此同时,我们在内部函数中会对75,77,72,84个数进行记忆,当返回值为四个数中的其中之一时,我们会将该记录存入函数之中,并且在游戏步骤上加1,其中我们还设定键盘上的c键为26,当选择c键时可进行重新选择操作,在该重新选择以后,我们设置返回主界面和退出游戏两个选项,可供玩家进行选择。

6.游戏界面函数

在游戏界面函数中,我们设定了游戏的各种形状来代表我们游戏内部的不同内容,分别以‘■’代表墙体,‘○’代表目标位置,‘★’代表箱子,‘♀’代表人,和‘㊣’代表箱子在目标位置上的效果展示,与此同时,在界面的最下边,我们增加有撤销(Ctrl+z),选择(c)和游戏步数记录选项,可实时记录玩家进行的游戏步骤,效果图如下:

7.向左函数

在游戏按键中的向左函数中,我们有进行多项判断,我们所依据的是小人向左位置的地址进行返回值,如果我们检测到该数组内部的值为零时进行判断,我们将记录小人左侧函数的数组赋值给4,然后进行判断,同时,如果该数组上元数等于2,我们要使人员移动到目标位置上,同时恢复目标位置的函数,使其恢复到原来位置,同时对该位置进行标记,记录人员经过该位置,方便我们进行重播函数的操作,

如果说我们检测到该函数内的值为零,或者是3的话,我们可以执行将箱子推到空白位置上的函数操作,如果该函数为5或者为1的话,我们要执行的是将箱子从目标位置上推出的函数操作,如果该函数值为3且为2,我们要执行的是将箱子推到目标位置上的函数操作,且人在目标位置上用来抵消仍不动的情况。

8.向右函数

我们在执行向右函数时,所依据的原理和向左函数类似,我们对右键的地址来进行判断且返回值,如果说函数值等于零,我们则进行以下操作,如果说返回值等于2,我们要将人员移到目标位置之上,同时恢复目标位置及原来的状态标志,该位置记录仍在该位置上的地址,方便我们进行重播操作,否则如果说该函数值为3且为0的话,我们将箱子推到空白位置上,如果按函数值为5或者不等于1的话,我们要将箱子从目标位置上推出,移动到下一个目标位置,且还是目标位置,如果该函数值为3且为2的话,要将箱子推到目标位置上。

9.向下函数

在向下函数中,我们对向下按键的地址进行返回,并且读取判断,如果说数组记录中为2,要将人要移到目标位置上,同时恢复目标位置的原来状态标志,该位置记录仍在目标位置上的地址,方便我们进行重播操作,如果该数组的值为3且等于0,将箱子推到空白位置之上,将箱子从标位置上推出,如果下一个位置还是目标位置,我们将该值为5或4,如果下一个位置是空白,之后我们将该数组值赋为3且为4,如果该数组的值为3且为2,我们要将箱子推到目标位置上,并且如果说该数组值为5的话,将箱子推到目标位置之上,仍在目标位置上,否则如果人不在目标位置之上的话,我们将该函数值赋值为0,同时抵消人不动的情况。

10.向上函数

在执行向上函数时,我们对应函数值返回的地址值进行判断,如果该数组值为0,则我们将该数组值赋值为4,否则如果说该函数值为2,我们要说明人在目标位置之上,同时恢复目标位置的原来状态标志,该位置记录人在目标位置上的地址,方便进行重播操作,如果该数组位置为3且为0,我们将箱子推到空白位置之上,否则如果数组值为5或不等于1,要将箱子从目标位置上推出,如果下一个位置还是目标位置,我们则将输出值赋值为5,将另一个数组赋值为4,如果该数组赋值为3,且另一个数组数值为2,要将箱子推到目标位置上,并且将该值赋值为5,将箱子在目标位置上,仍在目标位置之上,若人在目标位直之上,则抵调整波动的情况。

11.通关函数

在玩家进行通关以后,我们系统会自动识别,并且返回一个通关界面,该界面我们会对玩家进行询问的操作,该操作分为四步,继续,观看通关视频过程,查看最好记录,退出界面,返回主界面,当玩家进行1到4的选择以后,我们会返回相应的操作,并且可以在按任意键回到主页面。

12.最佳记录函数

在最佳记录函数中,我们设定一个值来记录游戏玩家的步数,每当游戏玩家对按键进行操作一次,则该函数定义的变量则加一次,当我们读取到该玩家通关以后,将应该数据进行保存,当我们检测到有最好记录时,即该步数为最小值时,确定为最佳记录。

13.入队列函数

在入队列函数中,主要运用数据结构的队列知识,设置入队列函数,并定义指针变量指向头结点,相关数值在入队列以后,会自动的将数值赋值到队头位置,并且循环使searchp节点不为空,然后按照次序,将数值依次从队头向对尾进行赋值运算,

14.出队列函数

在出队列操作中,主要依据队列相关规则,设置指针变量,将队头元素赋值给指针,同时在进行if语句的判断,将for循环之中如i的数值小于正方形的边长,则使用队头接收searchp的数值,与此同时,让count的数值不断的进行减减操作,

三、最后总结

截止到这里,推箱子游戏的基本功能就完成了,最后把它总结一下,我们设计的推箱子小游戏,合理的使用了数据结构中队列的知识点,在使用这些知识点的时候,我们也对游戏过程进行了详细的优化,通过这次推箱子游戏的设计,大家应该能学到队列在实际应用中的操作,同时这也很好地让大家对数据结构的知识点进行了一个巩固和复习,也从中学到了游戏界面,布局的构造思想和构造方法,以及键盘与代码之间的有效联系,所以这个设计能够学习到的东西还是很多的了。

我把完整源码放在了最后,小伙伴们可以自己修改地图界面、设定关卡。

四、完整源码

//推箱子小游戏
#include<iostream>
#include<windows.h>
#include<stdlib.h>
#include<conio.h>
#include<fstream>
#include<iomanip>
using namespace std;
const int roomsize = 9;//设计房子内部为正方形,边长为9
int map[roomsize + 2][roomsize + 2]; //推箱子房子布局的数据结构:二维数组
int followmap[1000];
int data;//记录最短步骤数目
int times = 0;
int array[2] = { 100, 100 }; //记录最好成绩
char String[30] = "开始比赛...........";
//以下为前几轮游戏房子中细节布局的数据结构:二维数组的实际内容
int map1[roomsize + 2][roomsize + 2] =
{   //0,1,2,3,4,5,6,7,8,9,10{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, //0{ -1, 0, 0, 0, 0, 1, 1, 1, 1, 1, -1 },          //1{ -1, 0, 0, 0, 0, 1, 2, 0, 0, 1, -1 },          //2{ -1, 1, 1, 1, 0, 1, 0, 3, 0, 1, -1 },          //3{ -1, 1, 2, 1, 0, 1, 0, 0, 0, 1, -1 },          //4{ -1, 1, 2, 1, 0, 1, 0, 3, 0, 1, -1 },          //5{ -1, 1, 2, 1, 1, 1, 0, 3, 0, 1, -1 },          //6{ -1, 1, 0, 0, 0, 0, 3, 4, 0, 1, -1 },          //7{ -1, 1, 0, 0, 1, 0, 0, 0, 0, 1, -1 },          //8{ -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1 },          //9{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } //10
};
int map2[roomsize + 2][roomsize + 2] =
{   //0,1,2,3,4,5,6,7,8,9,10{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },//0{ -1, 0, 1, 1, 1, 1, 1, 0, 0, -1, -1 },        //1{ -1, 0, 1, 4, 0, 0, 1, 1, 0, -1, -1 },        //2{ -1, 0, 1, 0, 3, 0, 0, 1, 0, -1, -1 },        //3{ -1, 1, 1, 1, 0, 1, 0, 1, 1, -1, -1 },        //4{ -1, 1, 2, 1, 0, 1, 0, 0, 1, -1, -1 },        //5{ -1, 1, 2, 3, 0, 0, 1, 0, 1, -1, -1 },        //6{ -1, 1, 2, 0, 0, 0, 3, 0, 1, -1, -1 },        //7{ -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1 },        //8{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },//9{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } //10
};
int map3[roomsize + 2][roomsize + 2] =
{   //0,1,2,3,4,5,6,7,8,9,10{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },//0{ -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1 },        //1{ -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1 },        //2{ -1, 1, 1, 0, 0, 0, 0, 1, 1, -1, -1 },        //36{ -1, 1, 0, 3, 0, 3, 3, 0, 1, -1, -1 },        //4{ -1, 1, 2, 2, 2, 2, 2, 2, 1, -1, -1 },        //5{ -1, 1, 0, 3, 3, 0, 3, 0, 1, -1, -1 },        //6{ -1, 1, 1, 1, 0, 1, 1, 1, 1, -1, -1 },        //7{ -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1 },        //8{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },//9{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } //10
};
int map4[roomsize + 2][roomsize + 2] =
{   //0,1,2,3,4,5,6,7,8,9,10{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },//0{ -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1 },        //1{ -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, -1 },        //2{ -1, 1, 0, 3, 0, 1, 1, 1, 1, -1, -1 },        //3{ -1, 1, 0, 0, 0, 2, 2, 1, 1, -1, -1 },        //4{ -1, 1, 0, 0, 1, 2, 1, 1, 1, -1, -1 },        //5{ -1, 1, 0, 3, 0, 4, 3, 0, 1, -1, -1 },        //6{ -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, -1 },        //7{ -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1 },        //8{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },//9{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } //10
};class node
{
public:int data[1000];int positionL;//位置左int positionH;//位置node *next;};
/*
*队列
*/
class linkqueue//定义队列类
{
private://定义私有数据成员node *front;int count;
public://定义公有数据成员linkqueue();~linkqueue();void insert(int item[]);//定义公有成员函数void out(int item[]);void clearqueue(void);int getcount();
};
linkqueue::linkqueue()//定义相同类名的派生类
{front = new node;//将定义的变量赋值给队头front->next = NULL;//队头指向空节点count = 0;
}
linkqueue::~linkqueue()
{clearqueue();count = 0;
}void linkqueue::out(int item[])//出队列
{node *searchp;searchp = front->next;//将队头元素赋值给指针for (int i = 0; i<(roomsize + 2)*(roomsize + 2); i++)//使i的值小于正方形滴边长item[i] = searchp->data[i];front->next = searchp->next;//队头接收searchpdelete searchp;count--;
}void linkqueue::insert(int item[])//进队
{node *newnodep = new node, *searchp = front; while (searchp->next != NULL)//循环使searchp节点不为空searchp = searchp->next;for (int i = 0; i<121; i++)newnodep->data[i] = item[i];newnodep->next = searchp->next;searchp->next = newnodep;count++;
}
void linkqueue::clearqueue(void)//定义依据于linkequeue的派生类
{if (front->next == NULL)//若头结点为空。则返回return;while (front->next != NULL)//若队头结点不为空,则将头结点赋值给指针{node *searchp;searchp = front->next;front->next = searchp->next;delete searchp;}count = 0;
}
int linkqueue::getcount()//定义依据于linkequeue的派生类用来返回count滴值
{return count;
}
/*
*栈
*/
class  seqstack//定义类
{
public://设定公有成员函数seqstack();~seqstack();void clearseqstack(void);void push(int item[], int &line, int &lie);//括号内为只接收变量滴地址void pop(int item[], int &line, int &lie);
private:node *top;
};
seqstack::seqstack()
{top = new node;top->next = NULL;
}
seqstack::~seqstack()
{}void seqstack::push(int item[], int &line, int &lie)//定义以seqtack类滴push(推)的类,用来记录推动箱子的地址和位置
{node *newnodep, *searchp = top;newnodep = new node;for (int i = 0; i<(roomsize + 2)*(roomsize + 2); i++)newnodep->data[i] = item[i];newnodep->positionH = line;//将地址进行返回newnodep->positionL = lie;//将地址进行返回newnodep->next = searchp->next;searchp->next = newnodep;}void seqstack::pop(int item[], int &line, int &lie)
{node *newnodep, *searchp = top;if (searchp->next != NULL){newnodep = top->next;for (int i = 0; i<(roomsize + 2)*(roomsize + 2); i++)item[i] = newnodep->data[i];line = newnodep->positionH;lie = newnodep->positionL;top->next = newnodep->next;delete newnodep;}
}
void seqstack::clearseqstack(void)
{if (top->next == NULL)return;while (top->next != NULL){node *searchp;searchp = top->next;top->next = searchp->next;delete searchp;}
}//对象:箱子
class box//记录人位置滴函数
{int positionh;//人的位置纵坐标int positionl;//人的位置横坐标int flag;//标志位,记录人在目标位置上int gate;//这个变量是记录关数int count;//这个变量是记录步数seqstack st;linkqueue linkqu;
public:box();void begin();//开始界面void choose_gate();//选关提示void choose();//游戏时c选项的提示void replay();//重玩void playing();//玩游戏时界面void display();//显示地图void left();//左方向void right();//右方向void down();//下方向void up();//上方向void test_flag();//过关提示void record();//这段函数为排行榜void travers();void returnpush();void returninseart();//void random();//这段函数为随机生成室内布局,暂时没有提供
};box::box()
{positionh = 0;positionl = 0;flag = 0;count = 0;gate = 0;
}
void box::begin()
{system("color 17");/*******************************输出游戏主界面***********************************/cout << "   ╭────────────-─────────────────-──╮" << endl <<//1                                                                       "<<endl<<//1"  │                                                                  │" << endl <<//2"  │              ★☆★       推箱子游戏        ★☆★               │" << endl <<//3"  │★☆★★☆★★☆★★☆★★☆★★☆★★☆★★☆★★☆★★☆★★☆★│" << endl <<//4"  │                            游戏介绍                              │" << endl <<//5"  │                                                                  │" << endl <<//6"  │怎么玩这个游戏呢?我来介绍一下:这是小人人(♀)小星星就是箱子啦(★)│" << endl <<//7"  │你要把星星放在这个地方喔(○),等到有了㊣.你就赢咯!快来挑战吧!!   │" << endl <<//8"  │                                                                  │" << endl <<//9"  │                           操作指令                               │" << endl <<//10"  │                                                                  │" << endl <<//11"  │使用方向键控制哦!'Ctrl+z' 用来撤销,'c'用来选择 'Esc'退出游戏!  │" << endl <<//12"  │                                                                  │" << endl <<//13"  │                                                                  │" << endl <<//14"  ╰─────────────────────────────────╯" << endl; //15choose_gate();//选择关数cout << String << endl;Sleep(1000);system("cls");linkqu.clearqueue();st.clearseqstack();playing();
}
void box::choose_gate()
{//system("color 10");int j, k;/*******************************输出游戏关卡选择界面***********************************/cout << "              ★               ╭────╮            ★      " << endl<< "             ★★             │ 关卡选择 │          ★★      " << endl<< "            ★  ★            │ 1.first  │         ★  ★        " << endl<< "       ★★★    ★★★       │ 2.scend  │    ★★★    ★★★     " <<endl<< "        ★          ★        │ 3.third  │     ★          ★        " << endl<< "         ★        ★         │ 4.forth  │      ★        ★          " << endl<< "          ★  ★  ★          │★★★★  │       ★  ★  ★            " << endl<< "          ★★  ★★          │  ★★★★│       ★★  ★★         " << endl<< "          ★      ★          ╰─────╯       ★      ★         " << endl<<endl<<endl;cout << "请选择关卡哟:";cin >> gate;do{switch (gate){case 1:for (j = 0; j<roomsize + 2; j++)//此处 j控制行,k控制列for (k = 0; k<roomsize + 2; k++)map[j][k] = map1[j][k];positionh = 7; positionl = 7;break;case 2:for (j = 0; j<roomsize + 2; j++)for (k = 0; k<roomsize + 2; k++)map[j][k] = map2[j][k];positionh = 2; positionl = 3;break;case 3:for (j = 0; j<roomsize + 2; j++)for (k = 0; k<roomsize + 2; k++)map[j][k] = map3[j][k];positionh =7, positionl = 5;break;case 4:for (j = 0; j<roomsize + 2; j++)for (k = 0; k<roomsize + 2; k++)map[j][k] = map4[j][k];positionh = 6, positionl = 5;break;default:cout << "输入错误啦^_^请重新输入哟@v@!";cin >> gate;}} while (gate>4);
}
void box::choose()//选项
{int choice;cout << " ╭────────╮" << endl<< " │1. 重播         │" << endl<< " │2. 主界面       │" << endl<< " │3. 最好的记录   │" << endl<< " │4. 退出         │" << endl<< " ╰────────╯" << endl;cin >> choice;switch (choice){case 1:system("cls");replay();break;case 2:system("cls");begin();break;case 3:record();system("cls");playing();break;case 4:exit(0);}
}
void box::replay()//将游戏步骤进行重播
{int j, k;count = 0;flag = 0;st.clearseqstack();linkqu.clearqueue();do{switch (gate){case 1:for (j = 0; j<roomsize + 2; j++)for (k = 0; k<roomsize + 2; k++)map[j][k] = map1[j][k];positionh = 7; positionl = 7;break;case 2:for (j = 0; j<roomsize + 2; j++)for (k = 0; k<roomsize + 2; k++)map[j][k] = map2[j][k];positionh = 2; positionl = 3;break;case 3:for (j = 0; j<roomsize + 2; j++)for (k = 0; k<roomsize + 2; k++)map[j][k] = map3[j][k];positionh = positionl = 4;break;case 4:for (j = 0; j<roomsize + 2; j++)for (k = 0; k<roomsize + 2; k++)map[j][k] = map4[j][k];positionh = 6, positionl = 5;break;}} while (gate>4);playing();
}
void box::playing()//Ascii码键盘键位:左为75 右为77 上为72 下为80
{int choice, i, l, r, item[1000],j,k;count = 0;cout << "游戏开始";while (1){display();switch (_getch()){case 72:returninseart();returnpush();up();count++;break;case 80:returninseart();returnpush();down();count++;break;case 75:returninseart();returnpush();left();count++;break;case 77:returninseart();returnpush();right();count++;break;//case 'x':case 26:i = 0;system("cls");st.pop(item, l, r);for (j = 0; j<roomsize + 2; j++)for (k = 0; k<roomsize + 2; k++){map[j][k] = item[i];i++;}positionl = r; positionh = l;display();break;case 'c':case 'C':choose();break;//case 'q':case 27:cout << " ╭──────────────╮" << endl<< " │请给你选择喔:              │" << endl<< " │   1. 我要返回主界面        │" << endl<< " │   2. 我不玩了退出游戏      │" << endl<< " ╰──────────────╯" << endl;cin >> choice;switch (choice){case 1:count = 0;Sleep(500);system("cls");begin();break;case 2:exit(0);}default:break;}system("cls");}
}
void box::display()
{cout << endl << endl << endl << endl << endl << endl;for (int i = 1; i <= roomsize; i++){cout << setw(30);for (int j = 1; j <= roomsize; j++){if (map[i][j] == 0) cout << "  ";if (map[i][j] == 1) cout << "■";//墙if (map[i][j] == 2) cout << "○";//目标位置if (map[i][j] == 3) cout << "★";//箱子if (map[i][j] == 4) cout << "♀";//人if (map[i][j] == 5) cout << "㊣";//箱子在目标位置上}cout << endl;}cout << endl << endl;cout << "撤销(Ctrl+z)★★★" << "选择(c)★★★" << "游戏步数:" << count << endl;
}
void box::left()//向左函数
{if (map[positionh][positionl - 1] == 0){map[positionh][positionl - 1] = 4;if (flag == 1){map[positionh][positionl] = 2;  flag = 0;}elsemap[positionh][positionl] = 0;positionl--;}else if (map[positionh][positionl - 1] == 2)//人要到目标位置上{map[positionh][positionl - 1] = 4;if (flag == 1)map[positionh][positionl] = 2;//恢复目标位置else{map[positionh][positionl] = 0;//恢复原来的状态flag = 1;//标志位,记录人在目标位置上}positionl--;}else if (map[positionh][positionl - 1] == 3 && map[positionh][positionl - 2] == 0)//将箱子推到空白位置上{map[positionh][positionl - 2] = 3;map[positionh][positionl - 1] = 4;if (flag == 1){map[positionh][positionl] = 2; flag = 0;}elsemap[positionh][positionl] = 0;positionl--;}else if (map[positionh][positionl - 1] == 5 && map[positionh][positionl - 2] != 1)//要将箱子从目标位置上推出{if (map[positionh][positionl - 2] == 2)//下一个位置还是目标位置{map[positionh][positionl - 2] = 5;map[positionh][positionl - 1] = 4;if (flag == 1)map[positionh][positionl] = 2;else{map[positionh][positionl] = 0; flag = 1;}}else if (map[positionh][positionl - 2] == 0)//下一个位置是空白{map[positionh][positionl - 2] = 3;map[positionh][positionl - 1] = 4;if (flag == 1)map[positionh][positionl] = 2;else{map[positionh][positionl] = 0; flag = 1;}}positionl--;}else if (map[positionh][positionl - 1] == 3 && map[positionh][positionl - 2] == 2)//要将箱子推到目标位置上{map[positionh][positionl - 2] = 5;//箱子在目标位置上map[positionh][positionl - 1] = 4;if (flag == 1)//人在目标位置上{map[positionh][positionl] = 2; flag = 0;}else //人不在目标位置上map[positionh][positionl] = 0;positionl--;}else count--;//抵消人不动的情况test_flag();}
void box::right()//向右函数
{if (map[positionh][positionl + 1] == 0){map[positionh][positionl + 1] = 4;if (flag == 1){map[positionh][positionl] = 2;  flag = 0;}elsemap[positionh][positionl] = 0;positionl++;}else if (map[positionh][positionl + 1] == 2)//人要到目标位置上{map[positionh][positionl + 1] = 4;if (flag == 1)map[positionh][positionl] = 2;//恢复目标位置else{map[positionh][positionl] = 0;//恢复原来的状态flag = 1;//标志位,记录人在目标位置上}positionl++;}else if (map[positionh][positionl + 1] == 3 && map[positionh][positionl + 2] == 0)//将箱子推到空白位置上{map[positionh][positionl + 2] = 3;map[positionh][positionl + 1] = 4;if (flag == 1){map[positionh][positionl] = 2; flag = 0;}elsemap[positionh][positionl] = 0;positionl++;}else if (map[positionh][positionl + 1] == 5 && map[positionh][positionl + 2] != 1)//要将箱子从目标位置上推出{if (map[positionh][positionl + 2] == 2)//下一个位置还是目标位置{map[positionh][positionl + 2] = 5;map[positionh][positionl + 1] = 4;if (flag == 1)map[positionh][positionl] = 2;else{map[positionh][positionl] = 0; flag = 1;}}else if (map[positionh][positionl + 2] == 0)//下一个位置是空白{map[positionh][positionl + 2] = 3;map[positionh][positionl + 1] = 4;if (flag == 1)map[positionh][positionl] = 2;else{map[positionh][positionl] = 0; flag = 1;}}positionl++;}else if (map[positionh][positionl + 1] == 3 && map[positionh][positionl + 2] == 2)//要将箱子推到目标位置上{map[positionh][positionl + 2] = 5;//箱子在目标位置上map[positionh][positionl + 1] = 4;if (flag == 1)//人在目标位置上{map[positionh][positionl] = 2; flag = 0;}else //人不在目标位置上map[positionh][positionl] = 0;positionl++;}else count--;//抵消人不动的情况test_flag();
}
void box::down()//向下函数
{if (map[positionh + 1][positionl] == 0){map[positionh + 1][positionl] = 4;if (flag == 1){map[positionh][positionl] = 2; flag = 0;}elsemap[positionh][positionl] = 0;positionh++;}else if (map[positionh + 1][positionl] == 2)//人要到目标位置上{map[positionh + 1][positionl] = 4;if (flag == 1)map[positionh][positionl] = 2;//恢复目标位置else{map[positionh][positionl] = 0;//恢复原来的状态flag = 1;//标志位,记录人在目标位置上}positionh++;}else if (map[positionh + 1][positionl] == 3 && map[positionh + 2][positionl] == 0)//将箱子推到空白位置上{map[positionh + 2][positionl] = 3;map[positionh + 1][positionl] = 4;if (flag == 1){map[positionh][positionl] = 2; flag = 0;}elsemap[positionh][positionl] = 0;positionh++;}else if (map[positionh + 1][positionl] == 5 && map[positionh + 2][positionl] != 1)//要将箱子从目标位置上推出{if (map[positionh + 2][positionl] == 2)//下一个位置还是目标位置{map[positionh + 2][positionl] = 5;map[positionh + 1][positionl] = 4;if (flag == 1)map[positionh][positionl] = 2;else{map[positionh][positionl] = 0; flag = 1;}}else if (map[positionh + 2][positionl] == 0)//下一个位置是空白{map[positionh + 2][positionl] = 3;map[positionh + 1][positionl] = 4;if (flag == 1)map[positionh][positionl] = 2;else{map[positionh][positionl] = 0; flag = 1;}}positionh++;}else if (map[positionh + 1][positionl] == 3 && map[positionh + 2][positionl] == 2)//要将箱子推到目标位置上{map[positionh + 2][positionl] = 5;//箱子在目标位置上map[positionh + 1][positionl] = 4;if (flag == 1)//人在目标位置上{map[positionh][positionl] = 2; flag = 0;}else //人不在目标位置上map[positionh][positionl] = 0;positionh++;}else count--;//抵消人不动的情况test_flag();
}
void box::up()//向上函数
{if (map[positionh - 1][positionl] == 0){map[positionh - 1][positionl] = 4;if (flag == 1){map[positionh][positionl] = 2; flag = 0;}elsemap[positionh][positionl] = 0;positionh--;}else if (map[positionh - 1][positionl] == 2)//人要到目标位置上{map[positionh - 1][positionl] = 4;if (flag == 1)map[positionh][positionl] = 2;//恢复目标位置else{map[positionh][positionl] = 0;//恢复原来的状态flag = 1;//标志位,记录人在目标位置上}positionh--;}else if (map[positionh - 1][positionl] == 3 && map[positionh - 2][positionl] == 0)//将箱子推到空白位置上{map[positionh - 2][positionl] = 3;map[positionh - 1][positionl] = 4;if (flag == 1){map[positionh][positionl] = 2; flag = 0;}elsemap[positionh][positionl] = 0;positionh--;}else if (map[positionh - 1][positionl] == 5 && map[positionh - 2][positionl] != 1)//要将箱子从目标位置上推出{if (map[positionh - 2][positionl] == 2)//下一个位置还是目标位置{map[positionh - 2][positionl] = 5;map[positionh - 1][positionl] = 4;if (flag == 1)map[positionh][positionl] = 2;else{map[positionh][positionl] = 0; flag = 1;}}else if (map[positionh - 2][positionl] == 0)//下一个位置是空白{map[positionh - 2][positionl] = 3;map[positionh - 1][positionl] = 4;if (flag == 1)map[positionh][positionl] = 2;else{map[positionh][positionl] = 0; flag = 1;}}positionh--;}else if (map[positionh - 1][positionl] == 3 && map[positionh - 2][positionl] == 2)//要将箱子推到目标位置上{map[positionh - 2][positionl] = 5;//箱子在目标位置上map[positionh - 1][positionl] = 4;if (flag == 1)//人在目标位置上{map[positionh][positionl] = 2; flag = 0;}else //人不在目标位置上map[positionh][positionl] = 0;positionh--;}else count--;//抵消人不动的情况test_flag();}
void box::test_flag()
{int choice;int item[1000];for (int i = 1; i <= roomsize; i++)for (int j = 1; j <= roomsize; j++){if (map[i][j] == 3)return;}system("cls");count++;data = count;times++;display();returninseart();cout << "╭──────────────╮" << endl<< "│恭喜小可爱呀!你通关啦哟!  │" << endl<< "│★★★ 再来一局不?★★★   │" << endl<< "│1. 继续                     │" << endl<< "│2. 观看通关过程             │" << endl<< "│3. 最好滴记录               │" << endl<< "│4. 退出呀                   │" << endl<< "╰──────────────╯" << endl;cin >> choice;switch (choice){case 1:count = 0;Sleep(500);system("cls");begin();break;case 2:travers();cout << "按任意键回到主界面哟..." << endl;_getch();system("cls");begin();break;case 3:record();system("cls");cout << "按任意键回到主界面哟..." << endl;begin();break;case 4:cout << "★★★嘻嘻!欢迎再次游戏★★★" << endl;cout << "★★★按任意键退出喔★★★" << endl;_getch();exit(0);}
}
void box::record()//最佳记录
{int rhigh;if (times % 2)array[0] = data;elsearray[1] = data;if (array[0]>array[1])rhigh = array[1];elserhigh = array[0];if (times % 2)array[0] = rhigh;elsearray[1] = rhigh;cout << "最优秀滴记录:" << rhigh << endl;_getch();
}
void box::travers()
{int i, l = linkqu.getcount(), item[1000];while (l){i = 0;linkqu.out(item);for (int j = 0; j<roomsize + 2; j++)for (int k = 0; k<roomsize + 2; k++){map[j][k] = item[i];i++;}system("cls");display();Sleep(50);l--;}
}
void box::returnpush()
{int i = 0, l, r;for (int j = 0; j<roomsize + 2; j++)for (int k = 0; k<roomsize + 2; k++){if (map[j][k] == 4){l = j;r = k;}followmap[i] = map[j][k];i++;}st.push(followmap, l, r);
}
void box::returninseart()
{int i = 0;for (int j = 0; j<roomsize + 2; j++)for (int k = 0; k<roomsize + 2; k++){followmap[i] = map[j][k];i++;}linkqu.insert(followmap);
}//主程序
int main()
{box Mybox;system("color B0");Mybox.begin();return 0;
}

觉得有用的小伙伴可以点赞关注哟!

有问题的小伙伴可以在评论区留言提出!

我是灰小猿!我们下期见!

程序员带你回味童年,一起用C语言做一个“推箱子”玩!【文末源码】相关推荐

  1. 程序员小姐姐写出代码版《本草纲目》毽子操,附上源码 !

    点击上方蓝色字体,选择"标星公众号" 优质文章,第一时间送达 来源:程序人生 (ID:coder_life) "腰间的赘肉咔咔掉!人鱼线马甲线我想要!",&qu ...

  2. Java程序员月薪达到三万,需要技术水平达到什么程度?(文末送书)

    最近跟朋友在一起聚会的时候,提了一个问题,说Java程序员如何能月薪达到三万,技术水平需要达到什么程度?人回答说这只能是大企业或者互联网企业工程师才能拿到.也许是的,小公司或者非互联网企业拿二万的不太 ...

  3. 情人节程序员用HTML网页表白【全屏3D相册】 HTML5七夕情人节表白网页源码 HTML+CSS+JavaScript

    这是程序员表白系列中的100款网站表白之一,旨在让任何人都能使用并创建自己的表白网站给心爱的人看. 此波共有100个表白网站,可以任意修改和使用,很多人会希望向心爱的男孩女孩告白,生性腼腆的人即使那个 ...

  4. 情人节程序员用HTML网页表白【七夕告白(520气球)】 HTML5七夕情人节表白网页源码 HTML+CSS+JavaScript

    这是程序员表白系列中的100款网站表白之一,旨在让任何人都能使用并创建自己的表白网站给心爱的人看. 此波共有100个表白网站,可以任意修改和使用,很多人会希望向心爱的男孩女孩告白,生性腼腆的人即使那个 ...

  5. 情人节程序员用HTML网页表白【守护爱情(泡泡游戏)】 HTML5七夕情人节表白网页源码 HTML+CSS+JavaScript

    这是程序员表白系列中的100款网站表白之一,旨在让任何人都能使用并创建自己的表白网站给心爱的人看. 此波共有100个表白网站,可以任意修改和使用,很多人会希望向心爱的男孩女孩告白,生性腼腆的人即使那个 ...

  6. 程序员面试防坑宝典,助你秋招一臂之力(建议收藏,文末有彩蛋)

    自我介绍 您好,很荣幸有机会来参加公司的面试 1.个人经历(我是谁,我来自哪里,年龄,学历,从业经历)实习加上正职 2.公司为什么要选你(应聘岗位中最重要的3个技能点,说清楚相关经验)我能做好我要做的 ...

  7. c语言 游戏程序,C语言做的推箱子游戏源程序

    #include #include #include //图形界面 #include #include using namespace std; #define VK_SHIFT  0x10 #pra ...

  8. 程序员带半箱辣条参加东京奥运,网友:这不是辣条,是狗粮!

    整理 | 王晓曼 出品 | 程序人生(ID:coder _life) 7月23日,东京奥运会开幕在即,一条#程序员带半箱辣条参加东京奥运#的消息登上微博热搜,引发了网友们的热议. 程序员自带辣条参加奥 ...

  9. python开发pc软件_程序员带你十天快速入门Python,玩转电脑软件开发(二)

    关注今日头条-做全栈攻城狮,学代码也要读书,爱全栈,更爱生活.提供程序员技术及生活指导干货. 如果你真想学习,请评论学过的每篇文章,记录学习的痕迹. 请把所有教程文章中所提及的代码,最少敲写三遍,达到 ...

最新文章

  1. 生成24位字符串ID__IdGenerator.java
  2. C语言再学习 -- 文件
  3. [ubuntu setting]Change system language
  4. java socket编程聊天室_Java Socket通信之聊天室功能
  5. vue 属性 computed
  6. Mac OS 系统的发展历史
  7. 怎么得到PreparedStatement查询条数的结果
  8. P3376 (最大流 dinic)
  9. 这可能是最全最好的BLAST教程
  10. forwarding
  11. PHP 调用百度人脸检测
  12. 如何静下心做些事情呢
  13. 【论文笔记】Camera Style Adaption for Person Re-identification
  14. IntelliJ IDEA的数据库管理工具实在太方便了
  15. Mac百度云盘不限速操作步骤
  16. 借助CatGPT让turtlesim小乌龟画曲线
  17. python中strip_python中的strip是什么意思
  18. rtmp协议规范详解
  19. 20200228视频播放器的字幕支持
  20. 论遇到事情的沉着与冷静

热门文章

  1. 初学者笔记:Scanf间隔符号的使用
  2. 自定义dns服务器是什么,dns是什么意思?dns怎么设置(手动设置/软件设置)
  3. android 自动打开wifi热点
  4. CSS几种定位的使用
  5. QWebEngineView如何忽略SSL证书错误
  6. KeyTweak 键盘按键功能修改
  7. 闲来没事自己研究了下RBAC
  8. 数字电路之Verilog红绿灯设计
  9. axis监控记录服务器显示画面,AXIS VMS CMS-M 中心管理服务器
  10. Gentoo 2005.1 完整的USE参数清单中文详解(转)