Skip to content

Commit

Permalink
add 41_aleph4 from 40_aleph3
Browse files Browse the repository at this point in the history
  • Loading branch information
TheDuck314 committed Dec 12, 2018
1 parent 933b5b7 commit 23e4004
Show file tree
Hide file tree
Showing 49 changed files with 631,029 additions and 47 deletions.
4 changes: 2 additions & 2 deletions analyzer/spawn_stats.py
Expand Up @@ -76,8 +76,8 @@ def main():
# print(game_fn)
stats = analyze_one_game(game_fn)
ratio = (stats.final_profit - stats.profit_at_last_spawn_turn - stats.carried_at_last_spawn_turn) / stats.ships_at_last_spawn_turn
# if stats.map_size == 64 and stats.num_players == 4:
if stats.num_players == 4:
if stats.map_size == 64 and stats.num_players == 4:
# if stats.num_players == 4:
print("{} ratio = {:.1f} {}".format(bn, ratio, stats))

if __name__ == "__main__":
Expand Down
1 change: 1 addition & 0 deletions bots/40_aleph3/MyBot.cpp
Expand Up @@ -871,6 +871,7 @@ struct Bot {
// TODO: optimal value probably depends on map size
// TODO: optimal value probably depends on phase of game??
// does it depend on how far away the target is??
// I found 2.5 was slightly better for 4p but reverted it after poor live performance
const double move_on_mult = Game::num_players == 2 ? MINE_MOVE_ON_MULT.get(3.0)
: MINE_MOVE_ON_MULT.get(3.0);
bool should_move = tgt_eff_halite > move_on_mult * here_eff_halite; // TUNE
Expand Down
32 changes: 32 additions & 0 deletions bots/41_aleph4/CMakeLists.txt
@@ -0,0 +1,32 @@
cmake_minimum_required(VERSION 2.8)

project(MyBot)

find_package(Torch REQUIRED)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O2 -Wall -Wno-unused-function -pedantic")
set(CMAKE_EXE_LINKER_FLAGS "-Wl,-rpath=./libtorch/lib")

include_directories(${CMAKE_SOURCE_DIR}/hlt)

get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)

