package main import "fmt" type GameResult int const ( GameOngoing GameResult = iota WhiteWins BlackWins Draw ) type Game struct { Board *Board Turn int Over bool Result GameResult MoveNum int } func NewGame() *Game { return &Game{ Board: NewBoard(), Turn: White, Over: false, Result: GameOngoing, MoveNum: 1, } } func (g *Game) MakeMove(input string) (string, error) { if g.Over { return "", fmt.Errorf("game is over") } m, err := g.Board.ParseMove(input) if err != nil { return "", err } s := g.Board.Grid[m.From.Row][m.From.Col] if s.Piece == Empty || s.Color != g.Turn { return "", fmt.Errorf("no %s piece on %s", colorName(g.Turn), algebraic(m.From)) } legalMoves := g.Board.generateLegalMoves(g.Turn) found := false for _, lm := range legalMoves { if lm.From == m.From && lm.To == m.To && lm.Promotion == m.Promotion { found = true break } } if !found { return "", fmt.Errorf("illegal move: %s", input) } g.Board.MoveHistory = append(g.Board.MoveHistory, input) g.Board.applyMove(*m) if g.Turn == White { g.Turn = Black g.MoveNum++ } else { g.Turn = White } oppMoves := g.Board.generateLegalMoves(g.Turn) if len(oppMoves) == 0 { g.Over = true if g.Board.isInCheck(g.Turn) { if g.Turn == White { g.Result = BlackWins } else { g.Result = WhiteWins } } else { g.Result = Draw } } return input, nil } func (g *Game) Render() string { out := g.Board.Display(g.Turn) if g.Over { switch g.Result { case WhiteWins: out += "\n === CHECKMATE! WHITE WINS! ===\n" case BlackWins: out += "\n === CHECKMATE! BLACK WINS! ===\n" case Draw: out += "\n === STALEMATE! DRAW ===\n" } } else { out += fmt.Sprintf("\n Move %d | %s to move\n", g.MoveNum, colorName(g.Turn)) } return out } func algebraic(p Position) string { return string(rune('a'+p.Col)) + string(rune('0'+(8-p.Row))) }