我尝试用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
语句?
每一个帮助都将受到高度赞赏。 (很抱歉在初稿中含糊不清。)
答案 0 :(得分:2)
注意:您在原始帖子中未包含任何样本数据,因此您的答案里程会有所不同。
你有很多问题,而不只是一个问题。除了不是DRY之外,你的代码也不是 testable ,因为它不会被分解成离散的操作。你可以(也可能应该)做很多事情:
简而言之,您需要重构代码以使其更加模块化,并利用该语言迭代数据对象,而不是像目前那样使用每个元素一个条件。
例如,请考虑以下事项:
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#select或Array#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