首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Blackjack策略仿真

Blackjack策略仿真
EN

Code Review用户
提问于 2018-08-11 17:01:28
回答 2查看 1.5K关注 0票数 1

我对python非常陌生(编码了大约两天),并创建了一个模拟21点游戏的程序,这样我就可以在多次迭代中找到最佳策略。

问题是,当我运行它时,我的CPU达到99.8%,它冻结了(我运行在终端中)--有没有人建议我如何修改我的代码,以减少CPU的密集性?--我想了解我做错了什么,代码只是一点乐趣!

正如我所说的,我对此很陌生,因此代码并不是很优雅,但它工作得很好。

代码语言:javascript
复制
import random
q = 0

#simple counter that will record the score of games over time
win_count = 0
draw_count = 0
lose_count = 0
bust_count = 0

#User input for when the game is run, it will allow them to choose the number of games to be played (iterations) and also the score at which the player will hold.
iterations = input('Number of iterations: ')
hold_score = input('Hold score for the player: ')

#defining the card values, suits and decks.
for x in range(0, iterations):
    s2 = 2
    s3 = 3
    s4 = 4
    s5 = 5
    s6 = 6
    s7 = 7
    s8 = 8
    s9 = 9
    s10 = 10
    sj = 10
    sq = 10
    sk = 10
    sa = 11
    c2 = 2
    c3 = 3
    c4 = 4
    c5 = 5
    c6 = 6
    c7 = 7
    c8 = 8
    c9 = 9
    c10 = 10
    cj = 10
    cq = 10
    ck = 10
    ca = 11
    d2 = 2
    d3 = 3
    d4 = 4
    d5 = 5
    d6 = 6
    d7 = 7
    d8 = 8
    d9 = 9
    d10 = 10
    dj = 10
    dq = 10
    dk = 10
    da = 11
    h2 = 2
    h3 = 3
    h4 = 4
    h5 = 5
    h6 = 6
    h7 = 7
    h8 = 8
    h9 = 9
    h10 = 10
    hj = 10
    hq = 10
    hk = 10
    ha = 11


    spades = [s2, s3, s4, s5, s6, s7, s8, s9, s10, sj, sq, sk, sa]
    clubs = [c2, c3, c4, c5, c6, c7, c7, c8, c9, c10, cj, cq, ck, ca]
    diamonds = [d2, d3, d4, d5, d6, d7, d8, d9, d10, dj, dq, dk, da]
    hearts = [h2, h3, h4, h5, h6, h7, h8, h9, h10, hj, hq, hk, ha]
    deck = [s2, s3, s4, s5, s6, s7, s8, s9, s10, sj, sq, sk, sa, c2, c3, c4, c5, c6, c7, c8, c9, c10, cj, cq, ck, ca, d2, d3, d4, d5, d6, d7, d7, d8, d9, d10, dj, dq, dk, da, h2, h3, h4, h5, h6, h7, h8, h9, h10, hj, hq, hk, ha]
    deck_standard = [s2, s3, s4, s5, s6, s7, s8, s9, s10, sj, sq, sk, sa, c2, c3, c4, c5, c6, c7, c8, c9, c10, cj, cq, ck, ca, d2, d3, d4, d5, d6, d7, d7, d8, d9, d10, dj, dq, dk, da, h2, h3, h4, h5, h6, h7, h8, h9, h10, hj, hq, hk, ha]

#List for the cards the dealer and player holds

    dealer = []
    user_1 = []

#Randomly gives the player and dealer two cards each - and then remove these cards from the deck of cards so it cannot be used again.

    card_1 = random.choice(deck)
    deck.remove(card_1)
    user_1.append(card_1)

    card_2 = random.choice(deck)
    deck.remove(card_2)
    dealer.append(card_2)

    card_3 = random.choice(deck)
    deck.remove(card_3)
    user_1.append(card_3)

    card_4 = random.choice(deck)
    deck.remove(card_4)
    dealer.append(card_4)

#Calculates the number of cards the player/dealer has - also defines their scores to be zero.
    dealer_card_count = len(dealer)
    user_1_card_count = len(user_1)
    dealer_score = 0
    user_1_score = 0


#Looks at the two cards each player has and calculates their score - then adds this score to their score.
    for x in range(0, dealer_card_count):
        dealer_score = dealer_score + int(dealer[x])

    for x in range(0, user_1_card_count):
        user_1_score = user_1_score + int(user_1[x])

