primitive predictive AI
This commit is contained in:
parent
cfa4d64492
commit
791fffdebb
27
game/ai.go
27
game/ai.go
|
@ -1,5 +1,7 @@
|
||||||
package game
|
package game
|
||||||
|
|
||||||
|
import "log"
|
||||||
|
|
||||||
func chooseCommand(s State, teamID int) command {
|
func chooseCommand(s State, teamID int) command {
|
||||||
t := s.Teams[teamID]
|
t := s.Teams[teamID]
|
||||||
h := ActiveBot(t)
|
h := ActiveBot(t)
|
||||||
|
@ -28,3 +30,28 @@ func chooseCommand(s State, teamID int) command {
|
||||||
|
|
||||||
return speedUp
|
return speedUp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func smartChooseCommand(s State, teamID int) command {
|
||||||
|
bestCmd, bestN := speedUp, 0
|
||||||
|
|
||||||
|
log.Printf("team %d base score: %d", teamID, score(s, teamID))
|
||||||
|
for _, cmd := range []command{speedUp, slowDown, left, right} {
|
||||||
|
ss := doCommand(cmd, s, teamID)
|
||||||
|
n := score(ss, teamID)
|
||||||
|
log.Printf("team %d score %s: %d", teamID, cmd, n)
|
||||||
|
if n > bestN {
|
||||||
|
bestCmd, bestN = cmd, n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bestCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func score(s State, teamID int) int {
|
||||||
|
t := s.Teams[teamID]
|
||||||
|
b := ActiveBot(t)
|
||||||
|
if b == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return b.Position.Pos
|
||||||
|
}
|
||||||
|
|
|
@ -32,5 +32,25 @@ func doCommand(cmd command, s State, teamID int) State {
|
||||||
}
|
}
|
||||||
|
|
||||||
s = updateBot(s, *b)
|
s = updateBot(s, *b)
|
||||||
|
|
||||||
|
if b := ActiveBot(s.Teams[teamID]); b != nil {
|
||||||
|
s = moveBot(s, *b)
|
||||||
|
}
|
||||||
|
s = maybePassBaton(s, teamID)
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c command) String() string {
|
||||||
|
switch c {
|
||||||
|
case speedUp:
|
||||||
|
return "speed up"
|
||||||
|
case slowDown:
|
||||||
|
return "slow down"
|
||||||
|
case left:
|
||||||
|
return "go left"
|
||||||
|
case right:
|
||||||
|
return "go right"
|
||||||
|
}
|
||||||
|
return "(unknown)"
|
||||||
|
}
|
||||||
|
|
|
@ -4,11 +4,9 @@ import "log"
|
||||||
|
|
||||||
func UpdateState(s State, sOld State) State {
|
func UpdateState(s State, sOld State) State {
|
||||||
for i := range s.Teams {
|
for i := range s.Teams {
|
||||||
s = doCommand(chooseCommand(s, i), s, i)
|
cmd := smartChooseCommand(s, i)
|
||||||
if b := ActiveBot(s.Teams[i]); b != nil {
|
log.Printf("team %d chose to %v", i, cmd)
|
||||||
s = moveBot(s, *b)
|
s = doCommand(cmd, s, i)
|
||||||
}
|
|
||||||
s = maybePassBaton(s, i)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, t := range s.Teams {
|
for _, t := range s.Teams {
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package game
|
package game
|
||||||
|
|
||||||
import "log"
|
|
||||||
|
|
||||||
func accelerate(b Bot) Bot {
|
func accelerate(b Bot) Bot {
|
||||||
if b.a < -maxA {
|
if b.a < -maxA {
|
||||||
b.a = -maxA
|
b.a = -maxA
|
||||||
|
@ -24,7 +22,6 @@ func accelerate(b Bot) Bot {
|
||||||
func moveBot(s State, b Bot) State {
|
func moveBot(s State, b Bot) State {
|
||||||
for i := 0; i < b.v; i++ {
|
for i := 0; i < b.v; i++ {
|
||||||
if o := collide(b.Position.Pos+1, b.Position.Lane, s); o != nil {
|
if o := collide(b.Position.Pos+1, b.Position.Lane, s); o != nil {
|
||||||
log.Printf("bot %d crashed into %#v!", b.ID, o)
|
|
||||||
return destroyBot(s, b)
|
return destroyBot(s, b)
|
||||||
} else {
|
} else {
|
||||||
b.Position.Pos++
|
b.Position.Pos++
|
||||||
|
|
5
main.go
5
main.go
|
@ -1,6 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"relay/game"
|
"relay/game"
|
||||||
"relay/gfx"
|
"relay/gfx"
|
||||||
|
@ -34,6 +35,7 @@ func run() {
|
||||||
Frames: 20,
|
Frames: 20,
|
||||||
}
|
}
|
||||||
sOld := s
|
sOld := s
|
||||||
|
turn := 1
|
||||||
|
|
||||||
for !w.Closed() && !s.GameOver {
|
for !w.Closed() && !s.GameOver {
|
||||||
switch {
|
switch {
|
||||||
|
@ -45,12 +47,15 @@ func run() {
|
||||||
sOld = s
|
sOld = s
|
||||||
}
|
}
|
||||||
case w.Pressed(pixelgl.KeySpace):
|
case w.Pressed(pixelgl.KeySpace):
|
||||||
|
log.Printf("TURN %d", turn)
|
||||||
rs.Animating = true
|
rs.Animating = true
|
||||||
rs.Frame = 0
|
rs.Frame = 0
|
||||||
s = game.UpdateState(s, sOld)
|
s = game.UpdateState(s, sOld)
|
||||||
|
turn++
|
||||||
if s.GameOver {
|
if s.GameOver {
|
||||||
s = game.NewState()
|
s = game.NewState()
|
||||||
sOld = s
|
sOld = s
|
||||||
|
turn = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue