Python发现了!卡

2024-10-01 00:22:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我在试着模拟“发现它!”用Python牌。对于那些不知道什么叫“发现它!”是一种流行的纸牌游戏,一副牌上有55张牌,每张牌上有8个随机符号(例如一个球、一个波等)。每一张牌都有一个与其他牌相同的符号。 基本上,玩家画一张牌,并将其与一张“公用卡”(每个人都能看到)进行比较,首先发现他/她与“公用卡”相同的符号的玩家获胜。在

但我只是想生成一副牌,而不是游戏本身。在

所以,假设我有这些东西:

符号列表:

symbols = ["pelikan", "palma", "rukavnik", "morskyKon", "mraznicka", "kormidlo", "lehatko", "drink", "vedro", "Aloha", "koral", "nanuk", "opalovaciKrem", "Splash!", "plutva", "morskaPanna", "meduza", "krab", "stopa", "Wipeout", "pistol", "zralociaPlutva", "plachetnica", "raketa", "slnko", "sandala", "melon", "harpuna", "stolicka", "zachranneKoleso", "lietajuciTanier", "ryba", "hrad", "kalamar", "fotoaparat", "osuska", "naramok", "sarkan", "kotva", "fakla", "kamene", "snehoveGule", "motyka", "kosatka", "plavky", "odtlacokMusle", "klobuk", "ponorka", "morskyJez", "more", "musla", "slnecnik", "potapacskeOkuliare", "slnecneOkuliare", "majak", "vlna", "lopta"]

一副卡片(目前为6张),字典中的每一个键代表一张卡片,每一个键的值是由8个符号组成的列表,目前为空:

^{pr2}$

为每张卡生成随机符号,以避免重复

import random
for card, symboly in cardDeck.items():
    symboly = []
    for i in range(8):
        symbol = random.choice(symbols)
        while symbol in symboly:
            symbol = random.choice(symbols)
        symboly.append(symbol)
    cardDeck.update({card : set(symboly)})

这就是我的问题所在——我知道该怎么做,但我不知道在Python中是否可以做到这一点,如果可以,怎么做。我意识到我需要从所有的卡片上做组合(每一个可能的对),然后对每个组合随机挑选符号,直到它有一个共同的符号(即每个组合的交集长度是1)。据我所知,组合可以很容易地由itertools.组合(卡片组,2)。然后我试着执行上面写的东西,但不知怎么的我不知道如何用Python编写它。(我对它的学习还比较少,我想在Python中尝试一下会很有趣。)

任何想法都很受欢迎。提前谢谢。在


Tags: in游戏列表for玩家符号randomcard
2条回答

你可以为有限的Desarguesian射影平面构造关联矩阵,而无需反复尝试。下面是我编写的一些Python代码,它们已经在Python 2.7和Python 3.6中进行了测试:

def incidence_matrix(p = 7): # p can be any prime

    # Generate all p^3 - 1 points in affine space, minus the origin:
    points = [(a,b,c) for a in range(p) for b in range(p) for c in range(p)][1::]

    # Quotient by the equivalence relation to give the projective plane points:
    scale = lambda t, k : tuple([((k * v) % p) for v in t])
    canonise = lambda t : (sorted([scale(t, k) for k in range(1, p)])[0])
    points = list(set(map(canonise, points)))

    # We identify each point with its dual line by taking orthogonal complements.
    # A line is incident with a point if the pole of the line is orthogonal to
    # the point, which can be evaluated straightforwardly:
    innerprod = lambda x, y : (sum([a*b for (a, b) in zip(x, y)]) % p)
    imatrix = [[1 if (innerprod(x, y) == 0) else 0 for x in points] for y in points]

    # Output the incidence matrix:
    return imatrix

对于p^n阶的射影平面,其中n>;=2,它是相似的,但稍微复杂一些:不需要在整数模p中工作,而是需要在有限域F_u(p^n)中操作。幸运的是,7是prime,所以上面简单的代码就足够了。在

好吧,我已经读了很多,要点如下:

游戏可以理解为7阶的finite projective plane的物理表达式;57张牌和57个符号,每对牌共享一个符号,每对符号共享一张牌。由于不明原因,制造商决定任意丢弃两张卡片。在

(更一般地说,你可以*生成一个任意阶的有限射影平面N==p**N,其中p是一个质数,N是一个正整数;结果将有N**2+N+1个卡片,并且相同数量的符号,并且N+1个符号将出现在每张卡片上。)*这是一个强烈的猜想,但只有在N<;=11时才得到明确的证明。

你要生成的是一个57*57的关联矩阵-哪些符号出现在哪些卡片上-它遵循以下规则:

  1. 每行正好包含8个1
  2. 每列正好包含8个1
  3. 每对行正好有11个共同点
  4. 每对列正好有11个共同点。在

编辑:

我写了一个算法,我计算了大概需要150天才能得到所需的结果——这比看上去要复杂得多;-)

然后我做了更多的搜索,发现SAGE math package正好可以满足您的需要(而且速度更快):

import sage

