-
Notifications
You must be signed in to change notification settings - Fork 0
/
world-map.rb
147 lines (126 loc) · 4.31 KB
/
world-map.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# -*- coding: utf-8 -*-
require_relative 'region.rb'
require_relative 'super-region.rb'
require_relative 'server-settings.rb'
class WorldMap
attr_accessor :super_regions, :my_super_regions, :regions, :my_regions
def initialize(round, settings)
@super_regions = []
@regions = []
@my_regions = []
@my_super_regions = []
@visible_regions = []
@settings = settings
@round = round
end
def owned_by_symbol(player_name)
case player_name
when @settings[:your_bot] then :me
when @settings[:opponent_bot][0] then :enemy
when 'neutral' then :neutral
else raise(format('unsupported players: %s', player_name))
end
end
def update_map(raw_line)
@round.update_map()
@visible_regions = []
while raw_line.length >= 3
action = raw_line.shift(3)
region_id, player_name, forces = action[0].to_i, action[1], action[2].to_i
region = @regions[region_id - 1]
now_owned_by = owned_by_symbol(player_name)
region.forces = forces
if region.owned_by == :me
lost_region(region) if now_owned_by != :me
else
claim_region(region) if now_owned_by == :me
end
@visible_regions << region
end
(@my_regions - @visible_regions).each{|region| lost_region(region)}
end
def path_between_regions(start_region_id, end_region_id)
@regions[start_region_id - 1].path_to{|region| end_region_id == region.id}
end
def map_to_string()
" == Regions == \n" +
@regions.map do |region|
region.id.to_s + (region.owned_by == :me ? "y" : "o") +
region.forces.to_s +
" -> (" + region.neighbours.map{|neighbour| neighbour.id}.join(", ") + ")"
end.join("\n") + "\n" +
" == My Regions == \n" +
@my_regions.map do |region|
region.id.to_s + (region.owned_by == :me ? "y" : "o") +
region.forces.to_s +
" -> (" + region.neighbours.map{|neighbour| neighbour.id}.join(", ") + ")"
end.join("\n")
end
def setup_line(raw_line)
raise 'raw_line is not split on space' unless raw_line.kind_of?(Array)
command = raw_line.shift
case command
when 'super_regions' then
raw_line.each_index do |index|
if index.even?
@super_regions << SuperRegion.new(raw_line[index].to_i,
raw_line[index + 1].to_i)
end
end
when 'regions' then
raw_line.each_index do |index|
if index.even?
region = Region.new(raw_line[index].to_i,
@super_regions[raw_line[index + 1].to_i - 1])
@regions << region
region.super_region.push_region(region)
end
end
@regions.each{|r| r.owned_by = :neutral}
when 'neighbors' then
raw_line.each_index do |index|
if index.even?
region_id, neighbours = raw_line[index].to_i, raw_line[index + 1]
neighbours = neighbours.split(',').map do |neighbour|
c = @regions[neighbour.to_i - 1]
c.append_neighbours(@regions[region_id - 1])
c
end
@regions[region_id - 1].append_neighbours(neighbours)
end
end
@super_regions.each{|sr| sr.calculate_neighbour_regions()}
when 'wastelands' then
raw_line.each_index do |index|
@regions[raw_line[index].to_i - 1].owned_by = :neutral
end
when 'opponent_starting_regions' then
raw_line.each_index do |index|
@regions[raw_line[index].to_i - 1].owned_by = :enemy
end
else
raise format('Unknown map command %s, see documentation.', command)
end
end
private
def claim_region(region)
region = @regions[region - 1] unless region.kind_of?(Region)
region.owned_by = :me
@my_regions << region
# Check if we also claimed the super_region
unless region.super_region.regions.any?{|r| r.owned_by != :me}
@my_super_regions.push(region.super_region)
@round.super_region_changes[:gained].push(region.super_region)
end
end
def lost_region(region)
region = @regions[region_id - 1] unless region.kind_of?(Region)
region.owned_by = :enemy
@my_regions.delete(region)
# Check if we also lost a super-region
if @my_super_regions.include?(region.super_region)
@my_super_regions.delete(region.super_region)
@round.super_region_changes[:lost].push(region.super_region)
end
end
end