首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >写一个赢七人游戏的程序

写一个赢七人游戏的程序
EN

Code Golf用户
提问于 2018-07-11 18:24:51
回答 4查看 907关注 0票数 6

在python中构建一个可以赢得七人游戏的函数,条件是只有2个玩家

以下是来自维基百科维基百科的说明:

所有的牌都是发给玩家的,即使结果是一些玩家比其他玩家多出一张牌。七颗心的主人从演奏开始。同样地,其他三个七人随后可能会被当作各自套装的第一张牌。在此之后,牌可以依次加到王牌和王牌上。不能放牌的玩家。如果你有一张牌要打,你就不能通过。得到七颗心的人是第一个玩的。

卡片将随机分配给用户和计算机。

该函数将有两个参数:

  1. 剩余的电脑扑克牌列表
  2. 列出已经玩过的卡片

卡片的语法如下:

[value, suit]

例如,金,“俱乐部”

西服的清单如下:

  • 俱乐部
  • 黑桃
  • 钻石

值的列表如下:

  • 1
  • 2
  • 3.
  • 11(杰克)
  • 12(皇后)
  • 13(国王)

玩家1的剩余牌将存储在名为card_1_rem的列表中,而第2名玩家的剩余卡将存储在名为card_2_rem的列表中。

已经玩过的牌将存储在一个名为played_cards的列表中。

该函数必须将播放的卡片附加到名为played_cards的列表中,并为名为card_1_remcard_2_rem的列表减去项。

一个函数的返回将是竞争者的输入。

先打完牌的人,就赢了。

获胜条件

第一步:用户将提交他们的程序。

第二步:我将互相测试程序。

第三步:在连续50场比赛中保持第一名(以最低的跑分来衡量)的第一个项目将是赢家。这将有助于消除运气的影响。但是,最多将进行10000场比赛,如果没有一个球员达到第一标准,那么在10000场比赛后总分最低的球员将获胜。

第四步:所有的结果将上传到一个github回购(我很快就会做)。

输家必须数他的分数如下:1,2:2,3:3,4:4,5:5,6:6,7:8,9:9,10 : 10,杰克: 10,王后: 10,国王: 10,例如,如果一位国王和一位王牌留在输家手中,他会得到11分。目标是将你所得到的分数降到最低。胜利者得零分

IMP :只允许在Python 3语言中提交。

此挑战的控制器代码如下(主要更新已经完成):https://gist.github.com/Salil03/19a093554205b52d05dc7dc55992375a

EN

回答 4

Code Golf用户

回答已采纳

发布于 2018-07-13 14:51:41

战术

结果完全不同,我觉得它应该有一个单独的条目。这一个计算稍微聪明的分数,不仅着眼于下一步,而且未来的选择为每个球员,以及根据他们持有的牌。似乎做得比“协同”版本要好得多,足以击败神秘的player2优势。

代码语言:javascript
运行
复制
def tactical(cards_in_hand, played_cards):
    def list2dict(lst):
        d = {}
        for val, suit in lst:
            if suit in d:
                d[suit].append(val)
            else:
                d[suit] = [val]
        return d
    def play_card(card):
        cards_in_hand.remove(card)
        played_cards.append(card)

    hand = list2dict(cards_in_hand)
    if not played_cards:
        if 7 in hand['hearts']:
            play_card([7, 'hearts'])
        return (cards_in_hand, played_cards)
    table = list2dict(played_cards)

    playable_cards = {}
    for suit in hand:

        if suit not in table:
            if 7 in hand[suit]:
                # Do I hold the majority of the cards of this suit?
                suit_advantage = (len(hand[suit]) - 6.5)
                playable_cards[(7, suit)] = suit_advantage * 20
                if 6 in hand[suit] and 8 in hand[suit]:
                    # opponent can't immediately make use of this 
                    playable_cards[(7, suit)] += 20
            continue

        visible = set(table[suit] + hand[suit])
        opp_hand = set(range(1,14)) - visible

        highcard = max(table[suit]) + 1
        if highcard in hand[suit]:
            advantage = sum(c > highcard for c in hand[suit]) - sum(c > highcard for c in opp_hand)
            playable_cards[(highcard, suit)] = advantage * 10
            if highcard + 1 in opp_hand:
                playable_cards[(highcard, suit)] -= 20

        lowcard = min(table[suit]) - 1
        if lowcard in hand[suit]:
            advantage = sum(c < lowcard for c in hand[suit]) - sum(c < lowcard for c in opp_hand)
            playable_cards[(lowcard, suit)] = advantage * 10
            if lowcard - 1 in opp_hand:
                playable_cards[(lowcard, suit)] -= 20

    if not playable_cards:
        return (cards_in_hand, played_cards)

    best_card = max(playable_cards, key=playable_cards.get)
    #print(hand, "\n", table, "\n", best_card, ":", playable_cards[best_card])
    play_card(list(best_card))

    return (cards_in_hand, played_cards)
