Skip to content

Commit

Permalink
Update dependencies, improve README
Browse files Browse the repository at this point in the history
- Upgraded all build dependencies to the latest versions, remove
deprecated dependencies.
- Update README with instructions on viewing in your browser, restore
lines in index.html to how they should be
  • Loading branch information
timjrobinson committed Jul 28, 2019
1 parent 74b4a29 commit 841acc5
Show file tree
Hide file tree
Showing 6 changed files with 691 additions and 2,131 deletions.
2 changes: 1 addition & 1 deletion .babelrc
@@ -1,3 +1,3 @@
{
"presets": ["es2015"]
"presets": ["@babel/preset-env"]
}
61 changes: 35 additions & 26 deletions README.md
Expand Up @@ -4,41 +4,25 @@ A 2D battleground simulation where AI's fight each other and evolve over time to

## Overview

Many colleges and companies hold virtual AI battles for their engineers. You are given a sandbox environment with a few
Many universities and companies hold virtual AI battles for their engineers. You are given a sandbox environment with a few
simple rules and must produce an AI algorithm that can beat all others. For a battle this year I decided to build an evolutionary
algorithm based off the [Evolving Neural Networks through Augmenting Topologies (NEAT) paper](http://nn.cs.utexas.edu/downloads/papers/stanley.ec02.pdf)
and inspired by the [Mar/IO project](https://www.youtube.com/watch?v=qv6UVOQ0F44).
and inspired by the [Mar/IO project](https://www.youtube.com/watch?v=qv6UVOQ0F44). This required building a simulator and system to train these AI's
against each other, which is what this package contains.

The system initially creates 100 random genomes, then makes them fight each other, each AI playing 5 battles per round. At
the end of each round the weakest bots are culled, and the strongest bots go on to have children, which inherit their parents
genes plus get some random mutations of their own. The remaining parents and all the children then play each other in the next round. Over time this leads to more and more intelligent AI's battling each other.

### How battles work

The battle is played in 75ms ticks. Each tick each AI is given the following information:

- **xPos** - *int [0 - MAP_WIDTH]* Your bots x (horizontal) coordinate, where 0 is the left hand most column and MAP_WIDTH the right hand most column.
- **yPos** - *int [0 - MAP_HEIGHT]* - Your bots y (vertical) coordinate, where 0 is the top of the screen and MAP_HEIGHT is the bottom.
- **rotation** - *int [0 - 360]* - The angle your bot is facing in degrees, where 0 degrees is east, 90 degrees is north, 180 west, 270 south.
- **bullets** - *Array<Bullet>* - Any of your bullets currently on the screen. Each bullet is an object of {xPos, yPos, rotation}.
otherPlayer - An object with the above properties for the other player

This object is sent to the bot each tick and the bot uses that to make it's next decision. Then it must return an object containing the following:

- **ds** - *boolean* - Is the bot shooting or not
- **dx** - *int [-15 - 15]* - The x-speed of the bot, from -15 (west) to 15 (east)
- **dy** - *int [-15 - 15]* - The y-speed of the bot, from -15 (north) to 15 (south)
- **dh** - *int [-15 - 15]* - The rotation speed of the bot, where -15 is counterclockwise and 15 is clockwise

You can only have a maximum of 5 bullets on the screen at once and they are destroyed when they hit the opponent or wall. Each player has 5 lives.

genes plus get some random mutations of their own. The remaining parents and all the children then play each other in the next round. Over time this leads to more and more intelligent AI's battling each other and constantly creating new strategies and counter-strategies.

## Setup

```
npm install
```

The code is written using ES6 functionality and is compiled for the browser using Webpack and compiled
for NodeJS using Babel. The browser entrypoint is `src/index.js` and the NodeJS entrypoint is `src/coordinator.js`.

## Usage

### Training
Expand All @@ -50,7 +34,7 @@ You can first train many games using NodeJS and then view some of the battles be
#### Browser Training

- `npm run compile-browser` to run webpack and compile all the files.
- Open `dist/index.html` in your browser.
- Open `dist/index.html` in your browser (loading via `file:///path/to/evolutionary-ai-battle/dist/index.html` is fine).

You should see the red bot chilling out not doing much, while the blue bot does something randomly. In the initial stages of training
only the red bot is trained, while the blue bot has a random move / shoot algorithm to give some variety to the battles. Because
Expand All @@ -68,7 +52,13 @@ This will compile all the src files into `dist/nodejs/` then run `node dist/node

### Watching

To watch a battle between two AI's you can do the following:
To watch a battle between two trained AI's you can do the following:

- Open `src/index.js`
- Change the two commented out lines to a species file generated by NodeJS training
- Run `npm run compile-browser`
- Open `dist/index.html` in your browser (loading via `file:///path/to/evolutionary-ai-battle/dist/index.html` is fine)


## Configuration Options

Expand Down Expand Up @@ -126,7 +116,26 @@ These are just default values, each genome will randomly modify these options ov
- Gene - A gene describes a link between two neurons in the AI's brain. Each gene belongs to one genome and a genome has many genes.
- Innovation - An innovation number is given to each gene upon creation. If a gene is passed to a child it is given the same innovation number. When two parents create children all genes come from the strongest parent, except those genes with the same innovation number, they are picked from one parent at random.

## AI Implementation FAQ
## Implementation FAQ

### How do battles work?

The battle is played in 75ms ticks. Each tick each AI is given the following information:

- **xPos** - *int [0 - MAP_WIDTH]* Your bots x (horizontal) coordinate, where 0 is the left hand most column and MAP_WIDTH the right hand most column.
- **yPos** - *int [0 - MAP_HEIGHT]* - Your bots y (vertical) coordinate, where 0 is the top of the screen and MAP_HEIGHT is the bottom.
- **rotation** - *int [0 - 360]* - The angle your bot is facing in degrees, where 0 degrees is east, 90 degrees is north, 180 west, 270 south.
- **bullets** - *Array<Bullet>* - Any of your bullets currently on the screen. Each bullet is an object of {xPos, yPos, rotation}.
otherPlayer - An object with the above properties for the other player

This object is sent to the bot each tick and the bot uses that to make it's next decision. Then it must return an object containing the following:

- **ds** - *boolean* - Is the bot shooting or not
- **dx** - *int [-15 - 15]* - The x-speed of the bot, from -15 (west) to 15 (east)
- **dy** - *int [-15 - 15]* - The y-speed of the bot, from -15 (north) to 15 (south)
- **dh** - *int [-15 - 15]* - The rotation speed of the bot, where -15 is counterclockwise and 15 is clockwise

You can only have a maximum of 5 bullets on the screen at once and they are destroyed when they hit the opponent or wall. Each player has 5 lives.

### How does the bot brain map work?

Expand Down
7 changes: 2 additions & 5 deletions babel.config.js
@@ -1,12 +1,9 @@
const presets = [
[
"@babel/env",
"@babel/preset-env",
{
targets: {
edge: "17",
firefox: "60",
chrome: "67",
safari: "11.1",
node: "current"
},
useBuiltIns: "usage",
},
Expand Down

0 comments on commit 841acc5

Please sign in to comment.