Browse Source

Linker and other changes

master
Khaled Nassar 4 years ago
parent
commit
a41b44ddf6
5 changed files with 75 additions and 67 deletions
  1. +17
    -6
      main.go
  2. +1
    -0
      models/models.go
  3. +1
    -1
      strategies/common.go
  4. +44
    -33
      strategies/linker.go
  5. +12
    -27
      strategies/simple.go

+ 17
- 6
main.go View File

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

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

@@ -60,6 +60,7 @@ func main() {
}

strategy.Execute(stars, flights, links)
fmt.Println("done")
}
}

@@ -74,10 +75,10 @@ func parseLine(text string) bool {
var x, y int
x, _ = strconv.Atoi(parts[i])
y, _ = strconv.Atoi(parts[i+1])
star := models.Star {
Idx: i - 1,
X: x,
Y: y,
star := &models.Star{
Idx: i - 1,
X: x,
Y: y,
Richness: 0,
Owner: -2,
Ships: -2,
@@ -92,11 +93,12 @@ func parseLine(text string) bool {
var owner, _ = strconv.Atoi(parts[3])
var ships, _ = strconv.Atoi(parts[4])
var turns, _ = strconv.Atoi(parts[5])
star := &stars[idx]
star := stars[idx]
star.Richness = richness
star.Owner = owner
star.Ships = ships
star.Turns = turns
star.FlightsAllowed = 3
break
case "link":
var source_idx, _ = strconv.Atoi(parts[1])
@@ -129,5 +131,14 @@ func parseLine(text string) bool {
return true
}

// Update star flight data
for i, s := range stars {
for _, f := range flights {
if f.SourceStar == i {
s.FlightsAllowed--
}
}
}

return false
}

+ 1
- 0
models/models.go View File

@@ -8,6 +8,7 @@ type Star struct {
Owner int
Ships int
Turns int
FlightsAllowed int
}

type Flight struct {

+ 1
- 1
strategies/common.go View File

@@ -32,7 +32,7 @@ func calculateDistanceCeiling(source *models.Star, target *models.Star) int {

func flightTurnDistance(source, target *models.Star) int {
if source.Idx == target.Idx {
return 0;
return 0
}

return int(math.Ceil(float64(calculateDistanceCeiling(source, target)) / 10.0))

+ 44
- 33
strategies/linker.go View File

@@ -8,71 +8,82 @@ import (
type LinkerStrategy struct {
}

func (ls *LinkerStrategy) Execute(stars []models.Star, flights []models.Flight, links []models.Link) {
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)
friendlyDistanceMatrix := make(map[models.Star]*models.Star)
for i, s := range stars {

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

// Keep track of own stars
// Keep track of friendly 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
dst, distance := stars[j], 0
if src.Idx == dst.Idx {
// Shouldn't happen, but oh well
continue
}

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

// The source is lower than the destination, so skip it
if src.Y > dst.Y {
continue
}

flightDistance = flightTurnDistance(&src, &dst)
// We only want to map to friendlies, not own
if !dst.Friendly() {
continue
}

friendlyDistanceMatrix[src][dst] = flightDistance
distance = calculateDistanceCeiling(src, dst)
currentLowest, exists := friendlyDistanceMatrix[*src]
if exists {
currentDistance := calculateDistanceCeiling(src, currentLowest)
if currentDistance < distance {
continue
}
}
// Only add it if it's the currently closest friendly star from source
friendlyDistanceMatrix[*src] = dst
}
}

top3Picks := []struct {
src *models.Star
dst *models.Star
distance int
}{
{nil, nil, 300 * 300},
{nil, nil, 300 * 300},
{nil, nil, 300 * 300},
}
var nextLinkSource, nextLinkTarget *models.Star
minDistance := 300 * 300
for src, dst := range friendlyDistanceMatrix {
// If the source is not owned by me, must be a different closer commander
// so skip it
if !src.OwnedByMe() {
continue
}

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
}
}
if ls.insufficientShipsForLinking(&src) {
continue
}

distance := calculateDistanceCeiling(&src, dst)
if distance < minDistance {
nextLinkSource = &src
nextLinkTarget = dst
}
}

fmt.Println("done")
if nextLinkSource != nil && nextLinkTarget != nil {
// Send a ship out to link
fmt.Printf("fly %d %d %d\n", nextLinkSource.Idx, nextLinkTarget.Idx, 2)
}
}

func (s *LinkerStrategy) insufficientShipsForLinking(star *models.Star) bool {

+ 12
- 27
strategies/simple.go View File

@@ -8,20 +8,11 @@ import (
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

// Check if source star is already in flight
inFlight := false
for _, f := range flights {
if f.SourceStar == i {
inFlight = true
}
}
if inFlight {
// No more flights allowed for that node
if s.FlightsAllowed <= 0 {
continue
}

@@ -30,8 +21,8 @@ func (s *SimpleStrategy) Execute(stars []models.Star, flights []models.Flight, l
continue
}

// Wait till we have at least 30 ships
if s.Ships < 30 {
// Wait till we have a sufficient number of ships
if s.Ships < 10 {
continue
}

@@ -46,30 +37,24 @@ func (s *SimpleStrategy) Execute(stars []models.Star, flights []models.Flight, l

// Check if ship is within distance
//fmt.Printf("TARGET => IDX=%d, X=%d, Y=%d, OWNER=%d, RICH=%d, SHIPS=%d\n", t.Idx, t.X, t.Y, t.Owner, t.Richness, t.Ships)
//flightTurnDistance := calculateDistanceCeiling(&t, &s)
////fmt.Println(flightTurnDistance)
//if flightTurnDistance > 60 {
// continue
//}
flightTurnDistance := flightTurnDistance(s, t)
if flightTurnDistance > 6 {
continue
}

// 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 {
insufficientShips := (s.Ships / 2) <= ((t.Ships + (flightTurnDistance * t.Richness)) + 5)
if t.Owner == 2 && insufficientShips {
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)
total++
break
}

// We can only schedule 3 flights per round
if total == 3 {
s.FlightsAllowed--
break
}
}

fmt.Println("done")
}

Loading…
Cancel
Save