确定骰子游戏中多个回合赢家的功能存在问题

时间:2019-05-28 16:12:32

标签: ruby dice

我们有一项任务来确定骰子游戏的最终赢家。这是完整的规则:

在此游戏中,您将与另外两名计算机玩家发生冲突。有三回合。在每个回合开始时,玩家掷出两个骰子。该回合的掷骰总数将添加到您的积分中。您的分数总是从零开始。每个连续的回合将点加到总数中。在第三轮结束时,得分最高者赢得比赛。

要求 ———————— 每个玩家有两个骰子 玩家每回合掷骰一次 在每个回合结束时显示每个球员的分数 在每个回合结束时显示回合的领导者 提示用户滚动以开始下一个 三轮比赛结束后 玩家得分一直持续到比赛结束 游戏结束后,宣布获胜者 宣布获胜者后,您可以选择重新开始或退出

除了如何确定游戏的最终赢家以外,我已经进行了所有工作。我尝试过使用if / elsif语句创建一种名为“ gameWinner”的新方法,从每个回合中获取总分并将其分别相加。但是,程序一旦到达即会中断。我想不出如何解决这个问题,但我输入的内容似乎都无法正常工作。

def welcome
    puts ""
    puts "Let's roll some die! You will be competing against 2 computers in 3 rounds, each player having 2 die."
    puts "Please enter your name and press 'Enter'"
    puts ""
    @userName = gets.chomp
    puts ("Welcome, " + @userName + ". Let's roll those die!")
    puts ""
end

def round(round)
    result_1 = Random.new.rand(1..6)
    result_2 = Random.new.rand(1..6)
    total_1 = result_1 + result_2

    result_3 = Random.new.rand(1..6)
    result_4 = Random.new.rand(1..6)
    total_2 = result_3 + result_4

    result_5 = Random.new.rand(1..6)
    result_6 = Random.new.rand(1..6)
    total_3 = result_5 + result_6

    winner = [total_1, total_2, total_3].max
    players = {total_1 => @userName, total_2 => "Computer 1", total_3 => "Computer 2"}.max

    puts "Round #{round}"
    puts "#{@userName}, your die are a #{result_1} and a #{result_2}, totaling #{total_1}"
    puts "Computer 1's die are a #{result_3} and a #{result_4}, totaling #{total_2}"
    puts "Computer 2's die are a #{result_5} and a #{result_6}, totaling #{total_3}"
    puts "Round #{round} highest score is: #{winner}"
        if total_1> total_2 && total_3
            puts "#{@userName} is the winner!"
        elsif total_2 > total_1 && total_3
            puts "Computer 1 is the winner!"
        elsif total_3 > total_1 && total_2
            puts "Computer 2 is the winner!"
        else
            puts "It was a tie, there are no winners."
        end
    puts ""  
end

def gameWinner(rounds)
    if total_1> total_2 && total_3
        roundWinner1 = 1
    elsif total_2 > total_1 && total_3
        roundWinner2 = 1
    else total_3 > total_1 && total_2
        roundWinner3 = 1
    end

    gameSummary1 = roundWinner1 + roundWinner1 + roundWinner1
    gameSummary2 = roundWinner2 + roundWinner2 + roundWinner2
    gameSummary3 = roundWinner3 + roundWinner3 + roundWinner3
    winnerOA = [gameSummary1, gameSummary2, gameSummary3].max

    puts "The winner of the game is #{winnerOA}"
end

def playAgain
    puts "Would you like to start over? (Y/N)\n"
    answer = gets.chomp.upcase
    if answer == "Y"
        play
    elsif answer == "N"
        puts "Thank you for playing.\n"
    else
        playAgain
    end    
  end

def play
    welcome
    round(1)
    round_1 = round(1)   
    round(2)
    round(3)
    gameWinner    
    playAgain
end

play

我希望该程序能够报告总冠军,但我只是在如何获得它方面空白。

这是gameWinner函数引发的错误:

  

跟踪(最近一次通话最近):2:从rollEm2.rb:83:在'1:从rollEm2.rb:79:在播放中rollEm2.rb:44:在`gameWinner'中:错误的参数数量(给定0,预期为1)(ArgumentError)

2 个答案:

答案 0 :(得分:1)

