最新无聊在玩华容道,结果玩的时候,有些关不知道怎么过,就自己想着写程序来求最小还原步数。经过一番搜索和思考,写出来下面的代码,其中借鉴了别人的红黑树的代码,还有就是使用广度搜索来求解的思想。
在写算法的过程中,突然想到还有其他的单人游戏也是可以用广度搜索来求解的,因此,就针对这类游戏写了一个框架,适用于状态数不会太变态的游戏,例如华容道,Unblock me(移动木块)之类的游戏。3阶以上的魔方就不能用这个框架,状态数太多,使用广度搜索的话内存完全不够用。
file: OnePlayerMap
#ifndef ONEPLAYERMAP_H_ #define ONEPLAYERMAP_H_ #include <stdlib.h> struct OnePlayerMap { OnePlayerMap() :mLastMap(NULL) ,mNext(NULL) ,mStep(0) {count++;}; virtual ~OnePlayerMap() {count--;} static int count; virtual bool less_equal(const OnePlayerMap* status) = 0; // 判断是否是结局或目标状态 virtual bool isEnd() = 0; // 返回由这一个状态能转变到的所有状态的链表, 即广度搜索 virtual OnePlayerMap* getNextStatuses() = 0; // 显示或打印这个状态 virtual void print() = 0; OnePlayerMap* mLastMap; OnePlayerMap* mNext; int mStep; }; #endif /* ONEPLAYERMAP_H_ */
游戏状态的基类,派生类必须实现那几个纯虚函数。
bool isEnd() 是判断当前状态是否是目标状态,例如曹操是否移到出口。
bool less_equal(const OnePlayerMap* status) 是判断当前状态是否小于等于status的状态,这个方法是用来在插入红黑树时使用的。
OnePlayerMap* getNextStatuses() 是返回一个链表,这个链表的内容是由当前状态衍生出来的下一步的所有状态。
void print()是显示或打印当前的状态,这个可以根据需要自己定义打印的格式。
file:RBTree.h
#include <stdlib.h> #include <string> #include <iostream> #include <functional> template <typename T, typename Comp = std::less_equal<T> > class RedBlackTree { typedef bool RB_TREE_COLOR; const static RB_TREE_COLOR BLACK = false; const static RB_TREE_COLOR RED = true; struct Node{ T key; bool color; Node* parent; Node* left; Node* right; Node(T data_, bool color_, Node* p, Node* l, Node* r) :key(data_),color(color_),parent(p),left(l),right(r){} ~Node(){} }; Node* NIL; Node* root; Comp compare; bool isUnique;// is all data unique public: RedBlackTree(bool unique=true, Node* p=NULL, Node* q=NULL, Node* e=NULL) :isUnique(unique) { NIL = new Node(0, BLACK, NIL, NIL, NIL);//哨兵结点 root = NIL; } ~RedBlackTree() { DeleteTree(root); delete NIL; } void LeftRotate(Node* x); void RightRotate(Node* y); bool RBInsert(T data); // true: insert success, false: has equals data. void RBInsertFixup(Node* z); void RBDelete(T data); void RBDeleteFixUp(Node* x); Node* TreeSearchNumber(Node* x, T k); Node* TreeSuccessor(Node* x); void DeleteTree(Node* x); void PrintTree(Node* x); Node* GetNode(void); Node* TreeMinIMUM(Node* x ); }; template<typename T, typename Comp> typename RedBlackTree<T, Comp>::Node* RedBlackTree<T, Comp>::TreeMinIMUM(Node* x) { while (x->left != NIL) x = x->left; return x; } template<typename T, typename Comp> typename RedBlackTree<T, Comp>::Node* RedBlackTree<T, Comp>::GetNode(void) { return root; } template<typename T, typename Comp> void RedBlackTree<T, Comp>::PrintTree(Node* x) { if (NIL != x) { //std::cout << x->key << std::endl; x->key->print(); if (NIL != x->left) { PrintTree(x->left); } if (NIL != x->right) { PrintTree(x->right); } } } template<typename T, typename Comp> void RedBlackTree<T, Comp>::DeleteTree(Node* x) { if (x != NIL) { if (NIL != x->left) { DeleteTree(x->left); } if (NIL != x->right) { DeleteTree(x->right); } delete x; x = NULL; } } template<typename T, typename Comp> typename RedBlackTree<T, Comp>::Node* RedBlackTree<T, Comp>::TreeSearchNumber(Node* x, T k) { if (x == NIL || k == x->key) return x; if (compare(x->key, k)) return TreeSearchNumber(x->left, k); else return TreeSearchNumber(x->right, k); } template<typename T, typename Comp> typename RedBlackTree<T, Comp>::Node* RedBlackTree<T, Comp>::TreeSuccessor(Node* x) //存在两种情况: { if (x->right != NIL) //如果结点x的右子树非空,则x的后继即右子树中的最左的结点。 return TreeMinIMUM(x->right); Node* y = x->parent; //如果结点x的右子树为空,且x有一个后继y,则y是x的最低祖先结点, while ((y != NIL) && (x == x->right)) //且y的左儿子也是x的祖先票篇 p154,p155《算法导论》 { x = y; y = y->parent; } return y; } template<typename T, typename Comp> void RedBlackTree<T, Comp>::LeftRotate(Node* x) { Node* y = x->right; //y是x的右结点 if (NIL == y) return; x->right = y->left; //让x的右指针指向y的左结点。 if (NIL != y->left) //y的左结点不是哨兵 y->left->parent = x; //让y的左结点的parent指向x y->parent = x->parent; //让y的父子针指向x的父结点 if (x->parent == NIL) //x为根结点 { root = y; //让y成为根结点 } else if (x == x->parent->left) //如果x为左子女 { x->parent->left = y; //y便代替x成为左子女 } else x->parent->right = y; //否则代替x成为右子女 y->left = x; //x成为y的左子女 x->parent = y; //y成为x的父结点 } template<typename T, typename Comp> void RedBlackTree<T, Comp>::RightRotate(Node* y) { Node* x = y->left; if (NIL == x) return; y->left = x->right; if (x->right != NIL) x->right->parent = y; x->parent = y->parent; if (y->parent == NIL) { root = x; } else if (y == y->parent->right) { y->parent->right = x; } else { y->parent->left = x; } x->right = y; y->parent = x; } template<typename T, typename Comp> bool RedBlackTree<T, Comp>::RBInsert(T data) { Node* x = root; Node* y = NIL; while (x != NIL) { y = x; if (compare(data, x->key)) // 如果data <= x->key { if (isUnique && compare(x->key, data)) {// 如果a<=b同时b<=a,那么a=b. // 找到相同的节点,如果不允许相同节点,则返回 return false; } if (x->left != NIL) { x = x->left; } else { break; } } else { if (x->right != NIL) { x = x->right; } else { break; } } } Node* z = new Node(data, RED, y, NIL, NIL); //将要插入的结点 if (y == NIL) root = z; else if (compare(data, y->key)) y->left = z; else y->right = z; RBInsertFixup(z); return true; } //在调用RBInsertFixup(),那些红黑树的性质可能会被破坏呢?性质1和性质3当然继续成立, //因为新插入的结点的子女都是哨兵NIL。性质5即从一个制定结点开始的每条路径上黑结点的个数 //都是相等的,也会成立,因为结点z本身就是具有哨兵子女的红结点。因此,可能被破坏的就是根节点2, //以及一个红结点不能有红子女的性质4。这两个可能的破坏是因为z被着为红色。如果z是根结点则破坏了性质2, //如果z的父结点是红色就破坏了性质4. template<typename T, typename Comp> void RedBlackTree<T, Comp>::RBInsertFixup(Node* z) { Node* y = NIL; while (root != z && z->parent->color == RED) { if (z->parent == z->parent->parent->left) { y = z->parent->parent->right; if (y != NIL && y->color == RED) { z->parent->color = BLACK; y->color = BLACK; z->parent->parent->color = RED; z = z->parent->parent; } else { if (z == z->parent->right) { z = z->parent; LeftRotate(z); } z->parent->color = BLACK; z->parent->parent->color = RED; //还没旋转 RightRotate(z->parent->parent); } } else { y = z->parent->parent->left; if (y != NIL && y->color == RED) { z->parent->color = BLACK; y->color = BLACK; z->parent->parent->color = RED; z = z->parent->parent; } else { if (z == z->parent->left) { z = z->parent; RightRotate(z); } z->parent->color = BLACK; z->parent->parent->color = RED; LeftRotate(z->parent->parent); } } } //while root->color = BLACK; } template<typename T, typename Comp> void RedBlackTree<T, Comp>::RBDelete(T data) { Node* x = NIL; Node* y = NIL; //查找看有没有值和同结点指示的一样 Node* z = TreeSearchNumber(root, data); //找到此结点 if ((z->left == NIL) || (z->right == NIL)) { y = z; } else { y = TreeSuccessor(z); } if (y->left != NIL) { x = y->left; } else { x = y->right; } x->parent = y->parent; if (y->parent == NIL) root = x; else if (y == y->parent->left) y->parent->left = x; else y->parent->right = x; if (y != z) z->key = y->key; if (y->color == BLACK && NIL != x) RBDeleteFixUp(x); delete y; } template<typename T, typename Comp> void RedBlackTree<T, Comp>::RBDeleteFixUp(Node* x) { Node* w = NIL; while (x != root && BLACK == x->color) { if (x == x->parent->left) { w = x->parent->right; if (NIL == w) continue; if (w->color == RED) { w->color = BLACK; x->parent->color = RED; LeftRotate(x->parent); w = x->parent->right; } if (NIL != w->left && BLACK == w->left->color && NIL != w->right && BLACK == w->right->color) { w->color = RED; x = x->parent; } else { if (NIL != w->right && BLACK == w->right->color) { w->left->color = BLACK; w->color = RED; RightRotate(w); w = x->parent->right; } w->color = x->parent->color; x->parent->color = BLACK; w->right->color = BLACK; LeftRotate(x->parent); x = root; } } else { w = x->parent->left; if (NIL == w) continue; if (RED == w->color) { w->color = BLACK; x->parent->color = RED; RightRotate(x->parent); } if (NIL != w->left && BLACK == w->left->color && NIL != w->right && BLACK == w->right->color) { w->color = RED; x = x->parent; } else { if (NIL != w->left && w->left->color == BLACK) { w->right->color = BLACK; w->color = RED; LeftRotate(w); w = x->parent->left; } w->color = w->parent->color; w->parent->color = BLACK; w->left->color = BLACK; RightRotate(w->parent); x = root; } } } x->color = BLACK; }这个是红黑树的实现代码,是从别人那拷贝过来,根据我的需要增加了一个仿函数的模板参数.这里就不详细介绍了。
file:OnePlayerGame.h
#ifndef ONEPLAYERGAME_H_ #define ONEPLAYERGAME_H_ #include <functional> #include "RBTree.h" #include "OnePlayerMap.h" using namespace std; //仿函数,用来对两个指针类型的对象调用其less_euqal(T)函数 template <class T> struct less_euqal_pointer: public binary_function<T, T, bool> { bool operator()(const T&x, const T& y) const { return (*x).less_equal(y); } }; class OnePlayerGame { public: OnePlayerGame(OnePlayerMap* state) :mStartState(state) ,mEndState(NULL) ,mHasSolution(false) { mStartState->mNext = mStartState; } virtual ~OnePlayerGame() { clear(); } bool startFindSolution(int maxStep = 10000); // 缺省最大寻找10000步数, 查找步数大于maxStep时报失败,广度搜索 bool hasSolution() {return mHasSolution;} void printSolution(); protected: void clear();//清除占用的内存 OnePlayerMap* mStartState; OnePlayerMap* mEndState; bool mHasSolution; RedBlackTree<OnePlayerMap*, less_euqal_pointer<OnePlayerMap*> > mRedBlackTree; }; #endif /* ONEPLAYERGAME_H_ */调用步骤是,构造时传入初始状态,然后调用startFindSolution(maxStep), 找到solution返回true,否则返回false,maxStep是尝试的最大步数,超过这个步数则失败。
bool hasSolution()返回调用startFindSolution是否找到solution的结果
printSolution()如果有找到solution,则调用此方法将每一步打印出来,从上到下是从最终结果往初始状态一步一步显示出来,以后可以考虑反过来显示。
file:OnePlayerGame.cpp
#include <stdio.h> #include "OnePlayerGame.h" int OnePlayerMap::count = 0; bool OnePlayerGame::startFindSolution(int maxStep) { OnePlayerMap* p = mStartState; OnePlayerMap* tail = mStartState->mNext; mHasSolution = false; while(p != NULL && p->mStep < maxStep) { if (p->isEnd()) { mHasSolution = true; mEndState = p; break; } OnePlayerMap* nextStatus = p->getNextStatuses();//返回环形链表,最后一个元素的mNext是nextStatus。 tail->mNext = nextStatus; while(tail->mNext != NULL) { if (mRedBlackTree.RBInsert(tail->mNext)) {//插入成功,没有重复 tail->mNext->mStep = p->mStep + 1; tail = tail->mNext; } else { // 已经有重复的状态了,删除该状态 OnePlayerMap* temp = tail->mNext; tail->mNext = tail->mNext->mNext; delete temp; } } p = p->mNext; } return mHasSolution; } void OnePlayerGame::printSolution() { if (mHasSolution) { //printf("total states:%d\n", state->count); int count = 0; OnePlayerMap* p = mEndState; while(p != NULL) { p->print(); p = p->mLastMap; count++; } printf("total steps:%d\n", count); } else { printf("can't found solution\n"); } } void OnePlayerGame::clear() { OnePlayerMap* p = mStartState->mNext; while (p != NULL) { OnePlayerMap* temp = p; p=p->mNext; delete temp; } }
file:HuaRongDaoMap.h
#ifndef HUARONGDAOMAP_H_ #define HUARONGDAOMAP_H_ #include <stdlib.h> #include "OnePlayerMap.h" class HuaRongDaoMap : public OnePlayerMap { public: HuaRongDaoMap() :mCao(0) ,mShujiang(0) ,mHengjiang(0) ,mBing(0) ,mKongge(0) {} HuaRongDaoMap(const char chessNumber, const char chess[]); HuaRongDaoMap(const HuaRongDaoMap& status) :mCao(status.mCao) ,mShujiang(status.mShujiang) ,mHengjiang(status.mHengjiang) ,mBing(status.mBing) ,mKongge(status.mKongge) { } bool less_equal(const OnePlayerMap* status); virtual bool isEnd(){return (mCao == 10);} virtual OnePlayerMap* getNextStatuses(); // 交换一个数中两个部分的位值 // value: 被交换的数 // source, target :要交换的位的起始位置 // length: 要交换的位数 int switchbits(int value, int source, int target, int length) { int x = ((value >> source) ^ (value >> target)) & ((1U << length) - 1); // XOR temporary return value ^ ((x << source) | (x << target)); } virtual void print(); char mCao;// possible value 0 - 11, int mShujiang; int mHengjiang; int mBing; int mKongge; }; #endif /* HUARONGDAOMAP_H_ */
file:HuaRongDao.cpp
#include <stdio.h> #include <assert.h> #include "HuaRongDaoMap.h" HuaRongDaoMap::HuaRongDaoMap(const char chessNumber, const char chess[]) :mShujiang(0) ,mHengjiang(0) ,mBing(0) ,mKongge(0) { int bMap = 0; int position = 0; int squalNumber = 0; for (int i = 0; i < chessNumber; i++) { switch(chess[i]) { case 'k':// kongge squalNumber++; mKongge |= (1 << position); bMap |= (1 << position); break; case 'b':// bing squalNumber++; mBing |= (1 << position); bMap |= (1 << position); break; case 's':// shujiang squalNumber += 2; mShujiang |= (1 << position); bMap |= (1 << position); bMap |= (1 << (position + 4)); break; case 'h':// hengjiang { squalNumber += 2; int x = position & 0x3; int y = position >> 2; mHengjiang |= (1 << (y * 3 + x)); bMap |= (3 << position); } break; case 'c':// cao { squalNumber += 4; int x = position & 0x3; int y = position >> 2; mCao = y * 3 + x; bMap |= (3 << position); bMap |= (3 << (position + 4)); } break; } while(bMap >> position & 1) { position++; } } assert(squalNumber == 20); } OnePlayerMap* HuaRongDaoMap::getNextStatuses() { HuaRongDaoMap head; OnePlayerMap* point = &head; // move cao int caoX = mCao % 3; // 7, x=1, y = 2 int caoY = mCao / 3; // 2, x=2, y = 0 if (caoX > 0) { int leftOne = (caoY << 2) + caoX - 1; if ((1 << leftOne & mKongge) && (1 << (leftOne + 4) & mKongge)) { // move left HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mCao = mCao - 1; state->mKongge = switchbits(state->mKongge, leftOne + 2, leftOne, 1); state->mKongge = switchbits(state->mKongge, leftOne + 2 + 4, leftOne + 4, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; } } if (caoX < 2) { int rightOne = (caoY << 2) + caoX + 2; if ((1 << rightOne & mKongge) && (1 << (rightOne + 4) & mKongge)) { // move right HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mCao = mCao + 1; state->mKongge = switchbits(state->mKongge, rightOne - 2, rightOne, 1); state->mKongge = switchbits(state->mKongge, rightOne - 2 + 4, rightOne + 4, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; } } if (caoY > 0) { int upOne = (caoY << 2) - 4 + caoX; if ((1 << upOne & mKongge) && (1 << (upOne + 1) & mKongge)) { // move up HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mCao = mCao - 3; state->mKongge = switchbits(state->mKongge, upOne + 8, upOne, 1); state->mKongge = switchbits(state->mKongge, upOne + 8 + 1, upOne + 1, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; } } if (caoY < 3) { int downOne = (caoY << 2) + 8 + caoX ;// cao 的下面位置,用来判断是否是空格 if ((1 << downOne & mKongge) && (1 << (downOne + 1) & mKongge)) { // move down HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mCao = mCao + 3; state->mKongge = switchbits(state->mKongge, downOne - 8, downOne, 1); state->mKongge = switchbits(state->mKongge, downOne - 8 + 1, downOne + 1, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; } } // move heng jiang for (int i = 0; i < 15; i++) { if (mHengjiang >> i & 1) { int hengX = i % 3; int hengY = i / 3; if (hengX > 0) { int leftOne = (hengY << 2) + hengX - 1; if (1 << leftOne & mKongge) { // move 1 left HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mHengjiang = switchbits(state->mHengjiang, i, i - 1, 1); state->mKongge = switchbits(state->mKongge, leftOne, leftOne + 2, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; if ( hengX > 1 && (1 << (leftOne - 1) & mKongge)) { // move 2 left HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mHengjiang = switchbits(state->mHengjiang, i, i - 2, 1); state->mKongge = switchbits(state->mKongge, leftOne - 1, leftOne - 1 + 2, 2); state->mLastMap = this; point->mNext = state; point = point->mNext; } } } if (hengX < 2) { int rightOne = (hengY << 2) + hengX + 2; if (1 << rightOne & mKongge) { // move 1 right HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mHengjiang = switchbits(state->mHengjiang, i, i + 1, 1); state->mKongge = switchbits(state->mKongge, rightOne, rightOne - 2, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; if (hengX < 1 && (1 << (rightOne + 1) & mKongge)) { // move 2 right HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mHengjiang = switchbits(state->mHengjiang, i, i + 2, 1); state->mKongge = switchbits(state->mKongge, rightOne, rightOne - 2, 2); state->mLastMap = this; point->mNext = state; point = point->mNext; } } } if (hengY > 0) { int upOne = (hengY << 2) + hengX - 4; if ((1 << upOne & mKongge) && (1 << (upOne + 1) & mKongge)) { // move up HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mHengjiang = switchbits(state->mHengjiang, i, i - 3, 1); state->mKongge = switchbits(state->mKongge, upOne, upOne + 4, 2); state->mLastMap = this; point->mNext = state; point = point->mNext; } } if (hengY < 4) { int downOne = (hengY << 2) + hengX + 4; if ((1 << downOne & mKongge) && (1 << (downOne + 1) & mKongge)) { // move down HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mHengjiang = switchbits(state->mHengjiang, i, i + 3, 1); state->mKongge = switchbits(state->mKongge, downOne, downOne - 4, 2); state->mLastMap = this; point->mNext = state; point = point->mNext; } } } } // move shu jiang for (int i = 0; i < 16; i++) { if (mShujiang >> i & 1) { int shuX = i & 3; int shuY = i >> 2; if (shuX > 0) { int leftOne = i - 1; if ((1 << leftOne & mKongge) && (1 << (leftOne + 4) & mKongge)) { // move left HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mShujiang = switchbits(state->mShujiang, i, i - 1, 1); state->mKongge = switchbits(state->mKongge, leftOne, leftOne + 1, 1); state->mKongge = switchbits(state->mKongge, leftOne + 4, leftOne + 4 + 1, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; } } if (shuX < 3) { int rightOne = i + 1; if ((1 << rightOne & mKongge) && (1 << (rightOne + 4) & mKongge)) { // move right HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mShujiang = switchbits(state->mShujiang, i, i + 1, 1); state->mKongge = switchbits(state->mKongge, rightOne, rightOne - 1, 1); state->mKongge = switchbits(state->mKongge, rightOne + 4, rightOne + 4 - 1, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; } } if (shuY > 0) { int upOne = i - 4; if (1 << upOne & mKongge) { // move 1 up HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mShujiang = switchbits(state->mShujiang, i, i - 4, 1); state->mKongge = switchbits(state->mKongge, upOne, upOne + 8, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; if (shuY > 1 && (1 << (upOne - 4) & mKongge)) { // move 2 up HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mShujiang = switchbits(state->mShujiang, i, i - 8, 1); state->mKongge = switchbits(state->mKongge, upOne, upOne + 8, 1); state->mKongge = switchbits(state->mKongge, upOne - 4, upOne + 4, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; } } } if (shuY < 3) { int downOne = i + 8; if (1 << downOne & mKongge) { // move 1 down HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mShujiang = switchbits(state->mShujiang, i, i + 4, 1); state->mKongge = switchbits(state->mKongge, downOne, downOne - 8, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; if (shuY < 2 && (1 << (downOne + 4) & mKongge)) { // move 2 down HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mShujiang = switchbits(state->mShujiang, i, i + 8, 1); state->mKongge = switchbits(state->mKongge, downOne, downOne - 8, 1); state->mKongge = switchbits(state->mKongge, downOne + 4, downOne - 4, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; } } } } } // move bing for (int i = 0; i < 20; i++) { if (mBing >> i & 1) { int bingX = i & 3; int bingY = i >> 2; if (bingX > 0) { if (1 << (i - 1) & mKongge) { // move l left HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mBing = switchbits(state->mBing, i, i - 1, 1); state->mKongge = switchbits(state->mKongge, i - 1, i, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; if (bingX > 1 && (1 << (i - 2) & mKongge)) { // move 2 left HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mBing = switchbits(state->mBing, i, i - 2, 1); state->mKongge = switchbits(state->mKongge, i - 2, i, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; } if (bingY > 0 && (1 << (i - 5) & mKongge)) { // move left up HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mBing = switchbits(state->mBing, i, i - 5, 1); state->mKongge = switchbits(state->mKongge, i - 5, i, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; } if (bingY < 4 && (1 << (i + 3) & mKongge)) { // move left down HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mBing = switchbits(state->mBing, i, i + 3, 1); state->mKongge = switchbits(state->mKongge, i + 3, i, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; } } } if (bingX < 3) { if (1 << (i + 1) & mKongge) { // move 1 right HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mBing = switchbits(state->mBing, i, i + 1, 1); state->mKongge = switchbits(state->mKongge, i + 1, i, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; if (bingX < 2 && (1 << (i + 2) & mKongge)) { // move 2 right HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mBing = switchbits(state->mBing, i, i + 2, 1); state->mKongge = switchbits(state->mKongge, i + 2, i, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; } if (bingY > 0 && (1 << (i - 3) & mKongge)) { // move right up HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mBing = switchbits(state->mBing, i, i - 3, 1); state->mKongge = switchbits(state->mKongge, i - 3, i, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; } if (bingY < 4 && (1 << (i + 5) & mKongge)) { // move right down HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mBing = switchbits(state->mBing, i, i + 5, 1); state->mKongge = switchbits(state->mKongge, i + 5, i, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; } } } if (bingY > 0) { if (1 << (i - 4) & mKongge) { // move 1 up HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mBing = switchbits(state->mBing, i, i - 4, 1); state->mKongge = switchbits(state->mKongge, i - 4, i, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; if (bingY > 1 && (1 << (i - 8) & mKongge)) { // move 2 up HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mBing = switchbits(state->mBing, i, i - 8, 1); state->mKongge = switchbits(state->mKongge, i - 8, i, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; } if (bingX > 0 && (1 << (i - 5) & mKongge)) { // move up left HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mBing = switchbits(state->mBing, i, i - 5, 1); state->mKongge = switchbits(state->mKongge, i - 5, i, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; } if (bingX < 3 && (1 << (i - 3) & mKongge)) { // move up right HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mBing = switchbits(state->mBing, i, i - 3, 1); state->mKongge = switchbits(state->mKongge, i - 3, i, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; } } } if (bingY < 4) { if (1 << (i + 4) & mKongge) { // move 1 down HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mBing = switchbits(state->mBing, i, i + 4, 1); state->mKongge = switchbits(state->mKongge, i + 4, i, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; if (bingY < 3 && (1 << (i + 8) & mKongge)) { // move 2 down HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mBing = switchbits(state->mBing, i, i + 8, 1); state->mKongge = switchbits(state->mKongge, i + 8, i, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; } if (bingX > 0 && (1 << (i + 3) & mKongge)) { // move down left HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mBing = switchbits(state->mBing, i, i + 3, 1); state->mKongge = switchbits(state->mKongge, i + 3, i, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; } if (bingX < 3 && (1 << (i + 5) & mKongge)) { // move down right HuaRongDaoMap* state = new HuaRongDaoMap(*this); state->mBing = switchbits(state->mBing, i, i + 5, 1); state->mKongge = switchbits(state->mKongge, i + 5, i, 1); state->mLastMap = this; point->mNext = state; point = point->mNext; } } } } } point->mNext = NULL; return head.mNext; } void HuaRongDaoMap::print() { char map[4][5]; int caoX = mCao % 3; int caoY = mCao / 3; map[caoX][caoY] = 5; map[caoX + 1][caoY] = 5; map[caoX][caoY + 1] = 5; map[caoX + 1][caoY + 1] = 5; for (int i = 0; i < 15; i++) { if (1 << i & mHengjiang) { int hengX = i % 3; int hengY = i / 3; map[hengX][hengY] = 4; map[hengX + 1][hengY] = 4; } } for (int i = 0; i < 16; i++) { if (1 << i & mShujiang) { int shuX = i & 3; int shuY = i >> 2; map[shuX][shuY] = 3; map[shuX][shuY + 1] = 3; } } for (int i = 0; i < 20; i++) { if (1 << i & mBing) { map[i & 3][i >> 2] = 1; } } for (int i = 0; i < 20; i++) { if (1 << i & mKongge) { map[i & 3][i >> 2] = 0; } } for (int i = 0; i < 5; i++) { for (int j = 0; j < 4; j++) { printf("%d ", map[j][i]); } printf("\n"); } printf("\n"); } bool HuaRongDaoMap::less_equal(const OnePlayerMap* status) { const HuaRongDaoMap* newData = dynamic_cast<const HuaRongDaoMap*>(status); assert(newData != NULL); int val = (mHengjiang << 16 | mShujiang); int newval = (newData->mHengjiang << 16 | newData->mShujiang); if (val != newval) { return val <= newval; } int val2 = ((mBing << 4) | mCao); int newval2 = (newData->mBing << 4) | newData->mCao; return val2 <= newval2; }
file:main.cpp
#include <stdio.h> #include <sys/time.h> #include "OnePlayerGame.h" #include "HuaRongDaoMap.h" int main() { { HuaRongDaoMap state(12,"kcksbhbbhsbh"); printf("play game\n"); OnePlayerGame oneGame(&state); struct timeval tpstart,tpend; gettimeofday(&tpstart,NULL); //获取时间 oneGame.startFindSolution(); gettimeofday(&tpend,NULL); printf("find solution time is %ld usecond\n", 1000000 * (tpend.tv_sec - tpstart.tv_sec) + tpend.tv_usec-tpstart.tv_usec); if (oneGame.hasSolution()) { oneGame.printSolution(); } else { printf("can't find solution.\n"); } printf("OnePlayerMap allocate Node Count:%d\n", OnePlayerMap::count); } printf("OnePlayerMap Node Count after release:%d\n", OnePlayerMap::count); return 0; }这个框架只用参照HuaRongDaoMap.h(.cpp),重新写一个派生类,实现那几个函数,就可以很简单的运行了。