Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby中的嵌入式循环_Ruby - Fatal编程技术网

Ruby中的嵌入式循环

Ruby中的嵌入式循环,ruby,Ruby,我想写一个程序来模拟骰子游戏。这个想法是掷五个骰子,得到尽可能低的分数——三的值为0。掷完五个骰子后,玩家/机器人必须从五个骰子中选择至少一个(或多个)骰子,然后掷出其余的骰子。这就是给我带来问题的原因。如果没有三,那么我推动机器人的骰子的“守护者”数组最终是空的,这就需要一个嵌入式循环。由于我对编码相当陌生,我真的无法找到一种方法来创建一个嵌入式循环,以确保至少有一个骰子被指定为保管者。为了你的理智起见,我要说,我现在介绍的这个程序的“beta”版本旨在做以下工作:创建一个机器人,尝试在一轮骨

我想写一个程序来模拟骰子游戏。这个想法是掷五个骰子,得到尽可能低的分数——三的值为0。掷完五个骰子后,玩家/机器人必须从五个骰子中选择至少一个(或多个)骰子,然后掷出其余的骰子。这就是给我带来问题的原因。如果没有三,那么我推动机器人的骰子的“守护者”数组最终是空的,这就需要一个嵌入式循环。由于我对编码相当陌生,我真的无法找到一种方法来创建一个嵌入式循环,以确保至少有一个骰子被指定为保管者。为了你的理智起见,我要说,我现在介绍的这个程序的“beta”版本旨在做以下工作:创建一个机器人,尝试在一轮骨骼上获得最低分数。骰子掷一次。然后他试着选择尽可能低的分数。如果没有三个(等于0),他选择一个。我试图解决的问题是创建一个嵌入式循环,确保为keeper阵列选择至少一个骰子。代码主要是为了演示我的解决方案有多丑陋,并给出一个更好的解决方案

#rolls dice
srand
dice = []
5.times do 
  dice.push(rand(6)+1)
end
puts dice
puts " "

#initialize keeper and roll again arrays
i = 0
keeper = []
roll_again = []


#select any 3s from the dice roll and put them in keeper
dice.each do |d| 
  if d == 3 
    keeper.push(d)
  else
    i +=1  #dummy operation to keep if statement functioning, tragically ugly code
  end
end

#in the case that no threes were rolled, ones are selected
if keeper.length == 0
  dice.each do |f|
    if f == 1
      keeper.push(f)
    else
      i+= 1
    end
  end
else 
  i += 1
end

puts "Keeper:"
puts keeper
puts "Roll Again:"
puts roll_again

对于初学者来说,你做得很好:-)我将向你展示一些可以帮助你做这个练习的东西,通过尝试不同的东西并试图理解它们,你会学到最好的东西

>> dice = [5,1,2,2,6,4] #=> [5, 1, 2, 2, 6, 4]
>> if (threes = dice.select { |d| d == 3 }).empty?
..   ones = dice.select { |d| d == 1 }
..   end #=> [1]
>> threes #=> []
>> ones #=> [1]
您可以做的另一件事是将骰子阵列分组:

>> dice.group_by { |d| d } #=> {5=>[5], 1=>[1], 2=>[2, 2], 6=>[6], 4=>[4]}
这样,您可以立即看到给定数字的数组是否为空。注意,在Ruby中很容易实现数组差异,这可能有助于移除骰子:

>> [3,1,3,5,1,7] - [3]  #=> [1, 5, 1, 7]
事实上,数组相交也是查看某个元素是否是数组的一部分的一个好方法:

>> ([3,1,3,5,1,7] & [3]).empty? #=> false
>> ([4,1,2,5,1,7] & [3]).empty? #=> true

还有一些提示:您的
else
分支不需要伪语句,只需将它们省略即可。我还强烈建议浏览
Array
Enumerable
的文档,其中有很多有用的方法。

当然有很多方法可以做到这一点。但是看一看:我做了一些一般性的修改,使它更。。。鲁比

# A custom helper method
class Array
  def take_while_num # Modeled off take_while, but also pass in the length so far
    arr = []
    each do |e|
      # Call the block with this element and the current length,
      # and stop if it returns false
      if yield(e, arr.length)
        arr << e
      else
        break
      end
    end
    arr
  end
end

dice = Array.new(5) { rand(6)+1 } # 5 random numbers
puts "Original dice: #{dice.inspect}"

# Sort the dice by value (3s are worth 0), then take all 3s
# or if there are no 3s, take whatever is at the front
keep = dice.sort_by {|d| d == 3 ? 0 : d }.take_while_num {|d, n| n.zero? or d == 3 }
# Remove the ones we're keeping from the list of dice
dice -= keep

puts "Dice: #{dice.inspect}"
puts "Keep: #{keep.inspect}"

顺便说一句,迈克尔·科尔创造了methodfinder gem。因此:

$ sudo gem install methodfinder
现在我们可以找到我们需要的方法:

[2,3,2,3,4,3,2].find_method { |x| x.unknown(3) == [3,3,3] }
=> grep
所以我会这样写你的算法:

def keep dice
  threes = dice.grep(3)
  threes.empty? ? [dice.min] : threes
end

如果没有三个或一个呢?在这一点上,这并不重要。我会继续说:如果数组仍然为空,那么选择2,然后选择4等等。但是如果没有嵌入循环,我认为这段代码看起来会非常难看。除非无法使用嵌入式循环。基本上,为了回答您的问题,目前编写的程序并不是为了完整地模拟一轮。只要程序可以在数组中有三个或一个的时候进行测试,就足以满足我的目的——这仅仅是为了学习如何编写代码。那么
i
的用途是什么?你增加了它,但似乎没有使用它。这绝对是这段代码中最荒谬的部分。我所能想到的就是让if语句工作,在else语句中包含一些东西作为虚拟操作。所以我增加了一个我知道不会使用的变量。当然,这是一个糟糕的编码。Rubyists通常用2个空格缩进,而不是4个空格。我只是用“掷骰子”的方法写了一个回复,并使用了一点。选择以获得3。。。但是我认为Michael关于在控制台中使用Array和Enumerable API中的方法的建议是一个很好的建议。谢谢你的回答和鼓励。表情符号可以让人安心。我还不能完全理解你的答案,但我会在周一解决。在ruby-doc.com的帮助下,我相信它将阐明很多关于ruby和编码的一般知识,并帮助我走上正轨。@Bodidarma,你需要安装ruby Gems。以下是我的说明,如何使用Ruby Gems和Rails安装RVM:
def keep dice
  threes = dice.grep(3)
  threes.empty? ? [dice.min] : threes
end