2012-06-07 2 views
1

Может кто-нибудь помочь мне выяснить, почему я получаю следующую ошибку в строке: 78- $ player_total = $ player_cards.inject (: +)Ruby-Прерывистая ошибка w/nil не может быть принудительно введена в Fixnum (TypeError)

Я тоже получил его с линией: 15 ломтиков! - но это, кажется, остановилось?

Какая ошибка может быть периодической?

Несвязанный вопрос: как вы добавляете номера строк в сообщение в stackoverflow?

bjtrial.rb: 78: в +': nil can't be coerced into Fixnum (TypeError) from bjtrial.rb:78:in каждый ' из bjtrial.rb: 78: в блоке inject' from bjtrial.rb:78:in в start_trial' от bjtrial.rb: 76: в each' from bjtrial.rb:76:in start_trial» от bjtrial.rb: 90: в` '

@paradise: рубин -v рубин 1.9.3p194 (2012-04-20 ревизия 35410) [x86_64-darwin11.3.0]

#blackjack trial player hits 10-7 once vs. 11, 2 
$deck = (((2..11).to_a+[10]*3)*4) 
$rand= rand($deck.length) 
$dealer_win = 0 
$player_win = 0 
$tie = 0 

$p1 = 10 #players cards 
$p2 = 7 

$d1 = 11 #dealers cards 
$d2 = 2 

#deal & remove dealt cards deck 
$dealer_cards = Array([$deck.slice!($deck.index($d1)),$deck.slice!($deck.index($d2))]) 
$player_cards = Array([$deck.slice!($deck.index($p1)),$deck.slice!($deck.index($p2))]) 

$trials = 2 
$dealer_win = 0 
$playerWin = 0 

def hit_card 
    #remove hit card from the deck 
    $hit_card = $deck.slice!($rand) 
    $hit_card 
end 

def show_dealer_cards 
    total = $dealer_cards.inject(:+) 
    puts 
    puts "Dealer's cards are: #{$dealer_cards.inspect}" 
    puts "Dealer's total is: #{$dealer_cards.inject(:+)}" 
    sleep 1 
    def check_dealer_total 
     total = $dealer_cards.inject(:+) 

     if total > 21 && $dealer_cards.count(11) < 1 
      puts "Dealer Busted- Player wins!" 
      $player_win += 1 
     elsif total > 21 && $dealer_cards.count(11) >= 1 
      puts "Over 21- with an ace to factor:" 
      $dealer_cards[$dealer_cards.index(11)] -= 10 
      puts "Now the dealer has:" 
      show_dealer_cards 
     elsif total <= 16 || total == 17 && $dealer_cards.count(11) == 1 
      hit_card 
      puts "Dealer draws a:#{$hit_card}" 
      $dealer_cards.push($hit_card) 
      show_dealer_cards 
     else 
      player_total = $player_cards.inject(:+) 
      dealer_total = $dealer_cards.inject(:+) 

      puts "Results:" 
      puts "Player has #{player_total}" 
      puts "Dealer has #{dealer_total}" 

      if player_total < dealer_total 
       puts "Dealer Wins!" 
       $dealer_win += 1 
      elsif player_total == dealer_total 
       puts "It's a tie! Nobody Wins" 
       $tie += 1 
      else 
       puts "Player Wins!" 
       $player_win += 1 
      end 

     end 
    end 
    check_dealer_total 
end 

def start_trial 

    for i in (1..$trials).to_a 
     $player_cards.push(hit_card) #player hits once and stays or busts 
     $player_total = $player_cards.inject(:+) #this is line 78 

     if $player_total > 21 
      puts "Player Busted" 
      $dealer_win += 1 
     else 
     show_dealer_cards 
     end 

    end 
end 

start_trial 

puts 
puts "Player Cards: #{$p1}, #{$p2} (alwalys hits once)" 
puts "Dealers Cards: #{$d1}, #{$d2} (plays normally)" 
puts "Number of trials: #{$trials}" 
puts "Ties: #{$tie}" 
puts "Player Wins: #{$player_win}" 
puts "Dealer Wins: #{$dealer_win}" 

мне пришлось переместить $ рандов в функцию hit_card так как он будет периодически указывать на значение nil в th e массив.

Он работает - я думаю, его точное .. Не делайте ставку на свой дом в Вегасе на нем еще. LOL

И спасибо за другой отзыв re: глобальные переменные. Я не получил, что далеко, но ...

#blackjack trial player hits 10-7 once vs. 11, x 
$dealer_win = 0.0 
$player_win = 0.0 
$tie = 0.0 

$trials = 500000 
#Hit Once to hit... 
$strategy = "Hit Once" 

def hit_card 
    $rand= rand($deck.length) 
    #remove hit card from the deck 
    $hit_card = $deck.slice!($rand) 
    $hit_card 
end 

def show_dealer_cards 
    total = $dealer_cards.inject(:+) 
    #puts 
    #puts "Dealer's cards are: #{$dealer_cards.inspect}" 
    #puts "Dealer's total is: #{$dealer_cards.inject(:+)}" 
    #sleep 1 
    def check_dealer_total 
     total = $dealer_cards.inject(:+) 

     if total > 21 && $dealer_cards.count(11) < 1 
      #puts "Dealer Busted- Player wins!" 
      $player_win += 1.0 
     elsif total > 21 && $dealer_cards.count(11) >= 1 
      #puts "Over 21- with an ace to factor:" 
      $dealer_cards[$dealer_cards.index(11)] -= 10 
      #puts "Now the dealer has:" 
      show_dealer_cards 
     elsif total <= 16 || total == 17 && $dealer_cards.count(11) == 1 
      hit_card 
      #puts "Dealer draws a:#{$hit_card}" 
      $dealer_cards.push($hit_card) 
      show_dealer_cards 
     else 
      player_total = $player_cards.inject(:+) 
      dealer_total = $dealer_cards.inject(:+) 

      #puts "Results:" 
      #puts "Player has #{player_total}" 
      #puts "Dealer has #{dealer_total}" 

      if player_total < dealer_total 
       #puts "Dealer Wins!" 
       $dealer_win += 1.0 
      elsif player_total == dealer_total 
       #puts "It's a tie! Nobody Wins" 
       $tie += 1.0 
      else 
       #puts "Player Wins!" 
       $player_win += 1.0 
      end 

     end 
    end 
    check_dealer_total 
end 

def start_trial 

    for i in (1..$trials).to_a 

     $deck = (((2..11).to_a+[10]*3)*4).shuffle 

     $p1 = 10 #players cards 
     $p2 = 7 

     $d1 = 11 #dealers cards 
     $d2 = hit_card #just a random card 

     #deal & remove dealt cards deck 
     $dealer_cards = Array([$deck.slice!($deck.index($d1)),$deck.slice!($deck.index($d2))]) 
     $player_cards = Array([$deck.slice!($deck.index($p1)),$deck.slice!($deck.index($p2))]) 

     if $strategy == "Hit Once" 
      $player_cards.push(hit_card) #player hits once and stays or busts 
     else 
      $strategy = "Stand" 
     end 

     $player_total = $player_cards.inject(:+) #this is line 78 

     if $player_total > 21 
      #puts "Player Busted" 
      $dealer_win += 1.0 
     else 
     show_dealer_cards 
     end 

    end 
end 

start_trial 

puts 
puts '*' * 80 
puts "Player Cards: #{$p1}, #{$p2}" 
puts "Strategy: #{$strategy}" 
puts "Dealers Cards: #{$d1}, x" 
puts "Number of trials: #{$trials}" 
puts "Ties: #{$tie}" 
puts "Player Wins: #{$player_win}" 
puts "Dealer Wins: #{$dealer_win}" 
puts "Win Percentage: %.2f" % (($player_win/$trials) * 100) 
puts "Loss Percentage: %.2f" % (($dealer_win/$trials) * 100) 
puts "Tie Percentage: %.2f" % (($tie/$trials) * 100) 
puts '*' * 80 
+2

У вас 'nil' внутри' $ player_cards'. Проверьте, что содержит массив, и проследите, куда его поместили. Кроме того, не связанный с вашей проблемой, вы используете слишком много глобальных переменных; это не PHP, поэтому наберите '' 'использование. Предпочтительно, чтобы не существовать, если можете. – Amadan

ответ

0

я нашел совершенно другую проблему в вашей программе:

def start_trial 

    for i in (1..$trials).to_a 
     $player_cards.push(hit_card) #player hits once and stays or busts 
     $player_total = $player_cards.inject(:+) #this is line 78 

     if $player_total > 21 
      puts "Player Busted" 
      $dealer_win += 1 
     else 
     show_dealer_cards 
     end 

    end 
end 

Йор работает суд дважды, без повторной инициализации игроков деки , Таким образом, рука игрока становится [10, 7, 8, 9]. Если вы проведете 50 проб, у вас закончится карта.

Вы запускаете start_trial только два раза и получаете ошибку?

Вот мой результат на самом деле работает ваш код:

load './bj.rb' 
Player Busted 
Player Busted 

Player Cards: 10, 7 (alwalys hits once) 
Dealers Cards: 11, 2 (plays normally) 
Number of trials: 2 
Ties: 0 
Player Wins: 0 
Dealer Wins: 2 
=> true 

Но если изменить $trials = 100, то я получаю такую ​​же неудачу:

load './bj.rb' 
Player Busted 
TypeError: nil can't be coerced into Fixnum 
    from /rails/Stack/bj.rb:78:in `+' 

Я надеюсь, что это помогает.

Удачи!

+0

Хорошо. Спасибо за помощь. Прочитав вашу помощь, я подумал, что «повторная инициализация игровой колоды» означало перемещение колод/рукописных заданий в цикл for - тогда она будет сбрасываться каждый раз, правильно? Я сделал это, но все же вижу ту же ошибку. Я не вижу, как растет массив players_cards ... Я добавил изменения в сообщение. Может быть, я неправильно понял повторную инициализацию? – user1441236

+0

Хорошо, я нашел свою ошибку. Вы были правы относительно ошибки инициализации. Я переехал, пытаясь понять это - он должен быть в цикле for. Однако причиной моей прерывистой ошибки был $ rand из $ deck.длина была слишком ранней и в конечном итоге соответствовала hit_card. Перемещение этого в функцию hit_card разрешает это. Спасибо за вашу помощь. – user1441236

+0

Можете ли вы, пожалуйста, поддержать и принять ответ. Кроме того, я хотел бы увидеть обновленный код. Пожалуйста, напишите, что в нижней части вашего вопроса или моего ответа в качестве окончательного рабочего кода. Удачи! – Anil