基于A*算法的迷宫游戏开发

项目目标和主要内容
实验任务:
1)对九宫重排问题,建立图的启发式搜索求解方法;
2)用A*算法求解九宫重排问题。
实验要求:
3х3九宫棋盘,放置数码为1~8的8个棋子,棋盘中留有一个空格,空格周围的棋子可以移动到空格中,从而改变棋盘的布局。根据给定初始布局和目标布局,移动棋子从初始布局到达目标布局,求解移动步骤并输出。请设计算法,使用合适的搜索策略,在较少的空间和时间代价下找到最短路径。

1.2项目的主要功能
根据给定的初始状态和目标状态,使用合适的搜索策略,在较少的空间和时间代价下找到最短路径。

系统设计
(1)把起点加入openlist
(2)重复如下过程:
a.遍历openlist,查找F值最小的节点,把它作为当前要处理的节点
b.把这个节点移到close list(已经考察过的列表)
c.对当前节点的所有邻近节点
如果它是不可抵达的或者它在close list中,忽略它。否则,做如下操作
如果它不在openlist 中,检查这条路径(即经由当前节点到达它那里)是否更好,用G值作参考。更小的G值表示这是更好的路径。如果是这样,把它的父亲设置为当前方格,并重新计算它的G和F值。如果你的open list是按F值排序的花,改变你可能需要重新排序。
d.停止,当你
把重点加入到了open list中,此时路径已经找到了,或者查找终点失败,并且openlist是空的,此时没有路径
(3)保存路径。从重点开始,每个方格沿着父节点移动直至起点,这就是路径

源代码:
#pragma comment(lib, "winmm.lib ")
#include <windows.h>
#include
#include
#include
#include

using namespace std;
class Node {
public:
int Nine[3][3];
int f;
int h;
Node* child1, * child2, * child3, * child4;
Node* parent;
Node(int a[3][3], Node* p = NULL, Node* c1 = NULL, Node* c2 = NULL, Node* c3 = NULL, Node* c4 = NULL,int H=0)
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
Nine[i][j] = a[i][j];
parent = p;
child1 = c1;
child2 = c2;
child3 = c3;
child4 = c4;
h = H;
}
void setf(int g) { f = h + g; }
friend bool operator==(Node a, Node b)
{
bool flag = 1;
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
if (a.Nine[i][j] != b.Nine[i][j])return false;
return true;
}
friend bool operator>(Node a, Node b)
{
if (a.f > b.f)return 1;
else return 0;
}
};
class EightPuzzle {
private:
Node* start;
Node* target;
deque<Node*> dict;
stack shortpath;
public:
EightPuzzle(int a[3][3], int b[3][3]) { start = new Node(a); target = new Node(b); }
bool compare(Node* root, Node p);
void grow(Node* leaf);
void swap(int& a, int& b);
void Astar();
void print();
bool isexist();
};
bool EightPuzzle::isexist() {
int a = 0, b = 0;
for (int i = 0; i < 9; i++)
for (int j = 0; j < i; j++)
if (start->Nine[j] > start->Nine[i])a++;
for (int i = 0; i < 9; i++)
for (int j = 0; j < i; j++)
if (target->Nine[j] > target->Nine[i])b++;
if (a % 2 == b % 2)return 1;
else return 0;
}
bool EightPuzzle::compare(Node* root, Node p) {
if (root != NULL && root == p)return 1;
if (root->child1 != NULL)compare(root->child1, p);
if (root->child2 != NULL)compare(root->child2, p);
if (root->child3 != NULL)compare(root->child3, p);
if (root->child4 != NULL)compare(root->child4, p);
return 0;
}
void EightPuzzle::swap(int& a, int& b) {
int tmp = a;
a = b;
b = tmp;
}
void EightPuzzle::grow(Node
leaf) {
int a[3][3];
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
a[i][j] = leaf->Nine[i][j];
int x = 0, y = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (a[i][j] == 0) { x = i; y = j; }
}
}
if ((x - 1) >= 0)
{
Node p = leaf;
swap(p.Nine[x][y], p.Nine[x - 1][y]);
if (!compare(start, p))
{
Node
q = new Node§; leaf->child1 = q; q->parent = leaf;
q->h = leaf->h + 1;
int count = 0;
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
if (q->Nine[i][j] != target->Nine[i][j])count++;
q->setf(count);
dict.push_back(q);
}
}
if (x + 1 <= 2)
{
Node p = leaf;
swap(p.Nine[x][y], p.Nine[x + 1][y]);
if (!compare(start, p))
{
Node
q = new Node§; leaf->child1 = q; q->parent = leaf;
q->h = leaf->h + 1;
int count = 0;
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
if (q->Nine[i][j] != target->Nine[i][j])count++;
q->setf(count);
dict.push_back(q);
}
}
if (y - 1 >= 0)
{
Node p = leaf;
swap(p.Nine[x][y], p.Nine[x][y - 1]);
if (!compare(start, p))
{
Node
q = new Node§; leaf->child1 = q; q->parent = leaf;
q->h = leaf->h + 1;
int count = 0;
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
if (q->Nine[i][j] != target->Nine[i][j])count++;
q->setf(count);
dict.push_back(q);
}
}
if (y + 1 <= 2)
{
Node p = leaf;
swap(p.Nine[x][y], p.Nine[x][y + 1]);
if (!compare(start, p))
{
Node
q = new Node§; leaf->child1 = q; q->parent = leaf;
q->h = leaf->h + 1;
int count = 0;
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
if (q->Nine[i][j] != target->Nine[i][j])count++;
q->setf(count);
dict.push_back(q);
}
}
}
void EightPuzzle::Astar() {
if (isexist() == 0) { cout << “没有移动方法能从起始状态到目标状态!”; exit(1); }
else { cout << “移动步骤如下:\n”; }
Node* p = start;
dict.push_back§;
while (!(*p == target))
{
dict.pop_front();
grow§;
sort(dict.begin(), dict.end());
p = dict.front();
}
Node
q = p;
while (q != NULL)
{
shortpath.push(q);
q = q->parent;
}
}
void EightPuzzle::print() {
while (!shortpath.empty()) {
Node p = shortpath.top();
shortpath.pop();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++)
cout << p.Nine[i][j] << ’ ';
cout << endl;
}
cout << endl;
}
}
int main(int argc, char
argv[]) {
int a[3][3];
int b[3][3];
cout << “以九宫格形式输入初始状态:\n”;
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
cin >> a[i][j];
cout << “以九宫格形式输入最终状态:\n”;
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
cin >> b[i][j];
EightPuzzle test(a, b);
test.Astar();
test.print();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值