11-02-2010, 09:05 PM
(Modification du message : 12-02-2010, 12:09 PM par Sephi-Chan.)
Voilà, je pense que c'est bon. Voici le code :
Et la sortie sur la console :
Sephi-Chan
class Sphere
attr_reader :index, :ring_index
def initialize(ring_index, index)
@ring_index = ring_index
@index = index
end
# Return true if the sphere is on the x or y axe.
def on_axe?
[ 'TOP', 'RIGHT', 'BOTTOM', 'LEFT' ].include?(position)
end
def position
@position ||= if @index == 0 && @ring_index == 0
'ORIGIN'
elsif @index == 0
'TOP'
elsif @index == @ring_index
'RIGHT'
elsif 2 * @ring_index == @index
'BOTTOM'
elsif 3 * @ring_index == @index
'LEFT'
elsif @index < @ring_index
'TOPRIGHT'
elsif @index < 2 * @ring_index
'BOTTOMRIGHT'
elsif @index < 3 * @ring_index
'BOTTOMLEFT'
else
'TOPLEFT'
end
end
def to_s
"(#{@ring_index}; #{@index})"
end
end
class Graph
attr_accessor :grid
def initialize(grid = [])
@grid = grid
end
def generate(rings_count)
@grid = []
@grid[0] = [ Sphere.new(0, 0) ]
rings_count.times do |ring_index|
ring_index += 1
@grid[ring_index] = []
(0..(ring_index * 4 - 1)).each do |index|
@grid[ring_index] << Sphere.new(ring_index, index)
end
end
@grid
end
def neighbours(ring_index, index)
sphere = sphere_at_coordinates(ring_index, index)
neighbours = case sphere.position
when 'ORIGIN'
[
sphere_at_coordinates(sphere.ring_index + 1, sphere.index),
sphere_at_coordinates(sphere.ring_index + 1, sphere.index + 1),
sphere_at_coordinates(sphere.ring_index + 1, sphere.index + 2),
sphere_at_coordinates(sphere.ring_index + 1, sphere.index + 3)
]
when 'TOP'
[
sphere_at_coordinates(sphere.ring_index + 1, sphere.index),
sphere_at_coordinates(sphere.ring_index + 1, sphere.index + 1),
sphere_at_coordinates(sphere.ring_index - 1, sphere.index),
sphere_at_coordinates(sphere.ring_index + 1, sphere.index - 1)
]
when 'TOPRIGHT'
[
sphere_at_coordinates(sphere.ring_index + 1, sphere.index + 1),
sphere_at_coordinates(sphere.ring_index + 1, sphere.index),
sphere_at_coordinates(sphere.ring_index - 1, sphere.index - 1),
sphere_at_coordinates(sphere.ring_index - 1, sphere.index)
]
when 'RIGHT'
[
sphere_at_coordinates(sphere.ring_index + 1, sphere.index),
sphere_at_coordinates(sphere.ring_index + 1, sphere.index + 2),
sphere_at_coordinates(sphere.ring_index + 1, sphere.index + 1),
sphere_at_coordinates(sphere.ring_index - 1, sphere.index - 1)
]
when 'BOTTOMRIGHT'
[
sphere_at_coordinates(sphere.ring_index + 1, sphere.index + 1),
sphere_at_coordinates(sphere.ring_index + 1, sphere.index + 2),
sphere_at_coordinates(sphere.ring_index - 1, sphere.index - 1),
sphere_at_coordinates(sphere.ring_index - 1, sphere.index - 2)
]
when 'BOTTOM'
[
sphere_at_coordinates(sphere.ring_index - 1, sphere.index - 2),
sphere_at_coordinates(sphere.ring_index + 1, sphere.index + 1),
sphere_at_coordinates(sphere.ring_index + 1, sphere.index + 2),
sphere_at_coordinates(sphere.ring_index + 1, sphere.index + 3)
]
when 'BOTTOMLEFT'
[
sphere_at_coordinates(sphere.ring_index + 1, sphere.index + 3),
sphere_at_coordinates(sphere.ring_index + 1, sphere.index + 2),
sphere_at_coordinates(sphere.ring_index - 1, sphere.index - 3),
sphere_at_coordinates(sphere.ring_index - 1, sphere.index - 2)
]
when 'LEFT'
[
sphere_at_coordinates(sphere.ring_index + 1, sphere.index + 4),
sphere_at_coordinates(sphere.ring_index + 1, sphere.index + 2),
sphere_at_coordinates(sphere.ring_index + 1, sphere.index + 3),
sphere_at_coordinates(sphere.ring_index - 1, sphere.index - 3),
]
when 'TOPLEFT'
[
sphere_at_coordinates(sphere.ring_index + 1, sphere.index + 3),
sphere_at_coordinates(sphere.ring_index + 1, sphere.index + 4),
sphere_at_coordinates(sphere.ring_index - 1, sphere.index - 3),
sphere_at_coordinates(sphere.ring_index - 1, sphere.index - 4)
]
end
# Adjacent spheres are in the neighbours, except for origin sphere.
if sphere.position != 'ORIGIN'
neighbours << sphere_at_coordinates(sphere.ring_index, sphere.index - 1)
neighbours << sphere_at_coordinates(sphere.ring_index, sphere.index + 1)
end
neighbours.delete_if { |sphere| sphere.nil? }
end
# Return the sphere at the given coordinates or nil.
# Handle "outs of bounds" positions.
def sphere_at_coordinates(ring_index, index)
if @grid[ring_index]
real_index = index % @grid[ring_index].size
@grid[ring_index][real_index]
else
nil
end
end
end
graph = Graph.new
graph.generate(3)
puts
graph.grid.each_with_index do |ring, ring_index|
ring.each_with_index do |sphere, index|
puts "Neighbours of #{sphere} are #{graph.neighbours(sphere.ring_index, sphere.index).join(", ")}."
end
end
puts
Et la sortie sur la console :
Neighbours of (0; 0) are (1; 0), (1; 1), (1; 2), (1; 3).
Neighbours of (1; 0) are (2; 0), (2; 1), (0; 0), (2; 7), (1; 3), (1; 1).
Neighbours of (1; 1) are (2; 1), (2; 3), (2; 2), (0; 0), (1; 0), (1; 2).
Neighbours of (1; 2) are (0; 0), (2; 3), (2; 4), (2; 5), (1; 1), (1; 3).
Neighbours of (1; 3) are (2; 7), (2; 5), (2; 6), (0; 0), (1; 2), (1; 0).
Neighbours of (2; 0) are (3; 0), (3; 1), (1; 0), (3; 11), (2; 7), (2; 1).
Neighbours of (2; 1) are (3; 2), (3; 1), (1; 0), (1; 1), (2; 0), (2; 2).
Neighbours of (2; 2) are (3; 2), (3; 4), (3; 3), (1; 1), (2; 1), (2; 3).
Neighbours of (2; 3) are (3; 4), (3; 5), (1; 2), (1; 1), (2; 2), (2; 4).
Neighbours of (2; 4) are (1; 2), (3; 5), (3; 6), (3; 7), (2; 3), (2; 5).
Neighbours of (2; 5) are (3; 8), (3; 7), (1; 2), (1; 3), (2; 4), (2; 6).
Neighbours of (2; 6) are (3; 10), (3; 8), (3; 9), (1; 3), (2; 5), (2; 7).
Neighbours of (2; 7) are (3; 10), (3; 11), (1; 0), (1; 3), (2; 6), (2; 0).
Neighbours of (3; 0) are (2; 0), (3; 11), (3; 1).
Neighbours of (3; 1) are (2; 0), (2; 1), (3; 0), (3; 2).
Neighbours of (3; 2) are (2; 1), (2; 2), (3; 1), (3; 3).
Neighbours of (3; 3) are (2; 2), (3; 2), (3; 4).
Neighbours of (3; 4) are (2; 3), (2; 2), (3; 3), (3; 5).
Neighbours of (3; 5) are (2; 4), (2; 3), (3; 4), (3; 6).
Neighbours of (3; 6) are (2; 4), (3; 5), (3; 7).
Neighbours of (3; 7) are (2; 4), (2; 5), (3; 6), (3; 8).
Neighbours of (3; 8) are (2; 5), (2; 6), (3; 7), (3; 9).
Neighbours of (3; 9) are (2; 6), (3; 8), (3; 10).
Neighbours of (3; 10) are (2; 7), (2; 6), (3; 9), (3; 11).
Neighbours of (3; 11) are (2; 0), (2; 7), (3; 10), (3; 0).
Sephi-Chan