sol = sage.combinat.designs.block_design.projective_plane(7)

for row in sol.incidence_matrix().rows():
    print(row)

产生一个解决方案需要半秒钟:

^{pr2}$

然后将其转换为您想要的纸牌游戏是非常直接的:

symbols = sorted(
    [
        "pelikan", "palma", "rukavnik", "morskyKon", "mraznicka", "kormidlo",
        "lehatko", "drink", "vedro", "Aloha", "koral", "nanuk", "opalovaciKrem",
        "Splash!", "plutva", "morskaPanna", "meduza", "krab", "stopa", "Wipeout",
        "pistol", "zralociaPlutva", "plachetnica", "raketa", "slnko", "sandala",
        "melon", "harpuna", "stolicka", "zachranneKoleso", "lietajuciTanier", "ryba",
        "hrad", "kalamar", "fotoaparat", "osuska", "naramok", "sarkan", "kotva",
        "fakla", "kamene", "snehoveGule", "motyka", "kosatka", "plavky",
        "odtlacokMusle", "klobuk", "ponorka", "morskyJez", "more", "musla",
        "slnecnik", "potapacskeOkuliare", "slnecneOkuliare", "majak", "vlna", "lopta"
    ],
    key = str.lower
)

cards = [
    [symbol for symbol, use_it in zip(symbols, row) if use_it]
    for row in sorted(sol.incidence_matrix().rows())
]

产生

