最新无聊在玩华容道,结果玩的时候,有些关不知道怎么过,就自己想着写程序来求最小还原步数。经过一番搜索和思考,写出来下面的代码,其中借鉴了别人的红黑树的代码,还有就是使用广度搜索来求解的思想。
在写算法的过程中,突然想到还有其他的单人游戏也是可以用广度搜索来求解的,因此,就针对这类游戏写了一个框架,适用于状态数不会太变态的游戏,例如华容道,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),重新写一个派生类,实现那几个函数,就可以很简单的运行了。