程序员带你回味童年,一起用C语言做一个“推箱子”玩!【文末源码】
这篇文章是用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语言做一个“推箱子”玩!【文末源码】相关推荐
- 程序员小姐姐写出代码版《本草纲目》毽子操,附上源码 !
点击上方蓝色字体,选择"标星公众号" 优质文章,第一时间送达 来源:程序人生 (ID:coder_life) "腰间的赘肉咔咔掉!人鱼线马甲线我想要!",&qu ...
- Java程序员月薪达到三万,需要技术水平达到什么程度?(文末送书)
最近跟朋友在一起聚会的时候,提了一个问题,说Java程序员如何能月薪达到三万,技术水平需要达到什么程度?人回答说这只能是大企业或者互联网企业工程师才能拿到.也许是的,小公司或者非互联网企业拿二万的不太 ...
- 情人节程序员用HTML网页表白【全屏3D相册】 HTML5七夕情人节表白网页源码 HTML+CSS+JavaScript
这是程序员表白系列中的100款网站表白之一,旨在让任何人都能使用并创建自己的表白网站给心爱的人看. 此波共有100个表白网站,可以任意修改和使用,很多人会希望向心爱的男孩女孩告白,生性腼腆的人即使那个 ...
- 情人节程序员用HTML网页表白【七夕告白(520气球)】 HTML5七夕情人节表白网页源码 HTML+CSS+JavaScript
这是程序员表白系列中的100款网站表白之一,旨在让任何人都能使用并创建自己的表白网站给心爱的人看. 此波共有100个表白网站,可以任意修改和使用,很多人会希望向心爱的男孩女孩告白,生性腼腆的人即使那个 ...
- 情人节程序员用HTML网页表白【守护爱情(泡泡游戏)】 HTML5七夕情人节表白网页源码 HTML+CSS+JavaScript
这是程序员表白系列中的100款网站表白之一,旨在让任何人都能使用并创建自己的表白网站给心爱的人看. 此波共有100个表白网站,可以任意修改和使用,很多人会希望向心爱的男孩女孩告白,生性腼腆的人即使那个 ...
- 程序员面试防坑宝典,助你秋招一臂之力(建议收藏,文末有彩蛋)
自我介绍 您好,很荣幸有机会来参加公司的面试 1.个人经历(我是谁,我来自哪里,年龄,学历,从业经历)实习加上正职 2.公司为什么要选你(应聘岗位中最重要的3个技能点,说清楚相关经验)我能做好我要做的 ...
- c语言 游戏程序,C语言做的推箱子游戏源程序
#include #include #include //图形界面 #include #include using namespace std; #define VK_SHIFT 0x10 #pra ...
- 程序员带半箱辣条参加东京奥运,网友:这不是辣条,是狗粮!
整理 | 王晓曼 出品 | 程序人生(ID:coder _life) 7月23日,东京奥运会开幕在即,一条#程序员带半箱辣条参加东京奥运#的消息登上微博热搜,引发了网友们的热议. 程序员自带辣条参加奥 ...
- python开发pc软件_程序员带你十天快速入门Python,玩转电脑软件开发(二)
关注今日头条-做全栈攻城狮,学代码也要读书,爱全栈,更爱生活.提供程序员技术及生活指导干货. 如果你真想学习,请评论学过的每篇文章,记录学习的痕迹. 请把所有教程文章中所提及的代码,最少敲写三遍,达到 ...
最新文章
- 生成24位字符串ID__IdGenerator.java
- C语言再学习 -- 文件
- [ubuntu setting]Change system language
- java socket编程聊天室_Java Socket通信之聊天室功能
- vue 属性 computed
- Mac OS 系统的发展历史
- 怎么得到PreparedStatement查询条数的结果
- P3376 (最大流 dinic)
- 这可能是最全最好的BLAST教程
- forwarding
- PHP 调用百度人脸检测
- 如何静下心做些事情呢
- 【论文笔记】Camera Style Adaption for Person Re-identification
- IntelliJ IDEA的数据库管理工具实在太方便了
- Mac百度云盘不限速操作步骤
- 借助CatGPT让turtlesim小乌龟画曲线
- python中strip_python中的strip是什么意思
- rtmp协议规范详解
- 20200228视频播放器的字幕支持
- 论遇到事情的沉着与冷静