Algorithm 生成随机性相当于洗牌的可赢纸牌游戏

Algorithm 生成随机性相当于洗牌的可赢纸牌游戏,algorithm,random,shuffle,Algorithm,Random,Shuffle,如果给你: 一个好的洗牌算法(一个好的随机性来源加上洗牌方法,不受任何会使结果产生偏差的常见陷阱的影响) 一种神奇的函数,如果某个游戏序列可以赢牌,则取洗牌牌组并返回True;如果不可避免地导致失利,则返回False 然后,通过使用(1)生成一大组起始牌组,然后使用(2)将它们过滤到可赢牌组,就可以生成一组“分布均匀”的可赢牌交易。这种随机生成可能性并从中选择的方法,在你试图避免微妙的选择偏差潜入你的结果时,总是一个很好的起点 问题是(2)是难的(可能是NP难的,取决于游戏),甚至它的近似值在计

如果给你:

  • 一个好的洗牌算法(一个好的随机性来源加上洗牌方法,不受任何会使结果产生偏差的常见陷阱的影响)
  • 一种神奇的函数,如果某个游戏序列可以赢牌,则取洗牌牌组并返回True;如果不可避免地导致失利,则返回False
  • 然后,通过使用(1)生成一大组起始牌组,然后使用(2)将它们过滤到可赢牌组,就可以生成一组“分布均匀”的可赢牌交易。这种随机生成可能性并从中选择的方法,在你试图避免微妙的选择偏差潜入你的结果时,总是一个很好的起点

    问题是(2)是难的(可能是NP难的,取决于游戏),甚至它的近似值在计算上都很昂贵(比如说,如果你在iPad上)。然而,更便宜的算法,如从赢的位置开始,随机“取消移动”将游戏反转回起点,可能会对特定的牌组洗牌产生偏见,这很难量化或避免


    在生成这样的可赢游戏方面,有什么有趣的算法或研究吗?

    嗯,我对纸牌知之甚少,但这就是我解决问题的方法。请参阅我的伪代码

    //假设您已经创建了一个“卡片”对象

    生成一个列表组;//一个列表,包含纸牌组中您可以在纸牌游戏中使用的每张牌,以及您可以在纸牌游戏中使用的每张牌的数量。
    生成列表表;
    而(deck.size()>0){//这是真正的代码。
    table.add(deck.remove((int)(Math.random()*deck.size());
    }
    //完成了。你们知道,桌子上有一张完全乱序的牌单。
    //现在,你想怎么分就怎么分。
    

    我对第二部分一无所知。

    由于纸牌游戏的变化如此之大,在这种普遍性水平上进行推理本身就很困难。为了集中我们的想法,让我们举一个特别的例子:四十个小偷。这是一个双包游戏,从空的基础开始,向上建造;一个空的垃圾堆;和一个布局的十个预先处理面对面堆四张牌。垃圾堆和布局堆的顶部卡片外露。每次移动时,您可以:

    把一张显露的卡片移到它的合法位置,不必担心。 背部
  • 只有在合法的情况下,才能将暴露的卡移动到布局中的一堆上 穿着同一套衣服向下建筑
  • 将暴露的卡移动到空的布局插槽中
  • 将一张卡片从库存到废品的顶部
  • 初学者按照所述顺序玩这些选项。(我玩的实现实际上有一个提示按钮,提示相应的移动。)我估计,通过该策略,可赢得的交易不到十分之一,而可赢得的交易的实际比例约为三分之一

    现在,如果你通过随机的联合国行动来产生可赢的交易,那么就有一个难以量化的偏差;我并不反对这一点。不过,我认为,在那些碰巧可以赢的交易中,交易往往比平均水平更难,因为初学者的策略几乎无法赢得任何交易


    然而,你可以故意使联合国的行动不随机。如果你选择一个与初学者的策略相反的动作,你会得到一个初学者的策略:例如,如果只是作为最后的手段,你不可能从一个基金会转移到一个基金会,那么从浪费到基金会总是正确的。从一个已解决的位置,我生成随机突变,直到我到达一个具有给定“复杂性”(级别)的起点还有许多生成算法,可以生成可解的假摔接龙、雷区、惯性等情况。你可以看看他的问题生成器。第2部分是这个问题存在的全部原因。
    “如果你得到了…一个好的洗牌算法…”
    -已经给出了洗牌算法,任务不是写一个。值得赞扬的是,你的洗牌是正确的,而大多数人最初的尝试是不正确的。但是速度太慢了,因为与简单的索引访问相比,List.remove()非常昂贵。
    Generate a List<Cards> deck;// A list populated with every card in deck that you can use in Solitaire with the number of each card you can use in Solitaire.
    Generate a List<Cards> table;
    while(deck.size()>0){//This is the real code.
         table.add(deck.remove((int)(Math.random()*deck.size())));
    }
    //And done. You know have a perfectly shuffled list of Cards in table.
    //Now divide the list up however you want.