我为游戏板创建了一系列瓷砖。我的数组的每个元素都是一个散列,格式如下:
{'x' => x, 'y' => y, 'base' => "base"}
'base'的值可以是任何没有空格的字符串。
我想根据图块的X / Y值找到任何特定图块的索引,而不管图块的基值。
我对如何实现这一点的第一个想法是使用index()方法搜索数组的内容,如下所示:
active_tile = tile.index({'x' => 3, ''y' => 2, 'base' => "WILDCARD_HERE" })
但是,我不知道如何为此实现通配符。任何建议将不胜感激。
如果有人知道我使用的方法肯定不是一个有效的方法,我也会感谢有关更好的存储和检索方法的建议。
为了完整性,这里是我正在使用的整段代码:
class Map
attr_reader :max_ns # maximum north-south size
attr_reader :max_ew # maximum east-west size
attr_reader :tile # the array of tiles
def initialize(tall, wide)
@max_ns = tall
@max_ew = wide
# Create an array of tiles with X/Y coordinates and a tile base type.
@tile = []
(1..tall).each do |y|
(1..wide).each do |x|
@tile.push({'x' => x, 'y' => y, 'base' => "ocean"})
end
end
# Pick a spot to start a continent.
rand_y = rand(3..tall - 2)
rand_x = rand(3..wide - 2)
continental_base = @tile.index({'x' => rand_x, 'y' => rand_y, 'base' => "ocean"})
@tile[continental_base]['base'] = "land"
# Now spiral around that spot, creating a larger land mass
# finish writing the function to grab the array indices of the tile's neighbors first.
end
# Function to find the array indices of the tiles neighboring any given tile.
def tile_neighbors(x, y)
# First get the index of the tile with the given X & Y coordinates.
cur_tile = @tile.index({'x' => x, 'y' => y, 'base' => "/\A(...)\z/"})
end
end
答案 0 :(得分:1)
是的,使用Array#index是明智的:
arr = [{x: 1, y: 2, base: "Yo, how ya' doin'?"},
{x: 1, y: 3, base: "Hey, bro!"},
{x: 2, y: 5, z: 4 }]
target = { x: 1, y: 2 }
arr.index { |h| h.values_at(*target.keys) == target.values } #=> 0
target = { x: 1, y: 3 }
arr.index { |h| h.values_at(*target.keys) == target.values } #=> 1
target = { y: 5, x: 2 }
arr.index { |h| h.values_at(*target.keys) == target.values } #=> 2
target = { x: 2, y: 'cat' }
arr.index { |h| h.values_at(*target.keys) == target.values } #=> nil
答案 1 :(得分:0)
首先,使用您当前的数据结构的解决方案。当您使用常规参数调用index
时,它会进行精确匹配,因此无效。但是如果你传递块,那么它将返回块返回true的第一个元素的索引:
cur_tile = @tile.index { |tile| tile['x'] == x && tile['y'] == y }
但是,我不确定为什么你不会只使用二维数组的tile,其中x
和y
是数组的索引,因此@tiles[0][0]
是x和y均为0的那个:
[ [ base00, base01, base02, ... ],
[ base10, base11, base12, ... ] ]
答案 2 :(得分:0)
我想根据图块的X / Y值找到任何特定图块的索引,而不管图块的基值。
那么,让自己轻松一点,根据他们的X / Y值创建所有图块的哈希:
array = [
{'x' => 1, 'y' => 1, 'base' => "asdf"},
{'x' => 2, 'y' => 1, 'base' => "sdfg"},
{'x' => 1, 'y' => 2, 'base' => "dfgh"},
{'x' => 2, 'y' => 2, 'base' => "fghj"}
]
hash = array.map{ |h| ['%i/%i' % [ h['x'], h['y'] ], h] }.to_h
hash
# => {"1/1"=>{"x"=>1, "y"=>1, "base"=>"asdf"},
# "2/1"=>{"x"=>2, "y"=>1, "base"=>"sdfg"},
# "1/2"=>{"x"=>1, "y"=>2, "base"=>"dfgh"},
# "2/2"=>{"x"=>2, "y"=>2, "base"=>"fghj"}}
根据X / Y坐标找到一个哈希突然变得容易:
hash['1/1'] # => {"x"=>1, "y"=>1, "base"=>"asdf"}
如果您想快速搜索碱基,可以轻松创建类似的哈希:
hash = array.map{ |h| [h['base'], h] }.to_h
hash
# => {"asdf"=>{"x"=>1, "y"=>1, "base"=>"asdf"},
# "sdfg"=>{"x"=>2, "y"=>1, "base"=>"sdfg"},
# "dfgh"=>{"x"=>1, "y"=>2, "base"=>"dfgh"},
# "fghj"=>{"x"=>2, "y"=>2, "base"=>"fghj"}}
hash['asdf'] # => {"x"=>1, "y"=>1, "base"=>"asdf"}
并且,只要没有关键的冲突,就没有任何东西可以说两者不能都是同一个大哈希的一部分:
hash1 = array.map{ |h| ['%i/%i' % [ h['x'], h['y'] ], h] }.to_h
hash2 = array.map{ |h| [h['base'], h] }.to_h
hash = hash1.merge(hash2)
# => {"1/1"=>{"x"=>1, "y"=>1, "base"=>"asdf"},
# "2/1"=>{"x"=>2, "y"=>1, "base"=>"sdfg"},
# "1/2"=>{"x"=>1, "y"=>2, "base"=>"dfgh"},
# "2/2"=>{"x"=>2, "y"=>2, "base"=>"fghj"},
# "asdf"=>{"x"=>1, "y"=>1, "base"=>"asdf"},
# "sdfg"=>{"x"=>2, "y"=>1, "base"=>"sdfg"},
# "dfgh"=>{"x"=>1, "y"=>2, "base"=>"dfgh"},
# "fghj"=>{"x"=>2, "y"=>2, "base"=>"fghj"}}
hash['1/1'] # => {"x"=>1, "y"=>1, "base"=>"asdf"}
hash['asdf'] # => {"x"=>1, "y"=>1, "base"=>"asdf"}
很容易找到与模式匹配的所有瓷砖:
hash.values_at(*hash.keys.grep(/^a/)) # => [{"x"=>1, "y"=>1, "base"=>"asdf"}]
hash.values_at(*hash.keys.grep(/h$/)) # => [{"x"=>1, "y"=>2, "base"=>"dfgh"}]
hash.values_at(*hash.keys.grep(/dfg/)) # => [{"x"=>2, "y"=>1, "base"=>"sdfg"}, {"x"=>1, "y"=>2, "base"=>"dfgh"}]
或:
hash.values_at(*hash.keys.grep(%r#^1/#)) # => [{"x"=>1, "y"=>1, "base"=>"asdf"}, {"x"=>1, "y"=>2, "base"=>"dfgh"}]
hash.values_at(*hash.keys.grep(%r#/2$#)) # => [{"x"=>1, "y"=>2, "base"=>"dfgh"}, {"x"=>2, "y"=>2, "base"=>"fghj"}]
使用散列的最大优点是它非常快。无论您是想要电路板上的第一块,最后一块还是其他任何一块,查找速度都一样快。数组对于保存你想要按顺序处理的东西很有用,但是当你想快速找到它们时它们很糟糕,但这就是Hashes有用的地方。