票数 2
EN

Code Golf用户

发布于 2018-07-12 22:22:09

协同

我不是真正的Python人,但我想试一试。这将在每个回合建立一组可玩的牌,并为每个牌分配一个简单的静态分数。得分最高的牌被使用(假设有任何可玩的牌)。

代码语言:javascript
运行
复制
def synergistic(cards_in_hand, played_cards):
    def list2dict(lst):
        d = {}
        for val, suit in lst:
            if suit in d:
                d[suit].append(val)
            else:
                d[suit] = [val]
        return d
    def play_card(card):
        cards_in_hand.remove(card)
        played_cards.append(card)

    hand = list2dict(cards_in_hand)
    if not played_cards:
        if 7 in hand['hearts']:
            play_card([7, 'hearts'])
        return (cards_in_hand, played_cards)
    table = list2dict(played_cards)

    playable_cards = {}
    for suit in hand:
        if 7 in hand[suit]:
            playable_cards[(7, suit)] = -1

        if suit not in table:
            continue
        visible = set(table[suit] + hand[suit])
        opp_hand = set(range(1,14)) - visible
        highcard = max(table[suit]) + 1

        if highcard in hand[suit]:
            if highcard+1 in opp_hand:
                playable_cards[(highcard, suit)] = 1
            else:
                playable_cards[(highcard, suit)] = 2

        lowcard = min(table[suit]) - 1
        if lowcard in hand[suit]:
            if lowcard - 1 in opp_hand:
                playable_cards[(lowcard, suit)] = 0
            else:
                playable_cards[(lowcard, suit)] = 1


    if not playable_cards:
        return (cards_in_hand, played_cards)

    best_card = list(max(playable_cards, key=playable_cards.get))
    #print(hand, "\n", table, "\n", best_card)
    play_card(best_card)

    return (cards_in_hand, played_cards)

顺便说一下,控制器似乎有几个问题,包括分数的计算和比较。我对这里的控制器,请看一下做了一些修改,如果这看起来是对的,我会更新您的版本。

