程序员带你回味童年,一起用C语言做一个“推箱子”玩!文末源码
Posted 灰小猿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了程序员带你回味童年,一起用C语言做一个“推箱子”玩!文末源码相关的知识,希望对你有一定的参考价值。
这篇文章是用C语言做了一个推箱子小游戏,实现起来比较简单,和大家一起回味一下童年捧着按键机玩推箱子的日子!文末附带万字源码!
目录
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;//队头接收searchp
delete 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; //15
choose_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;
}
else
map[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;
}
else
map[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;
}
else
map[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;
}
else
map[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;
}
else
map[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;
}
else
map[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;
}
else
map[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;
}
else
map[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;
else
array[1] = data;
if (array[0]>array[1])
rhigh = array[1];
else
rhigh = array[0];
if (times % 2)
array[0] = rhigh;
else
array[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语言做一个“推箱子”玩!文末源码的主要内容,如果未能解决你的问题,请参考以下文章