HDU 1732 Push Box bfs

本文介绍了一个基于广度优先搜索(BFS)算法的Sokoban游戏求解器实现。通过C语言编程,利用多维数组记录游戏状态,并采用结构体节点来存储箱子和玩家的位置信息。通过对玩家及箱子的移动逻辑进行详细解析,实现了游戏从初始状态到目标状态的有效搜索。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;

char graph[9][9];
bool vis[9][9][9][9][9][9][9][9];
int m,n;
int dx[] = {0,0,1,-1};
int dy[] = {1,-1,0,0};

//X人 *箱子 #墙 @hole

struct Node{
    int x[4],y[4];  //0-2为箱子,3为人
    int step;
}t;

bool judge(int x,int y){
    if(x>=0 && x<m && y>=0 && y<n && graph[x][y]!='#')
        return true;
    return false;
}

int bfs(){
    queue<Node> q;
    Node cur,next;
    vis[t.x[0]][t.y[0]][t.x[1]][t.y[1]][t.x[2]][t.y[2]][t.x[3]][t.y[3]] = true;
    q.push(t);
    while(!q.empty()){
        cur = q.front();
        q.pop();
        //判断是否到达目标状态
        if(graph[cur.x[0]][cur.y[0]]=='@' && graph[cur.x[1]][cur.y[1]]=='@' && graph[cur.x[2]][cur.y[2]]=='@')
            return cur.step;
        for(int i=0;i<4;i++){
            next = cur;
            next.x[3] += dx[i];
            next.y[3] += dy[i];  //人进行移动
            if(judge(next.x[3],next.y[3])){  //人到达的位置是否合法
                bool flag = false;
                for(int j=0;j<3;j++){  //看人的新位置是否与某个箱子重合
                    if(next.x[3]==next.x[j] && next.y[3]==next.y[j]){
                        next.x[j] += dx[i];  //该箱子被推动了
                        next.y[j] += dy[i];
                        if(!judge(next.x[j],next.y[j]))
                            flag = true;
                        for(int k=0;k<3;k++){  //看其他箱子是否阻挡了该箱子的位置
                            if(j!=k && next.x[j]==next.x[k] && next.y[j]==next.y[k])
                                flag = true;
                        }
                    }
                }
                if(flag) continue;
                if(vis[next.x[0]][next.y[0]][next.x[1]][next.y[1]][next.x[2]][next.y[2]][next.x[3]][next.y[3]]) continue;
                vis[next.x[0]][next.y[0]][next.x[1]][next.y[1]][next.x[2]][next.y[2]][next.x[3]][next.y[3]] = true;
                next.step ++;
                q.push(next);
                
            }
        }
    }
    return -1;
}

int main(){
    while(scanf("%d%d",&m,&n)!=EOF){
        int idx = 0;
        t.step = 0;
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++){
                scanf(" %c",&graph[i][j]);
                if(graph[i][j]=='*'){
                    t.x[idx] = i;
                    t.y[idx++] = j;  //箱子的位置
                }
                else if(graph[i][j]=='X'){
                    t.x[3] = i;
                    t.y[3] = j;     //人的位置
                }
            }
        memset(vis,false,sizeof(vis));
        int res = bfs();
        printf("%d\n",res);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值