Robot Wars
Introduction
RobotWars is a web based robot was simulator which is inspired by the original RobotWar by MUSE software.
Only the idea is borrowed from the orignal game. Robot characteristics and battle field is written from scratch (in erlang) with no reference to the original game. The main innovation in this variant is that battles are fought over the internet. Combatting robots are simulated with its custom programmed fighting strategy or AI on local machines. The battlefield and simulator is run on a central service accessible via an HTTP API.
The target of each player is to program a robot AI in any language of choice and fight other robots to the death. The fight with other robots are controlled through the common combat simulation service accessible on the following url.
http://robotwars.ideell.se/
Apart from the simulation service a combat viewer has been developed. The viewer is able to show in detail how a fight has progressed.
Open the root url http://robotwars.ideell.se/ to see the existing battles that have been run on the server. Different fights are shown on the following url.
http://robotwars.ideell.se/view/<battle-id>/<simulation-step>
API examples using curl
The game master first need to create a battle where opponents can join. A battle configuration is returned.
curl -s -d '{"type":"create"}' -H "Content-Type: application/json"
-X POST http://robotwars.ideell.se/create
# => { "id":787352956,
"width":100,
"height":100,
"timeout":1000,
"state":"open",
"created":"2019-02-10T17:54:05Z" }
A configuration for the battle is returned.
ida unique identity that is used to reference the battle(width,height)size of the battlefieldtimeoutmaximum time in milli seconds robot clients have each round to sent its commandstateof the battle. See description of valid values belowcreatedbattle creation time
As soon as opponents are informed about the battle identity, they can join by specifying the battle id and a name for the robot. A robot configuration is returned.
curl -s -d '{"type":"enter", "id":787352956, "name":"MrRobot"}'
-H "Content-Type: application/json" -X POST http://robotwars.ideell.se/enter
# => { "id":328610546,
"battle":787352956,
"name":"MrRobot",
"x":77,
"y":66,
"angle":136,
"aim":106,
"energy":100 }
Robots get a random location, angle and aim on the battle field and start with power of 100.
ida unique identity that is used to reference the robot(x,y)position is the location on the battlefield relative- origo (0,0) is located in the bottom left corner in the viewer
anglespecify the direction of the robot in degreesangle0has the same direction as the x-axis i.e. to the right in the viewer
aimspecify the direction of the cannon/scanner tower relative the robotaim0is defined as pointing directly forward in the robots direction- note that changing the direction angle of the robot also affect where the tower aim
energydefine the power left for the robotenergyis only consumed then the robot is hit by a cannon fire
- robots have a radius of 5
Robots can execute from a single computer or from different computers. One way is to create a single program/script that controls the game (a "master" program) which in turn start different client robot programs.
It is the game master that decide when the game starts. The game master can ping the battle to check battle state.
curl -s -d '{"type":"ping", "id":787352956}' -H "Content-Type: application/json"
-X POST http://robotwars.ideell.se/ping
# => {"state":"open","robots":[328610546,802403610]}
The robots field contain the identities of robots that have joined the game.
The game master decide when to start the battle based on e.g. number of entrants or time period after opponents was informed about the battle. The battle is started with a start command.
curl -s -d '{"type":"start", "id":787352956}' -H "Content-Type: application/json" -X POST http://robotwars.ideell.se/start
# => {"robots":[328610546,802403610,656339793]}
After entering the battle, robots also need to wait until the battle is started. Robots can also check battle state through ping command.
curl -s -d '{"type":"ping", "id":787352956}' -H "Content-Type: application/json"
-X POST http://robotwars.ideell.se/ping
# => {"id":787352956,"width":100,"height":100,"timeout":1000,"state":"running"}
When battle state change from open to running robots can start to send commands.
Battle can be in the following states:
openpingreturn battle state and entered robots- e.g.
{"state":"open","robots":[...]}
running,finishedandclosedpingreturn battle data{"id":787352956,"width":100,"height":100,"timeout":1000,"state":"running", "created":"2019-02-10T17:54:05Z"}
During a running battle, robots can send a single command with a maximum timeout of 1000 ms each battle round. Failing to send a command within 1000 ms is the same as sending a nop (no operation) command.
One of the following commands (walk, turn, aim, scan, fire and nop) can be sent in a round.
A walk command move the robot in the angle direction of the robot
- number of steps is limited to +/- 10 steps
- robot stop when walk movement hit a wall
- other robots do not effect your movement
Example:
curl -s -d '{"type":"walk", "id":328610546, "steps":8}'
-H "Content-Type: application/json" -X POST http://robotwars.ideell.se/command
# => { "robot":
{
"id":730700238,
"battle":173310470,
"name":"MrRobot",
"x":82,
"y":0,
"angle":343,
"aim":41,
"energy":20
},
"result":
{
"walk":
{
"x":8,
"y":0
}
}
}
A turn change the direction of the robot a specified angle relative current direction
- angle change is limited to +/- 180 degrees (i.e. a complete turn is possible)
- note that the tower aim is relative the robot direction and rotate with the rotation of the robot
Example:
curl -s -d '{"type":"turn", "id":328610546, "angle":5}'
-H "Content-Type: application/json" -X POST http://robotwars.ideell.se/command
# => { "robot":
{
"id":730700238,
"battle":173310470,
"name":"MrRobot",
"x":74,
"y":0,
"angle":337,
"aim":41,
"energy":20
},
"result":
{
"turn":5
}
}
An aim change the aim of the cannon/scanner tower relative current aim
- angle change is limited to +/- 180 degrees
- note that the tower aim is relative the robot direction
- tower aim relative battle field is robot angle + aim
Example:
curl -s -d '{"type":"aim", "id":328610546, "angle":10}'
-H "Content-Type: application/json" -X POST http://robotwars.ideell.se/command
# => { "robot":
{
"id":231079204,
"battle":173310470,
"x":57,
"y":54,
"angle":202,
"aim":176,
"energy":100
},
"result":
{
"aim":10
}
}
A scan command detect other robots in the direction of the cannon tower
anglespecify the angle where robots are detected- angle is limited to maximum 90 degrees
- within +/- (angle/2) relative tower all robots identities and corresponding distance are returned
- it is enough if the outer radius (of 5) of the robot is within scan angle to be detected
- robots with energy 0 are not visible in a scan
Example:
curl -s -d '{"type":"scan", "id":328610546, "angle":15}'
-H "Content-Type: application/json" -X POST http://robotwars.ideell.se/command
# => { "robot":
{
"id":944065924,
"battle":173310470,
"name":"MrRobot",
"x":99,
"y":4,
"angle":37,
"aim":188,
"energy":38
},
"result":
{
"scanned":
[
{ "737167333":23 }
]
}
}
A fire command fire hit the first robot in in the direction of the tower
- A robot may be hit if the laser pass through the outer radius (of 5) of the robot
- the damaged robot decrease power randomly by 10-30 points
- a robot has lost if power go down to 0
- the damaged robot identity and its power loss is returned in the call
- robots with energy 0 does not effect fire
Example:
curl -s -d '{"type":"fire", "id":328610546}' -H "Content-Type: application/json"
-X POST http://robotwars.ideell.se/command
# => { "robot":
{
"id":730700238,
"battle":173310470,
"name":"MrRobot",
"x":95,
"y":0,
"angle":1,
"aim":77,
"energy":20
},
"result":
{
"damaged":
[
{"737167333":-15}
]
}
}
A nop command does nothing. It should be used if you don't want to do an operation in a specific turn because simulation will complete faster when all robots has sent a command.
curl -s -d '{"type":"nop", "id":328610546}' -H "Content-Type: application/json"
-X POST http://robotwars.ideell.se/command
# => { "robot":
{
"id":730700238,
"battle":173310470,
"name":"MrRobot",
"x":95,
"y":0,
"angle":1,
"aim":77,
"energy":20
},
"result":
{
"nop":"empty"
}
}
The order of execution of commands is the following:
walkturnandaimscanandfire
Commands can be sent until only one robot has energy above zero. At this stage the battle is finished.
The game master can check the battle status via ping.
curl -s -d '{"type":"ping", "id":787352956}' -H "Content-Type: application/json"
-X POST http://robotwars.ideell.se/ping
# => {"id":787352956,"width":100,"height":100,"timeout":1000,"state":"finished"}
After that the game master can close the game.
curl -s -d '{"type":"close", "id":328610546}' -H "Content-Type: application/json"
-X POST http://robotwars.ideell.se/close`
# => {
"battle":{"id":753756259,"width":100,"height":100,"timeout":1000,"state":"closed",,"created":"2019-02-10T17:54:05Z"},
"robots":[
{"id":795767293,"battle":753756259,"name":"MrRobot","x":18,"y":82,"angle":108,"aim":60,"energy":0},
{"id":475298804,"battle":753756259,"name":"Rand1","x":30,"y":99,"angle":82,"aim":12,"energy":0},
{"id":93040013,"battle":753756259,"name":"Rand2","x":26,"y":79,"angle":335,"aim":251,"energy":52}
]
}
After a game has finished the game simulation data can be retrieved and allow clients to visualise the battle progress.
stepspecify the simulation step you want to extract data from- data is returned as an array of
{"meta":{...}, "command":{...}, "robot":{...}, "result":{...}} metaspecify battle and robot ids and requested steprobotspecify robot state after step has completedcommandandresultis the same data returned when command was sent
Example:
curl -s -d "{"type":"simdata", "id":787352956, "step":0}"
-H "Content-Type: application/json" -X POST $HOST/simdata`
# => [
{
"meta":{"battle_id":787352956,"step":0,"robot_id":663512003},
"command":{"type":"walk","id":663512003,"steps":2},
"robot":{"id":663512003,"battle":787352956,"name":"MrRobot","x":68,"y":1,"angle":253,"aim":289,"energy":100},
"result":{"walk":{"x":-1,"y":-2}}
},
{ "meta":{"battle_id":787352956,"step":0,"robot_id":212732548},
"command":{"type":"fire","id":212732548},
"robot":{"id":212732548,"battle":787352956,"name":"Rand1","x":85,"y":60,"angle":0,"aim":14,"energy":100},
"result":{"damaged":[]}
},
{ "meta":{"battle_id":787352956,"step":0,"robot_id":737167333},
"command":{"type":"fire","id":737167333},
"robot":{"id":737167333,"battle":787352956,"name":"Rand1","x":36,"y":84,"angle":336,"aim":158,"energy":100},
"result":{"damaged":[]}
}
]
Random test robots
If you want to test a full battle I have built a naive/random robots that "fight to the power-down".
There is one master script that control the battle and start each robot. The robots also have their own script.
These scripts are dependent on ksh and jq.
- master.sh - master script will start robot script as sub-process
- robot.sh - an example robot script in ksh
There is also an example robot in ruby and python.
It takes a few minutes for these stupid robots to kill each other off. Surely your robot can do better?
Try it!
Battle Visualization
A visualisation engine has been made to show the progress of a battle.
Check it out here:
You can change battle and step and run simulation by the simple input fields.
Press Run to animate the battle.