[
    ['Aloha', 'drink', 'fakla', 'fotoaparat', 'harpuna', 'hrad', 'kalamar', 'kamene'],
    ['Aloha', 'klobuk', 'koral', 'kormidlo', 'kosatka', 'kotva', 'krab', 'lehatko'],
    ['Aloha', 'lietajuciTanier', 'lopta', 'majak', 'meduza', 'melon', 'more', 'morskaPanna'],
    ['Aloha', 'morskyJez', 'morskyKon', 'motyka', 'mraznicka', 'musla', 'nanuk', 'naramok'],
    ['Aloha', 'odtlacokMusle', 'opalovaciKrem', 'osuska', 'palma', 'pelikan', 'pistol', 'plachetnica'],
    ['Aloha', 'plavky', 'plutva', 'ponorka', 'potapacskeOkuliare', 'raketa', 'rukavnik', 'ryba'],
    ['Aloha', 'sandala', 'sarkan', 'slnecneOkuliare', 'slnecnik', 'slnko', 'snehoveGule', 'Splash!'],
    ['Aloha', 'stolicka', 'stopa', 'vedro', 'vlna', 'Wipeout', 'zachranneKoleso', 'zralociaPlutva'],
    ['drink', 'klobuk', 'lietajuciTanier', 'morskyJez', 'odtlacokMusle', 'plavky', 'sandala', 'stolicka'],
    ['drink', 'koral', 'majak', 'mraznicka', 'pelikan', 'rukavnik', 'Splash!', 'zralociaPlutva'],
    ['drink', 'kormidlo', 'melon', 'naramok', 'opalovaciKrem', 'potapacskeOkuliare', 'snehoveGule', 'zachranneKoleso'],
    ['drink', 'kosatka', 'morskaPanna', 'motyka', 'pistol', 'plutva', 'slnko', 'vedro'],
    ['drink', 'kotva', 'lopta', 'nanuk', 'osuska', 'ryba', 'slnecnik', 'stopa'],
    ['drink', 'krab', 'meduza', 'morskyKon', 'plachetnica', 'raketa', 'slnecneOkuliare', 'Wipeout'],
    ['drink', 'lehatko', 'more', 'musla', 'palma', 'ponorka', 'sarkan', 'vlna'],
    ['fakla', 'klobuk', 'morskaPanna', 'nanuk', 'pelikan', 'potapacskeOkuliare', 'slnecneOkuliare', 'vlna'],
    ['fakla', 'koral', 'lopta', 'morskyKon', 'opalovaciKrem', 'plutva', 'sarkan', 'stolicka'],
    ['fakla', 'kormidlo', 'meduza', 'musla', 'pistol', 'ryba', 'sandala', 'zralociaPlutva'],
    ['fakla', 'kosatka', 'more', 'morskyJez', 'osuska', 'raketa', 'Splash!', 'zachranneKoleso'],
    ['fakla', 'kotva', 'lietajuciTanier', 'mraznicka', 'plachetnica', 'ponorka', 'snehoveGule', 'vedro'],
    ['fakla', 'krab', 'majak', 'naramok', 'palma', 'plavky', 'slnko', 'stopa'],
    ['fakla', 'lehatko', 'melon', 'motyka', 'odtlacokMusle', 'rukavnik', 'slnecnik', 'Wipeout'],
    ['fotoaparat', 'klobuk', 'more', 'mraznicka', 'opalovaciKrem', 'ryba', 'slnko', 'Wipeout'],
    ['fotoaparat', 'koral', 'lietajuciTanier', 'naramok', 'pistol', 'raketa', 'slnecnik', 'vlna'],
    ['fotoaparat', 'kormidlo', 'majak', 'motyka', 'osuska', 'ponorka', 'slnecneOkuliare', 'stolicka'],
    ['fotoaparat', 'kosatka', 'melon', 'nanuk', 'plachetnica', 'plavky', 'sarkan', 'zralociaPlutva'],
    ['fotoaparat', 'kotva', 'morskaPanna', 'morskyKon', 'palma', 'rukavnik', 'sandala', 'zachranneKoleso'],
    ['fotoaparat', 'krab', 'lopta', 'musla', 'odtlacokMusle', 'potapacskeOkuliare', 'Splash!', 'vedro'],
    ['fotoaparat', 'lehatko', 'meduza', 'morskyJez', 'pelikan', 'plutva', 'snehoveGule', 'stopa'],
    ['harpuna', 'klobuk', 'melon', 'morskyKon', 'pistol', 'ponorka', 'Splash!', 'stopa'],
    ['harpuna', 'koral', 'morskaPanna', 'musla', 'osuska', 'plavky', 'snehoveGule', 'Wipeout'],
    ['harpuna', 'kormidlo', 'lopta', 'morskyJez', 'plachetnica', 'rukavnik', 'slnko', 'vlna'],
    ['harpuna', 'kosatka', 'meduza', 'mraznicka', 'palma', 'potapacskeOkuliare', 'slnecnik', 'stolicka'],
    ['harpuna', 'kotva', 'more', 'naramok', 'odtlacokMusle', 'plutva', 'slnecneOkuliare', 'zralociaPlutva'],
    ['harpuna', 'krab', 'lietajuciTanier', 'motyka', 'pelikan', 'ryba', 'sarkan', 'zachranneKoleso'],
    ['harpuna', 'lehatko', 'majak', 'nanuk', 'opalovaciKrem', 'raketa', 'sandala', 'vedro'],
    ['hrad', 'klobuk', 'meduza', 'naramok', 'osuska', 'rukavnik', 'sarkan', 'vedro'],
    ['hrad', 'koral', 'more', 'motyka', 'plachetnica', 'potapacskeOkuliare', 'sandala', 'stopa'],
    ['hrad', 'kormidlo', 'lietajuciTanier', 'nanuk', 'palma', 'plutva', 'Splash!', 'Wipeout'],
    ['hrad', 'kosatka', 'majak', 'morskyKon', 'odtlacokMusle', 'ryba', 'snehoveGule', 'vlna'],
    ['hrad', 'kotva', 'melon', 'musla', 'pelikan', 'raketa', 'slnko', 'stolicka'],
    ['hrad', 'krab', 'morskaPanna', 'morskyJez', 'opalovaciKrem', 'ponorka', 'slnecnik', 'zralociaPlutva'],
    ['hrad', 'lehatko', 'lopta', 'mraznicka', 'pistol', 'plavky', 'slnecneOkuliare', 'zachranneKoleso'],
    ['kalamar', 'klobuk', 'majak', 'musla', 'plachetnica', 'plutva', 'slnecnik', 'zachranneKoleso'],
    ['kalamar', 'koral', 'melon', 'morskyJez', 'palma', 'ryba', 'slnecneOkuliare', 'vedro'],
    ['kalamar', 'kormidlo', 'morskaPanna', 'mraznicka', 'odtlacokMusle', 'raketa', 'sarkan', 'stopa'],
    ['kalamar', 'kosatka', 'lopta', 'naramok', 'pelikan', 'ponorka', 'sandala', 'Wipeout'],
    ['kalamar', 'kotva', 'meduza', 'motyka', 'opalovaciKrem', 'plavky', 'Splash!', 'vlna'],
    ['kalamar', 'krab', 'more', 'nanuk', 'pistol', 'rukavnik', 'snehoveGule', 'stolicka'],
    ['kalamar', 'lehatko', 'lietajuciTanier', 'morskyKon', 'osuska', 'potapacskeOkuliare', 'slnko', 'zralociaPlutva'],
    ['kamene', 'klobuk', 'lopta', 'motyka', 'palma', 'raketa', 'snehoveGule', 'zralociaPlutva'],
    ['kamene', 'koral', 'meduza', 'nanuk', 'odtlacokMusle', 'ponorka', 'slnko', 'zachranneKoleso'],
    ['kamene', 'kormidlo', 'more', 'morskyKon', 'pelikan', 'plavky', 'slnecnik', 'vedro'],
    ['kamene', 'kosatka', 'lietajuciTanier', 'musla', 'opalovaciKrem', 'rukavnik', 'slnecneOkuliare', 'stopa'],
    ['kamene', 'kotva', 'majak', 'morskyJez', 'pistol', 'potapacskeOkuliare', 'sarkan', 'Wipeout'],
    ['kamene', 'krab', 'melon', 'mraznicka', 'osuska', 'plutva', 'sandala', 'vlna'],
    ['kamene', 'lehatko', 'morskaPanna', 'naramok', 'plachetnica', 'ryba', 'Splash!', 'stolicka']
]

相关问题 更多 >