這篇文章是用C語言做了一個推箱子小遊戲,實現起來比較簡單,和大家一起回味一下童年捧著按鍵機玩推箱子的日子!文末附帶萬字原始碼!
目錄
Hello,你好呀,我是灰小猿!一個超會寫bug的程式猿!
還記得我們曾經的那個推箱子嗎,記得小時候家裡只有按鍵的諾基亞的時候,推箱子、貪吃蛇都是我天天最經常玩的遊戲,然後最近正好有小夥伴問我有沒有做過相關的開發,所以今天在這裡跟大家一個用C語言實現的簡單推箱子的小遊戲,帶著大家一起回味一下童年呀!【點贊收藏,上車坐好!】
推箱子游戲程式的設計為分別設定各型別函數類,設定推箱子房子佈局的資料結構二維陣列,以及記錄最短步驟數目以及最好成績的二維陣列,通過函數對房子進行佈局,定義資料結構佇列類,並設定公有成員函數和私有成員函數。
與此同時,我運用C++中的派生類相關知識設定相同類名以及不同類名的物件,用於構造推箱子游戲的分佈函數,設定資料結構出隊和入隊函數,同時設計以箱子為物件,依據於人的橫縱座標位置的函數,設計基於遊戲資料介面的,開始介面通關提示、遊戲時選項提示、玩遊戲時介面顯示地圖左右上下方向通關提示以及排行榜等。
同時,根據遊戲要求設定輸出遊戲主介面和遊戲關卡選擇介面,用於我們的操作,構造將遊戲步驟進行重新播放的函數,根據以上以及各型別詳細函數設定主函數並進行操作執行遊戲,以此來達到使遊戲平穩執行的要求。除上述內容之外,在製作遊戲時,我還運用了多元分組的構造模式,使得程式內容簡單易懂,任何有程式基礎的人都可以進行交流學習。接下來我跟大家分享一下主要的模組設計,最後附上完整原始碼供大家參考!小夥伴們別忘了三連支援,收藏學習呀!
在程式中我利用類與物件完成了對遊戲地圖的設計,以及對於關卡的選擇等眾多功能。並且利用資料結構中的理念,實現了對人與箱子的定位和時間步數等功能的實現。總體來說,該程式涵蓋了我們所學習的相關知識,雖然遊戲有點簡單,但是其中內容卻涉獵甚廣,
推箱子游戲的設計目的,在於合理有效運用資料結構棧與佇列,以及C++中的類與物件以及派生類的相關知識,將遊戲中的各個環節拆分開來,運用派生類將各個環節串聯起來,達到實現程式穩定執行的目的。以下是總體設計圖:
在box下的begin派生類中,我們的主要功能是輸出遊戲介面,在該函數中,我們對遊戲內部功能進行了詳細介紹,其中包括遊戲玩法和操作指令,與此同時,對遊戲主介面進行了詳細優化,在該函數中,在遊戲功能的介紹上,我們分別使用星星,圓圈和特殊符號代表箱子,目標位置和推箱子的小人物,我們呼叫進行觀察,選擇的函數來完成遊戲,玩家對遊戲關卡的選擇,並且在操作指令上對進行復原選擇和退出遊戲進行了詳細介紹,方便玩家更好的遊戲體驗,
在遊戲選擇介面中,我們採用雙五角星的介面圖形動畫,在中間設定關卡選項,選擇選項中有1到4個關卡可供選擇,在使用者進行關卡選擇以後,可將選擇關卡的序號進行返回到函數之中,函數對玩家選擇的序號進行識別,一次對1到4個關卡進行選擇判斷,然後在程式中跳轉到相應的函數介面,供玩家進行遊戲,倘若玩家輸入的序號不在1到4之間,則系統會自動提示輸入錯誤,請重新輸入的字樣。
在派生類選擇函數中,我們設定了重播,主介面,最好記錄,退出四個選項,當玩家遊戲無法通關時,可按鍵盤上的c鍵來跳轉出選擇介面進行玩家的選擇,和選擇關卡的設定一樣,我們在玩家反饋過來的1到4四個序號進行判斷,然後依次作出重播放,返回主介面,跳轉出最好記錄,退出系統四個功能。
在遊戲玩一下通關以後,我們會設定一個遊戲步驟重播函數,在該函數執行以後,玩家可以觀看由程式對玩家步驟進行記錄而設定好的遊戲步驟重播,在該函數中,我們主要是依據玩家進行上下左右方向鍵操作,對其方向的使用進行儲存到陣列之中,當玩家選擇進行遊戲步驟重播時,我們可將該二維陣列中的資料釋放出來,達到將遊戲步驟進行重新播放的效果。
在遊戲開始以後,有玩家可通過上下左右方向鍵來進行遊戲中小人的控制操作,而遊戲中小人控制操作的方向鍵,我們所依據的是Ascii碼鍵盤鍵位,其中左鍵為75號,右鍵為77號上鍵為72號,下鍵為80號,在開始遊戲以後,玩家對按鍵進行操作,與此同時,我們在內部函數中會對75,77,72,84個數進行記憶,當返回值為四個數中的其中之一時,我們會將該記錄存入函數之中,並且在遊戲步驟上加1,其中我們還設定鍵盤上的c鍵為26,當選擇c鍵時可進行重新選擇操作,在該重新選擇以後,我們設定返回主介面和退出遊戲兩個選項,可供玩家進行選擇。
在遊戲介面函數中,我們設定了遊戲的各種形狀來代表我們遊戲內部的不同內容,分別以‘■’代表牆體,‘○’代表目標位置,‘★’代表箱子,‘♀’代表人,和‘㊣’代表箱子在目標位置上的效果展示,與此同時,在介面的最下邊,我們增加有復原(Ctrl+z),選擇(c)和遊戲步數記錄選項,可實時記錄玩家進行的遊戲步驟,效果圖如下:
在遊戲按鍵中的向左函數中,我們有進行多項判斷,我們所依據的是小人向左位置的地址進行返回值,如果我們檢測到該陣列內部的值為零時進行判斷,我們將記錄小人左側函數的陣列賦值給4,然後進行判斷,同時,如果該陣列上元數等於2,我們要使人員移動到目標位置上,同時恢復目標位置的函數,使其恢復到原來位置,同時對該位置進行標記,記錄人員經過該位置,方便我們進行重播函數的操作,
如果說我們檢測到該函數內的值為零,或者是3的話,我們可以執行將箱子推到空白位置上的函數操作,如果該函數為5或者為1的話,我們要執行的是將箱子從目標位置上推出的函數操作,如果該函數值為3且為2,我們要執行的是將箱子推到目標位置上的函數操作,且人在目標位置上用來抵消仍不動的情況。
我們在執行向右函數時,所依據的原理和向左函數類似,我們對右鍵的地址來進行判斷且返回值,如果說函數值等於零,我們則進行以下操作,如果說返回值等於2,我們要將人員移到目標位置之上,同時恢復目標位置及原來的狀態標誌,該位置記錄仍在該位置上的地址,方便我們進行重播操作,否則如果說該函數值為3且為0的話,我們將箱子推到空白位置上,如果按函數值為5或者不等於1的話,我們要將箱子從目標位置上推出,移動到下一個目標位置,且還是目標位置,如果該函數值為3且為2的話,要將箱子推到目標位置上。
在向下函數中,我們對向下按鍵的地址進行返回,並且讀取判斷,如果說陣列記錄中為2,要將人要移到目標位置上,同時恢復目標位置的原來狀態標誌,該位置記錄仍在目標位置上的地址,方便我們進行重播操作,如果該陣列的值為3且等於0,將箱子推到空白位置之上,將箱子從標位置上推出,如果下一個位置還是目標位置,我們將該值為5或4,如果下一個位置是空白,之後我們將該陣列值賦為3且為4,如果該陣列的值為3且為2,我們要將箱子推到目標位置上,並且如果說該陣列值為5的話,將箱子推到目標位置之上,仍在目標位置上,否則如果人不在目標位置之上的話,我們將該函數值賦值為0,同時抵消人不動的情況。
在執行向上函數時,我們對應函數值返回的地址值進行判斷,如果該陣列值為0,則我們將該陣列值賦值為4,否則如果說該函數值為2,我們要說明人在目標位置之上,同時恢復目標位置的原來狀態標誌,該位置記錄人在目標位置上的地址,方便進行重播操作,如果該陣列位置為3且為0,我們將箱子推到空白位置之上,否則如果陣列值為5或不等於1,要將箱子從目標位置上推出,如果下一個位置還是目標位置,我們則將輸出值賦值為5,將另一個陣列賦值為4,如果該陣列賦值為3,且另一個陣列數值為2,要將箱子推到目標位置上,並且將該值賦值為5,將箱子在目標位置上,仍在目標位置之上,若人在目標位直之上,則抵調整波動的情況。
在玩家進行通關以後,我們系統會自動識別,並且返回一個通關介面,該介面我們會對玩家進行詢問的操作,該操作分為四步,繼續,觀看通關視訊過程,檢視最好記錄,退出介面,返回主介面,當玩家進行1到4的選擇以後,我們會返回相應的操作,並且可以在按任意鍵回到主頁面。
在最佳記錄函數中,我們設定一個值來記錄遊戲玩家的步數,每當遊戲玩家對按鍵進行操作一次,則該函數定義的變數則加一次,當我們讀取到該玩家通關以後,將應該資料進行儲存,當我們檢測到有最好記錄時,即該步數為最小值時,確定為最佳記錄。
在入佇列函數中,主要運用資料結構的佇列知識,設定入佇列函數,並定義指標變數指向頭結點,相關數值在入佇列以後,會自動的將數值賦值到隊頭位置,並且迴圈使searchp節點不為空,然後按照次序,將數值依次從隊頭向對尾進行賦值運算,
在出佇列操作中,主要依據佇列相關規則,設定指標變數,將隊頭元素賦值給指標,同時在進行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;
}
覺得有用的小夥伴可以點贊關注喲!
有問題的小夥伴可以在評論區留言提出!
我是灰小猿!我們下期見!