调用gameWinner的方法没有参数,但看起来您的方法中未使用预期的参数。因此,请尝试将其从定义中删除:

def gameWinner
  #... your method code
end

答案 1 :(得分:1)

这是使用Player类的更像Ruby的问题解决方法。请注意,玩家数和回合数不是固定的。我省略了要求玩家掷骰子的提示。如果该类的定义的前两行是头疼的话,请不要担心-请参阅答案末尾的说明。

class Player
  @players = []
  singleton_class.send(:attr_reader, :players)

  attr_reader :name, :cum_score

  def initialize(name)
     @name = name
     @cum_score = 0
     self.class.players << self
  end

  def blow_on_dice
    # Come to papa!
  end

  def throw
    score = rand(1..6) + rand(1..6) 
    @cum_score += score
    score
  end
end

def show_winners(scores)
  max_score = scores.values.max
  winners = scores.select { |_,v| v == max_score }.keys
  if winners.size == 1
    puts "Winner with a score of #{max_score} is #{winners.first}"
  else
    print "Winners of round with a score of #{max_score} are "
    winners.each_with_index do |name,i|
      print name
      print case i
            when winners.size-1 then ''
            when winners.size-2 then ' and '
            else                ', '
            end
    end
    puts
  end
end

Player.new('Cary')
  #=> #<Player:0x000059a79738b768 @name="Cary", @cum_score=0> 
Player.new('Hal')
  #=> #<Player:0x000059a7973d7690 @name="Hal", @cum_score=0> 
Player.new('Deep Thought')
  #=> #<Player:0x000059a79756f318 @name="Deep Thought", @cum_score
nbr_rounds = 3

players = Player.players
  #=> [#<Player:0x000059a79738b768 @name="Cary", @cum_score=0>,
  #    #<Player:0x000059a7973d7690 @name="Hal", @cum_score=0>,
  #    #<Player:0x000059a79756f318 @name="Deep Thought", @cum_score=0>] 

(1..nbr_rounds).each do |round|
  puts "\nResults for round #{round}"
  scores = players.each_with_object({}) do |p,h|
    p.blow_on_dice
    score = p.throw
    puts "#{p.name} throws #{score}"
    h[p.name] = score
  end
  show_winners(scores)
end

Results for round 1
Cary throws 8
Hal throws 9
Deep Thought throws 9
Winners of round with a score of 9 are Hal and Deep Thought

Results for round 2
Cary throws 7
Hal throws 9
Deep Thought throws 9
Winners of round with a score of 9 are Hal and Deep Thought

Results for round 3
Cary throws 7
Hal throws 11
Deep Thought throws 6
Winner with a score of 11 is Hal

puts "\nResults for all rounds"
scores = players.each_with_object({}) do |p,h|
  h[p.name] = p.cum_score
  puts "#{p.name} had a total score of #{p.cum_score}"
end

Results for all rounds
Cary had a total score of 22
Hal had a total score of 29
Deep Thought had a total score of 24

show_winners(scores)

Winner with a score of 29 is Hal

如果是行

puts "scores = #{scores}"

插入show_winners中第一行之前,对于每三个循环计算显示以下内容:

scores = {"Cary"=>7, "Hal"=>5, "Deep Thought"=>7}
scores = {"Cary"=>4, "Hal"=>7, "Deep Thought"=>3}
scores = {"Cary"=>10, "Hal"=>11, "Deep Thought"=>8}

对于总计计算,显示以下内容:

scores = {"Cary"=>21, "Hal"=>23, "Deep Thought"=>18}

请注意,@players是该类的instance_variable(相对于该类的实例)。第singleton_class.send(:attr_reader, :players)行为该变量创建了一个吸气剂,使我们可以编写Player.players来获取已创建的Players实例的数组。该行的几种替代方法之一如下:

class << self
  attr_reader :players
end

或者,已经创建的Players实例的集合将保留在类之外,但是容易出错(例如,如果以后添加了播放器):

players = [Player.new('Cary'), Player.new('Hal'), Player.new('Deep Thought')]

完成类定义后,将简化为以下内容。

class Player
  attr_reader :name, :cum_score

  def initialize(name)
     @name = name
     @cum_score = 0
  end

  def throw
    ...
  end
end

但是,这种设计容易出错(例如,如果以后添加了播放器),并且players没有更新。