【SeedCoder2015年 热身题6 搜索】Move Game (题目)

来源:互联网 发布:狗窝图片及价格淘宝网 编辑:程序博客网 时间:2024/06/05 08:58

【问题】


现有如下一款游戏,游戏的目的是通过”左,右,上,下”滑动来移动红,绿,蓝色的小球,每操作一次所有小球最多只能移动一步(与2048不同),其中灰色区域块为禁止区域,小球不能移动到该位置。若所有有色小球停留在对应的色区块下,则游戏结束。那么对于该游戏关卡,最少需要多少步才能完成。


【输入】

输入只由一组测试样例组成。该样例由两部分组成,第一部分为3×3的矩阵,矩阵每一行占据一列,每个数之间以Tab键隔开;其中0表示该单元未被小球和灰色壁垒占据,-1表示该单元被灰色壁垒占据,1表示被红色小球占据,2表示被绿色小球占据,3表示被蓝色小球占据;第二部分表示红,绿,蓝色块的位置,第一行表示红色色块的位置,第二行表示绿色色块的位置,第三行表示蓝色色块的位置。数字之间以Tab键隔开。

【输出】

对于每一次输出样例,输出最小的操作数。

【示例输入】

1         0             -1

3         2             0

-1         -1           0

1         2

0         1

0         0

--------------------------------------------------------------------------------------------------------------------------------------------------

【解答】

               该题目与上一道题目类似,都是利用宽度优先搜索。该示例代码未按照指定格式进行输出,输出了最短操作步骤,可以直接按照输出步骤完成该游戏。

