结合多个elsif'语句

时间:2017-06-03 14:27:32

标签: ruby

我尝试用Ruby编程蛇。为了让自己更熟悉Ruby。我通过将X和Y值保存在两个1D数组中来定义蛇的每个部分的位置,一个用于X值,另一个用于Y值。

 $x = [2,...]
 $y = [2,...]

(我忘了告诉我的是Snake的头部是通过用户输入移动的,而其余的只是继承了它之前的部分位置。)

def length(f)
if $length >= f
    $y[f] = $y[f-1]
    $x[f] = $x[f-1]
end
end

为了让Snake移动一下,我编程了这个。

for a in (1..20)  
  for b in (1..20)
    print " X "
  end  
  puts" "  
end

这给了我一个20 * 20的领域。

然后我试着像这样在场上展示蛇的每一部分。(同时还在场地周围画一个边界。)

for a in (1..20)
for b in (1..20)
    if a == 1 || a == 20
        if b == 1 || b == 20
            print " + "
        else
            print " - "
        end
    elsif b == 1 || b == 20
        print " | "
    elsif a == $x[0] && b == $y[0]
        body
    elsif a == $x[1] && b == $y[1]
        body
    elsif a == $x[2] && b == $y[2]
        body
    elsif a == $x[3] && b == $y[3]
        body
    elsif a == $x[4] && b == $y[4]
        body
    else
        print "   "  
    end

end
puts""
end

这样可行,但如果用户真的很好/有很多业余时间我需要为每个人分配elsif分配代表蛇的一部分,如果蛇应该有一个限制的长度100我需要发表100 elsif个陈述。(正文只是:

def body
print " # ".green
end


我尝试用这样的for loop修复它:

for c in (1..100)
  if a == $x[c] && b == $y[c]
    body
  end
end

和这个

 loop do  
    $x.size.times do |index|
        if $x[index] == a && $y[index] == b
            body
        end
    end
    break
 end

但遗憾的是,这并没有给予期望的结果,因为这会干扰吸引该领域寄宿生的if

有没有办法合并这些多个elsif语句?

每一个帮助都将受到高度赞赏。 (很抱歉在初稿中含糊不清。)

3 个答案:

答案 0 :(得分:2)

推荐的重构

注意:您在原始帖子中未包含任何样本数据,因此您的答案里程会有所不同。

你有很多问题,而不只是一个问题。除了不是DRY之外,你的代码也不是 testable ,因为它不会被分解成离散的操作。你可以(也可能应该)做很多事情:

  1. 将您的“身体”内容分解为不同的方法。
  2. 使用Array或Enumerator方法简化数据。
  3. 使用动态方法遍历数组,而不是固定范围或for循环。
  4. 在循环中使用 case / when 语句来处理同一变量的多个条件。
  5. 简而言之,您需要重构代码以使其更加模块化,并利用该语言迭代数据对象,而不是像目前那样使用每个元素一个条件。

    简化您的数据集并按程序处理

    例如,请考虑以下事项:

    def handle_matched_values array
    end
    
    def handle_mismatched_values array
    end
    
    paired_array = a.zip b
    
    matched_pairs   = paired_array.select { |subarray| subarray[0] == subarray[1] }
    unmatched_pairs = paired_array.reject { |subarray| subarray[0] == subarray[1] }
    
    matched_pairs.each { |pair| handle_matched_values pair }
    matched_pairs.each { |pair| handle_mismatched_values pair }
    

    在此示例中,您甚至可能不需要if语句。相反,您可以使用Array#selectArray#reject来查找与您想要的任何条件匹配的索引,然后为结果调用相关的处理程序。这具有非常程序化的优点,并且非常清楚地表明配对的数据集和处理程序是什么。它也非常易读,非常重要。

    动态循环和案例陈述

    如果您确实需要在单个循环中处理数据,请使用case语句来清理条件。例如:

    # Extract methods to handle each case.
    def do_something_with data; end
    def do_something_else_with data; end
    def handle_borders data; end
    
    # Construct your data any way you want.
    paired_array  = a.zip b
    
    # Loop over your data to evaluate each pair of values.
    paired_array.each do |pair|
      case pair
      when a == b
        do_something_with pair
      when a == paired_array.first || paired_array.last
         handle_borders pair
      else
         do_something_else_with pair
      end
    end
    

    当然,还有很多其他方法可以与大型数据集成对工作。目标是为您提供重构代码的基本结构。其余的由你决定!

答案 1 :(得分:1)

我会从这样的事情开始:

(1..20).each do |a|
  (1..20).each do |b|
    if [1, 20].include?(a)
      print([1, 20].include?(b) ? ' + ' : ' - ')

    elsif (1..100).any? { |i| a == $x[i] && b == $y[i] }
      body

    else
      print('   ')
    end

    puts('')
  end
end

答案 2 :(得分:0)

我想即使不是那么高级也可以作为解决方案?

 loop do  
    $x.size.times do |index|
        if $x[index] == a && $y[index] == b
            body
        end
    end
    break
 end