golang-chess/game.go

100 lines
1.9 KiB
Go

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)))
}