berlin-ai 0.0.38 → 0.0.39

Sign up to get free protection for your applications and to get access to all the features.
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