137 lines
2.3 KiB
Go
137 lines
2.3 KiB
Go
package game
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"omctf.ru/block-game-backend/schema"
|
|
"omctf.ru/block-game-backend/utils/xy"
|
|
)
|
|
|
|
type Tile struct {
|
|
Kind string `json:"kind"`
|
|
Pos xy.Point `json:"pos"`
|
|
Data json.RawMessage `json:"data"`
|
|
}
|
|
|
|
type Tiles struct {
|
|
size int
|
|
Tiles []Tile
|
|
}
|
|
|
|
func NewTiles(size int, tiles []schema.Tile) Tiles {
|
|
var result Tiles
|
|
result.size = size
|
|
for _, tile := range tiles {
|
|
result.Tiles = append(result.Tiles, Tile{
|
|
Kind: tile.Kind,
|
|
Pos: tile.Pos,
|
|
Data: tile.Data,
|
|
})
|
|
}
|
|
return result
|
|
}
|
|
|
|
func (t *Tiles) Size() int {
|
|
return t.size
|
|
}
|
|
|
|
func (t *Tiles) inBounds(p xy.Point) bool {
|
|
return p.X >= 0 && p.Y >= 0 && p.X < t.size && p.Y < t.size
|
|
}
|
|
|
|
func (t *Tiles) GetPlayerTile() (*Tile, error) {
|
|
playerIdx, err := t.GetTheOnlyIdx("player")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if playerIdx == -1 {
|
|
return nil, fmt.Errorf("player not found")
|
|
}
|
|
return &t.Tiles[playerIdx], nil
|
|
}
|
|
|
|
func (t *Tiles) Index(tile *Tile) int {
|
|
for i := range t.Tiles {
|
|
if &t.Tiles[i] == tile {
|
|
return i
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
|
|
func (t *Tiles) GetTheOnlyIdx(kind string) (int, error) {
|
|
result := -1
|
|
for i, tile := range t.Tiles {
|
|
if tile.Kind == kind {
|
|
if result != -1 {
|
|
return -1, ErrDuplicateType{}
|
|
}
|
|
result = i
|
|
}
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func (t *Tiles) GetTheOnly(kind string) (*Tile, error) {
|
|
i, err := t.GetTheOnlyIdx(kind)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if i == -1 {
|
|
return nil, nil
|
|
}
|
|
return &t.Tiles[i], nil
|
|
}
|
|
|
|
type TilesAt []*Tile
|
|
|
|
func (t *Tiles) At(p xy.Point) TilesAt {
|
|
var result TilesAt
|
|
for i := range t.Tiles {
|
|
if t.Tiles[i].Pos == p {
|
|
result = append(result, &t.Tiles[i])
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
type ErrDuplicateType struct{}
|
|
|
|
func (e ErrDuplicateType) Error() string {
|
|
return "multiple tiles of the requested type"
|
|
}
|
|
|
|
func (t TilesAt) Has(kind string) bool {
|
|
for _, tile := range t {
|
|
if tile.Kind == kind {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (t TilesAt) GetTheOnlyIdx(kind string) (int, error) {
|
|
result := -1
|
|
for i, tile := range t {
|
|
if tile.Kind == kind {
|
|
if result != -1 {
|
|
return -1, ErrDuplicateType{}
|
|
}
|
|
result = i
|
|
}
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func (t TilesAt) GetTheOnly(kind string) (*Tile, error) {
|
|
i, err := t.GetTheOnlyIdx(kind)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if i == -1 {
|
|
return nil, nil
|
|
}
|
|
return t[i], nil
|
|
}
|