Browse Source

Some changes, WIP

master
Khaled Nassar 4 years ago
parent
commit
78605139d7
6 changed files with 169 additions and 43 deletions
  1. +14
    -14
      main.go
  2. +16
    -0
      models/models.go
  3. +33
    -0
      strategies/common.go
  4. +100
    -0
      strategies/linker.go
  5. +1
    -3
      strategies/none.go
  6. +5
    -26
      strategies/simple.go

+ 14
- 14
main.go View File

@@ -12,9 +12,9 @@ import (
"time"
)

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

func main() {
// Write to logfile
@@ -23,7 +23,7 @@ func main() {
rand.Seed(10000)
filename := fmt.Sprintf("logs/%d.txt", r1.Intn(10000))
f, err := os.Create(filename)
if err != nil{
if err != nil {
panic(err)
}
defer f.Close()
@@ -31,19 +31,19 @@ func main() {
// Open stdin for reading
reader := bufio.NewReader(os.Stdin)

var gameComplete bool =false
var roundComplete bool =false
var gameComplete bool = false
var roundComplete bool = false

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

for gameComplete == false {
roundComplete = false

// Empty flights
flights = [] models.Flight{}
links = [] models.Link{}
flights = []models.Flight{}
links = []models.Link{}
for roundComplete == false {
text, err := reader.ReadString('\n')
if err != nil {
@@ -79,9 +79,9 @@ func parseLine(text string) bool {
X: x,
Y: y,
Richness: 0,
Owner: -2,
Ships: -2,
Turns: -2,
Owner: -2,
Ships: -2,
Turns: -2,
}
stars = append(stars, star)
}
@@ -102,7 +102,7 @@ func parseLine(text string) bool {
var source_idx, _ = strconv.Atoi(parts[1])
var target_idx, _ = strconv.Atoi(parts[2])

link := models.Link {
link := models.Link{
SourceStar: source_idx,
TargetStar: target_idx,
}
@@ -116,7 +116,7 @@ func parseLine(text string) bool {
var owner, _ = strconv.Atoi(parts[4])
var turns, _ = strconv.Atoi(parts[5])

flight := models.Flight {
flight := models.Flight{
SourceStar: source_idx,
TargetStar: target_idx,
Ships: ship_count,

+ 16
- 0
models/models.go View File

@@ -22,3 +22,19 @@ type Link struct {
SourceStar int
TargetStar int
}

func (s *Star) Unowned() bool {
return s.Owner < 0
}

func (s *Star) OwnedByMe() bool {
return s.Owner == 0
}

func (s *Star) Friendly() bool {
return s.Owner == 1
}

func (s *Star) Enemy() bool {
return s.Owner == 2
}

+ 33
- 0
strategies/common.go View File

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

import (
"botg/models"
"math"
)

type StarAffiliation int

const (
Own StarAffiliation = 0
Friend StarAffiliation = 1
Enemy StarAffiliation = 2
)

func flightTurnDistance(x, y int, star *models.Star) int {
pointDistance := distanceBetweenPoints(x, y, star.X, star.Y)

if pointDistance == 0 {
return 0
}

return int(math.Ceil(pointDistance / 10))
}

func distanceBetweenPoints(x1, y1, x2, y2 int) float64 {
// Is it the same point? The distance is defined as 0
if x1 == x2 && y1 == y2 {
return 0
}

return math.Sqrt(math.Pow(float64(x1-x2), 2) + math.Pow(float64(y1-y2), 2))
}

+ 100
- 0
strategies/linker.go View File

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

import (
"botg/models"
"fmt"
)

type LinkerStrategy struct {
}

func (ls *LinkerStrategy) Execute(stars []models.Star, flights []models.Flight, links []models.Link) {
friendly := make([]int, 10)
friendlyDistanceMatrix := make(map[models.Star]map[models.Star]int)
for i, s := range stars {

// Skip unowned and enemy stars
if s.Unowned() || s.Enemy() {
continue
}

// Keep track of own stars
if s.OwnedByMe() || s.Friendly() {
friendly = append(friendly, i)
}

friendlyDistanceMatrix[s] = make(map[models.Star]int)
}

// Keep a map of all the distances
for i := 0; i < len(friendly); i++ {
src := stars[i]
for j := i + 1; j < len(friendly); j++ {
dst, flightDistance := stars[j], 0
if src.Idx == dst.Idx {
// Shouldn't happen, but oh well
continue
}

if ls.linkedOrInProgress(&src, &dst, links, flights) {
continue
}

flightDistance = flightTurnDistance(src.X, src.Y, &dst)

friendlyDistanceMatrix[src][dst] = flightDistance
}
}

top3Picks := []struct {
src *models.Star
dst *models.Star
distance int
}{
{nil, nil, 300 * 300},
{nil, nil, 300 * 300},
{nil, nil, 300 * 300},
}

for src, dstmap := range friendlyDistanceMatrix {
for dst, distance := range dstmap {
for i := 0; i < len(top3Picks); i++ {
if top3Picks[i].src == nil {
top3Picks[i].src = &src
top3Picks[i].dst = &dst
break
}
if distance < top3Picks[i].distance {
top3Picks[i].src = &src
top3Picks[i].dst = &dst
}
}
}
}

fmt.Println("done")
}

func (s *LinkerStrategy) insufficientShipsForLinking(star *models.Star) bool {
return star.Ships < 5
}

func (s *LinkerStrategy) linkedOrInProgress(src *models.Star, dst *models.Star, links []models.Link, flights []models.Flight) bool {
linking := false

for _, l := range links {
if (l.SourceStar == src.Idx && l.TargetStar == dst.Idx) || (l.SourceStar == dst.Idx && l.TargetStar == src.Idx) {
linking = true
break
}
}

for _, f := range flights {
if (f.SourceStar == src.Idx && f.TargetStar == dst.Idx) || (f.SourceStar == dst.Idx && f.TargetStar == src.Idx) {
linking = true
break
}
}

return linking
}

+ 1
- 3
strategies/none.go View File

@@ -6,10 +6,8 @@ import (
)

type NoneStrategy struct {

}

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


+ 5
- 26
strategies/simple.go View File

@@ -3,15 +3,13 @@ package strategies
import (
"botg/models"
"fmt"
"math"
)

type SimpleStrategy struct {

}

func (s *SimpleStrategy) Execute(stars[] models.Star, flights[] models.Flight, links[] models.Link) {
func (s *SimpleStrategy) Execute(stars []models.Star, flights []models.Flight, links []models.Link) {
for i, s := range stars {
// Maximum flights per star per round is 3
total := 0
@@ -56,13 +54,13 @@ func (s *SimpleStrategy) Execute(stars[] models.Star, flights[] models.Flight, l

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

// TODO: Find best destination
// Fly to this target, and skip processing all remaining potential target stars
fmt.Printf("fly %d %d %d\n", i, j, s.Ships / 2)
fmt.Printf("fly %d %d %d\n", i, j, s.Ships/2)
total++
break
}
@@ -83,7 +81,7 @@ func calculateDistanceCeiling(source *models.Star, target *models.Star) int {
ub := 300 * 2
for lb < ub {
mb := (lb + ub) / 2
if mb * mb >= squareDist {
if mb*mb >= squareDist {
ub = mb
} else {
lb = mb + 1
@@ -92,22 +90,3 @@ func calculateDistanceCeiling(source *models.Star, target *models.Star) int {

return lb
}

func flightTurnDistance(x, y int, star *models.Star) int {
pointDistance := distanceBetweenPoints(x, y, star.X, star.Y)

if pointDistance == 0 {
return 0
}

return int(math.Ceil(pointDistance / 10))
}

func distanceBetweenPoints(x1, y1, x2, y2 int) float64 {
// Is it the same point? The distance is defined as 0
if x1 == x2 && y1 == y2 {
return 0
}

return math.Sqrt(math.Pow(float64(x1 - x2), 2) + math.Pow(float64(y1 - y2), 2))
}

Loading…
Cancel
Save