#code to say that if the user has less cards than the pre-defined hold score - give them another card and add that card to their score.

    while (int(user_1_score) <= int(hold_score)):
        if (int(user_1_card_count)<6):
            card_5 = random.choice(deck)
            deck.remove(card_5)
            user_1.append(card_5)
            user_1_score = 0
            user_1_card_count = len(user_1)
            for x in range(0, user_1_card_count):
                user_1_score = user_1_score + int(user_1[x])

# sets the hold score for the dealer as that of the user (so that the dealer knows how high he has to aim for)

    hold_score_dealer = user_1_score

# Same  as above - but for the dealer.
    if (int(user_1_score) < int(21)):
        while (int(dealer_score) <= int(hold_score_dealer)):
            if (int(dealer_card_count)<6):
                card_6 = random.choice(deck)
                deck.remove(card_6)
                dealer.append(card_6)
                dealer_score = 0
                dealer_card_count = len(dealer)
                for x in range(0, dealer_card_count):
                    dealer_score = dealer_score + int(dealer[x])


#code so that if the user or the dealer have 5 cards they win automatically (5 card rule)
    if (int(user_1_card_count) ==5):
        if (int(dealer_card_count) !=5):
            if (int(user_1_score)) <22:
                win_count = win_count + 1

    if (int(user_1_card_count) == 5):
        if (int(dealer_card_count) == 5):
            if (int(user_1_score) < 22):
                if (int(dealer_score) <22):
                    draw_count = draw_count + 1
            elif (int(user_1_score) > 22):
                bust_count = bust_count + 1

    if (int(dealer_card_count) == 5):
        if(int(user_1_card_count) != 5):
            if (int(dealer_score) <22):
                lose_count = lose_count + 1


#Code to deal with all possible outcomes (assuming they don't have 5 cards) - and add to the counter.
    if (int(user_1_card_count) != 5):
        if (int(dealer_card_count) != 5):
                if (int(user_1_score) > int(dealer_score)):
                        if (int(user_1_score) < int(22)):
                                win_count = win_count + 1
                        elif (int(user_1_score) > int(21)):
                            if (int(dealer_score) < int(22)):
                                lose_count = lose_count + 1
                            elif (int(user_1_score) > int(21)):
                                if (int(dealer_score) > int (21)):
                                        draw_count = draw_count + 1
                                        bust_count = bust_count + 1
                elif (int(user_1_score) < int(dealer_score)):
                    if(int(user_1_score) > 21):
                        draw_count = draw_count + 1
                        bust_count = bust_count + 1



    if (int(user_1_card_count) != 5):
        if (int(dealer_card_count) != 5):
                if (int(user_1_score) == int(dealer_score)):
                    if (int(user_1_score)) < int(22):
                        draw_count = draw_count + 1
                    elif (int(user_1_score) > 21):
                            draw_count = draw_count + 1
                            bust_count = bust_count + 1

    if (int(user_1_card_count) != 5):
        if (int(dealer_card_count) != 5):
                if (int(user_1_score) < int(dealer_score)):
                        if (int(dealer_score) < int(22)):
                                lose_count = lose_count + 1
                        elif (int(dealer_score) > int(21)):
                            if (int(user_1_score) < int(22)):
                                win_count = win_count + 1

#Code to print the progress of the iterations over time
    if (q == iterations * 0.2):
        print "20%"
    if (q == iterations * 0.4):
        print "40%"
    if (q == iterations * 0.6):
        print "60%"
    if (q == iterations * 0.8):
        print "80%"
    if (q == iterations * 1):
        print "100%"
    gc.collect()
    print q
    q = q + 1

# Code to print the final scores after all iterations are complete.
print "Total iterations: " + str(iterations)
print "*****"
print "Win count  : " + str(win_count) +" ("+ str((float(win_count))/float(iterations)*100) +"%)"
print "Draw count : " + str(draw_count) +" ("+ str((float(draw_count))/float(iterations)*100) +"%)"
print "Lose count : " + str(lose_count) +" ("+ str((float(lose_count))/float(iterations)*100) +"%)"
print "Bust count : " + str(bust_count) +" ("+ str((float(bust_count))/float(iterations)*100) +"%)"
print ""
EN

回答 2

Code Review用户

发布于 2018-08-14 13:53:09

看一看这几行:

代码语言:javascript
复制
while (int(user_1_score) <= int(hold_score)):
    if (int(user_1_card_count)<6):

如果玩家抽了六张牌,而他们的得分仍然低于或等于保持分数,会发生什么情况?例如,假设持有分数为15,他们绘制2♣2♦2♥2♠3♣3♦,使他们的分数为14。接下来会发生什么?

