initial skeleton
This commit is contained in:
commit
bd149c3d5d
86
board.go
Normal file
86
board.go
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
//Board represents main game board
|
||||||
|
type Board struct {
|
||||||
|
board [][]*Tile
|
||||||
|
size int
|
||||||
|
}
|
||||||
|
|
||||||
|
//NewBoard creates a new board instance
|
||||||
|
func NewBoard(size int) *Board {
|
||||||
|
b := make([][]*Tile, size)
|
||||||
|
var colour Colour
|
||||||
|
for i := 0; i < size; i++ {
|
||||||
|
b[i] = make([]*Tile, size)
|
||||||
|
if i < size/2 {
|
||||||
|
colour = Blue
|
||||||
|
} else {
|
||||||
|
colour = Red
|
||||||
|
}
|
||||||
|
for j := 0; j < size; j++ {
|
||||||
|
b[i][j] = &Tile{i, j, true, nil, colour}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &Board{
|
||||||
|
board: b,
|
||||||
|
size: size,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Board) validatePoint(x, y int) bool {
|
||||||
|
if x < 0 || x >= len(b.board) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if y < 0 || y >= len(b.board) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
//GetPiece returns the piece at a given location
|
||||||
|
func (b *Board) GetPiece(x, y int) (*Piece, error) {
|
||||||
|
if !b.validatePoint(x, y) {
|
||||||
|
return nil, errors.New("GetPiece invalid location")
|
||||||
|
}
|
||||||
|
return b.board[x][y].Piece(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//Place a piece on the board; returns false if a piece is already there
|
||||||
|
func (b *Board) Place(x, y int, p *Piece) (bool, error) {
|
||||||
|
if !b.validatePoint(x, y) {
|
||||||
|
return false, errors.New("Place invalid location")
|
||||||
|
}
|
||||||
|
if b.board[x][y].Piece() != nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
err := b.board[x][y].Place(p)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//Remove a piece from a tile
|
||||||
|
func (b *Board) Remove(x, y int) error {
|
||||||
|
if !b.validatePoint(x, y) {
|
||||||
|
return errors.New("Remove invalid location")
|
||||||
|
}
|
||||||
|
b.board[x][y].Remove()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//GetColor returns color of tile
|
||||||
|
func (b *Board) GetColor(x, y int) Colour {
|
||||||
|
return b.board[x][y].Colour()
|
||||||
|
}
|
||||||
|
|
||||||
|
//AddRiver puts a river tile at specified location
|
||||||
|
func (b *Board) AddRiver(x, y int) (bool, error) {
|
||||||
|
if !b.validatePoint(x, y) {
|
||||||
|
return false, errors.New("River invalid location")
|
||||||
|
}
|
||||||
|
b.board[x][y].AddTerrain()
|
||||||
|
return true, nil
|
||||||
|
}
|
63
command.go
Normal file
63
command.go
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var cmdRegxp = regexp.MustCompile("([a-zA-Z])([1-9])(x|-)([a-zA-Z])([1-9])")
|
||||||
|
var ranks = "ABCDEFHI"
|
||||||
|
|
||||||
|
//RawCommand is a game command, converted from algebraic notation
|
||||||
|
type RawCommand struct {
|
||||||
|
srcX int
|
||||||
|
srcY int
|
||||||
|
dstX int
|
||||||
|
dstY int
|
||||||
|
act string
|
||||||
|
}
|
||||||
|
|
||||||
|
//NewRawCommand creates a RawCommand struct from a algebraic notation string
|
||||||
|
func NewRawCommand(cmd string) (*RawCommand, error) {
|
||||||
|
res := cmdRegxp.FindAllString(cmd, -1)
|
||||||
|
if res == nil {
|
||||||
|
return nil, errors.New("error creating command from string")
|
||||||
|
}
|
||||||
|
sx := strings.Index(ranks, res[0])
|
||||||
|
dx := strings.Index(ranks, res[3])
|
||||||
|
sy, err := strconv.Atoi(res[1])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dy, err := strconv.Atoi(res[4])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &RawCommand{sx, sy, dx, dy, res[2]}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *RawCommand) String() string {
|
||||||
|
return fmt.Sprintf("%s%d%s%s%d", string(ranks[c.srcX]), c.srcY, c.act, string(ranks[c.dstX]), c.dstY)
|
||||||
|
}
|
||||||
|
|
||||||
|
//ParsedCommand is a game command after being run through the engine
|
||||||
|
type ParsedCommand struct {
|
||||||
|
srcX int
|
||||||
|
srcY int
|
||||||
|
srcRank string
|
||||||
|
dstX int
|
||||||
|
dstY int
|
||||||
|
dstRank string
|
||||||
|
act string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ParsedCommand) String() string {
|
||||||
|
if c.dstRank != "" {
|
||||||
|
return fmt.Sprintf("%s %s%d %s %s %s%d", c.srcRank, string(ranks[c.srcX]), c.srcY, c.act, c.dstRank, string(ranks[c.dstX]), c.dstY)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s %s%d %s %s %s%d", c.srcRank, string(ranks[c.srcX]), c.srcY, c.act, "empty", string(ranks[c.dstX]), c.dstY)
|
||||||
|
|
||||||
|
}
|
242
game.go
Normal file
242
game.go
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
)
|
||||||
|
|
||||||
|
//GameState is an int representing the current state the game's in
|
||||||
|
type GameState int
|
||||||
|
|
||||||
|
const (
|
||||||
|
gameLobby GameState = iota
|
||||||
|
gameSetup
|
||||||
|
gameTurnRed
|
||||||
|
gameTurnBlue
|
||||||
|
gameWinRed
|
||||||
|
gameWinBlue
|
||||||
|
)
|
||||||
|
|
||||||
|
//Colour reperensents player colour
|
||||||
|
type Colour int
|
||||||
|
|
||||||
|
//Colour consts
|
||||||
|
const (
|
||||||
|
Red Colour = iota
|
||||||
|
Blue
|
||||||
|
NoColour
|
||||||
|
)
|
||||||
|
|
||||||
|
//Game represents general game state
|
||||||
|
type Game struct {
|
||||||
|
board *Board
|
||||||
|
state GameState
|
||||||
|
}
|
||||||
|
|
||||||
|
//NewGame creates a new game and sets the state to lobby
|
||||||
|
func NewGame() *Game {
|
||||||
|
return &Game{
|
||||||
|
board: NewBoard(8),
|
||||||
|
state: gameLobby,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Game) String() string {
|
||||||
|
var board string
|
||||||
|
for i := 0; i < g.board.size; i++ {
|
||||||
|
board = board + "|"
|
||||||
|
for j := 0; j < g.board.size; j++ {
|
||||||
|
board = board + g.board.board[i][j].String()
|
||||||
|
}
|
||||||
|
board = board + "|\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("Status: %v\n%v", g.state, board)
|
||||||
|
}
|
||||||
|
|
||||||
|
//Parse a given RawCommand, return a ParsedCommand or an error
|
||||||
|
func (g *Game) Parse(p Player, cmd *RawCommand) (*ParsedCommand, error) {
|
||||||
|
if g.state != gameTurnRed && g.state != gameTurnBlue {
|
||||||
|
return nil, errors.New("game has not started")
|
||||||
|
}
|
||||||
|
if !g.board.validatePoint(cmd.srcX, cmd.srcY) || !g.board.validatePoint(cmd.dstX, cmd.dstY) {
|
||||||
|
return nil, errors.New("invalid location in command")
|
||||||
|
}
|
||||||
|
if (p.Colour() == Red && g.state != gameTurnRed) || (p.Colour() == Blue && g.state != gameTurnBlue) {
|
||||||
|
return nil, errors.New("not your turn")
|
||||||
|
}
|
||||||
|
start, err := g.board.GetPiece(cmd.srcX, cmd.srcY)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if cmd.act != "-" && cmd.act != "x" {
|
||||||
|
return nil, errors.New("invalid command action")
|
||||||
|
}
|
||||||
|
end, err := g.board.GetPiece(cmd.dstX, cmd.dstY)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if start == nil {
|
||||||
|
return nil, errors.New("empty start piece")
|
||||||
|
}
|
||||||
|
startRank := start.Rank.String()
|
||||||
|
endRank := ""
|
||||||
|
if end != nil {
|
||||||
|
endRank = end.Rank.String()
|
||||||
|
}
|
||||||
|
return &ParsedCommand{cmd.srcX, cmd.srcY, startRank, cmd.dstX, cmd.dstY, endRank, cmd.act}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//Mutate the game state given a ParsedCommand
|
||||||
|
func (g *Game) Mutate(cmd *ParsedCommand) (bool, error) {
|
||||||
|
var res bool
|
||||||
|
var err error
|
||||||
|
switch cmd.act {
|
||||||
|
case "-":
|
||||||
|
res, err = g.move(cmd.srcX, cmd.srcY, cmd.dstX, cmd.dstY)
|
||||||
|
case "x":
|
||||||
|
res, err = g.strike(cmd.srcX, cmd.srcY, cmd.dstX, cmd.dstY)
|
||||||
|
default:
|
||||||
|
return false, errors.New("invalid mutate action")
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if res {
|
||||||
|
if g.state == gameTurnRed {
|
||||||
|
g.state = gameTurnBlue
|
||||||
|
} else if g.state == gameTurnBlue {
|
||||||
|
g.state = gameTurnRed
|
||||||
|
} else {
|
||||||
|
return false, errors.New("bad game state")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetupPiece adds a piece to the board during setup
|
||||||
|
func (g *Game) SetupPiece(x, y int, p *Piece) (bool, error) {
|
||||||
|
if g.state != gameSetup {
|
||||||
|
return false, errors.New("Trying to setup piece when not in setup")
|
||||||
|
}
|
||||||
|
if !g.board.validatePoint(x, y) {
|
||||||
|
return false, errors.New("Invalid location")
|
||||||
|
}
|
||||||
|
if p.Owner != g.board.GetColor(x, y) {
|
||||||
|
return false, errors.New("Can't setup piece on enemy board")
|
||||||
|
}
|
||||||
|
return g.board.Place(x, y, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
//Start start the game
|
||||||
|
func (g *Game) Start() {
|
||||||
|
g.state = gameTurnRed
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Game) move(x, y, s, t int) (bool, error) {
|
||||||
|
startPiece, err := g.board.GetPiece(x, y)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
endPiece, err := g.board.GetPiece(s, t)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if startPiece == nil {
|
||||||
|
return false, errors.New("invalid start piece for move")
|
||||||
|
}
|
||||||
|
if endPiece != nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
res, err := g.board.Place(s, t, startPiece)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if res {
|
||||||
|
err = g.board.Remove(x, y)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Game) strike(x, y, s, t int) (bool, error) {
|
||||||
|
startPiece, err := g.board.GetPiece(x, y)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
endPiece, err := g.board.GetPiece(s, t)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if startPiece == nil {
|
||||||
|
return false, errors.New("invalid start piece for strike")
|
||||||
|
}
|
||||||
|
if endPiece == nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
distance := math.Sqrt(math.Pow(float64(s-x), 2) + math.Pow(float64(t-y), 2))
|
||||||
|
if distance > 1 && startPiece.Rank != 1 {
|
||||||
|
//trying to attack a piece more then 1 square away when not a scout
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
//bombs can't attack
|
||||||
|
if startPiece.Rank == 12 {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
r, err := g.combat(startPiece, endPiece)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
switch r {
|
||||||
|
case -1:
|
||||||
|
//startPiece lost
|
||||||
|
g.board.Remove(x, y)
|
||||||
|
case 0:
|
||||||
|
//tie
|
||||||
|
g.board.Remove(x, y)
|
||||||
|
g.board.Remove(s, t)
|
||||||
|
case 1:
|
||||||
|
//endPiece lost
|
||||||
|
g.board.Remove(s, t)
|
||||||
|
//scouts replace the piece that was destroyed
|
||||||
|
if startPiece.Rank == 1 {
|
||||||
|
g.board.Remove(x, y)
|
||||||
|
g.board.Place(s, t, startPiece)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Game) combat(atk, def *Piece) (int, error) {
|
||||||
|
if atk == nil || def == nil {
|
||||||
|
return 0, errors.New("invalid attacker or defender")
|
||||||
|
}
|
||||||
|
if atk.Hidden {
|
||||||
|
return 0, errors.New("trying to attack with a piece we know nothing about?")
|
||||||
|
}
|
||||||
|
if def.Hidden {
|
||||||
|
return 0, errors.New("defender has not been revealed to us")
|
||||||
|
}
|
||||||
|
//handle special cases first
|
||||||
|
//miner hitting bomb
|
||||||
|
if atk.Rank == 3 && def.Rank == 12 {
|
||||||
|
return 1, nil
|
||||||
|
}
|
||||||
|
//spy hitting marshal
|
||||||
|
if atk.Rank == 0 && def.Rank == 10 {
|
||||||
|
return 1, nil
|
||||||
|
}
|
||||||
|
//normal cases
|
||||||
|
if atk.Rank > def.Rank {
|
||||||
|
return 1, nil
|
||||||
|
} else if atk.Rank == def.Rank {
|
||||||
|
return 0, nil
|
||||||
|
} else {
|
||||||
|
return -1, nil
|
||||||
|
}
|
||||||
|
}
|
59
main.go
Normal file
59
main.go
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
red := NewDummyPlayer(Red)
|
||||||
|
blue := NewDummyPlayer(Blue)
|
||||||
|
game := NewGame()
|
||||||
|
game.state = gameSetup
|
||||||
|
addpiece(game, 0, Blue, 0, 0)
|
||||||
|
addpiece(game, 1, Blue, 0, 1)
|
||||||
|
addpiece(game, 2, Blue, 1, 2)
|
||||||
|
addpiece(game, 3, Blue, 2, 4)
|
||||||
|
addpiece(game, 3, Blue, 1, 3)
|
||||||
|
addpiece(game, 4, Blue, 2, 6)
|
||||||
|
addpiece(game, 5, Blue, 3, 3)
|
||||||
|
addpiece(game, 9, Blue, 0, 6)
|
||||||
|
addpiece(game, 9, Blue, 0, 7)
|
||||||
|
addpiece(game, 0, Blue, 3, 5)
|
||||||
|
addriver(game, 3, 2)
|
||||||
|
addriver(game, 4, 2)
|
||||||
|
addriver(game, 3, 6)
|
||||||
|
addriver(game, 4, 6)
|
||||||
|
addpiece(game, 0, Red, 4, 0)
|
||||||
|
addpiece(game, 1, Red, 4, 1)
|
||||||
|
addpiece(game, 2, Red, 5, 2)
|
||||||
|
addpiece(game, 3, Red, 6, 4)
|
||||||
|
addpiece(game, 3, Red, 5, 3)
|
||||||
|
addpiece(game, 4, Red, 6, 6)
|
||||||
|
addpiece(game, 5, Red, 7, 3)
|
||||||
|
addpiece(game, 9, Red, 4, 5)
|
||||||
|
addpiece(game, 9, Red, 4, 7)
|
||||||
|
addpiece(game, 0, Red, 7, 5)
|
||||||
|
|
||||||
|
fmt.Printf("%v %v\n%v\n", red, blue, game)
|
||||||
|
game.Start()
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func addpiece(game *Game, rank int, c Colour, x int, y int) {
|
||||||
|
res, err := game.SetupPiece(x, y, NewPiece(rank, c))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !res {
|
||||||
|
panic("can't setup")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func addriver(game *Game, x int, y int) {
|
||||||
|
res, err := game.board.AddRiver(x, y)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !res {
|
||||||
|
panic("can't river")
|
||||||
|
}
|
||||||
|
}
|
34
piece.go
Normal file
34
piece.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "strconv"
|
||||||
|
|
||||||
|
//Rank represents the rank of a piece
|
||||||
|
type Rank int
|
||||||
|
|
||||||
|
func (r Rank) String() string {
|
||||||
|
return strconv.Itoa(int(r))
|
||||||
|
}
|
||||||
|
|
||||||
|
//Piece :game piece
|
||||||
|
type Piece struct {
|
||||||
|
Rank Rank
|
||||||
|
Owner Colour
|
||||||
|
Hidden bool
|
||||||
|
}
|
||||||
|
|
||||||
|
//NewPiece creates a new piece
|
||||||
|
func NewPiece(r int, o Colour) *Piece {
|
||||||
|
return &Piece{
|
||||||
|
Rank: Rank(r),
|
||||||
|
Owner: o,
|
||||||
|
Hidden: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//NewHiddenPiece creates a new hidden piece
|
||||||
|
func NewHiddenPiece(o Colour) *Piece {
|
||||||
|
return &Piece{
|
||||||
|
Owner: o,
|
||||||
|
Hidden: true,
|
||||||
|
}
|
||||||
|
}
|
35
player.go
Normal file
35
player.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
//Player represents a player of the game
|
||||||
|
type Player interface {
|
||||||
|
ID() int
|
||||||
|
Colour() Colour
|
||||||
|
}
|
||||||
|
|
||||||
|
//DummyPlayer is the simplest implementation of a player
|
||||||
|
type DummyPlayer struct {
|
||||||
|
id Colour
|
||||||
|
}
|
||||||
|
|
||||||
|
//ID returns player ID
|
||||||
|
func (d *DummyPlayer) ID() int {
|
||||||
|
return int(d.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
//Colour returns player colour (same as ID)
|
||||||
|
func (d *DummyPlayer) Colour() Colour {
|
||||||
|
return d.id
|
||||||
|
}
|
||||||
|
|
||||||
|
//NewDummyPlayer creates a new player
|
||||||
|
func NewDummyPlayer(i Colour) *DummyPlayer {
|
||||||
|
return &DummyPlayer{i}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DummyPlayer) String() string {
|
||||||
|
if d.id == Red {
|
||||||
|
return "Red Player"
|
||||||
|
} else {
|
||||||
|
return "Blue Player"
|
||||||
|
}
|
||||||
|
}
|
103
tile.go
Normal file
103
tile.go
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
//Tile represents a spot on the board
|
||||||
|
type Tile struct {
|
||||||
|
x int
|
||||||
|
y int
|
||||||
|
passable bool
|
||||||
|
entity *Piece
|
||||||
|
colour Colour
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tile) String() string {
|
||||||
|
icon := "?"
|
||||||
|
if !t.passable {
|
||||||
|
icon = "X"
|
||||||
|
} else if t.entity != nil {
|
||||||
|
if !t.entity.Hidden {
|
||||||
|
icon = t.entity.Rank.String()
|
||||||
|
} else {
|
||||||
|
icon = "O"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
icon = " "
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("|%v|", icon)
|
||||||
|
}
|
||||||
|
|
||||||
|
//Place a piece on the tile
|
||||||
|
func (t *Tile) Place(p *Piece) error {
|
||||||
|
if p == nil {
|
||||||
|
return errors.New("tried to place nil piece")
|
||||||
|
}
|
||||||
|
if !t.passable {
|
||||||
|
return errors.New("tile not passable")
|
||||||
|
}
|
||||||
|
if t.entity != nil {
|
||||||
|
return errors.New("entity already present")
|
||||||
|
}
|
||||||
|
t.entity = p
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//Remove the piece from a tile
|
||||||
|
func (t *Tile) Remove() {
|
||||||
|
t.entity = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//Empty returns true if tile is empty
|
||||||
|
func (t *Tile) Empty() bool {
|
||||||
|
return t.entity == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//Team returns the team of the piece currently occupying it, or 0
|
||||||
|
func (t *Tile) Team() Colour {
|
||||||
|
if t.entity != nil {
|
||||||
|
return t.entity.Owner
|
||||||
|
}
|
||||||
|
return NoColour
|
||||||
|
}
|
||||||
|
|
||||||
|
//Occupied returns true if the tile is currently occupied
|
||||||
|
func (t *Tile) Occupied() bool {
|
||||||
|
return t.entity != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//Piece returns the current Piece if any
|
||||||
|
func (t *Tile) Piece() *Piece {
|
||||||
|
return t.entity
|
||||||
|
}
|
||||||
|
|
||||||
|
//Passable returns if the tile is passable
|
||||||
|
func (t *Tile) Passable() bool {
|
||||||
|
return t.passable
|
||||||
|
}
|
||||||
|
|
||||||
|
//Colour returns the tile colour
|
||||||
|
func (t *Tile) Colour() Colour {
|
||||||
|
return t.colour
|
||||||
|
}
|
||||||
|
|
||||||
|
//X returns tile X position
|
||||||
|
func (t *Tile) X() int {
|
||||||
|
return t.x
|
||||||
|
}
|
||||||
|
|
||||||
|
//Y returns tile y position
|
||||||
|
func (t *Tile) Y() int {
|
||||||
|
return t.y
|
||||||
|
}
|
||||||
|
|
||||||
|
//AddTerrain adds specified terrain to position
|
||||||
|
func (t *Tile) AddTerrain() bool {
|
||||||
|
if t.entity != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
t.passable = false
|
||||||
|
return true
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user