質問

Below is the code for a simulation of a simple blackjack game. The player and dealer (house) draw two cards. The player then hits until he reaches 17. The dealer (house) then hits until he draws with the player or goes bust. Considering the player plays first the odds of him winning should be less than 50% for any strategy. However, for some reason when I repeat the simulation it seems the player wins more than 50% of the time. There must be some error in my code giving me this result.

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;
役に立ちましたか?

解決

This code

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

Is wrong: that is calling oneplayergame three times: a loss is only counted if a player looses the second and 3rd calls, which would skew the results. You should only call oneplayergame once, assigning the result to a local variable

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top