票数 1
EN

Code Review用户

发布于 2018-09-02 19:36:36

在我到目前为止看到的代码清单中,包括您的OP和vash_ the _stampede的代码中,我看到的都是一个看起来有点像21点的任意纸牌游戏。这两种模式都不一样。但我想这是我的书呆子,因为我实际上是做游戏的。

与vash的代码一样,使用生成方法填充甲板是明智的。但我的做法会和他们的代码有点不同。首先,我不只是在数组中存储一个卡的数字,我至少也会存储一个“isUsed”标志,您可以切换这个标志将牌从游戏中取出,然后您可以在牌盘上迭代,将所有的‘isUsed’设置为false。这将节省每次创建或补充一个面板时的内存分配/取消分配。

第二,我会利用这样一个事实:您将在列表中存储多个关于卡片的信息,并将它们变成一个类,这样您就可以存储关于卡片的一些东西,比如西装、价值、使用的、表示的,以及您认为可能有用的任何东西。这将帮助您进一步开发程序,比如为屏幕保护程序制作图形版本;)

第三,21点规则:

每张牌手在每张牌开始时各发两张牌,一张一张,一张一张,从第一位的玩家开始,以经销商为结束。经销商把第一张牌朝上,第二张面朝下。

玩家牌加在一起,面数为10,aces计算为11,或1。

当玩家有一张王牌加一张脸(数到10s)时,他们就有一个21点,支付3比2。如果玩家有一个21点,而交易商有一个王牌显示,则提供与他们原来的赌注相同的保险,如果他们参加保险,而经销商也有一个21点,他们就会输掉赌注和保险。毒贩检查是否有黑手。在这种情况下,如果他们有一个黑板,它是揭示,保险支付,所有其他人输了。如果他们没有21点,保险就会被没收,比赛将继续正常进行。

当经销商有一个王牌展示,而没有玩家有一个21点,他们会检查隐藏的卡片,而不显示,看看他们是否有一个21点。如果经销商有一个21点,所有当前活跃的手都会输掉。

从离玩家1位置最近的第一个剩余玩家开始,继续播放。显示扑克牌的玩家的值被加在一起,玩家被要求打或站,除非特殊情况下在下面。每次玩家命中,他们会得到另一张牌,这是加在他们的总数。如果球员崩溃(超过21人),他们会立即输掉。如果他们击中21,他们不能采取任何更多的牌,一旦他们满足前面的条件之一,或有5张牌,行动到下一个玩家。(在我处理的地方,没有5张卡规则)

如果玩家有两张相同的牌,考虑到他们的牌号(国王只和其他国王一起计算,十张只有其他十张.)他们可以选择通过放置另一张与原来的赌局相等的赌注来分割牌,每一张分开的牌是作为一个单独的牌来玩,玩家最多可以有4只手。任何分裂,然后折断的手,都算作这个总数。

一旦所有球员的手都被玩过,每个球员都选择站着结束他们的动作回合,那就是交易商的动作。经销商公开他们的脸向下的牌,并按照一个特定的规则集:

如果经销商显示一个硬17或以上(任何一只手使用王牌为11是软的,任何只使用aces作为1s,或不包括一个王牌是硬的。Aces可以从11降到1中间)经销商将站立。如果他们显示一个软17或以下,他们将采取另一张卡。最多5张牌。如果经销商在这一点上破产,所有剩余的活跃手将得到1比1的报酬。

一旦经销商达到一个立场,他们的总数被比较每个球员的价值,按相反的交易顺序。如果经销商的总数更高,就会输掉赌注。如果经销商和玩家的手是相同的价值,这只手推,而玩家保持赌注。如果玩家的总数更高,那么玩家就会赢,并且赌注不会1比1。

大多数赌场认为21点游戏是一种高容量的游戏,因此他们在一只鞋中使用6到8个甲板的多层洗牌。

很抱歉,这与代码无关,但是一个解决问题的人实际上应该正确地玩游戏,哦,还有一件事。如果语句被认为是糟糕的形式,并且可能导致一些相当严重的开销,则会大大超过,但是我认为很多问题都是内存分配/dealloc。

另外,当你从牌面上拿牌时,先检查一下是否已经使用过,如果使用了,就再拿一张牌,如果没有用,就把它给玩家/经销商。这也会节省一些周期。

只有我的两块。

票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/201472

复制
相关文章

相似问题

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