//--------------------------------------【程序说明】-------------------------------------------//程序说明:上上下下ABAB//程序描述:搜索//IDE版本:Visual Studio 2013//作者:Arthur Lee//------------------------------------------------------------------------------------------------  //【1】头文件#include <fstream>#include <ctime>#include <list>#include <functional>//包含less<>等仿函数#include <algorithm>#include <deque>//包含deque类using namespace std;#define TIMER//【2】函数声明void InitialData();bool BreadthFirstSearch();//【3】定义枚举体,在几种方法中切换enum Method{BreadthFirst};enum Action{Left,Right,Up,Down};enum Color{Red=1,Green,Blue};class Point {public:int x;int y;Point(){x = 0;y = 0;}Point(int x0, int y0) :x(x0), y(y0){}//Point(Point& p) :x(p.x), y(p.y){}bool operator ==(Point pos){return (x == pos.x&&y == pos.y);}bool operator !=(Point pos){return !(*this == pos);}Point& operator = (const Point& p){this->x = p.x;this->y = p.y;return *this;}};Point PosTemp[3];//全局Point变量,类实现需要放在这之前//定义的判断准则bool CompareWithX_IndexIncrease(const int& x1, const int& x2){return less<int>()(PosTemp[x1].x, PosTemp[x2].x);}bool CompareWithX_IndexDecrease(const int& x1, const int& x2){return greater<int>()(PosTemp[x1].x, PosTemp[x2].x);}bool CompareWithY_IndexIncrease(const int& x1, const int& x2){return less<int>()(PosTemp[x1].y, PosTemp[x2].y);}bool CompareWithY_IndexDecrease(const int& x1, const int& x2){return greater<int>()(PosTemp[x1].y, PosTemp[x2].y);}class State{public:static Point FinalPoint[3];int Board[3][3];//游戏面板,0表示无占据,Red,Green,Blue表示有点占据。-1表示障碍物占据Point InitialPoint[3];//R,G,Blist<Action> Routine;State& operator =(const State& s){for (int i = 0; i < 3; ++i)for (int j = 0; j < 3; ++j)this->Board[i][j] = s.Board[i][j];for (int i = 0; i < 3; ++i){this->InitialPoint[i] = s.InitialPoint[i];}this->Routine = s.Routine;return *this;}bool IsFinalState(){int i = 0;for (; i < 3; ++i){if (InitialPoint[i] != FinalPoint[i])break;}if (i < 3)return false;elsereturn true;}bool operator == (State s){int i = 0;for (; i < 3; ++i){if (InitialPoint[i] != s.InitialPoint[i])break;}if (i < 3)return false;elsereturn true;}bool MoveOneStep(Action act, State& result){//NOTE:为保证修改形参Result,该函数必须以State&作为参数~~!!int Order[3] = { 0, 1, 2 };//0 - Red,1-Green,2-Blue;表示三者排序指标for (int i = 0; i < 3; ++i)PosTemp[i] = InitialPoint[i];result = *this;//result 储存转换后的最终的结果bool flag = false;//表示MoveOneStep 是否改变了状态。switch (act){case Left:sort(Order, Order + 3, CompareWithY_IndexIncrease);for (int i = 0; i < 3; ++i){if (InitialPoint[Order[i]].y >= 1 && result.Board[InitialPoint[Order[i]].x][InitialPoint[Order[i]].y - 1] == 0){result.Board[InitialPoint[Order[i]].x][InitialPoint[Order[i]].y] = 0;result.InitialPoint[Order[i]].y -= 1;result.Board[InitialPoint[Order[i]].x][InitialPoint[Order[i]].y - 1] = (Order[i] + 1);flag = true;}}break;case Right:sort(Order, Order + 3, CompareWithY_IndexDecrease);for (int i = 0; i < 3; ++i){if (InitialPoint[Order[i]].y<2 && result.Board[InitialPoint[Order[i]].x][InitialPoint[Order[i]].y + 1] == 0){result.Board[InitialPoint[Order[i]].x][InitialPoint[Order[i]].y] = 0;result.InitialPoint[Order[i]].y += 1;result.Board[InitialPoint[Order[i]].x][InitialPoint[Order[i]].y + 1] = (Order[i] + 1);flag = true;}}break;case Up:sort(Order, Order + 3, CompareWithX_IndexIncrease);for (int i = 0; i < 3; ++i){if (InitialPoint[Order[i]].x >= 1 && result.Board[InitialPoint[Order[i]].x - 1][InitialPoint[Order[i]].y] == 0){result.Board[InitialPoint[Order[i]].x][InitialPoint[Order[i]].y] = 0;result.InitialPoint[Order[i]].x -= 1;result.Board[InitialPoint[Order[i]].x - 1][InitialPoint[Order[i]].y] = (Order[i] + 1);flag = true;}}break;case Down:sort(Order, Order + 3, CompareWithX_IndexDecrease);for (int i = 0; i < 3; ++i){if (InitialPoint[Order[i]].x <2 && result.Board[InitialPoint[Order[i]].x + 1][InitialPoint[Order[i]].y] == 0){result.Board[InitialPoint[Order[i]].x][InitialPoint[Order[i]].y] = 0;result.InitialPoint[Order[i]].x += 1;result.Board[InitialPoint[Order[i]].x + 1][InitialPoint[Order[i]].y] = (Order[i] + 1);flag = true;}}break;default:break;}return flag;}};Point State::FinalPoint[3] = {};//【4】变量声明bool IsExistInHashTable(State);deque<State> HashTable;//充当hashtable 的功能State InitialState;State Result;//存放最终的结果int main(){#ifdef TIMERclock_t start = clock();#endif // TIMERifstream fin("in.txt");if (fin.fail())return 1;ofstream fout("out.txt");Method method = Method::BreadthFirst;bool flag = false;while (!fin.eof()){InitialData();for (int i = 0; i < 3; ++i)for (int j = 0; j < 3; ++j){fin >> InitialState.Board[i][j];switch (InitialState.Board[i][j]){case 1://红色InitialState.InitialPoint[0].x = i;InitialState.InitialPoint[0].y = j;break;case 2://绿色InitialState.InitialPoint[1].x = i;InitialState.InitialPoint[1].y = j;break;case 3:InitialState.InitialPoint[2].x = i;InitialState.InitialPoint[2].y = j;break;default:break;}}fin >> State::FinalPoint[0].x >> State::FinalPoint[0].y>> State::FinalPoint[1].x >> State::FinalPoint[1].y>> State::FinalPoint[2].x >> State::FinalPoint[2].y;switch (method){case BreadthFirst:flag = BreadthFirstSearch();break;default:break;}if (flag)//输出{fout << "the smallest steps to achieve the goal is " << Result.Routine.size() << "\n";while (!Result.Routine.empty()){switch (Result.Routine.front()){case Left:fout << "left" << "\t";break;case Right:fout << "right" << "\t";break;case Up:fout << "up" << "\t";break;case Down:fout << "down" << "\t";break;default:break;}Result.Routine.pop_front();}}elsefout << "there is no answer!" << "\n";fout << "\n";}#ifdef TIMERclock_t end = clock();double duration = (double)(end - start);fout << "runtime : " << duration << "ms" << endl;#endif // TIMERfout.close();return 0;}//【5】函数实现void InitialData(){HashTable.clear();}bool BreadthFirstSearch(){list<State> list_temp;State temp;list_temp.push_back(InitialState);HashTable.push_back(InitialState);while (!list_temp.empty()){temp = list_temp.front();list_temp.pop_front();for (int i = 0; i < 4; ++i){if (temp.MoveOneStep((Action)i, Result)){if (!IsExistInHashTable(Result)){Result.Routine.push_back((Action)i);list_temp.push_back(Result);HashTable.push_back(Result);if (Result.IsFinalState())return true;}}}}return false;}bool IsExistInHashTable(State s){for (int i = 0; i < HashTable.size(); ++i){if (HashTable[i] == s){return true;}}return false;}



0 0
原创粉丝点击