Моделирование блэкджека в Ruby приводит к странным вероятностям

Ниже приведен код для имитации простой игры в блэкджек. Игрок и дилер (хаус) берут по две карты. Затем игрок бьет до тех пор, пока не наберет 17. Затем дилер (дом) бьет до тех пор, пока он не вытянет с игроком или не разорится. Учитывая, что игрок играет первым, шансы на его победу должны быть менее 50% для любой стратегии. Однако по какой-то причине, когда я повторяю симуляцию, кажется, что игрок выигрывает более чем в 50% случаев. В моем коде должна быть какая-то ошибка, дающая мне этот результат.

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;

person Spike Fitsch    schedule 22.10.2012    source источник


Ответы (1)


Этот код

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

Неправильно: это колл oneplayergame три раза: проигрыш засчитывается только в том случае, если игрок проигрывает второй и третий коллы, что может исказить результаты. Вы должны вызывать oneplayergame только один раз, присваивая результат локальной переменной

person Frederick Cheung    schedule 22.10.2012