berlin-ai 0.0.38 → 0.0.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- MjhmMTFhMzAxZTcyYWY5NTQ0NjUwODE0ZGRlYmU5YzJhMTdjNzhiMQ==
5
- data.tar.gz: !binary |-
6
- NTM4MTYxM2FlOTM2YTNlMDljNTlkYTk3MmNkOGQ1Zjg1ZGExOGNlZA==
2
+ SHA1:
3
+ metadata.gz: 22c28ef7a0470b58c71d71b9947975d10c34556e
4
+ data.tar.gz: ab75d7229925952f3cc9fcf18770af8108b72478
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- OTAxMTc4YjdjYjA3YzdmOGEzOTQ2MzU3MGYyM2QxMmY4ZTY0YTIxYTVhMGQ1
10
- NDdhY2I5ZWY0MDZlMTQ3NzE3MzM3ZWY1Y2FmNDhlM2E4MjFhZTNiMTJjN2My
11
- ZjAxYmU5NWM0ZWVmOTg3OTQyN2IyMmQ0NTQ5NmFhNDFiZmY1ZTU=
12
- data.tar.gz: !binary |-
13
- MTNmYjljODRkODA5OTdkOGI1NTFlNTE0NjAwZjhhMDc5YzhkMzNiMWI1NGY0
14
- MjZmZmRhZmE2MThkZWRkNzg1N2FmYzEyYTI3OWNiMDIzZDk0MmE3NTIwNThj
15
- MGQyYzBlYjFhZjExZjNjYjQ5ZTFlNGFmYmFmYTY3MWU5NDNlMjM=
6
+ metadata.gz: 329a5d53d06b5bfb5b3e5af766c8650161826321dc3be37d63f6c5bc8ed5511ae7a640024deb386112af6136a62ddba1dc2ea335267a6b895e06d5b5ffa1a39d
7
+ data.tar.gz: 19b00836e5aadc401afe1b1f2b4aae3bace1493522776bf70cb791bc2ca56919881cca51b08bc5187778fc55033c6a06362baae304394c3853a45d467ca818cc
File without changes
data/README.md CHANGED
@@ -4,7 +4,7 @@ Berlin-Ai is a gem to quickly ramp up on the [Berlin](http://www.berlin-ai.com)
4
4
 
5
5
  ## Changelog
6
6
 
7
- [See changelog for recent changes](https://github.com/thirdside/berlin-ai/blob/master/LICENSE)
7
+ [See changelog for recent changes](https://github.com/thirdside/berlin-ai/blob/master/CHANGELOG.md)
8
8
 
9
9
  ## Usage
10
10
 
@@ -90,9 +90,10 @@ node.available_soldiers # Owned remaining soldiers on this node (result fr
90
90
  node.==(other) # Check if two nodes are the same.
91
91
  node.adjacent?(other_node) # Check if two nodes are adjacents.
92
92
  node.occupied? # Check if some soldiers are on the node.
93
- node.owned? # Check if a player (not only you) owns the node.
94
- node.mine? # Check if you own the node.
93
+ node.enemy? # Check if another player (not you) owns the node.
94
+ node.mine? (node.owned?) # Check if you own the node.
95
95
  node.free? # Check if no one own the node.
96
+ node.foreign? # Check if you don't own the node. Might belongs to an enemy or be free.
96
97
  node.owned_by?(player_id) # Check if the node is owned by a given player.
97
98
  node.adjacent_nodes # Get a list of adjacent nodes.
98
99
  node.adjacent_nodes_and_self # Get a list of adjacent nodes, including this node.
@@ -15,11 +15,13 @@ Gem::Specification.new do |s|
15
15
  s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
16
  s.summary = "Berlin Artificial Intelligence"
17
17
  s.description = "Berlin Artificial Intelligence"
18
+ s.license = "copyleft"
18
19
 
19
20
  s.add_dependency 'sinatra', '1.4.3'
20
21
  s.add_dependency 'yajl-ruby', '1.1.0'
21
22
  s.add_dependency 'sinatra-contrib', '1.4.1'
22
23
  s.add_dependency 'rainbow', '~>1.1.4'
24
+ s.add_dependency 'ruby-terminfo'
23
25
  s.add_dependency 'thin', '1.5.1'
24
26
 
25
27
  s.add_development_dependency 'minitest'
@@ -1,39 +1,100 @@
1
+ require "net/http"
2
+ require "uri"
1
3
  require 'rainbow'
4
+ require 'terminfo'
2
5
 
3
6
  module Berlin
4
7
  module Fake
5
8
 
6
- MAP_DEFINITION = {
7
- "directed" => false,
9
+ CITY_WALL = "\u2588"
10
+ NODE_WALL = "#"
11
+ PATH = "."
8
12
 
13
+ MAP_DEFINITION = {
9
14
  "types" => [
10
- {"name" => "node", "points" => 0, "soldiers_per_turn" => 0},
11
- {"name" => "city", "points" => 1, "soldiers_per_turn" => 1}
15
+ {"name" => "city","soldiers_per_turn" => 1,"points" => 1},
16
+ {"name" => "node","soldiers_per_turn" => 0,"points" => 0}
12
17
  ],
13
-
14
18
  "nodes" => [
15
- {"id" => 1, "type" => "city"},
16
- {"id" => 2, "type" => "node"},
17
- {"id" => 3, "type" => "city"},
18
- {"id" => 4, "type" => "node"},
19
- {"id" => 5, "type" => "node"},
20
- {"id" => 6, "type" => "city"},
21
- {"id" => 7, "type" => "node"},
22
- {"id" => 8, "type" => "city"}
19
+ {"id" => 1, "type" => "city", "x" => 10, "y" => 10},
20
+ {"id" => 2, "type" => "city", "x" => 30, "y" => 10},
21
+ {"id" => 3, "type" => "city", "x" => 10, "y" => 30},
22
+ {"id" => 4, "type" => "city", "x" => 30, "y" => 30},
23
+ {"id" => 5, "type" => "city", "x" => 90, "y" => 10},
24
+ {"id" => 6, "type" => "city", "x" => 70, "y" => 10},
25
+ {"id" => 7, "type" => "city", "x" => 90, "y" => 30},
26
+ {"id" => 8, "type" => "city", "x" => 70, "y" => 30},
27
+ {"id" => 9, "type" => "city", "x" => 10, "y" => 90},
28
+ {"id" => 10, "type" => "city", "x" => 10, "y" => 70},
29
+ {"id" => 11, "type" => "city", "x" => 30, "y" => 90},
30
+ {"id" => 12, "type" => "city", "x" => 30, "y" => 70},
31
+ {"id" => 13, "type" => "city", "x" => 90, "y" => 90},
32
+ {"id" => 14, "type" => "city", "x" => 70, "y" => 90},
33
+ {"id" => 15, "type" => "city", "x" => 90, "y" => 70},
34
+ {"id" => 16, "type" => "city", "x" => 70, "y" => 70},
35
+ {"id" => 17, "type" => "node", "x" => 25, "y" => 50},
36
+ {"id" => 18, "type" => "node", "x" => 75, "y" => 50},
37
+ {"id" => 19, "type" => "node", "x" => 40, "y" => 50},
38
+ {"id" => 20, "type" => "node", "x" => 60, "y" => 50},
39
+ {"id" => 21, "type" => "node", "x" => 50, "y" => 25},
40
+ {"id" => 22, "type" => "node", "x" => 50, "y" => 75},
41
+ {"id" => 23, "type" => "node", "x" => 50, "y" => 40},
42
+ {"id" => 24, "type" => "node", "x" => 50, "y" => 60}
23
43
  ],
24
-
25
- "paths" => [
44
+ "paths"=> [
26
45
  {"from" => 1, "to" => 2},
46
+ {"from" => 1, "to" => 3},
27
47
  {"from" => 2, "to" => 3},
28
- {"from" => 2, "to" => 5},
29
- {"from" => 3, "to" => 5},
30
- {"from" => 5, "to" => 8},
31
- {"from" => 8, "to" => 7},
32
- {"from" => 7, "to" => 4},
48
+ {"from" => 2, "to" => 4},
49
+ {"from" => 3, "to" => 4},
50
+ {"from" => 5, "to" => 6},
51
+ {"from" => 5, "to" => 7},
33
52
  {"from" => 6, "to" => 7},
34
- {"from" => 6, "to" => 4},
35
- {"from" => 4, "to" => 1},
36
- ]
53
+ {"from" => 6, "to" => 8},
54
+ {"from" => 7, "to" => 8},
55
+ {"from" => 9, "to" => 10},
56
+ {"from" => 9, "to" => 11},
57
+ {"from" => 10, "to" => 11},
58
+ {"from" => 10, "to" => 12},
59
+ {"from" => 11, "to" => 12},
60
+ {"from" => 13, "to" => 14},
61
+ {"from" => 13, "to" => 15},
62
+ {"from" => 14, "to" => 15},
63
+ {"from" => 14, "to" => 16},
64
+ {"from" => 15, "to" => 16},
65
+ {"from" => 4, "to" => 19},
66
+ {"from" => 4, "to" => 23},
67
+ {"from" => 8, "to" => 20},
68
+ {"from" => 8, "to" => 23},
69
+ {"from" => 12, "to" => 19},
70
+ {"from" => 12, "to" => 24},
71
+ {"from" => 16, "to" => 24},
72
+ {"from" => 16, "to" => 20},
73
+ {"from" => 17, "to" => 19},
74
+ {"from" => 18, "to" => 20},
75
+ {"from" => 21, "to" => 23},
76
+ {"from" => 22, "to" => 24},
77
+ {"from" => 3, "to" => 17},
78
+ {"from" => 10, "to" => 17},
79
+ {"from" => 7, "to" => 18},
80
+ {"from" => 15, "to" => 18},
81
+ {"from" => 6, "to" => 21},
82
+ {"from" => 2, "to" => 21},
83
+ {"from" => 11, "to" => 22},
84
+ {"from" => 14, "to" => 22}
85
+ ],
86
+ "setup" => {
87
+ "2" => {
88
+ "0" => [{"node" => 1,"number_of_soldiers" => 5}],
89
+ "1" => [{"node" => 13,"number_of_soldiers" => 5}]
90
+ },
91
+ "4" => {
92
+ "0" => [{"node" => 1,"number_of_soldiers" => 5}],
93
+ "1" => [{"node" => 5, "number_of_soldiers" => 5}],
94
+ "2" => [{"node" => 9, "number_of_soldiers" => 5}],
95
+ "3" => [{"node" => 13, "number_of_soldiers" => 5}]
96
+ }
97
+ }
37
98
  }
38
99
 
39
100
  GAME_INFO = {
@@ -46,16 +107,6 @@ module Berlin
46
107
  "player_id" => nil
47
108
  }
48
109
 
49
- GAME_STATE = [
50
- {"node_id" => 1, "player_id" => nil, "number_of_soldiers" => 0},
51
- {"node_id" => 2, "player_id" => nil, "number_of_soldiers" => 0},
52
- {"node_id" => 3, "player_id" => nil, "number_of_soldiers" => 0},
53
- {"node_id" => 4, "player_id" => nil, "number_of_soldiers" => 0},
54
- {"node_id" => 5, "player_id" => nil, "number_of_soldiers" => 0},
55
- {"node_id" => 6, "player_id" => nil, "number_of_soldiers" => 0},
56
- {"node_id" => 7, "player_id" => nil, "number_of_soldiers" => 0},
57
- {"node_id" => 8, "player_id" => nil, "number_of_soldiers" => 0}
58
- ]
59
110
 
60
111
  Move = Struct.new(:player_id, :from, :to, :number_of_soldiers)
61
112
 
@@ -106,23 +157,18 @@ module Berlin
106
157
 
107
158
  class Display
108
159
 
109
- attr_accessor *(1..8).map{ |n| "n#{n}"}
110
-
111
160
  COLORS = [:red, :green, :yellow, :blue]
112
161
 
113
- Node = Struct.new(:id, :ns)
114
-
115
- def initialize(state)
116
- js = state.as_json
117
- @player_ids = js.map{ |n| n['player_id'] }.uniq.compact.sort
162
+ Position = Struct.new(:x, :y)
118
163
 
119
- js.each do |node|
120
- id = node['node_id'].to_s.rjust(2)
121
- ns = node['number_of_soldiers'].to_s.rjust(2).foreground(color(node['player_id']))
164
+ def initialize(map_definition, state)
165
+ @map_definition = map_definition
166
+ @state = state.state
167
+ @player_ids = @state.map{ |id, n| n['player_id'] }.uniq.compact.sort
122
168
 
123
- display_node = Display::Node.new(id, ns)
124
- self.send("n#{node['node_id']}=", display_node)
125
- end
169
+ @height, @width = TermInfo.screen_size
170
+ @height -= @player_ids.length + 1
171
+ @map = 1.upto(@height).map { [" "] * @width }
126
172
  end
127
173
 
128
174
  def color(player_id)
@@ -130,34 +176,90 @@ module Berlin
130
176
  end
131
177
 
132
178
  def as_display
133
- ## The map is fully dynamic
134
- map = <<-MAP
135
- ____ ____ ____
136
- / \\ / \\ / \\
137
- | #{n1.id} |---------| #{n2.id} |---------| #{n3.id} |
138
- | #{n1.ns} | | #{n2.ns} | | #{n3.ns} |
139
- \\____/ \\____/ \\____/
140
- | \\ |
141
- | \\ |
142
- _+__ \\ _+__
143
- / \\ \\ / \\
144
- | #{n4.id} |-----\\ \\------| #{n5.id} |
145
- | #{n4.ns} | \\ | #{n5.ns} |
146
- \\____/ \\ \\____/
147
- | \\ |
148
- | \\ |
149
- _+__ \\___ _+__
150
- / \\ / \\ / \\
151
- | #{n6.id} |---------| #{n7.id} |---------| #{n8.id} |
152
- | #{n6.ns} | | #{n7.ns} | | #{n8.ns} |
153
- \\____/ \\____/ \\____/
154
- MAP
155
-
179
+ paths_as_display
180
+ nodes_as_display
181
+ map = @map.map(&:join).join("\n")
156
182
  [map, *@player_ids.map{ |id| id.to_s.foreground(color(id)) }].join("\n")
157
183
  end
184
+
185
+ def paths_as_display
186
+ @map_definition['paths'].each do |path|
187
+ from_node = @map_definition['nodes'][path['from']-1]
188
+ to_node = @map_definition['nodes'][path['to']-1]
189
+
190
+ from = node_position(from_node)
191
+ to = node_position(to_node)
192
+
193
+ draw_line(from, to)
194
+ end
195
+ end
196
+
197
+ def draw_line(from, to)
198
+ xs = range(from[0], to[0])
199
+ ys = range(from[1], to[1])
200
+
201
+ length = [xs.length, ys.length].max
202
+
203
+ (0...length).each do |n|
204
+ x = xs[(n.to_f/length * xs.length).floor]
205
+ y = ys[(n.to_f/length * ys.length).floor]
206
+
207
+ replace(x, y, PATH)
208
+ end
209
+ end
210
+
211
+ def range(from, to)
212
+ from > to ? (to..from).to_a.reverse : (from..to).to_a
213
+ end
214
+
215
+ def node_position(node)
216
+ x = (node['x'] / 100.0 * @width).to_i
217
+ y = (node['y'] / 100.0 * @height).to_i
218
+ [x, y]
219
+ end
220
+
221
+ def nodes_as_display
222
+ # ID###
223
+ # # 12#
224
+ # V###S
225
+ @map_definition['nodes'].each do |node|
226
+ node_state = @state[node['id']]
227
+
228
+ x, y = node_position(node)
229
+
230
+ player_color = color(node_state.player_id)
231
+
232
+ meta = @map_definition['types'].detect{|n| n['name'] == node['type']}
233
+ value = meta['soldiers_per_turn'] + meta['points']
234
+
235
+ wall = value > 0 ? CITY_WALL : NODE_WALL
236
+ (-1..1).each do |n|
237
+ replace(x-2, y+n, wall*5, player_color)
238
+ end
239
+
240
+ replace(x-2, y-1, node['id'])
241
+ number_of_soldiers = node_state.number_of_soldiers.to_s.center(3)
242
+ replace(x-1, y, number_of_soldiers, player_color)
243
+
244
+ if value > 0
245
+ soldiers_per_turn = meta['soldiers_per_turn'].to_s
246
+ replace(x-2, y+1, meta['points'])
247
+ replace(x+2, y+2 - soldiers_per_turn.length, soldiers_per_turn)
248
+ end
249
+ end
250
+ end
251
+
252
+ def replace(x, y, str, foreground = nil)
253
+ length = str.to_s.size
254
+ (0...length).each do |n|
255
+ char = str.to_s[n]
256
+ @map[y][x+n] = foreground ? char.foreground(foreground) : char
257
+ end
258
+ end
158
259
  end
159
260
 
160
261
  class State
262
+ attr_accessor :state
161
263
  def initialize(from_json)
162
264
  @state = from_json.inject({}) do |h, node|
163
265
  h[node['node_id']] = NodeState.new(node['node_id'], node['player_id'], node['number_of_soldiers'])
@@ -181,9 +283,9 @@ module Berlin
181
283
  def remove_soldiers(move)
182
284
  origin = @state[move.from]
183
285
  if origin.player_id != move.player_id
184
- errors << "Trying to move #{move.number_of_soldiers} soldiers from ##{move.from}. Node ##{move.from} belongs to #{origin.player_id}"
286
+ puts "Trying to move #{move.number_of_soldiers} soldiers from ##{move.from}. Node ##{move.from} belongs to #{origin.player_id}"
185
287
  elsif origin.number_of_soldiers < move.number_of_soldiers
186
- errors << "Trying to move #{move.number_of_soldiers} soldiers from ##{move.from}. Only #{origin.number_of_soldiers} soldiers available"
288
+ puts "Trying to move #{move.number_of_soldiers} soldiers from ##{move.from}. Only #{origin.number_of_soldiers} soldiers available"
187
289
  else
188
290
  origin.number_of_soldiers -= move.number_of_soldiers
189
291
  puts "\t[#{move.player_id}] Moves #{move.number_of_soldiers} soldiers from ##{move.from} to ##{move.to}"
@@ -217,55 +319,81 @@ end
217
319
 
218
320
  class Berlin::Fake::Game
219
321
 
220
- def initialize(number_of_ai)
221
- @turn = 0
222
-
223
- @city_nodes = Berlin::Fake::MAP_DEFINITION['nodes'].select{ |node| node['type'] == 'city' }.map{ |node| node['id'] }
224
- @ai_games = 1.upto(number_of_ai).map do |n|
225
- ai_name = "AI ##{n}"
226
- node = Berlin::Fake::GAME_STATE.detect{ |node| node['node_id'] == @city_nodes[n - 1] }
227
- node['player_id'] = ai_name
228
- node['number_of_soldiers'] = 5
229
- ai_info = Berlin::Fake::GAME_INFO.dup
230
- ai_info['player_id'] = ai_name
231
- ai_info['game_id'] = n
232
-
233
- ai_game = Berlin::AI::Game.new
234
- ai_game.id = ai_info['game_id']
235
- ai_game.map = Berlin::AI::Map.parse(Berlin::Fake::MAP_DEFINITION.merge('player_id' => ai_info['player_id']))
236
- ai_game.player_id = ai_info['player_id']
237
- ai_game.time_limit_per_turn = ai_info['time_limit_per_turn']
238
- ai_game.maximum_number_of_turns = ai_info['maximum_number_of_turns']
239
- ai_game.number_of_players = ai_info['number_of_players']
240
- ai_game
322
+ def initialize(options)
323
+ @options = options
324
+ number_of_ai = options[:test_ais]
325
+ @turn = 0
326
+ map_definition
327
+ @game_info = Berlin::Fake::GAME_INFO
328
+
329
+ @game_state = @map_definition['nodes'].map do |node|
330
+ {"node_id" => node['id'], "player_id" => nil, "number_of_soldiers" => 0}
241
331
  end
242
332
 
243
- player_name = "Player"
244
- player_info = Berlin::Fake::GAME_INFO.dup
245
- player_info['player_id'] = player_name
246
- player_info['game_id'] = 0
247
- node = Berlin::Fake::GAME_STATE.detect{ |node| node['node_id'] == @city_nodes[number_of_ai] }
248
- node['player_id'] = player_name
249
- node['number_of_soldiers'] = 5
250
-
251
- @player_game = Berlin::AI::Game.new
252
- @player_game.id = player_info['game_id']
253
- @player_game.map = Berlin::AI::Map.parse(Berlin::Fake::MAP_DEFINITION.merge('player_id' => player_info['player_id']))
254
- @player_game.player_id = player_info['player_id']
255
- @player_game.time_limit_per_turn = player_info['time_limit_per_turn']
256
- @player_game.maximum_number_of_turns = player_info['maximum_number_of_turns']
257
- @player_game.number_of_players = player_info['number_of_players']
258
-
259
- @state = Berlin::Fake::State.new(Berlin::Fake::GAME_STATE.dup)
333
+ @state = Berlin::Fake::State.new(@game_state.dup)
334
+
335
+ @city_nodes = @map_definition['nodes'].select{ |node| node['type'] == 'city' }.map{ |node| node['id'] }
336
+
337
+ start_points = @map_definition['setup'][(number_of_ai + 1).to_s]
338
+
339
+ unless start_points
340
+ puts("This map cannot be played with #{number_of_ai+1} players. #{@map_definition['setup'].keys.join(', ')} are possible only")
341
+ exit
342
+ end
343
+
344
+ players = 1.upto(number_of_ai).map{ |n| "AI ##{n}" } << "Player"
345
+
346
+ @ai_games = players.each.with_index.map do |name, index|
347
+ start_points[index.to_s].each do |point|
348
+ node = @state.state[point['node']]
349
+
350
+ node['player_id'] = name
351
+ node['number_of_soldiers'] = point['number_of_soldiers']
352
+ end
353
+ ai_info = @game_info.dup
354
+ ai_info['player_id'] = name
355
+ ai_info['game_id'] = index
356
+
357
+ map = Berlin::AI::Map.parse(@map_definition.dup.merge('player_id' => ai_info['player_id']))
358
+ game = Berlin::AI::Game.new
359
+ game.map = map
360
+ game.id = ai_info['game_id']
361
+ game.player_id = ai_info['player_id']
362
+ game.time_limit_per_turn = ai_info['time_limit_per_turn']
363
+ game.maximum_number_of_turns = ai_info['maximum_number_of_turns']
364
+ game.number_of_players = ai_info['number_of_players']
365
+ game.reset!
366
+
367
+ game
368
+ end
369
+
370
+ @player_game = @ai_games.pop
371
+ end
372
+
373
+ def map_definition
374
+ return @map_definition if @map_definition
375
+ if @options[:map_id]
376
+ uri = URI.parse("http://berlin-ai.com/maps/#{@options[:map_id]}.json")
377
+ response = Net::HTTP.get_response(uri)
378
+ begin
379
+ @map_definition = JSON(response.body).fetch('map').fetch('representation')
380
+ rescue => e
381
+ puts "There was a problem downloading the map #{@options[:map_id]}"
382
+ puts e.message
383
+ exit
384
+ end
385
+ else
386
+ @map_definition = Berlin::Fake::MAP_DEFINITION
387
+ end
260
388
  end
261
389
 
262
390
  def run
263
- puts Berlin::Fake::Display.new(@state).as_display
391
+ puts Berlin::Fake::Display.new(@map_definition, @state).as_display
264
392
  pause
265
393
  while !@state.winner? && @turn < Berlin::Fake::GAME_INFO['maximum_number_of_turns']
266
394
  turn
267
395
  pause
268
- puts Berlin::Fake::Display.new(@state).as_display
396
+ puts Berlin::Fake::Display.new(@map_definition, @state).as_display
269
397
  pause
270
398
  end
271
399
  end
@@ -17,7 +17,7 @@ set :verbose, true
17
17
  set :logger, Logger.new(STDOUT)
18
18
 
19
19
  # set tests to false
20
- $test_ais = false
20
+ options = {}
21
21
 
22
22
  # Parse options
23
23
  OptionParser.new do |opts|
@@ -42,12 +42,16 @@ OptionParser.new do |opts|
42
42
  set :logger, Logger.new(l || 'berlin.log')
43
43
  end
44
44
 
45
+ opts.on("-m MAP_ID", "--map MAP_ID", "Which map to use from Berlin. Use in conjunction with TEST") do |m|
46
+ options[:map_id] = m
47
+ end
48
+
45
49
  opts.on("-t N", "--test N", Integer, "Test against N random AI") do |t|
46
50
  if t < 0 || t > 3
47
51
  puts "This map supports a maximum of 3 AI"
48
52
  exit 1
49
53
  end
50
- $test_ais = t
54
+ options[:test_ais] = t
51
55
  end
52
56
 
53
57
  opts.on("-v", "--verbose", "Print information to STDOUT") do
@@ -101,8 +105,8 @@ def log level, message
101
105
  settings.logger.send(level, message) if settings.logger
102
106
  end
103
107
 
104
- if $test_ais
105
- at_exit { Berlin::Fake::Game.new($test_ais).run }
108
+ if options[:test_ais]
109
+ at_exit { Berlin::Fake::Game.new(options).run }
106
110
  else
107
111
  set :app_file, $0
108
112
  end
@@ -2,7 +2,7 @@ module Berlin
2
2
  module AI
3
3
  MAJOR = 0
4
4
  MINOR = 0
5
- BUILD = 38
5
+ BUILD = 39
6
6
 
7
7
  VERSION = "#{MAJOR}.#{MINOR}.#{BUILD}"
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: berlin-ai
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.38
4
+ version: 0.0.39
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Blais
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-10-04 00:00:00.000000000 Z
13
+ date: 2014-01-02 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: sinatra
@@ -68,6 +68,20 @@ dependencies:
68
68
  - - ~>
69
69
  - !ruby/object:Gem::Version
70
70
  version: 1.1.4
71
+ - !ruby/object:Gem::Dependency
72
+ name: ruby-terminfo
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ type: :runtime
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - '>='
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
71
85
  - !ruby/object:Gem::Dependency
72
86
  name: thin
73
87
  requirement: !ruby/object:Gem::Requirement
@@ -86,28 +100,28 @@ dependencies:
86
100
  name: minitest
87
101
  requirement: !ruby/object:Gem::Requirement
88
102
  requirements:
89
- - - ! '>='
103
+ - - '>='
90
104
  - !ruby/object:Gem::Version
91
105
  version: '0'
92
106
  type: :development
93
107
  prerelease: false
94
108
  version_requirements: !ruby/object:Gem::Requirement
95
109
  requirements:
96
- - - ! '>='
110
+ - - '>='
97
111
  - !ruby/object:Gem::Version
98
112
  version: '0'
99
113
  - !ruby/object:Gem::Dependency
100
114
  name: pry
101
115
  requirement: !ruby/object:Gem::Requirement
102
116
  requirements:
103
- - - ! '>='
117
+ - - '>='
104
118
  - !ruby/object:Gem::Version
105
119
  version: '0'
106
120
  type: :development
107
121
  prerelease: false
108
122
  version_requirements: !ruby/object:Gem::Requirement
109
123
  requirements:
110
- - - ! '>='
124
+ - - '>='
111
125
  - !ruby/object:Gem::Version
112
126
  version: '0'
113
127
  description: Berlin Artificial Intelligence
@@ -120,7 +134,7 @@ executables:
120
134
  extensions: []
121
135
  extra_rdoc_files: []
122
136
  files:
123
- - CHANGELOG
137
+ - CHANGELOG.md
124
138
  - Gemfile
125
139
  - Gemfile.lock
126
140
  - LICENSE
@@ -144,7 +158,8 @@ files:
144
158
  - test/node_test.rb
145
159
  - test/test_ai.rb
146
160
  homepage: http://github.com/thirdside/berlin-ai
147
- licenses: []
161
+ licenses:
162
+ - copyleft
148
163
  metadata: {}
149
164
  post_install_message:
150
165
  rdoc_options: []
@@ -153,17 +168,17 @@ require_paths:
153
168
  - test
154
169
  required_ruby_version: !ruby/object:Gem::Requirement
155
170
  requirements:
156
- - - ! '>='
171
+ - - '>='
157
172
  - !ruby/object:Gem::Version
158
173
  version: '0'
159
174
  required_rubygems_version: !ruby/object:Gem::Requirement
160
175
  requirements:
161
- - - ! '>='
176
+ - - '>='
162
177
  - !ruby/object:Gem::Version
163
178
  version: '0'
164
179
  requirements: []
165
180
  rubyforge_project:
166
- rubygems_version: 2.1.5
181
+ rubygems_version: 2.0.14
167
182
  signing_key:
168
183
  specification_version: 4
169
184
  summary: Berlin Artificial Intelligence