2012-10-22 38 views
0

下面是一个简单的二十一点游戏的模拟代码。玩家和经销商(房子)抽两张牌。玩家然后击中,直到他达到17点。经销商(房子)然后击中,直到他与球员画或被破坏。考虑到球员首先出场,他的获胜几率应该低于任何策略的50%。但是,由于某些原因,当我重复模拟时,玩家似乎赢得了超过50%的时间。我的代码中必须有一些错误才能给出这个结果。Ruby中的二十一点模拟导致奇怪的概率

one_suit = [2,3,4,5,6,7,8,9,10,10,10,10,11]; #the value of the cards for blackjack 
$full_deck = one_suit*4; #clubs, diamonds, hearts and spades 
$deck = $full_deck.dup; #start off the game with a full deck 

class Player 
    attr_accessor :ace_count 
    attr_accessor :hand_value 

    def initialize(ace_count,hand_value) 
    @ace_count = ace_count; 
    @hand_value = hand_value; 
    end 

    def hit #instance method, vs. self.hit = class method 
    choice_of_card = rand($deck.length); #choose a random card out of the deck 
    drawn_card = $deck[choice_of_card]; #draw that random card from the deck 
    $deck.delete_at(choice_of_card); #remove that card from the array 
    if drawn_card == 11 #if you draw an ace 
    self.ace_count += 1; 
    end 
    self.hand_value += drawn_card; 
    end 


    def flip_aces 
    while self.hand_value > 21 && self.ace_count > 0 #repeat until hand is below 21 or aces are all flipped 
    self.ace_count -= 1 #ace gets flipped to a 1 
    self.hand_value -= 10 #ace goes from 11 to 1 
    end 
    end 

end 


def oneplayergame 
$deck = $full_deck.dup; #start a new game with a full deck 
#generate the house and the player 
house = Player.new(0,0); 
player1 = Player.new(0,0); 
#both the house and the player draw two cards 
house.hit; house.hit; player1.hit; player1.hit; 
while player1.hand_value <= 17 #PLAYER STRATEGY: ON WHAT CARD DOES THE PLAYER STAND 
    player1.hit; 
    player1.flip_aces; 
end 
while house.hand_value < player1.hand_value && player1.hand_value <=21 #HOUSE DRAWS CARDS IF UNDER PLAYER VALUE AND PLAYER IS NOT BUST 
    house.hit; 
    house.flip_aces; 
end 
#outcome 



if player1.hand_value < house.hand_value && house.hand_value <= 21 
    return -1; 
elsif player1.hand_value > house.hand_value && player1.hand_value <= 21 
    return 1; 
elsif player1.hand_value < house.hand_value && house.hand_value > 21 
    return 1; 
elsif player1.hand_value > house.hand_value && player1.hand_value > 21 
    return -1; 
else return 0; 
end 
end 

#the simulation 
wins = 0; 
losses = 0; 
rounds=10000; 

for i in 1..rounds 
oneplayergame; 
if oneplayergame >0 
    wins +=1; 
elsif oneplayergame <0 
    losses +=1 
end 
end 

print wins/(wins+losses).round(3)*100; 

回答

2

此代码

for i in 1..rounds 
oneplayergame; 
if oneplayergame >0 
    wins +=1; 
elsif oneplayergame <0 
    losses +=1 
end 

是错误的:正在调用oneplayergame三次:如果一个球员失去了第二次和第三次的呼叫,这将扭曲的结果的损失仅计算在内。您只应拨打oneplayergame一次,将结果分配给本地变量

+0

谢谢,这是完美的!学习到教训了! –