23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
# File 'lib/swint/game.rb', line 23
def run
system "clear" if @config.visual
counter = 0
@result.start = Time.now
until @game_end
counter += 1
no_robot_left = true
@robots.to_a.shuffle.each do |robot|
k, r = robot
r.speed.times do |step|
if !@game_end
answer = :do_nothing
dt = measure { answer = r.next(@map) } if r.has_energy?
case answer
when :move_to
no_robot_left = false
if r.use_energy?
dir = nil
dt += measure { dir = r.move }
npos = r.pos.add(DIRV[dir])
nstate = @map.state_of_field(npos)
if nstate==:goal
@robots.each { |key, b| b.end_game( (b==r) ? 'winner' : 'looser' ) }
@result.winner = k
@game_end = true
end
if [:free, :energy, :start].include?(nstate)
f, p = @map.fields[npos], @map.fields[r.pos]
r.restore if f.state==:energy
p.robot = false
f.robot = true
r.pos = npos
end
end
when :push_object
no_robot_left = false
if r.use_energy?
dir = nil
dt += measure { dir = r.push }
opos = r.pos.add(DIRV[dir])
ppos = opos.add(DIRV[dir])
ostate = @map.state_of_field(opos)
pstate = @map.state_of_field(ppos)
if pstate==:free || pstate==:energy
if ostate==:object
if r.power >= @map.fields[opos].weight
@map.fields[ppos].weight = @map.fields[opos].weight
@map.fields[opos].weight = 0
end
end
if ostate==:robot
rob = @robots.values.select { |ro| ro.pos==opos }.first
if r.power >= rob.weight
rob.pos = ppos
rob.restore if pstate==:energy
@map.fields[opos].robot = false
@map.fields[ppos].robot = true
end
end
end
end
when :shout
no_robot_left = false
dt += measure { msg = r.shout }
@robots.each do |rid, rob|
next if rid==k
rob.listen(msg) if hex_distance(r.pos, rob.pos) <= r.voice * 10
end
end
@result.step(k, dt || 0)
visualize(counter, step) if @config.visual && @config.step
end
end
end
visualize(counter) if @config.visual && !@config.step
if no_robot_left
@robots.each { |k, b| b.end_game('looser') }
@game_end = true
end
end
@result.rounds = counter
@result.end = Time.now
@result
end
|