tins2021/level.go

103 lines
1.9 KiB
Go
Raw Normal View History

package tins2021
import (
"math/rand"
"opslag.de/schobers/geom"
)
type Direction int
const (
DirectionDownRight Direction = iota
DirectionDownLeft
DirectionUpLeft
DirectionUpRight
)
type Level struct {
Player geom.Point
Tiles map[geom.Point]*Tile
}
func AdjacentPosition(pos geom.Point, dir Direction) geom.Point {
if pos.Y%2 == 0 {
switch dir {
case DirectionDownRight:
return geom.Pt(pos.X+1, pos.Y+1)
case DirectionDownLeft:
return geom.Pt(pos.X, pos.Y+1)
case DirectionUpLeft:
return geom.Pt(pos.X, pos.Y-1)
case DirectionUpRight:
return geom.Pt(pos.X+1, pos.Y-1)
default:
panic("invalid direction")
}
}
switch dir {
case DirectionDownRight:
return geom.Pt(pos.X, pos.Y+1)
case DirectionDownLeft:
return geom.Pt(pos.X-1, pos.Y+1)
case DirectionUpLeft:
return geom.Pt(pos.X-1, pos.Y-1)
case DirectionUpRight:
return geom.Pt(pos.X, pos.Y-1)
default:
panic("invalid direction")
}
}
func (l Level) CanPlayerMove(dir Direction) (geom.Point, bool) {
towards := AdjacentPosition(l.Player, dir)
from := l.Tiles[l.Player]
to := l.Tiles[towards]
if to == nil {
return geom.ZeroPt, false
}
if dir == DirectionDownRight || dir == DirectionDownLeft {
if !from.Inversed && to.Inversed {
return geom.ZeroPt, false
}
} else {
if from.Inversed && !to.Inversed {
return geom.ZeroPt, false
}
}
return towards, true
}
func (l *Level) MovePlayer(dir Direction) bool {
towards, allowed := l.CanPlayerMove(dir)
if !allowed {
return false
}
l.Tiles[l.Player].Invert()
l.Player = towards
return true
}
func NewRandomLevel() *Level {
f := &Level{
Tiles: map[geom.Point]*Tile{},
Player: geom.Pt(1, 1),
}
for y := 1; y <= 10; y++ {
endX := 10
if y%2 == 0 {
endX--
}
for x := 1; x <= endX; x++ {
f.Tiles[geom.Pt(x, y)] = &Tile{Inversed: rand.Intn(6) == 0}
}
}
return f
}
type Tile struct {
Inversed bool
}
func (t *Tile) Invert() { t.Inversed = !t.Inversed }