在python中构建一个可以赢得七人游戏的函数,条件是只有2个玩家
所有的牌都是发给玩家的,即使结果是一些玩家比其他玩家多出一张牌。七颗心的主人从演奏开始。同样地,其他三个七人随后可能会被当作各自套装的第一张牌。在此之后,牌可以依次加到王牌和王牌上。不能放牌的玩家。如果你有一张牌要打,你就不能通过。得到七颗心的人是第一个玩的。
卡片将随机分配给用户和计算机。
该函数将有两个参数:
卡片的语法如下:
[value, suit]
例如,金,“俱乐部”
西服的清单如下:
值的列表如下:
玩家1的剩余牌将存储在名为card_1_rem
的列表中,而第2名玩家的剩余卡将存储在名为card_2_rem
的列表中。
已经玩过的牌将存储在一个名为played_cards
的列表中。
该函数必须将播放的卡片附加到名为played_cards
的列表中,并为名为card_1_rem
或card_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
发布于 2018-07-13 14:51:41
结果完全不同,我觉得它应该有一个单独的条目。这一个计算稍微聪明的分数,不仅着眼于下一步,而且未来的选择为每个球员,以及根据他们持有的牌。似乎做得比“协同”版本要好得多,足以击败神秘的player2
优势。
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)
发布于 2018-07-12 22:22:09
我不是真正的Python人,但我想试一试。这将在每个回合建立一组可玩的牌,并为每个牌分配一个简单的静态分数。得分最高的牌被使用(假设有任何可玩的牌)。
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连胜。发布于 2018-07-16 11:28:12
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
https://codegolf.stackexchange.com/questions/168420
复制相似问题