八数码

八数码

#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
#include <conio.h>
using namespace std;

struct node {
    int mp[9];
    int x,y,dis,value;
    int getValue(){
        int v = 0;
        for(int i = 0; i < 9; i++)
            v = v * 10 + mp[i];
        this->value = v;
        return v;
    }
};

const int N = 4e5;
const int mod = 8e5;
//变量
node goal,start,state[N];
queue <node> q;
int dx[4] = {1,-1,0,0},dy[4] = {0,0,1,-1};
int cnt,hs[2 * N];
bool st[2 * N];

int find (int value){//找出这个状态对应的hash值,x 表示状态的 value
    int k = value % mod;
    while(hs[k] != -1 && hs[k] != value){
        // cout << " yes" << endl;
        k++;
        if(k == mod) k = 0;
    }
    return k;
}

void bfs(){
    state[cnt++] = goal;
    q.push(goal);
    hs[find(goal.value)] = goal.value;
    st[find(goal.value)] = 1;
    while(q.size()){
        node tt = q.front();
        q.pop();
        // cout << " yes" << endl;
        for(int i = 0; i < 4; i++){
            int xx = tt.x + dx[i],yy = tt.y + dy[i];
            if(xx >= 0 && xx < 3 && yy >= 0 && yy < 3){
                node tp = tt;
                swap(tp.mp[tt.x * 3 + tt.y],tp.mp[xx * 3 + yy]);
                tp.getValue();
                tp.x = xx,tp.y = yy;
                tp.dis = tt.dis + 1;
                if(!st[find(tp.value)]){
                    hs[find(tp.value)] = tp.value;
                    st[find(tp.value)] = 1;
                    state[cnt++] = tp;
                    q.push(tp);
                }
            }
        }
    }
}

void init(){
    memset(hs,-1,sizeof hs);
    goal.mp[0] = 1,goal.mp[1] = 2,goal.mp[2] = 3;
    goal.mp[3] = 8,goal.mp[4] = 0,goal.mp[5] = 4;
    goal.mp[6] = 7 ,goal.mp[7] = 6,goal.mp[8] = 5;
    goal.x = goal.y = 1,goal.value = 123804765;
    goal.dis = 0;
    bfs();
}

void print(bool flag){
    if(!flag){
        puts("这种状态是无法到达目的状态的");
        exit(0);
    }
    char sp[10];
    for(int i = 0; i < 9; i++)
        if(start.mp[i] == 0) sp[i] = ' ';
        else sp[i] = '0' + start.mp[i];
        printf("--------------------------------\n");
        printf("| %c %c %c | %d %d %d |\n",sp[0],sp[1],sp[2],1,2,3);
        printf("| %c %c %c | %d %d %d |\n",sp[3],sp[4],sp[5],8,0,4);
        printf("| %c %c %c | %d %d %d | dis:%d步\n",sp[6],sp[7],sp[8],7,6,5,start.dis);
        printf("--------------------------------\n");
}

void opera (char op){
    int xx,yy;
    xx = start.x ,yy = start.y;
    if(op == 'w'){
        if(xx > 0)  xx--;
    }
    else if(op == 's'){
        if(xx < 2)  xx ++;
    }
    else if(op == 'a'){
        if(yy > 0)  yy--;
    }
    else {
        if(yy < 2)  yy++;
    }
    swap(start.mp[start.x * 3 + start.y],start.mp[xx * 3 + yy]);
    start.x = xx,start.y = yy;
    start.getValue();
    bool flag = 0;
    for(int i = 0; i < cnt; i++){
        if(start.value == state[i].value){
            start.dis = state[i].dis;
            flag = 1;
            break;
        }
    }
    print(flag);
}
int main()
{
    init();
    cout << "请输入初始状态:" << endl;
    for(int i = 0; i < 9; i++)  {
        cin >> start.mp[i];
        if(start.mp[i] == 0)    start.x = i / 3, start.y = i % 3;
    }
    cout << "请输入w s a d 控制小空格上下左右移动,使其达到目标状态" << endl;

    while(start.value != goal.value){
        char op = getch();
        opera(op);
    }
    cout << "你赢了!" << endl;
    return 0;
}

posted @ 2021-10-14 22:18  伍六柒-  阅读(60)  评论(0编辑  收藏  举报