class Berlin::Fake::Game

Public Class Methods

new(options) click to toggle source
# File lib/ai/fake.rb, line 322
def initialize(options)
  @options = options
  number_of_ai    = options[:test_ais]
  @turn           = 0
  map_definition
  @game_info      = Berlin::Fake::GAME_INFO

  @game_state = @map_definition['nodes'].map do |node|
    {"node_id" => node['id'], "player_id" => nil, "number_of_soldiers" => 0}
  end

  @state = Berlin::Fake::State.new(@game_state.dup)

  @city_nodes = @map_definition['nodes'].select{ |node| node['type'] == 'city' }.map{ |node| node['id'] }

  start_points = @map_definition['setup'][(number_of_ai + 1).to_s]

  unless start_points
    puts("This map cannot be played with #{number_of_ai+1} players. #{@map_definition['setup'].keys.join(', ')} are possible only")
    exit
  end

  players = 1.upto(number_of_ai).map{ |n| "AI ##{n}" } << "Player"

  @ai_games = players.each.with_index.map do |name, index|
    start_points[index.to_s].each do |point|
      node = @state.state[point['node']]

      node['player_id'] = name
      node['number_of_soldiers'] = point['number_of_soldiers']
    end
    ai_info = @game_info.dup
    ai_info['player_id'] = name
    ai_info['game_id'] = index

    map = Berlin::AI::Map.parse(@map_definition.dup.merge('player_id' => ai_info['player_id']))
    game = Berlin::AI::Game.new
    game.map                      = map
    game.id                       = ai_info['game_id']
    game.player_id                = ai_info['player_id']
    game.time_limit_per_turn      = ai_info['time_limit_per_turn']
    game.maximum_number_of_turns  = ai_info['maximum_number_of_turns']
    game.number_of_players        = ai_info['number_of_players']
    game.reset!

    game
  end

  @player_game = @ai_games.pop
end

Public Instance Methods

buffer_moves() click to toggle source
# File lib/ai/fake.rb, line 420
def buffer_moves
  moves = {}
  [@player_game, *@ai_games].each do |game|
    player_moves = {}

    game.moves.each do |move|
      move[:player_id] = game.player_id
      ref = "#{move[:from]}_#{move[:to]}"
      player_moves[ref] ||= Berlin::Fake::Move.new(game.player_id, move[:from], move[:to], 0)
      player_moves[ref].number_of_soldiers += move[:number_of_soldiers]
    end
    moves[game.player_id] = player_moves.values
  end
  moves
end
generate_moves() click to toggle source
# File lib/ai/fake.rb, line 436
def generate_moves
  @ai_games.each do |game|
    game.reset!
    game.update(@turn, @state.as_json)
    Berlin::Fake::Random.on_turn(game)
  end

  @player_game.update(@turn, @state.as_json)
  @player_game.reset!
  Berlin::AI::Player.on_turn(@player_game)
end
map_definition() click to toggle source
# File lib/ai/fake.rb, line 373
def map_definition
  return @map_definition if @map_definition
  if @options[:map_id]
    uri = URI.parse("http://berlin-ai.com/maps/#{@options[:map_id]}.json")
    response = Net::HTTP.get_response(uri)
    begin
      @map_definition = JSON(response.body).fetch('map').fetch('representation')
    rescue => e
      puts "There was a problem downloading the map #{@options[:map_id]}"
      puts e.message
      exit
    end
  else
    @map_definition = Berlin::Fake::MAP_DEFINITION
  end
end
pause() click to toggle source
# File lib/ai/fake.rb, line 401
def pause
  puts "Press any key to continue"
  gets
end
run() click to toggle source
# File lib/ai/fake.rb, line 390
def run
  puts Berlin::Fake::Display.new(@map_definition, @state).as_display
  pause
  while !@state.winner? && @turn < Berlin::Fake::GAME_INFO['maximum_number_of_turns']
    turn
    pause
    puts Berlin::Fake::Display.new(@map_definition, @state).as_display
    pause
  end
end
spawn() click to toggle source
# File lib/ai/fake.rb, line 416
def spawn
  @state.spawn(@city_nodes)
end
turn() click to toggle source
# File lib/ai/fake.rb, line 406
def turn
  @turn += 1
  generate_moves
  player_moves = buffer_moves

  @state.apply_moves(player_moves.values.flatten)

  spawn
end