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 }