1

我正在为 ruby​​ 控制台创建一个宾果游戏,其中数字被随机放入每个用户的散列中,包括宾果板,每个用户的散列被放入所有“宾果板”的数组中。我无法针对数组中的这些散列/板检查正确答案,因为它会针对所有用户而不是每个单独的用户板(散列)检查获胜列。下面的前三个信息/方法用作备份信息,而底部的两个方法是问题所在。如何切换方法以检查宾果卡数组中的一个哈希值的获胜组合,如果没有任何东西在下一个哈希值上重新开始,而不是从不同的卡片组合?

中奖组合如下

#here are the winning combinations

@columns = [      
  [:a1,:a2,:a3,:a4,:a5],
  [:b1,:b2,:b3,:b4,:b5],
  [:c1,:c2,:c3,:c4,:c5],
  [:d1,:d2,:d3,:d4,:d5],
  [:e1,:e2,:e3,:e4,:e5],

  [:a1,:b1,:c1,:d1,:e1],
  [:a2,:b2,:c2,:d2,:e2],
  [:a3,:b3,:c3,:d3,:e3],
  [:a4,:b4,:c4,:d4,:e4],
  [:a5,:b5,:c5,:d5,:e5],

  [:a1,:b2,:c3,:d4,:e5],
  [:e1,:d2,:c3,:b4,:a5]
]

此方法开始游戏,并将随机宾果游戏数字的散列填充到每个用户的数组中。该数组称为@bingo_cards

def start_game(user_goes_first)
#bingo slots
@places =  Hash.new { |hash, key| hash[key] = " "  }
@places_keys = [
  :a1,:a2,:a3,:a4,:a5,
  :b1,:b2,:b3,:b4,:b5,
  :c1,:c2,:c3,:c4,:c5,
  :d1,:d2,:d3,:d4,:d5,
  :e1,:e2,:e3,:e4,:e5
]

@bingo_cards = []


fill_cards(@users_count)


user_turn

结尾

此方法采用随机生成的数字并将它们转换为宾果卡(哈希),然后将它们放入数组(@bingo_cards)

def fill_cards(number)
  number.times do 
    @places_keys.each_with_index do |n,i| 
      @places[n] = pick_number(i)
    end
    @bingo_cards << @places.dup
  end
end

这是每次选择数字的地方 - @user = 'X',所以它用 X 替换数字

def user_turn
  put_line
  puts "\n  RUBY BINGO".purple
  draw_game
  print "\n Please type 'go' or type 'exit' to quit: ".neon
  STDOUT.flush
  input = gets.chomp.downcase.to_str
  put_bar
  if input.length == 2
    @random = rand(1..75)
    puts @random
    @bingo_cards.each do |bingo|
      @places_keys.each do |key|
        bingo[key] = @user if bingo[key] == @random
      end
    end
    put_line
    check_game(@user)
  else
    wrong_input unless input == :exit
  end
end

这是我遇到问题的地方。它确实正确计算了 X,但适用于每个用户。这意味着它只有在一个人玩的情况下才能正常工作。如果两个人在玩,如果一个用户在左上角连续有两个 X(表示数字出现),而另一个用户在右上角连续三个 x,则游戏结束 - 它应该只当用户有 5 个 X 时结束,即随机数在他们的板上被选中 5 次。

def times_in_column arr, item
 #count the number of X's in the column to see if 5 in a row
  times = 0
  @bingo_cards.each do |bingo|
    arr.each do |i| 
      times += 1 if bingo[i] == item
    end
  end
  times
end

此方法与上述方法一起负责检查游戏。

def check_game(next_turn)

  game_over = nil

  @bingo_cards.each do |bingo|
    @columns.each do |column|

    # see if user has won
      if times_in_column(column, @user) == 5
        put_line
        draw_game
        put_line
        puts ""
        puts " Game Over -- WINS!!!\n".blue
        game_over = true
        @user_score += 1
        ask_to_play_again(true)
      end
    end
  end

  unless game_over
    user_turn
  end
end

这是任何其他所需信息的要点- 我自始至终评论了所有内容。

4

2 回答 2

2

由于两个因素,您看到了您所看到的结果:

  1. @user在所有宾果卡上使用相同的值。事实上,@user永远不会改变。
  2. 您正在为每一列添加所有@user宾果卡的实例

如果您知道用户拥有哪些卡,则无需在卡上标记用户特定的标记,您只需检查用户拥有的卡即可。同样,如果您为每个用户使用唯一标记,则可以计算所有卡,前提是每个用户只有一张卡。如果用户可以玩多张牌,这在宾果游戏中很常见,那么单独查看每张牌的列仍然很重要。

顺便说一句,这段代码有很多质量问题,例如递归调用user_turn每一步。我强烈建议您对此进行代码审查。

于 2013-08-19T04:20:07.637 回答
2

这里有一个问题:

def times_in_column arr, item
 #count the number of X's in the column to see if 5 in a row
  times = 0
  @bingo_cards.each do |bingo|
    arr.each do |i| 
      times += 1 if bingo[i] == item
    end
  end
  times
end

考虑上面代码中发生的情况。times_in_column用一组键调用,比如顶部的那个[a1:, a2:, a3:, a4:, a5:]times设置为 0。对于游戏中的每张宾果卡,在卡上检查数组中的每个键,如果找到 X,times则增加。请注意,随着宾果卡循环 ( @bingo_cards.each do |bingo|) 的进行,times永远不会重置为 0,因此每次在循环中的任何宾果卡上找到 X 时,计数都会增加。

为了解决这个问题,我建议将宾果卡循环移出times_in_column方法,并调用times_in_column每个单独的宾果卡,然后检查返回值。

实际上,我建议重写此方法以获取一张宾果卡并检查所有可能的获胜模式(在@columns 中),并且对于每个获胜模式,从 0 开始计数,并记住是否曾经找到任何获胜模式5 Xs,如果是,则返回 true,否则返回 false。

于 2013-08-19T04:21:37.173 回答