can start a game
This commit is contained in:
parent
32e7fa3278
commit
6c356c9731
@ -47,7 +47,7 @@ func TestNewBoard(t *testing.T) {
|
||||
|
||||
func TestGetPiece(t *testing.T) {
|
||||
b := NewBoard(4)
|
||||
p := NewPiece(2, Red)
|
||||
p := NewPieceFromInt(2, Red)
|
||||
b.board[0][0].entity = p
|
||||
np, err := b.GetPiece(9, 9)
|
||||
if err == nil {
|
||||
@ -68,7 +68,7 @@ func TestGetPiece(t *testing.T) {
|
||||
|
||||
func TestPlace(t *testing.T) {
|
||||
b := NewBoard(4)
|
||||
p := NewPiece(2, Red)
|
||||
p := NewPieceFromInt(2, Red)
|
||||
res, err := b.Place(8, 9, p)
|
||||
if err == nil {
|
||||
t.Errorf("able to place in invalid location")
|
||||
@ -94,7 +94,7 @@ func TestPlace(t *testing.T) {
|
||||
|
||||
func TestRemove(t *testing.T) {
|
||||
b := NewBoard(4)
|
||||
p := NewPiece(2, Red)
|
||||
p := NewPieceFromInt(2, Red)
|
||||
|
||||
res, err := b.Place(0, 0, p)
|
||||
if err != nil {
|
||||
|
51
colour_enumer.go
Normal file
51
colour_enumer.go
Normal file
@ -0,0 +1,51 @@
|
||||
// Code generated by "enumer -type=Colour"; DO NOT EDIT.
|
||||
|
||||
//
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const _ColourName = "RedBlueNoColour"
|
||||
|
||||
var _ColourIndex = [...]uint8{0, 3, 7, 15}
|
||||
|
||||
func (i Colour) String() string {
|
||||
if i < 0 || i >= Colour(len(_ColourIndex)-1) {
|
||||
return fmt.Sprintf("Colour(%d)", i)
|
||||
}
|
||||
return _ColourName[_ColourIndex[i]:_ColourIndex[i+1]]
|
||||
}
|
||||
|
||||
var _ColourValues = []Colour{0, 1, 2}
|
||||
|
||||
var _ColourNameToValueMap = map[string]Colour{
|
||||
_ColourName[0:3]: 0,
|
||||
_ColourName[3:7]: 1,
|
||||
_ColourName[7:15]: 2,
|
||||
}
|
||||
|
||||
// ColourString retrieves an enum value from the enum constants string name.
|
||||
// Throws an error if the param is not part of the enum.
|
||||
func ColourString(s string) (Colour, error) {
|
||||
if val, ok := _ColourNameToValueMap[s]; ok {
|
||||
return val, nil
|
||||
}
|
||||
return 0, fmt.Errorf("%s does not belong to Colour values", s)
|
||||
}
|
||||
|
||||
// ColourValues returns all values of the enum
|
||||
func ColourValues() []Colour {
|
||||
return _ColourValues
|
||||
}
|
||||
|
||||
// IsAColour returns "true" if the value is listed in the enum definition. "false" otherwise
|
||||
func (i Colour) IsAColour() bool {
|
||||
for _, v := range _ColourValues {
|
||||
if i == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
@ -8,7 +8,7 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var cmdRegxp = regexp.MustCompile("([a-zA-Z])([1-9])(x|-)([a-zA-Z])([1-9])")
|
||||
var cmdRegxp = regexp.MustCompile("([a-zA-Z])([0-9])(x|-)([a-zA-Z])([0-9])")
|
||||
var ranks = "ABCDEFHIJKLMNOPQRSTUVWXYZ"
|
||||
|
||||
//RawCommand is a game command, converted from algebraic notation
|
||||
|
@ -17,6 +17,7 @@ func TestNewRawCommand(t *testing.T) {
|
||||
}{
|
||||
{"A1xC3", true, 0, 1, 2, 3, "x"},
|
||||
{"d7-d1", true, 3, 7, 3, 1, "-"},
|
||||
{"c0-c1", true, 2, 0, 2, 1, "-"},
|
||||
{"AA-k3", false, 0, 0, 0, 0, ""},
|
||||
{"a1/b4", false, 0, 0, 0, 0, ""},
|
||||
}
|
||||
|
18
game.go
18
game.go
@ -19,6 +19,7 @@ const (
|
||||
)
|
||||
|
||||
//Colour reperensents player colour
|
||||
//go:generate enumer -type=Colour
|
||||
type Colour int
|
||||
|
||||
//Colour consts
|
||||
@ -112,7 +113,7 @@ func (g *Game) Mutate(cmd *ParsedCommand) (bool, error) {
|
||||
return false, errors.New("bad game state")
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
return res, nil
|
||||
}
|
||||
|
||||
//SetupPiece adds a piece to the board during setup
|
||||
@ -120,11 +121,14 @@ 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 p == nil {
|
||||
return false, errors.New("Tried to setup a nil piece")
|
||||
}
|
||||
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 false, fmt.Errorf("Can't setup piece on enemy board: %v != %v", p.Owner, g.board.GetColor(x, y))
|
||||
}
|
||||
return g.board.Place(x, y, p)
|
||||
}
|
||||
@ -208,7 +212,7 @@ func (g *Game) strike(x, y, s, t int) (bool, error) {
|
||||
//endPiece lost
|
||||
g.board.Remove(s, t)
|
||||
//scouts replace the piece that was destroyed
|
||||
if startPiece.Rank == 1 {
|
||||
if startPiece.Rank == Scout {
|
||||
g.board.Remove(x, y)
|
||||
g.board.Place(s, t, startPiece)
|
||||
}
|
||||
@ -228,11 +232,15 @@ func (g *Game) combat(atk, def *Piece) (int, error) {
|
||||
}
|
||||
//handle special cases first
|
||||
//miner hitting bomb
|
||||
if atk.Rank == 3 && def.Rank == 12 {
|
||||
if atk.Rank == Miner && def.Rank == Bomb {
|
||||
return 1, nil
|
||||
}
|
||||
//anyone else hitting bomb
|
||||
if def.Rank == Bomb {
|
||||
return -1, nil
|
||||
}
|
||||
//spy hitting marshal
|
||||
if atk.Rank == 0 && def.Rank == 10 {
|
||||
if atk.Rank == Spy && def.Rank == Marshal {
|
||||
return 1, nil
|
||||
}
|
||||
//normal cases
|
||||
|
133
game_test.go
133
game_test.go
@ -1,29 +1,63 @@
|
||||
package main
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func dummyMiniGame() *Game {
|
||||
func dummyMiniGame() (*Game, error) {
|
||||
g := &Game{
|
||||
board: NewBoard(4),
|
||||
state: gameSetup,
|
||||
}
|
||||
//Setup terrain
|
||||
g.board.AddTerrain(1, 1, 1)
|
||||
g.board.AddTerrain(2, 2, 1)
|
||||
//Setup blue (5 pieces)
|
||||
g.SetupPiece(0, 0, NewPiece(0, Blue))
|
||||
g.SetupPiece(0, 1, NewPiece(1, Blue))
|
||||
g.SetupPiece(0, 2, NewPiece(2, Blue))
|
||||
g.SetupPiece(0, 3, NewPiece(3, Blue))
|
||||
g.SetupPiece(1, 3, NewPiece(4, Blue))
|
||||
//Setup red (5 pieces)
|
||||
g.SetupPiece(3, 0, NewPiece(0, Red))
|
||||
g.SetupPiece(3, 1, NewPiece(1, Red))
|
||||
g.SetupPiece(3, 2, NewPiece(2, Red))
|
||||
g.SetupPiece(3, 3, NewPiece(3, Red))
|
||||
g.SetupPiece(2, 1, NewPiece(4, Red))
|
||||
terrain := []struct {
|
||||
x, y, t int
|
||||
}{
|
||||
{1, 1, 1},
|
||||
{2, 2, 1},
|
||||
}
|
||||
for _, tt := range terrain {
|
||||
res, err := g.board.AddTerrain(tt.x, tt.y, tt.t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !res {
|
||||
return nil, errors.New("Error creating terrain")
|
||||
}
|
||||
}
|
||||
pieces := []struct {
|
||||
x, y int
|
||||
p *Piece
|
||||
}{
|
||||
{0, 0, NewPiece(Flag, Blue)},
|
||||
{3, 0, NewPiece(Spy, Blue)},
|
||||
{2, 0, NewPiece(Captain, Blue)},
|
||||
{3, 1, NewPiece(Marshal, Blue)},
|
||||
{0, 1, NewPiece(Bomb, Blue)},
|
||||
|
||||
return g
|
||||
{1, 2, NewPiece(Flag, Red)},
|
||||
{3, 2, NewPiece(Spy, Red)},
|
||||
{2, 3, NewPiece(Captain, Red)},
|
||||
{0, 2, NewPiece(Marshal, Red)},
|
||||
{0, 3, NewPiece(Bomb, Red)},
|
||||
}
|
||||
for _, tt := range pieces {
|
||||
res, err := g.SetupPiece(tt.x, tt.y, tt.p)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Piece %v,%v:%v", tt.x, tt.y, err)
|
||||
}
|
||||
if !res {
|
||||
return nil, errors.New("error placing dummy piece")
|
||||
}
|
||||
}
|
||||
_, err := g.SetupPiece(0, 0, NewPiece(Flag, Blue))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return g, nil
|
||||
}
|
||||
|
||||
func TestNewGame(t *testing.T) {
|
||||
@ -38,8 +72,8 @@ func TestNewGame(t *testing.T) {
|
||||
|
||||
func TestSetupPiece(t *testing.T) {
|
||||
g := NewGame()
|
||||
p1 := NewPiece(0, Blue)
|
||||
p2 := NewPiece(0, Red)
|
||||
p1 := NewPieceFromInt(0, Blue)
|
||||
p2 := NewPieceFromInt(0, Red)
|
||||
res, err := g.SetupPiece(0, 0, p1)
|
||||
if err == nil || res == true {
|
||||
t.Errorf("Expected to fail setup piece but didn't")
|
||||
@ -57,7 +91,7 @@ func TestSetupPiece(t *testing.T) {
|
||||
if err == nil {
|
||||
t.Error("expected to fail setting up piece in invalid spot")
|
||||
}
|
||||
res, err = g.SetupPiece(4, 0, p2)
|
||||
res, err = g.SetupPiece(4, 5, p2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -75,3 +109,62 @@ func TestStart(t *testing.T) {
|
||||
t.Fatal("expected game to start")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMiniCreation(t *testing.T) {
|
||||
g, err := dummyMiniGame()
|
||||
if err != nil {
|
||||
t.Fatalf("mini game not created: %v", err)
|
||||
}
|
||||
if g.state != gameSetup {
|
||||
t.Fatal("mini game not in right state")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMiniGame1(t *testing.T) {
|
||||
g, err := dummyMiniGame()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !g.Start() {
|
||||
t.Fatal("could not start mini game")
|
||||
}
|
||||
if g.state != gameTurnRed {
|
||||
t.Error("game starting on wrong turn")
|
||||
}
|
||||
r := NewDummyPlayer(Red)
|
||||
b := NewDummyPlayer(Blue)
|
||||
var moves = []struct {
|
||||
input string
|
||||
player Player
|
||||
res bool
|
||||
}{
|
||||
{"c3-b3", r, true},
|
||||
{"c0-c1", b, true},
|
||||
{"d2xd1", r, true},
|
||||
{"c1-d1", b, true},
|
||||
{"b3-c3", r, true},
|
||||
{"d1xd2", b, true},
|
||||
}
|
||||
i := 0
|
||||
for _, tt := range moves {
|
||||
tname := fmt.Sprintf("%v input: %v", i, tt.input)
|
||||
i++
|
||||
t.Run(tname, func(t *testing.T) {
|
||||
raw, err := NewRawCommand(tt.input)
|
||||
if err != nil {
|
||||
t.Fatalf("error creating RawCommand from %v:%v", tt.input, err)
|
||||
}
|
||||
parsed, err := g.Parse(tt.player, raw)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
res, err := g.Mutate(parsed)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if tt.res != res {
|
||||
t.Errorf("Expected command to be %v but was %v", tt.res, res)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
54
main.go
54
main.go
@ -3,43 +3,16 @@ 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()
|
||||
|
||||
//red := NewDummyPlayer(Red)
|
||||
//blue := NewDummyPlayer(Blue)
|
||||
g := NewGame()
|
||||
g.state = gameSetup
|
||||
printboardcolours(g)
|
||||
return
|
||||
}
|
||||
|
||||
func addpiece(game *Game, rank int, c Colour, x int, y int) {
|
||||
res, err := game.SetupPiece(x, y, NewPiece(rank, c))
|
||||
res, err := game.SetupPiece(x, y, NewPieceFromInt(rank, c))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -57,3 +30,18 @@ func addriver(game *Game, x int, y int) {
|
||||
panic("can't river")
|
||||
}
|
||||
}
|
||||
|
||||
func printboardcolours(g *Game) {
|
||||
for i := range g.board.board {
|
||||
for j := range g.board.board[i] {
|
||||
c := "X"
|
||||
if g.board.board[i][j].colour == Red {
|
||||
c = "R"
|
||||
} else if g.board.board[i][j].colour == Blue {
|
||||
c = "B"
|
||||
}
|
||||
fmt.Printf("%v", c)
|
||||
}
|
||||
fmt.Println("")
|
||||
}
|
||||
}
|
||||
|
14
piece.go
14
piece.go
@ -13,6 +13,7 @@ const (
|
||||
Captain
|
||||
General
|
||||
Marshal
|
||||
Bomb
|
||||
)
|
||||
|
||||
//Piece :game piece
|
||||
@ -22,8 +23,8 @@ type Piece struct {
|
||||
Hidden bool
|
||||
}
|
||||
|
||||
//NewPiece creates a new piece
|
||||
func NewPiece(r int, o Colour) *Piece {
|
||||
//NewPieceFromInt creates a new piece
|
||||
func NewPieceFromInt(r int, o Colour) *Piece {
|
||||
return &Piece{
|
||||
Rank: Rank(r),
|
||||
Owner: o,
|
||||
@ -31,6 +32,15 @@ func NewPiece(r int, o Colour) *Piece {
|
||||
}
|
||||
}
|
||||
|
||||
//NewPiece generates a piece by rank
|
||||
func NewPiece(r Rank, o Colour) *Piece {
|
||||
return &Piece{
|
||||
Rank: r,
|
||||
Owner: o,
|
||||
Hidden: false,
|
||||
}
|
||||
}
|
||||
|
||||
//NewHiddenPiece creates a new hidden piece
|
||||
func NewHiddenPiece(o Colour) *Piece {
|
||||
return &Piece{
|
||||
|
@ -7,9 +7,9 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const _RankName = "FlagSpyScoutMinerCaptainGeneralMarshal"
|
||||
const _RankName = "FlagSpyScoutMinerCaptainGeneralMarshalBomb"
|
||||
|
||||
var _RankIndex = [...]uint8{0, 4, 7, 12, 17, 24, 31, 38}
|
||||
var _RankIndex = [...]uint8{0, 4, 7, 12, 17, 24, 31, 38, 42}
|
||||
|
||||
func (i Rank) String() string {
|
||||
if i < 0 || i >= Rank(len(_RankIndex)-1) {
|
||||
@ -18,7 +18,7 @@ func (i Rank) String() string {
|
||||
return _RankName[_RankIndex[i]:_RankIndex[i+1]]
|
||||
}
|
||||
|
||||
var _RankValues = []Rank{0, 1, 2, 3, 4, 5, 6}
|
||||
var _RankValues = []Rank{0, 1, 2, 3, 4, 5, 6, 7}
|
||||
|
||||
var _RankNameToValueMap = map[string]Rank{
|
||||
_RankName[0:4]: 0,
|
||||
@ -28,6 +28,7 @@ var _RankNameToValueMap = map[string]Rank{
|
||||
_RankName[17:24]: 4,
|
||||
_RankName[24:31]: 5,
|
||||
_RankName[31:38]: 6,
|
||||
_RankName[38:42]: 7,
|
||||
}
|
||||
|
||||
// RankString retrieves an enum value from the enum constants string name.
|
||||
|
Loading…
Reference in New Issue
Block a user