做一个Yahtzee游戏,阵列不会出现在屏幕上

时间:2015-03-04 14:21:51

标签: ruby arrays class object methods

好的,所以我刚开始学习红宝石,我正在制作一个Yhatzee游戏,现在这就是我目前所在的地方:

class  Yhatzee

 def dices
    @dices.to_a= [
    dice1=rand(1..6),
    dice2=rand(1..6),
    dice3=rand(1..6),
    dice4=rand(1..6),
    dice5=rand(1..6)
    ]
  end

  def roll_dice
    @dices.to_a.each do |dice|
      puts dice
    end
  end
end

x = Yhatzee.new
puts x.roll_dice

现在我在数组之后键入.to_a的原因是我不断获得"未初始化的变量@ dices"错误,这似乎解决了它,我不明白为什么。

无论如何我的问题,我目前没有任何错误,但我的程序仍然不会在屏幕上打印任何内容。我希望它打印出阵列中每个骰子的价值......任何想法我做错了什么?当我在没有使用类或方法的情况下以程序样式执行它似乎有效,所以我认为如果我制作了“骰子”,它可能会起作用。方法公开。但没有运气。

2 个答案:

答案 0 :(得分:0)

这里有一些问题。首先@dicesnil因为它没有设置在任何地方。因此,当您致电@dices.to_a时,您将获得[]。此外,dices方法也不起作用,因为nil没有to_a=方法,并且将忽略您在数组中分配的局部变量。

似乎有点阅读,但我会做以下事情:(不是整个游戏只是你的代码的重构)

class  Yhatzee
  def dice
    @dice = Array.new(5){rand(1..6)}
  end
  def roll_dice
    puts dice
  end
end

x = Yhatzee.new
puts x.roll_dice

这里需要做很多其他考虑因素,但这至少应该让你开始。我将如何推荐扩展逻辑的小例子:(我在这里没有处理很多场景,所以不要复制粘贴。只是想给你一个更深入的了解)

require 'forwardable'
module Yahtzee
  module Display
    def show_with_index(arr)
      print arr.each_index.to_a
      print "\n"
      print arr
    end
  end
  class Roll
    include Display
    extend Forwardable 
    def_delegator :@dice, :values_at
    attr_reader :dice
        def initialize(dice=5)
            @dice = Array.new(dice){rand(1..6)}
        end
        def show
      show_with_index(@dice)
        end
    end
  class Turn
    class << self
      def start
        t = Turn.new
        t.show
        t
      end
    end
    attr_reader :rolls
    include Display
    def initialize
      @roll = Roll.new
      @rolls = 1
      @kept = []
    end
    def show
      @roll.show
    end
    def roll_again
      if available_rolls_and_dice
        @rolls += 1
        @roll = Roll.new(5-@kept.count)
        puts "Hand => #{@kept.inspect}"
        show
      else
        puts "No Rolls left" if @rolls == 3
        puts "Remove a Die to keep rolling" if @kept.count == 5
        show_hand
      end 
    end
    def keep(*indices)
      @kept += @roll.values_at(*indices)
    end
    def show_hand
      show_with_index(@kept)
    end
    def remove(*indices)
      indices.each do |idx| 
        @kept.delete_at(idx)
      end
      show_hand
    end
    private 
      def available_rolls_and_dice
        @rolls < 3 && @kept.count < 5
      end
  end
end   

答案 1 :(得分:0)

此代码的主要问题是您正在尝试在roll_dice方法中使用@dices实例变量,但是您没有在任何地方(正在使用的任何地方)定义实例变量。您已经创建了dices方法,但实际上并没有在任何地方实例化它。我在下面概述了一个修复:

class  Yhatzee

  def initialize
    create_dices
  end

  def roll_dice
    @dices.each do |dice|
      puts dice
    end
  end

  private

  def create_dices
    @dices = Array.new(5){rand(1..6)}
  end

end

x = Yhatzee.new
x.roll_dice

我做了一些简单的重构:

  1. 创建了一个initialize方法,该方法在类初始化时创建@dice实例变量。
  2. 制作&#39;骰子&#39;方法更具描述性,并将方法可见性更改为私有,因此只有类本身才能创建@dice。
  3. 清除了@dice实例变量
  4. 内部骰子的创建
  5. 我已经从roll_dice方法中省略了.to_a,现在我们从类中创建了变量,并且我们知道它是一个数组,除非我们明确重新定义它,否则它将会出现。
  6. 更新

    虽然我清理了类的实现,但是@engineersmnky很好地指出我每次调用roll_dice函数时都会看到roll会返回相同的结果,因此我写了两个函数来实现这个,一个定义一个实例变量供以后使用,一个实际上只返回结果。

    class  Yhatzee
    
      def roll_dice
       @dice = Array.new(5){rand(1..6)} # You will have access to this in other methods defined on the class
       @dice.each {|dice| puts dice }
      end
    
      def roll_dice_two
        Array.new(5){rand(1..6)}.each {|dice| puts dice } # This will return the results but will not be stored for later use
      end
    
    end
    
    x = Yhatzee.new
    x.roll_dice
    x.roll_dice # Will now return a new result