水量调节大师外挂(BFS)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36752486/article/details/84189193

      最近在室友推荐下玩水量调节大师,就是下图这个玩意儿。有些关卡智商不够用。。。就试了试用代码凑凑,没想到还真凑出来了。(⊙o⊙)…

附上游戏的下载链接:http://www.pc6.com/azyx/245880.html

忽略下面的大黑条,这游戏还没适配全面屏……

        喝了口水,接下来我们说重点。

         首先我们看看这个游戏的规则,只有三个瓶子(目前就玩到这儿,有四个咱们再说),每个瓶子只有四种操作

                   1、倒水给2号瓶。(假设这个瓶子编号为1)

                   2、倒水给三号瓶。

                   3、倒空。 

                    4、接满。

          并且给的操作步数也很有限。所以他的结构就是一种树形的结构,每一步之后可以再延伸四步,再往下走。(见下图)

                                                                              所以刚好用BFS来解。

          所以我们只要从上往下一层层来搜索即可。

          (搜索咋写的早就忘了,幸好我还有个小博客https://blog.csdn.net/qq_36752486/article/details/77160631

             看了看就试了试。。。)

          接下来我们来看代码即可。注释还是很多的。这个代码有个很大的问题就是用了string,在拼接的过程中非常耗时,

          考虑到不是打比赛,也不是非常要求效率就没改。(其实就是改成char[]跳了一堆bug,懒得去调试了(~ ̄▽ ̄)~ )

           再就是没有剪枝耗费了很多时间。当然我还是没改。233333333333

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<sstream>
using namespace std;
struct Node        ///瓶子的类,不不不,结构体
{
    int Now[3];     ///当前三个瓶子的水量
    int step;       ///步数
    string operate;
};
Node Begin, End;
int All[3];     ///三个瓶子的总水量。

int vis[101][101][101];   ///visit数组,记录是否访问过,1为真,0为假
int full_bottle, water, last_index;
int T, res;

int Sucess(Node a, Node b, int index)    ///结束判断数组,判断是否到达终点
{
    return (a.Now[index] == b.Now[index]);
}
/*void PR(Node m)
{
    printf("三个瓶子分别的总量:%d,%d,%d\n", m.All[1], m.All[2], m.All[3]);
    printf("三个瓶子分别的水量:%d,%d,%d\n", m.Now[1], m.Now[2], m.Now[3]);
    printf("当前步数:%d\n", m.step);
}*/
void Init()
{
    printf("请依次输入三个瓶子的储水量:");
    cin >> All[0] >> All[1] >> All[2];
    printf("请依次输入三个瓶子当前水量:");
    cin >> Begin.Now[0] >> Begin.Now[1] >> Begin.Now[2];
    Begin.step = 0;
    printf("请依次输入让几升的瓶子装入几升水:");
    cin >> full_bottle >> water;
    for(int i = 0; i < 3; i++)
    {
        if(All[i] == full_bottle)
        {
            End.Now[i] = water;
            last_index = i;
        }
    }
}

void BFS()
{
    queue<Node> Q;       ///建立队列,这儿建队有个好处,不用每次完了清空
    memset(vis, 0, sizeof(vis));
    Q.push(Begin);
    vis[Begin.Now[0]][Begin.Now[1]][Begin.Now[2]] = 1;
    while(!Q.empty())
    {
        Node u = Q.front();
        Q.pop();
        if(Sucess(u, End, last_index)) ///出口
        {
            res = u.step;
            printf("\n      一共需要如下%d步   \n",res);
            cout << u.operate<<endl;
            break;
        }
        for(int i = 0; i <= 2; i++)         ///三个瓶子之间倒水
        {
            for(int j = 0; j <= 2; j++)
            {
                if(i != j)
                {
                    Node over = u;
                    if(over.Now[i] >= All[j] - over.Now[j])   ///1的水比2空的部分多huozhexiangdeng
                    {
                        over.Now[i] = over.Now[i] - (All[j] - over.Now[j]);
                        over.Now[j] = All[j];
                    }
                    else
                    {
                        over.Now[j] = over.Now[j] + over.Now[i];
                        over.Now[i] = 0;
                    }
                    over.step = over.step + 1;

                    stringstream ss;
                    ss << All[i];
                    string si = ss.str();

                    stringstream sss;
                    sss << All[j];
                    string sj = sss.str();
                    string   cz = "      把" + si + "升瓶子倒到" + sj + "升瓶子   \n";
                    over.operate.append(cz);
                    if(!vis[over.Now[0]][over.Now[1]][over.Now[2]])
                    {
                        Q.push(over);
                        vis[over.Now[0]][over.Now[1]][over.Now[2]] = 1;
                    }
                }
            }
            Node now = u;               ///倒空某个瓶子
            now.Now[i] = 0;
            now.step = now.step + 1;
            // PR(now);
            stringstream ss;
            ss <<All[i];
            string si = ss.str();
            string cz = "      倒空" + si + "升瓶子   \n";
            now.operate.append(cz);
            Q.push(now);
            vis[now.Now[0]][now.Now[1]][now.Now[2]] = 1;

            Node now_2 = u;             ///倒满某个瓶子,其实这两段可以合成一段写的,太懒了,懒得整理
            now_2.Now[i] = All[i];
            now_2.step = now_2.step + 1;
            string cz_2 = "      装满" + si + "升瓶子   \n";
            now_2.operate.append(cz_2);
            // PR(now_2);
            Q.push(now_2);
            vis[now_2.Now[0]][now_2.Now[1]][now_2.Now[2]] = 1;
        }
    }
}

int main()
{
    // freopen("H:\\out.txt","w",stdout);
    printf("请输入要计算的组数:");
    cin >> T;
    while(T--)
    {
        Init();
        res = -1;
        BFS();
    }
    return 0;
}

另外,出于方便考虑,正常人也不会趴在电脑上玩手游。。。所以正在改写成安卓app。。。各位稍等。

猜你喜欢

转载自blog.csdn.net/qq_36752486/article/details/84189193
BFS
今日推荐