1. 程式人生 > >推箱子游戲C++實現原理

推箱子游戲C++實現原理

通過WSAD控制箱子上下左右移動,Q退出程式。

 { '*',' ','O','#','@' }分別表示牆,空白,方塊,目標地,人,可以根據自己喜歡重新設定

地圖為7行10例,可以根據自己喜歡調整地圖形式:

char map[7][11] = { "**********",
                        "**     ***",
                        "**O***   *",
                        "*   O  O *",
                        "* ##*

[email protected]**",
                        "**##*   **",
                        "**********", };

其他的程式碼裡面有相應的註釋。

#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include<vector>
using namespace std;

class Sokoban
{
private:
	int startx1, starty1, startx2, starty2, startx3, starty3, startx4, starty4;//箱子的起始位置,未用
	int endx1, endy1, endx2, endy2, endx3, endy3, endx4, endy4;//箱子終點位置
	int manx, many;//人的起始位置
	int boxx = 6, boxy = 9;
	char direction;
	bool controlswitch = true;
	char map[7][11] = { "**********",
						"**     ***",
						"**O***   *",
						"*   O  O *",
						"* ##* 
[email protected]
**", "**##* **", "**********", };//豎著的是x,橫著的是y char boxback[5] = { '*',' ','O','#','@' };//牆,空白,方塊,目標地,人 public: void Setpara();//箱子終點位置獲取 void Inputlocation();//輸入移動方向 void Getlocation();//獲取人的位置 bool Getcontrol();//控制while迴圈 void Move();//移動箱子 void Judgelocation();//判斷箱子是否到地形邊緣不能推動 void Resultshow();//重新整理顯示結果 }; bool Sokoban::Getcontrol() { return this->controlswitch; } void Sokoban::Inputlocation() { this->direction = getchar(); } void Sokoban::Setpara() { //從陣列圖中獲取重點位置,用於判斷箱子是否就為 vector<vector<int>> endbox; vector<int> endboxxy(2); for (int i = 0; i <= boxx; i++) { for (int j = 0; j <= boxy; j++) { if (map[i][j] == boxback[3]) { endboxxy[0] = i; endboxxy[1] = j; endbox.push_back(endboxxy); } } } this->endx1 = endbox[0][0]; this->endy1 = endbox[0][1]; this->endx2 = endbox[1][0]; this->endy2 = endbox[1][1]; this->endx3 = endbox[2][0]; this->endy3 = endbox[2][1]; this->endx4 = endbox[3][0]; this->endy4 = endbox[3][1]; } void Sokoban::Getlocation() { //獲取當前人物的位置,用於計算判斷推箱子 manx, many = 0, 0; for (int i = 0; i <= boxx; i++)//6 { for (int j = 0; j <= boxy; j++)//10 { if (map[i][j] == boxback[4]) { this->manx = i; this->many = j; //cout << "人物當前座標位置" << manx << "," << many << endl; } //cout << "當前座標位置" <<map[i][j]<< endl; } } } void Sokoban::Resultshow() { system("cls"); cout << "歡迎使用推箱子游戲:" <<endl; cout << "通過滑鼠按鍵WSAD控制上下所有移動,Q退出,輸入後回車" << endl; for (int i = 0; i <= boxx; i++) { puts(map[i]);//用於列印顯示a中的資料 } //用於重新整理避免人走過了目標提示就不在了 if (map[endx1][endy1] == boxback[1]) { map[endx1][endy1] = boxback[3]; } //用於重新整理避免人走過了目標提示就不在了 if (map[endx2][endy2] == boxback[1]) { map[endx2][endy2] = boxback[3]; } //用於重新整理避免人走過了目標提示就不在了 if (map[endx3][endy3] == boxback[1]) { map[endx3][endy3] = boxback[3]; } //用於重新整理避免人走過了目標提示就不在了 if (map[endx4][endy4] == boxback[1]) { map[endx4][endy4] = boxback[3]; } //用於判斷箱子是否被推進了目標區域 if (map[endx1][endy1]==boxback[2] && map[endx2][endy2] == boxback[2] && map[endx3][endy3] == boxback[2] && map[endx4][endy4] == boxback[2]) { this->controlswitch = false; cout << "遊戲通關" << endl; } } void Sokoban::Move() { if(map[manx][many] == boxback[4]) { cout << map[manx][many] << endl; //通過輸入的移動方向AWSD判斷箱子的移動方向,如果箱子移動方向是空地則向那個方向移動否則不動 if (direction == 'D' || direction == 'd') { if (map[manx][many + 1] == boxback[2] && (map[manx][many + 2] == boxback[1] || map[manx][many + 2] == boxback[3])) { map[manx][many] = boxback[1]; many++; map[manx][many] = boxback[4]; many++; map[manx][many] = boxback[2]; cout << "右移動了" << endl; } else if (map[manx][many + 1] == boxback[1] || map[manx][many + 1] == boxback[3]) { map[manx][many] = boxback[1]; many++; map[manx][many] = boxback[4]; cout << "右移動了" << endl; } } else if(direction == 'A' || direction == 'a') { if (map[manx][many - 1] == boxback[2] && (map[manx][many - 2] == boxback[1] || map[manx][many - 2] == boxback[3])) { map[manx][many] = boxback[1]; many--; map[manx][many] = boxback[4]; many--; map[manx][many] = boxback[2]; cout << "左移動了" << endl; } else if (map[manx][many - 1] == boxback[1] || map[manx][many - 1] == boxback[3]) { map[manx][many] = boxback[1]; many--; map[manx][many] = boxback[4]; cout << "左移動了" << endl; } } else if(direction == 'S' || direction == 's') { if (map[manx + 1][many] == boxback[2] && (map[manx + 2][many] == boxback[1] || map[manx + 2][many] == boxback[3])) { map[manx][many] = boxback[1]; manx++; map[manx][many] = boxback[4]; manx++; map[manx][many] = boxback[2]; cout << "下移動了" << endl; } else if (map[manx + 1][many] == boxback[1] || map[manx + 1][many] == boxback[3]) { map[manx][many] = boxback[1]; manx++; map[manx][many] = boxback[4]; cout << "下移動了" << endl; } } else if((direction == 'W' || direction == 'w')) { if (map[manx - 1][many] == boxback[2] && (map[manx - 2][many] == boxback[1] || map[manx - 2][many] == boxback[3])) { map[manx][many] = boxback[1]; manx--; map[manx][many] = boxback[4]; manx--; map[manx][many] = boxback[2]; cout << "上移動了" << endl; } else if (map[manx - 1][many] == boxback[1] || map[manx - 1][many] == boxback[3]) { map[manx][many] = boxback[1]; manx--; map[manx][many] = boxback[4]; cout << "上移動了" << endl; } } else if (direction == 'Q' || direction == 'q') { this->controlswitch = false; cout << "退出遊戲" << endl; } } } void Sokoban::Judgelocation() { for (int i = 0; i <= boxx; i++)//6 { for (int j = 0; j <= boxy; j++)//10 { if (map[i][j] == boxback[2]) { //如果箱子在終點則忽略不能移動就退出的提前終止遊戲機制 if (map[endx1][endy1] == boxback[2] || map[endx2][endy2] == boxback[2] || map[endx3][endy3] == boxback[2] || map[endx4][endy4] == boxback[2]) { cout << "加油哦!" << endl; } //當箱子相鄰兩邊是牆的時候,推不動了,就提前終止退出遊戲 else if ((map[i + 1][j] == boxback[0] && map[i][j + 1] == boxback[0]) || (map[i - 1][j] == boxback[0] && map[i][j - 1] == boxback[0]) || (map[i + 1][j] == boxback[0] && map[i][j - 1] == boxback[0]) || (map[i - 1][j] == boxback[0] && map[i][j + 1] == boxback[0])) { this->controlswitch = false; cout << "你輸了!" << endl; } } } } } int main() { //迷宮程式 //Maze maze; //maze.Run(); Sokoban sokoban; sokoban.Getlocation(); bool controlswitch = sokoban.Getcontrol(); sokoban.Setpara(); while (controlswitch) { sokoban.Resultshow(); sokoban.Inputlocation(); sokoban.Getlocation(); sokoban.Move(); sokoban.Judgelocation(); sokoban.Resultshow(); controlswitch = sokoban.Getcontrol(); } cout << "很高興見到你!" << endl; Sleep(1000000); return 0; }