add init-project command

This commit is contained in:
Ilion Beyst 2021-12-25 15:36:23 +01:00
parent d0a0fcfded
commit 92a13bac92
6 changed files with 134 additions and 3 deletions

View file

@ -1,3 +1,9 @@
# planetwars-localdev
Tools for developping planetwars bots locally.
Tools for developping planetwars bots locally.
## Getting started
1. Initialize your project directory: `pwcli init-project my_project`
2. Enter your fresh project: `cd my_project`
3. Run an example match: `pwcli run-match hex simplebot simplebot`

View file

@ -0,0 +1,43 @@
{
"planets": [
{
"name": "protos",
"x": -6,
"y": 0,
"owner": 1,
"ship_count": 6
},
{
"name": "duteros",
"x": -3,
"y": 5,
"ship_count": 6
},
{
"name": "tritos",
"x": 3,
"y": 5,
"ship_count": 6
},
{
"name": "tetartos",
"x": 6,
"y": 0,
"owner": 2,
"ship_count": 6
},
{
"name": "pemptos",
"x": 3,
"y": -5,
"ship_count": 6
},
{
"name": "extos",
"x": -3,
"y": -5,
"ship_count": 6
}
]
}

View file

@ -0,0 +1,10 @@
[bots]
# define a bot called simplebot
[bots.simplebot]
# The working directory for the bot.
path = "./bots/simplebot"
# What command to use for running the bot
argv = ["python", "simplebot.py"]

View file

@ -0,0 +1,33 @@
import sys, json
def move(command):
""" print a command record to stdout """
moves = []
if command is not None:
moves.append(command)
print(json.dumps({ 'moves': moves }))
# flush the buffer, so that the gameserver can receive the json-encoded line.
sys.stdout.flush()
for line in sys.stdin:
state = json.loads(line)
# you are always player 1.
my_planets = [p for p in state['planets'] if p['owner'] == 1]
other_planets = [p for p in state['planets'] if p['owner'] != 1]
if not my_planets or not other_planets:
# we don't own any planets, so we can't make any moves.
move(None)
else:
# find my planet that has the most ships
planet = max(my_planets, key=lambda p: p['ship_count'])
# find enemy planet that has the least ships
destination = min(other_planets, key=lambda p: p['ship_count'])
# attack!
move({
'origin': planet['name'],
'destination': destination['name'],
'ship_count': planet['ship_count'] - 1
})

View file

@ -22,6 +22,8 @@ struct Cli {
#[derive(Subcommand)]
enum Commands {
/// Initialize a new project
InitProject(InitProjectCommand),
/// Run a match
RunMatch(RunMatchCommand),
}
@ -34,6 +36,12 @@ struct RunMatchCommand {
bots: Vec<String>,
}
#[derive(Parser)]
struct InitProjectCommand {
/// project root directory
path: String,
}
#[derive(Serialize, Deserialize, Debug)]
struct ProjectConfig {
bots: HashMap<String, BotConfig>,
@ -49,6 +57,7 @@ pub async fn run() {
let matches = Cli::parse();
let res = match matches.command {
Commands::RunMatch(command) => run_match(command).await,
Commands::InitProject(command) => init_project(command),
};
if let Err(err) = res {
eprintln!("{}", err);
@ -89,7 +98,10 @@ async fn run_match(command: RunMatchCommand) -> io::Result<()> {
};
match_runner::run_match(match_config).await;
println!("match completed successfully");
// TODO: don't hardcode match path.
// maybe print the match result as well?
println!("wrote match log to matches/{}.log", timestamp);
Ok(())
}
@ -101,3 +113,29 @@ fn resolve_bot_config(project_dir: &Path, config: BotConfig) -> BotConfig {
argv: config.argv,
}
}
macro_rules! copy_asset {
($path:expr, $file_name:literal) => {
::std::fs::write(
$path.join($file_name),
include_bytes!(concat!("../assets/", $file_name)),
)?;
};
}
fn init_project(command: InitProjectCommand) -> io::Result<()> {
let path = PathBuf::from(&command.path);
// create directories
std::fs::create_dir_all(&path)?;
std::fs::create_dir(path.join("maps"))?;
std::fs::create_dir(path.join("matches"))?;
std::fs::create_dir_all(path.join("bots/simplebot"))?;
// create files
copy_asset!(path, "pw_project.toml");
copy_asset!(path.join("maps"), "hex.json");
copy_asset!(path.join("bots/simplebot"), "simplebot.py");
Ok(())
}

View file

@ -1,6 +1,7 @@
use std::fs::File;
use std::io;
use std::io::Read;
use std::path::PathBuf;
use serde_json;
@ -9,7 +10,7 @@ use super::rules::*;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
pub map_file: String,
pub map_file: PathBuf,
pub max_turns: u64,
}