Python 如何使用动态规划解决21点问题?

Python 如何使用动态规划解决21点问题?,python,dynamic-programming,memoization,blackjack,Python,Dynamic Programming,Memoization,Blackjack,这个问题来自这本书,是麻省理工学院视频中描述的问题的一个稍加修改的版本。问题如下: 21点是一种双人纸牌游戏,其规则如下: 玩家和庄家分别得到两张牌 然后,玩家可以“打”,或要求任意多张额外的牌,以使他或她的总数不超过21张 如果经销商的总数为16或更低,则必须命中,否则通过 最后,两人比较总数,最大总数不超过21人的一方为获胜者 对于这个问题,我们将卡片值简化为:每个 2到10张之间的卡计为面值,面值卡计为面值 10分,得分为1分 对牌组中的牌的顺序有充分的了解, 实现一个21点解算器,最

这个问题来自这本书,是麻省理工学院视频中描述的问题的一个稍加修改的版本。问题如下:

21点是一种双人纸牌游戏,其规则如下:

  • 玩家和庄家分别得到两张牌
  • 然后,玩家可以“打”,或要求任意多张额外的牌,以使他或她的总数不超过21张
  • 如果经销商的总数为16或更低,则必须命中,否则通过
  • 最后,两人比较总数,最大总数不超过21人的一方为获胜者
对于这个问题,我们将卡片值简化为:每个 2到10张之间的卡计为面值,面值卡计为面值 10分,得分为1分

对牌组中的牌的顺序有充分的了解, 实现一个21点解算器,最大化玩家的分数(即 就是,赢减去输)

本书的代码如下:

import random


class Deck:
    def __init__(self, seed=None):
        self.cards = [i for i in range(1, 10)] * 4 + [10] * 16
        random.seed(seed)
        random.shuffle(self.cards)

    def deal(self, start, n):
        return self.cards[start:start + n]


class Player:
    def __init__(self, hand):
        self.hand = hand
        self.total = 0

    def deal(self, cards):
        self.hand.extend(cards)
        self.total = sum(self.hand)


def cmp(x, y):
    return (x > y) - (x < y)


def play(deck, start, scores):
    player = Player(deck.deal(start, 2))
    dealer = Player(deck.deal(start + 2, 2))
    results = []

    for i in range(49 - start):
        count = start + 4
        player.deal(deck.deal(count, i))
        count += i

        if player.total > 21:
            results.append((-1, count))
            break

        while dealer.total < 17 and count < 52:
            dealer.deal(deck.deal(count, 1))
            count += 1
        if dealer.total > 21:
            results.append((1, count))
        else:
            results.append((cmp(player.total, dealer.total), count))

    options = []
    for score, next_start in results:
        options.append(score +
                       scores[next_start] if next_start <= 48 else score)
    scores[start] = max(options)


def blackjack(seed=None):
    deck = Deck(seed)
    scores = [0 for _ in range(52)]

    for start in range(48, -1, -1):
        play(deck, start, scores)

    return scores[0]
随机导入
舱面:
定义初始化(self,seed=None):
self.cards=[i代表范围(1,10)]*4+[10]*16
随机。种子(种子)
随机。洗牌(自我。牌)
def交易(自我、启动、n):
返回自助卡[开始:开始+n]
职业球员:
定义初始(自身,手):
手
self.total=0
def交易(自我、信用卡):
self.hand.extend(卡片)
self.total=总和(self.hand)
def cmp(x,y):
返回(x>y)-(x21:
结果。追加(-1,计数))
打破
当经销商总数<17且计数<52时:
庄家。交易(牌组。交易(计数,1))
计数+=1
如果dealer.total>21:
结果。追加((1,计数))
其他:
结果。追加((cmp(玩家总数、经销商总数)、计数))
选项=[]
对于分数,下一步从结果开始:
选项。追加(分数)+
如果下一次开始,则得分[下一次开始]