棋盘游戏

Posted fangbozhen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了棋盘游戏相关的知识,希望对你有一定的参考价值。

https://loj.ac/problem/10029

题目描述

  在一个4×4的棋盘上有 8个黑棋和8个白棋,当且仅当两个格子有公共边,这两个格子上的棋是相邻的。移动棋子的规则是交换相邻两个棋子。
给出一个初始棋盘和一个最终棋盘,请找出一个最短的移动序列使初始棋盘变为最终棋盘,输出最短序列的长度。

思路

  数据如此之小,显然是要我们搜索。而这里对棋盘可以直接简单的压缩为一个16位的二进制数,那么显然我们可以很好的存储状态。接下来要考虑的就是如何对当前状态进行拓展。首先我们易知操作世界上只有两种,一是交换左右棋子,二是交换上下棋子,我们只需要用位运算取出每一位的颜色并且判断与之交换的棋子颜色是否相同,再尝试进行两种交换判是否出现过即可。

代码

#include <bits/stdc++.h>
using namespace std;
bool vis[70000];
int step[70000];
queue<int> q;
int main() 
{
    int a=0,b=0;
    char s[5];
    for(int i=1;i<=4;i++)
    {
        scanf(" %s",s);
        for(int j=0;j<4;j++)
            a=a*2+s[j]-0;
    }
    for(int i=1;i<=4;i++)
    {
        scanf(" %s",s);
        for(int j=0;j<4;j++)
            b=b*2+s[j]-0;
    }
    q.push(a);
    vis[a]=1;step[a]=0;
    int p;
    while(!q.empty())
    {
        int now=q.front();q.pop();
        if(now==b)
        {
            printf("%d",step[now]);
            break ;
        }
        for(int i=0;i<16;i++)
        {
            if(i%4!=0&&(now&(1<<i)^(now&(1<<i-1)))&&!vis[p=now^(1<<i)^(1<<i-1)])
            {
                vis[p]=1;
                step[p]=step[now]+1;
                q.push(p);
            }
            if(i<12&&(now&(1<<i))^(now&(1<<i+4))&&!vis[p=now^(1<<i)^(1<<i+4)])
            {
                vis[p]=1;
                step[p]=step[now]+1;
                q.push(p);
            }
        }
    }
    return 0;
}

 

以上是关于棋盘游戏的主要内容,如果未能解决你的问题,请参考以下文章

移动椭圆的板绘图代码

[C语言]扫雷小游戏实现 注释 代码

[C语言]扫雷小游戏实现 注释 代码

HTML5 实现黑白棋游戏|附代码

棋盘游戏

C语言实现扫雷游戏(一步步教你如何写扫雷)