foreach(dir ${dirs})
file(GLOB_RECURSE SOURCE ${dir}/*.[ch]*)
set(SOURCE_FILES "${SOURCE_FILES}" ${SOURCE})
endforeach()

include_directories(${CMAKE_SOURCE_DIR})
set(SOURCE_FILES "${SOURCE_FILES}" MyBot.cpp)

add_executable(MyBot ${SOURCE_FILES})

target_link_libraries(MyBot "${TORCH_LIBRARIES}")

if(MINGW)
target_link_libraries(MyBot -static)
endif()
1,564 changes: 1,564 additions & 0 deletions bots/41_aleph4/MyBot.cpp

Large diffs are not rendered by default.

60 changes: 60 additions & 0 deletions bots/41_aleph4/hlt/Command.cc
@@ -0,0 +1,60 @@
#include "Command.h"

#include "Log.h"

Command Command::generate()
{
Command ret;
ret.type = Type::Generate;
return ret;
}

Command Command::move(int _ship_id, Direction _move_dir)
{
Command ret;
ret.type = Type::Move;
ret.ship_id = _ship_id;
ret.move_dir = _move_dir;
return ret;
}

Command Command::move(const Ship &ship, Direction _move_dir)
{
return move(ship.id, _move_dir);
}

Command Command::construct(int _ship_id)
{
Command ret;
ret.type = Type::Construct;
ret.ship_id = _ship_id;
return ret;
}

static char encode_dir(Direction d)
{
switch (d) {
case Direction::North: return 'n';
case Direction::South: return 's';
case Direction::East: return 'e';
case Direction::West: return 'w';
case Direction::Still: return 'o';
default:
Log::die("encode_dir unrecognized Direction %d", (int)d);
return 'x';
}
}

string Command::encode() const
{
if (type == Type::Generate) {
return "g";
} else if (type == Type::Move) {
return stringf("m %d %c", ship_id, encode_dir(move_dir));
} else if (type == Type::Construct) {
return stringf("c %d", ship_id);
} else {
Log::die("Command::encode() unknown type %d", (int)type);
return "";
}
}
32 changes: 32 additions & 0 deletions bots/41_aleph4/hlt/Command.h
@@ -0,0 +1,32 @@
#pragma once
#include <string>
#include "Geometry.h"
#include "Player.h"
using namespace std;

struct Command
{
// three kinds of command
// - spawn from shipyard: 'g'
// - move ship: 'm <shipid> [nsewo]'
// - turn ship into dropoff: 'c <shipid>'

enum class Type
{
Generate = 0,
Move = 1,
Construct = 2
};

Type type;
int ship_id;
Direction move_dir;

static Command generate();
static Command move(int _ship_id, Direction _move_dir);
static Command move(const Ship & ship, Direction _move_dir);
static Command stay(const Ship & ship) { return move(ship, Direction::Still); }
static Command construct(int _ship_id);

string encode() const;
};
109 changes: 109 additions & 0 deletions bots/41_aleph4/hlt/Constants.cc
@@ -0,0 +1,109 @@
#include "Constants.h"
#include <vector>
#include <sstream>
#include <unordered_map>
using namespace std;

int Constants::MAX_HALITE;
int Constants::SHIP_COST;
int Constants::DROPOFF_COST;
int Constants::MAX_TURNS;
int Constants::Constants::EXTRACT_RATIO;
double Constants::INV_EXTRACT_RATIO;
int Constants::MOVE_COST_RATIO;
bool Constants::INSPIRATION_ENABLED;
int Constants::INSPIRATION_RADIUS;
int Constants::INSPIRATION_SHIP_COUNT;
int Constants::INSPIRED_EXTRACT_RATIO;
double Constants::INSPIRED_BONUS_MULTIPLIER;
int Constants::INSPIRED_MOVE_COST_RATIO;

static const string& get_string(const unordered_map<string, string>& map, const string& key) {
auto it = map.find(key);
if (it == map.end()) {
//log::log("Error: constants: server did not send " + key + " constant.");
exit(1);
}
return it->second;
}

static int get_int(unordered_map<string, string>& map, const string& key) {
return stoi(get_string(map, key));
}

static double get_double(unordered_map<string, string>& map, const string& key) {
return stod(get_string(map, key));
}

static bool get_bool(unordered_map<string, string>& map, const string& key) {
const string string_value = get_string(map, key);
if (string_value == "true") {
return true;
}
if (string_value == "false") {
return false;
}

//log::log("Error: constants: " + key + " constant has value of '" + string_value +
// "' from server. Do not know how to parse that as boolean.");
exit(1);
}



void Constants::parse(const string &line)
{
string clean_line;
for (char c : line) {
switch (c) {
case '{':
case '}':
case ',':
case ':':
case '"':
clean_line.push_back(' ');
break;
default:
clean_line.push_back(c);
break;
}
}

stringstream input_stream(clean_line);
vector<string> tokens;

while (true) {
string token;
if (!std::getline(input_stream, token, ' ')) {
break;
}
if (!token.empty()) {
tokens.push_back(token);
}
}

if ((tokens.size() % 2) != 0) {
//log::log("Error: constants: expected even total number of key and value tokens from server.");
exit(1);
}

unordered_map<string, string> constants_map;

for (size_t i = 0; i < tokens.size(); i += 2) {
constants_map[tokens[i]] = tokens[i+1];
}

SHIP_COST = get_int(constants_map, "NEW_ENTITY_ENERGY_COST");
DROPOFF_COST = get_int(constants_map, "DROPOFF_COST");
MAX_HALITE = get_int(constants_map, "MAX_ENERGY");
MAX_TURNS = get_int(constants_map, "MAX_TURNS");
EXTRACT_RATIO = get_int(constants_map, "EXTRACT_RATIO");
INV_EXTRACT_RATIO = 1.0 / EXTRACT_RATIO;
MOVE_COST_RATIO = get_int(constants_map, "MOVE_COST_RATIO");
INSPIRATION_ENABLED = get_bool(constants_map, "INSPIRATION_ENABLED");
INSPIRATION_RADIUS = get_int(constants_map, "INSPIRATION_RADIUS");
INSPIRATION_SHIP_COUNT = get_int(constants_map, "INSPIRATION_SHIP_COUNT");
INSPIRED_EXTRACT_RATIO = get_int(constants_map, "INSPIRED_EXTRACT_RATIO");
INSPIRED_BONUS_MULTIPLIER = get_double(constants_map, "INSPIRED_BONUS_MULTIPLIER");
INSPIRED_MOVE_COST_RATIO = get_int(constants_map, "INSPIRED_MOVE_COST_RATIO");
}
36 changes: 36 additions & 0 deletions bots/41_aleph4/hlt/Constants.h
@@ -0,0 +1,36 @@
#pragma once

#include <string>
using namespace std;

class Constants final {
public:
// The maximum amount of halite a ship can carry.
static int MAX_HALITE;
// The cost to build a single ship.
static int SHIP_COST;
// The cost to build a dropoff.
static int DROPOFF_COST;
// The maximum number of turns a game can last.
static int MAX_TURNS;
// 1/EXTRACT_RATIO halite (rounded) is collected from a square per turn.
static int EXTRACT_RATIO;
// INV_EXTRACT_RATIO = 1/EXTRACT_RATIO
static double INV_EXTRACT_RATIO;
// 1/MOVE_COST_RATIO halite (rounded) is needed to move off a cell.
static int MOVE_COST_RATIO;
// Whether inspiration is enabled.
static bool INSPIRATION_ENABLED;
// A ship is inspired if at least INSPIRATION_SHIP_COUNT opponent ships are within this Manhattan distance.
static int INSPIRATION_RADIUS; // 4
// A ship is inspired if at least this many opponent ships are within INSPIRATION_RADIUS distance.
static int INSPIRATION_SHIP_COUNT; // 2
// An inspired ship mines 1/X halite from a cell per turn instead.
static int INSPIRED_EXTRACT_RATIO; // unused?
// An inspired ship that removes Y halite from a cell collects X*Y additional halite.
static double INSPIRED_BONUS_MULTIPLIER; // 2.0
// An inspired ship instead spends 1/X% halite to move.
static int INSPIRED_MOVE_COST_RATIO;

static void parse(const string &line);
};
39 changes: 39 additions & 0 deletions bots/41_aleph4/hlt/Game.cc
@@ -0,0 +1,39 @@
#include "Game.h"

int Game::num_players;
int Game::my_player_id;
vector<Player> Game::players;
Player* Game::me;
int Game::turn;
vector<Vec> Game::enemy_structures;
vector<Vec> Game::enemy_shipyards;
vector<Ship> Game::enemy_ships;
map<int, Ship> Game::id_to_ship;
map<int, int> Game::sid_to_pid;

void Game::post_update()
{
// populate enemy_structures
enemy_structures.clear();
for (const Player &p : players) {
if (p.id == my_player_id) continue;
std::copy(p.structures.begin(), p.structures.end(), std::back_inserter(enemy_structures));
}

// populate enemy_ships
enemy_ships.clear();
for (const Player &p : players) {
if (p.id == my_player_id) continue;
std::copy(p.ships.begin(), p.ships.end(), std::back_inserter(enemy_ships));
}

// populate id_to_ship and sid_to_pid
id_to_ship.clear();
sid_to_pid.clear();
for (const Player & p : players) {
for (Ship ship : p.ships) {
id_to_ship[ship.id] = ship;
sid_to_pid[ship.id] = p.id;
}
}
}
30 changes: 30 additions & 0 deletions bots/41_aleph4/hlt/Game.h
@@ -0,0 +1,30 @@
#pragma once

#include <vector>
#include "Constants.h"
#include "Player.h"
using namespace std;

class Game final {
public:
static int num_players;
static int my_player_id;

static vector<Player> players;
static Player *me;

static int turn;

static vector<Vec> enemy_structures;
static vector<Vec> enemy_shipyards;
static vector<Ship> enemy_ships;

static map<int, Ship> id_to_ship;
static map<int, int> sid_to_pid;

// update auxiliary structures after basic info is initialized at the beginning of the turn
// must be called after Player::post_update() is called on all players
static void post_update();

static int turns_left() { return Constants::MAX_TURNS - turn; }
};

0 comments on commit 23e4004

Please sign in to comment.