Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/svn/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 找到一个平衡这个游戏的算法_Algorithm - Fatal编程技术网

Algorithm 找到一个平衡这个游戏的算法

Algorithm 找到一个平衡这个游戏的算法,algorithm,Algorithm,我试着提取问题中我遇到麻烦的部分,这是我正在做的更大项目的一部分(不是家庭作业)。我认为把它描述成一个游戏是最容易的(因为我需要它来完成我正在做的游戏)。按照我的描述,这是一个单人游戏 开始从两个位置中的一个开始: 重量(2,0,-1)和一个红色播放 重量(3,1,-1)和两个红色 结束游戏在您没有更多游戏时结束。目标是以重量(0,0,0)结束游戏 有两种类型的播放红色和蓝色。给定一个剧本,你可以从四个作品中选择一个:a、B、C、D,它们会给你带来额外的重量和可能的额外剧本。规则如下: 在

我试着提取问题中我遇到麻烦的部分,这是我正在做的更大项目的一部分(不是家庭作业)。我认为把它描述成一个游戏是最容易的(因为我需要它来完成我正在做的游戏)。按照我的描述,这是一个单人游戏

开始从两个位置中的一个开始:

  • 重量
    (2,0,-1)
    和一个
    红色
    播放
  • 重量
    (3,1,-1)
    和两个
    红色
结束游戏在您没有更多游戏时结束。目标是以重量
(0,0,0)
结束游戏

有两种类型的播放
红色
蓝色
。给定一个剧本,你可以从四个作品中选择一个:
a、B、C、D
,它们会给你带来额外的重量和可能的额外剧本。规则如下:

  • 红色
    播放时:

    • A添加权重
      (0,-2,-1)
    • B添加重量
      (1,-1,-1)
      并添加一个
      红色
      播放
    • C加上重量
      (2,0,-1)
      和两个
      红色
    • D增加重量
      (0,2,1)
      和两个
      蓝色
      播放
blue
播放的规则类似,但权重的前两列是交换的,最后一列是反向的,播放的类型是反向的,因此您可以得到以下结果:

  • 蓝色
    播放时:

    • A增加重量
      (-2,0,1)
    • B添加重量
      (-1,1,1)
      ,并添加一个
      蓝色
      播放
    • C增加重量
      (0,2,1)
      和两个
      蓝色
      播放
    • D增加重量
      (2,0,-1)
      和两个
      红色
      播放
问题这场比赛能赢吗


我正试图编写一个程序,通过选择游戏来赢得游戏,这样当你没有更多的游戏时,最终的平衡是
(0,0,0)
。只是我似乎做不到。所以现在我认为可能没有赢得这场比赛的算法。我很想知道为什么会这样。如果有人对我如何证明这一点有任何想法,请让我知道!!或者,如果你尝试并找到了获胜的方法,那么也请告诉我。谢谢

将红牌和蓝牌的数量视为你位置的两个额外维度。这大大降低了问题的复杂性

下面,最后两个维度代表剩余的红色和蓝色,再次说明了问题

开始从两个位置中的一个开始:

  • 重量
    (2,0,-1,1,0)
  • 重量
    (3,-1,-1,2,0)
结束当你有体重时游戏结束
(0,0,0,0,0)

给定一个剧本,你可以从八个作品中选择一个:
Ar、Br、Cr、Dr、Ab、Bb、Cb、Db
,它们会给你额外的重量。规则如下:

  • Ar添加权重
    (0,-2,-1,-1,0)
  • Br添加权重
    (1,-1,-1,0,0)
  • Cr增加重量
    (2,0,-1,1,0)
  • Dr添加重量
    (0,2,1,-1,2)
  • Ab增加重量
    (-2,0,1,0,-1)
  • Bb增加重量
    (-1,1,0,0)
  • Cb增加重量
    (0,2,1,0,1)
  • Db增加权重
    (2,0,-1,2,-1)
此外,最后两个维度可能永远不会是负的


现在,它可以作为一个8变量方程来求解。可能我遗漏了一些东西,但仅通过检查,这一系列步骤似乎应该有效:

  • 以“重量<代码>(2,0,-1)和一个<代码>红色播放”开始
  • 拿一个
    red
    play,一个
    C
    ,它“增加了重量
    (2,0,-1)
    和两个
    red
    plays”,剩下的是重量
    (4,0,-2)
    和两个
    red
    plays
  • 拿一个
    red
    play,一个
    a
    ,它“增加重量
    (0,-2,-1)
    ”,剩下重量
    (4,-2,-3)
    和一个
    red
    play
  • 拿一个
    red
    play,一个
    D
    ,它“增加了重量
    (0,2,1)
    和两个
    blue
    plays”,剩下的是重量
    (4,0,-2)
    和两个
    blue
    plays
  • 拿一个
    blue
    play,一个
    a
    ,它“增加重量
    (-2,0,1)
    ”,剩下重量
    (2,0,-1)
    和一个
    blue
    play
  • 拿一个
    蓝色的
    玩法,一个
    a
    ,它“增加了重量
    (-2,0,1)
    ”,只剩下重量
    (0,0,0)
    ,没有玩法
再简单一点:

move        weight         plays
------      ---------      -------
            (2,0,-1)       red
red C       (4,0,-2)       red x2
red A       (4,-2,-3)      red
red D       (4,0,-2)       blue x2
blue A      (2,0,-1)       blue
blue A      (0,0,0)        -
。没有


编辑以添加:

我是如何发现这一点的:

