Discuz! Board

 找回密码
 立即注册
查看: 112|回复: 0

加入U盘内容

[复制链接]

15

主题

16

帖子

24万

积分

论坛元老

Rank: 8Rank: 8

积分
241078
发表于 2024-3-22 19:22:30 | 显示全部楼层 |阅读模式
#include <graphics.h>
#include<cstdio>
#include<bits/stdc++.h>
using namespace std;

#define Row 3
#define Col 3
int board[Row][Col];                //棋盘
key_msg keyMsg;                                //键盘
int zx,zy;//0的位置

int m1[3][3]={
        1,2,5,
        3,4,8,
        6,7,0,
} ;
int m2[3][3]={0};

PIMAGE pimgs[9];                        //棋盘图片

void loadImage()//图片载入
{
        char path[100];                        //加载图片路径
        for(int i=0;i<9;i++)
        {
                pimgs[i]=newimage();        //向计算机申请一个图片空间
                sprintf(path,"image/%d.png",i);//拼接图片相对路径
                getimage(pimgs[i],path);//将系统中的图片数据存入pimgs
        }
}

void draw()//图形绘制
{
        setcolor(RED);
        for(int i=0;i<Row;i++)
        for(int j=0;j<Col;j++)
        {
                if(board[i][j]>0)        putimage(j*100,i*100,pimgs[board[i][j]]);
        }
        setcolor(BLACK);
        line(100,0,100,300);
        line(200,0,200,300);
        line(0,100,300,100);
        line(0,200,300,200);
}

bool gameover()
{
        for(int i=0;i<Row;i++)
        for(int j=0;j<Col;j++)
        {
                if (board[i][j] != i*3+j)
                {
                        return false;
                }
        }
        //游戏结束
        return true;
}

void find_zero(int b[][3])//找到0,使用函数,可以提前结束寻找
{
        for(int i=0;i<Row;i++)
        for(int j=0;j<Col;j++)
        {
                if(b[i][j]==0)
                {
                        zx=i;
                        zy=j;
                        return;
                }
        }
}

int update_n(int m,int x)//根据现有棋盘特征值,动作 更新棋盘特征值
{
        int n=0;
        for(int i=2;i>=0;i--)//还原棋盘
        for(int j=2;j>=0;j--)
        {
                m2[i][j]=m%10;
                m=m/10;//形式参数,不会改变m的引用值
        }
       
        find_zero(m2);
       
        switch(x)
        {
                case 1:
                        if(zx<2)        swap(m2[zx][zy],m2[zx+1][zy]);
                        else return -1;//无法移动 返回-1
                        break;
                case 3:
                        if(zy<2)        swap(m2[zx][zy],m2[zx][zy+1]);
                        else return -1;
                        break;
                case 2:
                        if(zx>0)        swap(m2[zx][zy],m2[zx-1][zy]);
                        else return -1;
                        break;
                case 4:
                        if(zy>0)        swap(m2[zx][zy],m2[zx][zy-1]);
                        else return -1;
                        break;
                default:break;
        }
        for(int i=0;i<=2;i++)//更新棋盘特征值
        for(int j=0;j<=2;j++)
                n=n*10+m2[i][j];
        return n;
       
}

void bfs_8s()
{
        set<int> check;//标记用 集合
        int a[65536]={0};//特征值记录
        int b[65536]={0};//记录动作 1上 2下 3左 4右
        int c[65536]={0};//父节点记录         
        int h=0,t=1;

//        b[1]=0;
//        s[1]=1;
        int n=0;//特征值
        for(int i=0;i<=2;i++)
        for(int j=0;j<=2;j++)
                n=n*10+m2[i][j];
        check.insert(n);//标记值n纳入集合
        a[1]=n;//动作后的特征值
        b[1]=0;//记录动作
        c[1]=0;//父节点记录       
        cout<<n<<endl;
        while(1)
        {
                h++;
                for(int i=1;i<=4;i++)//四个方向
                {
                        int k=update_n(a[h],i);//特征值为n的组合,翻转位置j的棋子
                        //cout<<k<<endl;
                        if(k!=-1&&(!check.count(k)))//可以向i方向移动+特征值未出现过
                        {
                                t++;
                                check.insert(k);
                                a[t]=k;       
                                b[t]=i;
                                c[t]=h;
                        //        cout<<k<<" "<<i<<" "<<h<<" "<<endl;
                        //        getch();                               
                                if(k==12345678)//全黑
                                {
                                        h=t;
                                        int t2=t;
                                //        cout<<k<<" "<<i<<" "<<j<<" "<<h<<" "<<endl;
                                //        getch();
                                       
                                        while(1)
                                        {
                                                if(c[t2]==0) break;
                                                cout<<b[t2]<<"<-";
                                                //getch();
                                                t2=c[t2];
                                        }
                                        break;
                                }
                        }                        
                }
                if(h>=t) break;
        }
               
}

void update()
{
        find_zero(board);
        switch(keyMsg.key)
        {
                case 'W':
                        if(zx<2) swap(board[zx][zy],board[zx+1][zy]);
                        break;
                case 'A':
                        if(zy<2) swap(board[zx][zy],board[zx][zy+1]);
                        break;
                case 'S':
                        if(zx>0) swap(board[zx][zy],board[zx-1][zy]);
                        break;
                case 'D':
                        if(zy>0) swap(board[zx][zy],board[zx][zy-1]);
                        break;
                case 'Q':
                        memcpy(board, m1, sizeof(m1));
                        break;
                case 'E':
                        memcpy(m2, board, sizeof(board));
                        bfs_8s();
                        break;
                default:break;
        }
}








void start()//初始化
{
//关闭窗口不强制退出程序,以便进行游戏保存工作
//        setinitmode(INIT_RENDERMANUAL | INIT_NOFORCEEXIT, 100, 50);

        initgraph(Col*100,Row*100);//图形初始化        
        setcaption("翻转游戏");        //设置程序标题
        setbkcolor(WHITE);
        setlinewidth(5);// 设置当前线宽
        setcolor(RED);
        setfont(85,0,"微软雅黑");//(字体高度,字体宽度(为0即为自适应),字形)设置字体为25,幼圆字体
        setbkmode(TRANSPARENT); //设置文字背景色为透明(默认为有背景色)
        loadImage();
       
        memcpy(board, m1, sizeof(m1));
}



int main()
{
        start();
        while(1)
        {       
                while(kbmsg())
                {
                        keyMsg = getkey();
                        if ((keyMsg.msg == key_msg_down)&&((keyMsg.key=='A')||(keyMsg.key=='S')||
                        (keyMsg.key=='W')||(keyMsg.key=='D')||(keyMsg.key=='Q'))||(keyMsg.key=='E'))
                        {
                                update();       
                        }
                }

                draw();
                delay_fps(60);
                if(gameover())        {xyprintf(50,50,"获胜"); getch();}
                cleardevice();
        }
        getch();
        return 0;
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|DiscuzX

GMT+8, 2025-5-29 22:14 , Processed in 0.058388 second(s), 27 queries .

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.. 技术支持 by 巅峰设计

快速回复 返回顶部 返回列表