2019-01-15 18:03:52 +00:00
|
|
|
package soko
|
|
|
|
|
|
|
|
import (
|
|
|
|
"opslag.de/schobers/geom"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Level struct {
|
2019-01-16 06:33:04 +00:00
|
|
|
Width int
|
|
|
|
Height int
|
|
|
|
|
2019-01-15 18:51:57 +00:00
|
|
|
Tiles []TileType
|
2019-01-15 18:03:52 +00:00
|
|
|
Entities []EntityType
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l Level) IdxToPos(i int) geom.Point { return geom.Pt(i%l.Width, i/l.Width) }
|
|
|
|
|
|
|
|
func (l Level) PosToIdx(p geom.Point) int {
|
|
|
|
if p.X < 0 || p.Y < 0 || p.X >= l.Width || p.Y >= l.Height {
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
return p.Y*l.Width + p.X
|
|
|
|
}
|
2019-01-15 20:25:32 +00:00
|
|
|
|
2019-01-16 06:33:04 +00:00
|
|
|
func (l Level) Moves() []Moves {
|
|
|
|
moves := make([]Moves, len(l.Tiles))
|
|
|
|
w := l.Width
|
|
|
|
for y := 0; y < l.Height; y++ {
|
|
|
|
for x := 0; x < w; x++ {
|
|
|
|
var m Moves
|
|
|
|
idx := y*w + x
|
|
|
|
if y > 0 {
|
|
|
|
m.Valid = append(m.Valid, idx-w)
|
|
|
|
m.All[DirectionUp] = idx - w
|
|
|
|
} else {
|
|
|
|
m.All[DirectionUp] = -1
|
|
|
|
}
|
|
|
|
if y < (l.Height - 1) {
|
|
|
|
m.Valid = append(m.Valid, idx+w)
|
|
|
|
m.All[DirectionDown] = idx + w
|
|
|
|
} else {
|
|
|
|
m.All[DirectionDown] = -1
|
|
|
|
}
|
|
|
|
if x > 0 {
|
|
|
|
m.Valid = append(m.Valid, idx-1)
|
|
|
|
m.All[DirectionLeft] = idx - 1
|
|
|
|
} else {
|
|
|
|
m.All[DirectionLeft] = idx - 1
|
|
|
|
}
|
|
|
|
if x < (w - 1) {
|
|
|
|
m.Valid = append(m.Valid, idx+1)
|
|
|
|
m.All[DirectionRight] = idx + 1
|
|
|
|
} else {
|
|
|
|
m.All[DirectionRight] = idx + 1
|
|
|
|
}
|
|
|
|
moves[idx] = m
|
2019-01-15 20:25:32 +00:00
|
|
|
}
|
|
|
|
}
|
2019-01-16 06:33:04 +00:00
|
|
|
return moves
|
|
|
|
}
|
2019-01-15 20:25:32 +00:00
|
|
|
|
2019-01-16 06:33:04 +00:00
|
|
|
func (l Level) MoveIdx(idx int, dir Direction) int {
|
|
|
|
switch dir {
|
|
|
|
case DirectionUp:
|
|
|
|
if idx < l.Width {
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
return idx - l.Width
|
|
|
|
case DirectionRight:
|
|
|
|
if (idx+1)%l.Width == 0 {
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
return idx + 1
|
|
|
|
case DirectionDown:
|
|
|
|
if idx >= (l.Width*l.Height)-l.Width {
|
|
|
|
return -1
|
2019-01-15 20:25:32 +00:00
|
|
|
}
|
2019-01-16 06:33:04 +00:00
|
|
|
return idx + l.Width
|
|
|
|
case DirectionLeft:
|
|
|
|
if idx%l.Width == 0 {
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
return idx - 1
|
2019-01-15 20:25:32 +00:00
|
|
|
}
|
2019-01-16 06:33:04 +00:00
|
|
|
return -1
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l Level) Size() int { return l.Width * l.Height }
|
|
|
|
|
|
|
|
func (l Level) State() State {
|
|
|
|
return NewState(l)
|
2019-01-15 20:25:32 +00:00
|
|
|
}
|