Browse Source

Initial commit

master
xyrex 4 years ago
commit
d84166f720
8 changed files with 260 additions and 0 deletions
  1. +26
    -0
      README.md
  2. +1
    -0
      go.mod
  3. +0
    -0
      go.sum
  4. +1
    -0
      logs/placeholder.txt
  5. +132
    -0
      main.go
  6. +23
    -0
      models/models.go
  7. +15
    -0
      strategies/none.go
  8. +62
    -0
      strategies/simple.go

+ 26
- 0
README.md View File

@@ -0,0 +1,26 @@
# Battle of the Galaxies AI Bot

## Instructions

### Compile
`go build`

### Run simulator
`simulator ./botg ./botg test3`

## Logfiles
Logs are written to `./logs`.

You can replay a log like this:

`cat logs/xxxx.log | ./botg`

This enables you to add some debug logging.

## Strategies

Two strategies have been created:
- SimpleStrategy
- NoneStrategy
Change the strategy in main.go and compile a new version to change it.

+ 1
- 0
go.mod View File

@@ -0,0 +1 @@
module botg

+ 0
- 0
go.sum View File


+ 1
- 0
logs/placeholder.txt View File

@@ -0,0 +1 @@
Logs are written to this directory.

+ 132
- 0
main.go View File

@@ -0,0 +1,132 @@
package main

import (
"botg/models"
"botg/strategies"
"bufio"
"fmt"
"math/rand"
"os"
"strconv"
"strings"
"time"
)

var stars[] models.Star
var flights[] models.Flight
var links[] models.Link

func main() {
// Write to logfile
s1 := rand.NewSource(time.Now().UnixNano())
r1 := rand.New(s1)
rand.Seed(10000)
filename := fmt.Sprintf("logs/%d.txt", r1.Intn(10000))
f, err := os.Create(filename)
if err != nil{
panic(err)
}
defer f.Close()

// Open stdin for reading
reader := bufio.NewReader(os.Stdin)

var gameComplete bool =false
var roundComplete bool =false

// Run strategy
strategy := strategies.SimpleStrategy {}
//strategy := strategies.NoneStrategy {}

for gameComplete == false {
roundComplete = false

// Empty flights
flights = [] models.Flight{}
links = [] models.Link{}
for roundComplete == false {
text, err := reader.ReadString('\n')
if err != nil {
gameComplete = true
break
}

//Write to log
w := bufio.NewWriter(f)
w.WriteString(text)
w.Flush()

roundComplete = parseLine(text)
}

strategy.Execute(stars, flights, links)
}
}

func parseLine(text string) bool {
parts := strings.Split(text, " ")
command := strings.Trim(parts[0], "\n")

switch command {
case "stars":
// Process stars
for i := 1; i < len(parts)-1; i++ {
var x, y int
x, _ = strconv.Atoi(parts[i])
y, _ = strconv.Atoi(parts[i+1])
star := models.Star {
X: x,
Y: y,
Richness: 0,
Owner: -2,
Ships: -2,
Turns: -2,
}
stars = append(stars, star)
}
break
case "star":
var idx, _ = strconv.Atoi(parts[1])
var richness, _ = strconv.Atoi(parts[2])
var owner, _ = strconv.Atoi(parts[3])
var ships, _ = strconv.Atoi(parts[4])
var turns, _ = strconv.Atoi(parts[5])
star := &stars[idx]
star.Richness = richness
star.Owner = owner
star.Ships = ships
star.Turns = turns
break
case "link":
var source_idx, _ = strconv.Atoi(parts[1])
var target_idx, _ = strconv.Atoi(parts[2])

link := models.Link {
SourceStar: source_idx,
TargetStar: target_idx,
}

links = append(links, link)
break
case "flight":
var source_idx, _ = strconv.Atoi(parts[1])
var target_idx, _ = strconv.Atoi(parts[2])
var ship_count, _ = strconv.Atoi(parts[3])
var owner, _ = strconv.Atoi(parts[4])
var turns, _ = strconv.Atoi(parts[5])

flight := models.Flight {
SourceStar: source_idx,
TargetStar: target_idx,
Ships: ship_count,
Owner: owner,
Turns: turns,
}
flights = append(flights, flight)
break
case "done":
return true
}

return false
}

+ 23
- 0
models/models.go View File

@@ -0,0 +1,23 @@
package models

type Star struct {
X int
Y int
Richness int
Owner int
Ships int
Turns int
}

type Flight struct {
SourceStar int
TargetStar int
Ships int
Owner int
Turns int
}

type Link struct {
SourceStar int
TargetStar int
}

+ 15
- 0
strategies/none.go View File

@@ -0,0 +1,15 @@
package strategies

import (
"botg/models"
"fmt"
)

type NoneStrategy struct {

}

func (s NoneStrategy) Execute(stars[] models.Star, flights[] models.Flight, links[] models.Link) {
fmt.Println("done")
}


+ 62
- 0
strategies/simple.go View File

@@ -0,0 +1,62 @@
package strategies

import (
"botg/models"
"fmt"
)

type SimpleStrategy struct {

}

func (s SimpleStrategy) Execute(stars[] models.Star, flights[] models.Flight, links[] models.Link) {
total := 0

for i, s := range stars {
// Check if source star is already in flight
inFlight := false
for _, f := range flights {
if f.SourceStar == i {
inFlight = true
}
}
if inFlight {
break
}

// Only process owned stars
if s.Owner != 0 || s.Ships == 0 {
continue
}

// Wait till we have at least 30 ships
if s.Ships < 30 {
continue
}

// Determine target for this source
for j, t := range stars {
// Only target non-owned or enemy stars
if t.Owner != -1 && t.Owner != 2 {
continue
}

// If enemy star, make sure we have enough ships to attack it
if t.Owner == 2 && (s.Ships/2) - (t.Ships + (6 * t.Richness)) < 0 {
continue
}

// Fly to this target, and skip processing all remaining potential target stars
fmt.Printf("fly %d %d %d\n", i, j, s.Ships / 2)
total += 1
break
}

// We can only schedule 3 flights per round
if total == 3 {
break
}
}

fmt.Println("done")
}

Loading…
Cancel
Save