在控制器中有两件事我还没有修复:

  • 为什么循环条件是(win2 <= 50) and (win1 <= 100)?这可能是对称的,它应该退出循环时,任何一个球员有100连胜。
  • 在本地尝试一些控制器的运行,对两个玩家都具有相同的功能,玩家2在大多数情况下似乎都赢了--这不可能是游戏的固有特性,因为最初的7H要求会解决这个问题(正如评论中提到的@Veskah ),那么,还没有发现控制器缺陷吗?或者我的玩家代码以某种方式维持状态并有偏见?每场比赛,这并不像玩家2(从结果输出txt)中占据很大的优势,但不管怎样,每个控制器运行的总得分最终更偏向于玩家2,而不是随机的(玩家1's的总分通常是2的2倍)。
票数 2
EN

Code Golf用户

发布于 2018-07-16 11:28:12

SearchBot

代码语言:javascript
运行
复制
import random

suits = ["clubs", "diamonds", "hearts", "spades"]
suit_mul = 14
hearts = suit_mul * suits.index("hearts")

def evaluate(hand):
    return sum(min(c % suit_mul, 10) for c in hand)

def rollout(hand0, hand1, runs):
    sign = -1
    counts = [[0.] * 8 for _ in range(2)]
    def counts_index(card):
        return 2 * (card // suit_mul) + ((card % suit_mul) > 7)
    for card in hand0:
        counts[0][counts_index(card)] += 1
    for card in hand1:
        counts[1][counts_index(card)] += 1
    while True:
        if not hand1:
            return sign * evaluate(hand0)
        can_play = []
        for i, run in enumerate(runs):
            if run[0] == 8 or run[1] == 6:
                if run[1] != 6:
                    run[0] = 7
                if run[0] != 8:
                    run[1] = 7
            suit = suit_mul * i
            rank = run[0] - 1
            next_low = suit + rank
            if next_low in hand0:
                if next_low - 1 in hand0:
                    runs[i][0] -= 1
                    hand0.remove(next_low)
                    counts[0][counts_index(next_low)] -= 1
                    can_play = []
                    break
                can_play.append((next_low, 0, -1))
            rank = run[1] + 1
            next_high = suit + rank
            if next_high in hand0:
                if next_high + 1 in hand0:
                    runs[i][1] += 1
                    hand0.remove(next_high)
                    counts[0][counts_index(next_high)] -= 1
                    can_play = []
                    break
                can_play.append((next_high, 1, 1))
        if can_play:
            weights = [(a - 1) / (a + b - 1) if a + b - 1 > 0 else 0 for a, b in zip(*counts)]
            weighted = [(0 if t[0] % suit_mul == 7 else weights[counts_index(t[0])], t) for t in can_play]
            weight = sum(t[0] for t in weighted)
            total = random.uniform(0, weight)
            for (w, (card, index, direction)) in weighted:
                total -= w
                if total <= 0:
                    break
            hand0.remove(card)
            counts[0][counts_index(card)] -= 1
            runs[card // suit_mul][index] += direction
        hand0, hand1 = hand1, hand0
        counts[0], counts[1] = counts[1], counts[0]
        sign *= -1

def select_move(hand0, hand1, runs, n=40):
    if hearts + 7 in hand0:
        return hearts + 7
    if hearts + 7 in hand1:
        return
    can_play = []
    for i, run in enumerate(runs):
        suit = suit_mul * i
        rank = run[0] - 1
        next_low = suit + rank
        if next_low in hand0:
            if next_low - 1 in hand0:
                return next_low
            can_play.append((next_low, 0, -1))
        rank = run[1] + 1
        next_high = suit + rank
        if next_high in hand0:
            if next_high + 1 in hand0:
                return next_high
            can_play.append((next_high, 1, 1))
    if not can_play:
        return
    if len(can_play) == 1:
        return can_play[0][0]
    scores = [0 for _ in can_play]
    for i, (card, index, sign) in enumerate(can_play):
        hand0_copy = set(hand0)
        runs_copy = [list(r) for r in runs]
        hand0_copy.remove(card)
        runs_copy[card // suit_mul][index] += sign
        for j in range(n):
            scores[i] -= rollout(set(hand1), set(hand0_copy), [list(r) for r in runs_copy])
    return can_play[scores.index(max(scores))][0]


def search(cards_in_hand, played_cards):

    def play_card(c):
        if c is None:
            return
        suit = suits[c // suit_mul]
        rank = c % suit_mul
        for i, card in enumerate(cards_in_hand):
            if card[0] == rank and card[1] == suit:
                del cards_in_hand[i]
                played_cards.append([rank, suit])
                return
        assert(False)

    hand = set(suit_mul * suits.index(s) + v for v, s in cards_in_hand)
    played = set(suit_mul * suits.index(s) + v for v, s in played_cards)
    opponent_hand = (suit_mul * s + v for v in range(1, 14) for s in range(4))
    opponent_hand = set(c for c in opponent_hand if c not in hand and c not in played)
    runs = [[8, 6] for _ in range(4)]
    for i, run in enumerate(runs):
        suit = suit_mul * i
        while suit + run[0] - 1 in played:
            run[0] -= 1
        while suit + run[1] + 1 in played:
            run[1] += 1
    card = select_move(hand, opponent_hand, runs)
    play_card(card)
    return cards_in_hand, played_cards
票数 2
EN
页面原文内容由Code Golf提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codegolf.stackexchange.com/questions/168420

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档