我为你做了一件事。
我有一个用“w”类型的Tile对象填充二维数组的程序。然后程序选择数组中的随机点(中心)并尝试从中心转动半径为4的所有对象。不知怎的,程序没有这样做,我认为问题是数学公式,但我找不到错误。
class Map
def initialize(d1,d2)
@data = Array.new(d1) { Array.new(d2)}
end
def [](x, y)
@data[x][y]
end
def x(x)
@data[x]
end
def y(y)
@data[y]
end
def []=(x, y, value)
@data[x][y] = value
end
end
# TILES
class Tile
# Types = ["l", "w", "r"]
attr_accessor :type
def initialize(type)
@type = type
end
def set(string)
@type = string
end
def to_s
@type
end
end
# REAL ACTION HERE
def generate
h = 20
w = 20
i = 0
worldmap = Map.new(20, 20)
while i < h do
n = 0
while n < w do
worldmap.[] = (i, n, Tile.new("w"))
n = n + 1
end
i = i + 1
end
gen(worldmap)
look(worldmap)
end
def look(map)
z = 0
b = 0
c = 0
string = " "
while b < 20 do
while z < 20 do
string = string + map.[](b, z).to_s
z = z + 1
end
b = b + 1
puts string
c = c + 1
end
end
def gen(map)
circle_amount = 1
i = 0
x = 0
y = 0
while i < circle_amount do
#select a center
cy = (rand(1..20))
cx = (rand(1..20))
center = map.[](cx,cy)
center.set("C")
radius = 4
puts cy.to_s + " " + cx.to_s
while y < 20
while x < 20
offsetY = y - cy
offsetX = x - cx
distance = offsetY**2 + offsetX**2
if distance <= radius**2 then
tile = map.[](y, x)
tile.set("l") # I DID IT
end
x = x + 1
end
y = y + 1
end
i = i + 1
end
end
generate
以下是输出
的示例wwwwwwwwwwwwlllllwww wwwwwwwwwwwwlllllwww wwwwwwwwwwwwlllllwww wwwwwwwwwwwwlllllwww wwwwwwwwwwwwlllllwww wwwwwwwwwwwwlllllwww wwwwwwwwwwwwlllllwww wwwwwwwwwwwwlllllwww wwwwwwwwwwwwlllllwww wwwwwwwwwwwwlllllwww wwwwwwwwwwwwlllllwww wwwwwwwwwwwwlllllwww wwwwwwwwwwwwlllllwww wwwwwwwwwwwwlllllwww wwwwwwwwwwwwlllllwww wwwwwwwwwwwwlllllwww wwwwwwwwwwwwlllllwww wwwwwwwwwwwwlllllwww wwwwwwwwwwwwlllllwww wwwwwwwwwwwwlllllwww
C:/Users/borya/Documents/NetBeansProjects/LearningPurporse/lib/main.rb:7:in
[]': >undefined method
[]'for nil:NilClass(NoMethodError)
答案 0 :(得分:2)
> m = Map.new(5,5)
=> #<Map:0x007fa5d9838fc0 @data=[[nil, nil, nil, nil, nil], [nil, nil, nil, nil, nil], [nil, nil, nil, nil, nil], [nil, nil, nil, nil, nil], [nil, nil, nil, nil, nil]]>
ruby-1.9.3-p125 :040 > m[1,1]="hi"
(x=1, y=1) = hi
@data[x][y]=hi
=> "hi"
> m
=> #<Map:0x007fa5d9838fc0 @data=[[nil, nil, nil, nil, nil], [nil, "hi", nil, nil, nil], [nil, nil, nil, nil, nil], [nil, nil, nil, nil, nil], [nil, nil, nil, nil, nil]]>
我可能会将这些内容编写得更接近下面的内容,虽然它有点偏离袖口,但我保留了一些原始代码,即使它可能不是我原来的代码。
class Map
attr_reader :data, :x, :y
def initialize(x, y)
@x = x
@y = y
@data = Array.new(x) { Array.new(y) }
end
def set(&block)
(0..x-1).each do |i|
(0..y-1).each do |j|
result = yield i, j, @data[i][j]
@data[i][j] = result if result
end
end
end
def [](x, y)
@data[x][y]
end
def []=(x, y, value)
@data[x][y] = value
end
def dump
(0..x-1).each do |i|
string = ""
(0..y-1).each do |j|
string += "#{self[i, j]} "
end
puts string
end
end
end
def generate
map = Map.new(20, 20)
map.set { |x, y, at| Tile.new('w') }
gen(map)
end
def gen(map)
3.times do |i|
cy = rand(0..map.x-1)
cx = rand(0..map.y-1)
puts "cx=#{cx}, cy=#{cy}"
map[cx, cy].set('C')
map.dump
radius = 3.0
map.set do |x, y, at|
offsetX = x - cx
offsetY = y - cy
distance = Math.sqrt(offsetY**2 + offsetX**2)
distance.abs <= radius ? '.' : false
end
puts ''
map.dump
end
end
一旦你修好了数学,你就可以得到这样的结论:
w w w w w w w w w w w w w w w w w . w w
w w w w w w w w w w w w w w w . . . . .
w w w w w w w w w w w w w w w . . . . .
w w w w w w w w w w w w w w . . . . . .
w w w w w . w w w w w w w w w . . . . .
w w w . . . . . w w w w w w w . . . . .
w w w . . . . . w w w w w w w w w . w w
w w . . . . . . . w w w w w w w w w w w
w w w . . . . . w w w w w w w w w w w w
w w w . . . . . w w w w w w w w w w w w
w w w w w . w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w w w w w w w w w
w w w w w w w w w w w w . w w w w w w w
w w w w w w w w w w . . . . . w w w w w
w w w w w w w w w w . . . . . w w w w w
w w w w w w w w w . . . . . . . w w w w
w w w w w w w w w w . . . . . w w w w w
w w w w w w w w w w . . . . . w w w w w
警告:此代码高于您的技能等级,您可能希望将其转换为带有额外冗长的while循环,直到您继续进行。
Boris,由于多种原因,包括随机缩进/格式化和简单的语法错误,您的原始代码难以推理。一致地格式化代码非常重要。这样做可以让您和其他人更轻松地阅读它。
熟悉您正在使用的语言范例非常重要。一般来说,如果Ruby代码具有while循环,计数器增量等,当它们实际上不用于索引以外的任何东西时,它就是代码味道。 Canonical Ruby倾向于使用.each
,块等更具功能性的风格。
你的数学错误是对的,虽然我怀疑你不知道它有多么错误。像这样的数学真的易于调试:手工完成。画一个网格。拿着程序的(cx, cy)
并手动进行计算。做一些健全性检查,以确保你所做的你正在做的是(a)你实际做了什么,(b)有感觉。
例如,您的距离有时会达到数百。显然,当你的网格为(20, 20)
时,没有有意义......一旦你看到,解决方案很明显 - 你省略了一步。
同样的逻辑可以用于其余的数学问题。
玩电脑......是电脑。按照纸上的步骤操作。没有更快的理解途径,而是内化“屏幕下方”实际发生的事情。