既然这个问题引起了很多兴趣,也许我应该解释一下我是如何找到上述解决方案的。这基本上是运气;我偶然发现了两个关键的观察结果:

  • 红色A
    红色D
    按重量相互抵消(前者添加
    (0,-2,-1)
    ,后者添加
    (0,2,1)
    ),总共添加两个
    蓝色
    播放(都来自
    红色D
    ),没有
    红色
    播放;因此,如果您一个接一个地播放,您可以将两个
    红色
    播放“转换”为两个
    蓝色
    播放
  • 蓝色A
    取消了初始权重(它添加
    (2,0,-1)
    ),并且不添加播放,因此整个问题可以通过将一个
    红色
    播放“转换”为一个
    蓝色
    播放来解决
这给了我一个好的开始。我从
red C
开始,以便将两个
red
剧本“转换”为两个
blue
剧本,我立即发现
red C
也是
blue A
重量的“反面”,因此也可以用
blue A
来取消。在我的脑海里,这一切似乎抵消了perfectl
move        weight         plays
------      ---------      -------
            (3,1,-1)       red x2
red A       (3,-1,-2)      red
red B       (4,-2,-3)      red
red D       (4,0,-2)       blue x2
blue A      (2,0,-1)       blue
blue A      (0,0,0)        -
Start 1: (2, 0, -1)  Reds=1  Blues=0
Red B ==> (3, -1, -2)  Reds=1  Blues=0
Red B ==> (4, -2, -3)  Reds=1  Blues=0
Red D ==> (4, 0, -2)  Reds=0  Blues=2
Blue A ==> (2, 0, -1)  Reds=0  Blues=1
Blue A ==> (0, 0, 0)  Reds=0  Blues=0

Start 2: (3, 1, -1)  Reds=2  Blues=0
Red A ==> (3, -1, -2)  Reds=1  Blues=0
Red B ==> (4, -2, -3)  Reds=1  Blues=0
Red D ==> (4, 0, -2)  Reds=0  Blues=2
Blue A ==> (2, 0, -1)  Reds=0  Blues=1
Blue A ==> (0, 0, 0)  Reds=0  Blues=0
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SO8683939
{
  struct State
  {
    public int V1;
    public int V2;
    public int V3;
    public int Reds;
    public int Blues;
    public int Tokens { get { return Reds + Blues; } }
    public string Description;
    public State(int v1, int v2, int v3, int reds, int blues)
    {
      V1 = v1;
      V2 = v2;
      V3 = v3;
      Reds = reds;
      Blues = blues;
      Description = null;
    }
    public State Add(State other)
    {
      State sum;
      sum.V1 = V1 + other.V1;
      sum.V2 = V2 + other.V2;
      sum.V3 = V3 + other.V3;
      sum.Reds = Reds + other.Reds;
      sum.Blues = Blues + other.Blues;
      sum.Description = null;
      return sum;
    }
    public override string ToString()
    {
      var detail = string.Format("({0}, {1}, {2})  Reds={3}  Blues={4}", V1, V2, V3, Reds, Blues);
      if (Description != null)
      {
        return Description + ": " + detail;
      }
      return detail;
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      var start1 = new State(2, 0, -1, 1, 0) { Description = "Start 1" };
      var start2 = new State(3, 1, -1, 2, 0) { Description = "Start 2" };

      var end = new State(0, 0, 0, 0, 0);

      var redA = new State(0, -2, -1, -1, 0) { Description = "Red A" };
      var redB = new State(1, -1, -1, 0, 0) { Description = "Red B" }; ;
      var redC = new State(2, 0, -1, 1, 0) { Description = "Red C" }; ;
      var redD = new State(0, 2, 1, -1, 2) { Description = "Red D" }; ;
      var redOptions = new[] { redA, redB, redC, redD };

      var blueA = new State(-2, 0, 1, 0, -1) { Description = "Blue A" };
      var blueB = new State(-1, 1, 1, 0, 0) { Description = "Blue B" };
      var blueC = new State(0, 2, 1, 0, 1) { Description = "Blue C" };
      var blueD = new State(2, 0, -1, 2, -1) { Description = "Blue D" };
      var blueOptions = new[] { blueA, blueB, blueC, blueD };

      var startingPosition = start1;
      var maxSolutionLength = 5;

      var rand = new Random();
      var path = new List<State>();
      while (true)
      {
        var current = startingPosition;
        path.Clear();
        //Console.WriteLine("Starting");
        //Console.WriteLine(current);
        while (true)
        {
          State selected;
          if (current.Reds == 0)
          {
            selected = blueOptions[rand.Next(4)];
          }
          else if (current.Blues == 0)
          {
            selected = redOptions[rand.Next(4)];
          }
          else
          {
            if (rand.NextDouble() < 0.5)
            {
              selected = blueOptions[rand.Next(4)];
            }
            else
            {
              selected = redOptions[rand.Next(4)];
            }
          }
          //Console.WriteLine(selected);
          path.Add(selected);
          current = current.Add(selected);
          //Console.WriteLine(current);
          if (current.Equals(end))
          {
            Console.WriteLine("Success!");
            var retrace = startingPosition;
            Console.WriteLine(retrace);
            foreach (var selection in path)
            {
              retrace = retrace.Add(selection);
              Console.WriteLine("{0} ==> {1}", selection.Description, retrace);
            }
            Console.ReadLine();
            break;
          }
          else if (current.Tokens == 0)
          {
            // fail
            //Console.WriteLine("Fail");
            break;
          }
          else if (path.Count >= maxSolutionLength)
          {
            // fail
            //Console.WriteLine("Fail");
            break;
          }
        }
      }
    }
  }
}