rename bots to racers
This commit is contained in:
parent
d70dbd438c
commit
6e7ac9c1ba
16
game/ai.go
16
game/ai.go
|
@ -2,7 +2,7 @@ package game
|
|||
|
||||
func chooseCommand(s State, teamID int) command {
|
||||
t := s.Teams[teamID]
|
||||
h := ActiveBot(t)
|
||||
h := ActiveRacer(t)
|
||||
if collide(h.Position.Pos+1, h.Position.Lane, s) != nil {
|
||||
if h.Position.Lane <= t.Lane && h.Position.Lane < NumLanes-1 {
|
||||
return left
|
||||
|
@ -10,17 +10,17 @@ func chooseCommand(s State, teamID int) command {
|
|||
return right
|
||||
}
|
||||
|
||||
var nextBot *Bot
|
||||
for i, b := range t.Bots {
|
||||
var nextRacer *Racer
|
||||
for i, b := range t.Racers {
|
||||
if b.ID == h.ID+1 {
|
||||
nextBot = &t.Bots[i]
|
||||
nextRacer = &t.Racers[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if nextBot != nil {
|
||||
if h.Position.Lane != nextBot.Position.Lane {
|
||||
if abs(nextBot.Position.Pos-h.Position.Pos) < h.v {
|
||||
if nextRacer != nil {
|
||||
if h.Position.Lane != nextRacer.Position.Lane {
|
||||
if abs(nextRacer.Position.Pos-h.Position.Pos) < h.v {
|
||||
return slowDown
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ func smartChooseHelper(s State, teamID int, depth int) command {
|
|||
func score(s State, teamID int, depth int) int {
|
||||
if depth == 0 {
|
||||
t := s.Teams[teamID]
|
||||
b := ActiveBot(t)
|
||||
b := ActiveRacer(t)
|
||||
if b == nil {
|
||||
return 0
|
||||
}
|
||||
|
|
|
@ -16,36 +16,36 @@ func doCommand(cmd command, s State, teamID int) State {
|
|||
da := 1
|
||||
//da += rand.Intn(3) - 1
|
||||
|
||||
b := ActiveBot(s.Teams[teamID])
|
||||
if b == nil {
|
||||
r := ActiveRacer(s.Teams[teamID])
|
||||
if r == nil {
|
||||
return s
|
||||
}
|
||||
|
||||
switch cmd {
|
||||
case speedUp:
|
||||
b.a += da
|
||||
*b = accelerate(*b)
|
||||
s = updateBot(s, *b)
|
||||
r.a += da
|
||||
*r = accelerate(*r)
|
||||
s = updateRacer(s, *r)
|
||||
case slowDown:
|
||||
b.a -= da
|
||||
*b = accelerate(*b)
|
||||
s = updateBot(s, *b)
|
||||
r.a -= da
|
||||
*r = accelerate(*r)
|
||||
s = updateRacer(s, *r)
|
||||
case left:
|
||||
b.Position.Lane++
|
||||
s = updateBot(s, *b)
|
||||
r.Position.Lane++
|
||||
s = updateRacer(s, *r)
|
||||
case right:
|
||||
b.Position.Lane--
|
||||
s = updateBot(s, *b)
|
||||
r.Position.Lane--
|
||||
s = updateRacer(s, *r)
|
||||
case clearObstacle:
|
||||
pos := b.Position
|
||||
pos := r.Position
|
||||
pos.Pos++
|
||||
s = removeObstacle(s, pos)
|
||||
b.v = 0
|
||||
s = updateBot(s, *b)
|
||||
r.v = 0
|
||||
s = updateRacer(s, *r)
|
||||
}
|
||||
|
||||
if b := ActiveBot(s.Teams[teamID]); b != nil {
|
||||
s = moveBot(s, *b)
|
||||
if r := ActiveRacer(s.Teams[teamID]); r != nil {
|
||||
s = moveRacer(s, *r)
|
||||
}
|
||||
s = maybePassBaton(s, teamID)
|
||||
|
||||
|
|
88
game/game.go
88
game/game.go
|
@ -13,7 +13,7 @@ func UpdateState(s State, sOld State) State {
|
|||
}
|
||||
|
||||
for _, t := range s.Teams {
|
||||
if b := ActiveBot(t); b != nil && won(*b, s) {
|
||||
if r := ActiveRacer(t); r != nil && won(*r, s) {
|
||||
log.Printf("team %d won", t.id)
|
||||
s.GameOver = true
|
||||
}
|
||||
|
@ -24,47 +24,47 @@ func UpdateState(s State, sOld State) State {
|
|||
|
||||
func maybePassBaton(s State, teamID int) State {
|
||||
t := s.Teams[teamID]
|
||||
h := ActiveBot(t)
|
||||
h := ActiveRacer(t)
|
||||
if h == nil {
|
||||
return s
|
||||
}
|
||||
|
||||
for i, b := range t.Bots {
|
||||
if h.ID >= b.ID || h.Position.Lane != b.Position.Lane {
|
||||
for i, r := range t.Racers {
|
||||
if h.ID >= r.ID || h.Position.Lane != r.Position.Lane {
|
||||
continue
|
||||
}
|
||||
if abs(b.Position.Pos-h.Position.Pos) <= PassDistance {
|
||||
if abs(r.Position.Pos-h.Position.Pos) <= PassDistance {
|
||||
h.v = 0
|
||||
h.a = 0
|
||||
s = updateBot(s, *h)
|
||||
newH := t.Bots[i]
|
||||
s = updateRacer(s, *h)
|
||||
newH := t.Racers[i]
|
||||
newH.a = baseAccel
|
||||
t.Baton.HolderID = newH.ID
|
||||
s = updateTeam(s, t)
|
||||
return updateBot(s, newH)
|
||||
return updateRacer(s, newH)
|
||||
}
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func ActiveBot(t Team) *Bot {
|
||||
for _, b := range t.Bots {
|
||||
if b.ID == t.Baton.HolderID {
|
||||
return &b
|
||||
func ActiveRacer(t Team) *Racer {
|
||||
for _, r := range t.Racers {
|
||||
if r.ID == t.Baton.HolderID {
|
||||
return &r
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateBot(s State, b Bot) State {
|
||||
t := s.Teams[b.TeamID]
|
||||
for i, bb := range t.Bots {
|
||||
if bb.ID == b.ID {
|
||||
bots := append([]Bot{}, t.Bots[:i]...)
|
||||
bots = append(bots, b)
|
||||
bots = append(bots, t.Bots[i+1:]...)
|
||||
t.Bots = bots
|
||||
func updateRacer(s State, r Racer) State {
|
||||
t := s.Teams[r.TeamID]
|
||||
for i, rr := range t.Racers {
|
||||
if rr.ID == r.ID {
|
||||
racers := append([]Racer{}, t.Racers[:i]...)
|
||||
racers = append(racers, r)
|
||||
racers = append(racers, t.Racers[i+1:]...)
|
||||
t.Racers = racers
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -82,14 +82,14 @@ func updateTeam(s State, t Team) State {
|
|||
return s
|
||||
}
|
||||
|
||||
func destroyBot(s State, b Bot) State {
|
||||
// insert obstacle where bot was
|
||||
s.Obstacles = append(s.Obstacles, Obstacle{Position: b.Position})
|
||||
func destroyRacer(s State, r Racer) State {
|
||||
// insert obstacle where racer was
|
||||
s.Obstacles = append(s.Obstacles, Obstacle{Position: r.Position})
|
||||
|
||||
// spawn bot back at starting position
|
||||
b.Position = b.StartPos
|
||||
// spawn racer back at starting position
|
||||
r.Position = r.StartPos
|
||||
|
||||
return updateBot(s, b)
|
||||
return updateRacer(s, r)
|
||||
}
|
||||
|
||||
func removeObstacle(s State, pos Position) State {
|
||||
|
@ -106,8 +106,8 @@ func removeObstacle(s State, pos Position) State {
|
|||
return s
|
||||
}
|
||||
|
||||
func won(b Bot, s State) bool {
|
||||
return b.Position.Pos >= Steps
|
||||
func won(r Racer, s State) bool {
|
||||
return r.Position.Pos >= Steps
|
||||
}
|
||||
|
||||
func gameOver(s State) bool {
|
||||
|
@ -120,16 +120,16 @@ func gameOver(s State) bool {
|
|||
}
|
||||
|
||||
func legalMove(s State, teamID int, cmd command) bool {
|
||||
b := ActiveBot(s.Teams[teamID])
|
||||
if b == nil {
|
||||
r := ActiveRacer(s.Teams[teamID])
|
||||
if r == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
switch cmd {
|
||||
case left:
|
||||
return b.Position.Lane < NumLanes-1
|
||||
return r.Position.Lane < NumLanes-1
|
||||
case right:
|
||||
return b.Position.Lane > 0
|
||||
return r.Position.Lane > 0
|
||||
|
||||
}
|
||||
return true
|
||||
|
@ -150,13 +150,13 @@ type State struct {
|
|||
|
||||
type Team struct {
|
||||
id int
|
||||
Bots []Bot
|
||||
Racers []Racer
|
||||
Baton Baton
|
||||
won bool
|
||||
Lane int
|
||||
}
|
||||
|
||||
type Bot struct {
|
||||
type Racer struct {
|
||||
ID int
|
||||
TeamID int
|
||||
Position Position
|
||||
|
@ -186,22 +186,22 @@ type Obstacle struct {
|
|||
func NewState() State {
|
||||
var teams []Team
|
||||
for i := 0; i < NumTeams; i++ {
|
||||
var bots []Bot
|
||||
for j := 0; j < numBots; j++ {
|
||||
b := Bot{
|
||||
var racers []Racer
|
||||
for j := 0; j < numRacers; j++ {
|
||||
r := Racer{
|
||||
ID: i*NumTeams + j,
|
||||
TeamID: i,
|
||||
StartPos: Position{
|
||||
Lane: i,
|
||||
Pos: j * (Steps / numBots),
|
||||
Pos: j * (Steps / numRacers),
|
||||
},
|
||||
}
|
||||
b.Position = b.StartPos
|
||||
bots = append(bots, b)
|
||||
r.Position = r.StartPos
|
||||
racers = append(racers, r)
|
||||
}
|
||||
teams = append(teams, Team{
|
||||
id: i,
|
||||
Bots: bots,
|
||||
Racers: racers,
|
||||
Baton: Baton{HolderID: i * NumTeams},
|
||||
Lane: i,
|
||||
})
|
||||
|
@ -240,8 +240,8 @@ func randomOpenPosition(ts []Team, os []Obstacle) Position {
|
|||
|
||||
func positionOpen(pos Position, ts []Team, os []Obstacle) bool {
|
||||
for _, t := range ts {
|
||||
for _, b := range t.Bots {
|
||||
if b.Position == pos {
|
||||
for _, r := range t.Racers {
|
||||
if r.Position == pos {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -285,7 +285,7 @@ var (
|
|||
|
||||
const (
|
||||
Steps = 50
|
||||
numBots = 5
|
||||
numRacers = 5
|
||||
NumTeams = 8
|
||||
NumLanes = NumTeams
|
||||
)
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
package game
|
||||
|
||||
func accelerate(b Bot) Bot {
|
||||
if b.a < -MaxA {
|
||||
b.a = -MaxA
|
||||
func accelerate(r Racer) Racer {
|
||||
if r.a < -MaxA {
|
||||
r.a = -MaxA
|
||||
}
|
||||
if b.a > MaxA {
|
||||
b.a = MaxA
|
||||
if r.a > MaxA {
|
||||
r.a = MaxA
|
||||
}
|
||||
|
||||
b.v += b.a
|
||||
if b.v > MaxV {
|
||||
b.v = MaxV
|
||||
r.v += r.a
|
||||
if r.v > MaxV {
|
||||
r.v = MaxV
|
||||
}
|
||||
if b.v < -MaxV {
|
||||
b.v = -MaxV
|
||||
if r.v < -MaxV {
|
||||
r.v = -MaxV
|
||||
}
|
||||
|
||||
return b
|
||||
return r
|
||||
}
|
||||
|
||||
func moveBot(s State, b Bot) State {
|
||||
for i := 0; i < b.v; i++ {
|
||||
if o := collide(b.Position.Pos+1, b.Position.Lane, s); o != nil {
|
||||
return destroyBot(s, b)
|
||||
func moveRacer(s State, r Racer) State {
|
||||
for i := 0; i < r.v; i++ {
|
||||
if o := collide(r.Position.Pos+1, r.Position.Lane, s); o != nil {
|
||||
return destroyRacer(s, r)
|
||||
} else {
|
||||
b.Position.Pos++
|
||||
r.Position.Pos++
|
||||
}
|
||||
}
|
||||
|
||||
s = updateBot(s, b)
|
||||
s = updateRacer(s, r)
|
||||
return s
|
||||
}
|
||||
|
||||
|
@ -39,9 +39,9 @@ func collide(pos, lane int, s State) interface{} {
|
|||
}
|
||||
}
|
||||
for _, t := range s.Teams {
|
||||
for _, b := range t.Bots {
|
||||
if b.Position.Pos == pos && b.Position.Lane == lane {
|
||||
return b
|
||||
for _, r := range t.Racers {
|
||||
if r.Position.Pos == pos && r.Position.Lane == lane {
|
||||
return r
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
34
gfx/gfx.go
34
gfx/gfx.go
|
@ -29,12 +29,12 @@ type context struct {
|
|||
}
|
||||
|
||||
type spriteBank struct {
|
||||
bot pixel.Picture
|
||||
racer pixel.Picture
|
||||
obstacle pixel.Picture
|
||||
}
|
||||
|
||||
func NewSpriteBank() (*spriteBank, error) {
|
||||
bot, err := loadPicture("shuttle.png")
|
||||
racer, err := loadPicture("shuttle.png")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load picture: %w", err)
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ func NewSpriteBank() (*spriteBank, error) {
|
|||
}
|
||||
|
||||
return &spriteBank{
|
||||
bot: bot,
|
||||
racer: racer,
|
||||
obstacle: ob,
|
||||
}, nil
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ func Render(rs RenderState, sOld, sNew game.State, w *pixelgl.Window, sb spriteB
|
|||
tween: float64(rs.Frame) / float64(rs.Frames),
|
||||
w: w,
|
||||
}
|
||||
renderBots(ctx, colors, sb.bot)
|
||||
renderRacers(ctx, colors, sb.racer)
|
||||
renderObstacles(sNew, w, sb.obstacle)
|
||||
|
||||
rs.Frame++
|
||||
|
@ -108,17 +108,17 @@ func renderBackground(w *pixelgl.Window) {
|
|||
}
|
||||
}
|
||||
|
||||
func renderBots(ctx context, colors map[*game.Team]pixel.RGBA, pic pixel.Picture) {
|
||||
func renderRacers(ctx context, colors map[*game.Team]pixel.RGBA, pic pixel.Picture) {
|
||||
for i, t := range ctx.sNew.Teams {
|
||||
c := colors[&ctx.sNew.Teams[i]]
|
||||
for j, bot := range t.Bots {
|
||||
oldBot := ctx.sOld.Teams[i].Bots[j]
|
||||
renderBot(ctx, oldBot, bot, c, pic)
|
||||
for j, racer := range t.Racers {
|
||||
oldRacer := ctx.sOld.Teams[i].Racers[j]
|
||||
renderRacer(ctx, oldRacer, racer, c, pic)
|
||||
}
|
||||
|
||||
oldHolder, newHolder := game.ActiveBot(ctx.sOld.Teams[i]), game.ActiveBot(ctx.sNew.Teams[i])
|
||||
oldPos := lanePos(oldHolder.Position.Pos, oldHolder.Position.Lane, botWidth, ctx.w.Bounds())
|
||||
newPos := lanePos(newHolder.Position.Pos, newHolder.Position.Lane, botWidth, ctx.w.Bounds())
|
||||
oldHolder, newHolder := game.ActiveRacer(ctx.sOld.Teams[i]), game.ActiveRacer(ctx.sNew.Teams[i])
|
||||
oldPos := lanePos(oldHolder.Position.Pos, oldHolder.Position.Lane, racerWidth, ctx.w.Bounds())
|
||||
newPos := lanePos(newHolder.Position.Pos, newHolder.Position.Lane, racerWidth, ctx.w.Bounds())
|
||||
|
||||
pos := pixel.Vec{
|
||||
X: oldPos.X + ctx.tween*(newPos.X-oldPos.X),
|
||||
|
@ -128,12 +128,12 @@ func renderBots(ctx context, colors map[*game.Team]pixel.RGBA, pic pixel.Picture
|
|||
}
|
||||
}
|
||||
|
||||
func renderBot(ctx context, oldBot, bot game.Bot, c pixel.RGBA, pic pixel.Picture) {
|
||||
func renderRacer(ctx context, oldRacer, racer game.Racer, c pixel.RGBA, pic pixel.Picture) {
|
||||
im := imdraw.New(nil)
|
||||
im.Color = c
|
||||
|
||||
oldPos := lanePos(oldBot.Position.Pos, oldBot.Position.Lane, botWidth, ctx.w.Bounds())
|
||||
newPos := lanePos(bot.Position.Pos, bot.Position.Lane, botWidth, ctx.w.Bounds())
|
||||
oldPos := lanePos(oldRacer.Position.Pos, oldRacer.Position.Lane, racerWidth, ctx.w.Bounds())
|
||||
newPos := lanePos(racer.Position.Pos, racer.Position.Lane, racerWidth, ctx.w.Bounds())
|
||||
|
||||
pos := pixel.Vec{
|
||||
X: oldPos.X + ctx.tween*(newPos.X-oldPos.X),
|
||||
|
@ -172,14 +172,14 @@ func renderObstacles(s game.State, w *pixelgl.Window, pic pixel.Picture) {
|
|||
for _, o := range s.Obstacles {
|
||||
//im.Color = colornames.Slategray
|
||||
|
||||
pos := lanePos(o.Position.Pos, o.Position.Lane, botWidth, b)
|
||||
pos := lanePos(o.Position.Pos, o.Position.Lane, racerWidth, b)
|
||||
|
||||
im.Push(pos)
|
||||
|
||||
im.Clear()
|
||||
sprite := pixel.NewSprite(pic, pic.Bounds())
|
||||
sprite.Draw(w, pixel.IM.Moved(pos))
|
||||
//im.Circle(float64(botWidth), 0)
|
||||
//im.Circle(float64(racerWidth), 0)
|
||||
|
||||
im.Draw(w)
|
||||
}
|
||||
|
@ -216,6 +216,6 @@ func teamColors(ts []game.Team) map[*game.Team]pixel.RGBA {
|
|||
}
|
||||
|
||||
const (
|
||||
botWidth float64 = 17
|
||||
racerWidth float64 = 17
|
||||
batonWidth float64 = 12
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue