1
0
mirror of https://github.com/maaslalani/gambit.git synced 2025-01-03 22:52:10 +02:00
gambit/board.go
2021-11-27 18:13:04 -05:00

157 lines
3.2 KiB
Go

package main
import (
"fmt"
"strings"
)
const (
dimensions = 8
firstRow = 0
firstCol = 0
lastRow = dimensions - 1
lastCol = dimensions - 1
)
const (
header = "\n ┌───┬───┬───┬───┬───┬───┬───┬───┐ \n"
middle = "\n ├───┼───┼───┼───┼───┼───┼───┼───┤ \n"
footer = "\n └───┴───┴───┴───┴───┴───┴───┴───┘ \n"
footerLabels = "\n A B C D E F G H \n"
divider = " │ "
)
type Board struct {
Grid [dimensions][dimensions]*Piece
flipped bool
}
func (b *Board) Move(from, to string) {
fromPos, toPos := ToPosition(from), ToPosition(to)
p := b.Grid[fromPos[0]-1][fromPos[1]-1]
if p == nil {
return
}
cp := b.Grid[toPos[0]-1][toPos[1]-1]
if cp != nil {
// TODO: Capture
}
b.Grid[fromPos[0]-1][fromPos[1]-1] = nil
b.Grid[toPos[0]-1][toPos[1]-1] = p
p.Position = toPos
}
// Deserialize sets the board with pieces from a serialized format
// usually read from a file. Example: board.txt
func Deserialize(board string) *Board {
var b Board
lines := strings.Split(board, "\n")[:8]
for row, line := range lines {
for col, square := range line {
if square == '.' {
b.Grid[row][col] = nil
continue
}
var piece = &Piece{}
if square < 97 {
piece.Color = White
} else {
piece.Color = Black
}
switch strings.ToUpper(string(square)) {
case "B":
piece.Type = Bishop
case "K":
piece.Type = King
case "N":
piece.Type = Knight
case "P":
piece.Type = Pawn
case "Q":
piece.Type = Queen
case "R":
piece.Type = Rook
}
piece.Position = position{row, col}
b.Grid[row][col] = piece
}
}
return &b
}
// Serialize returns a string of the current board
// usually read from a file. Example: boards/board.1
func Serialize(b *Board) string {
var sb strings.Builder
for _, rank := range b.Grid {
for _, piece := range rank {
if piece == nil {
sb.WriteString(".")
continue
}
var sp string
switch piece.Type {
case Bishop:
sp = "B"
case King:
sp = "K"
case Knight:
sp = "N"
case Pawn:
sp = "P"
case Queen:
sp = "Q"
case Rook:
sp = "R"
}
if piece.Color == Black {
sp = strings.ToLower(sp)
}
sb.WriteString(sp)
}
sb.WriteString("\n")
}
return strings.TrimSuffix(sb.String(), "\n")
}
func FileToColumn(file string) int {
if len(file) < 1 {
return 0
}
return int([]rune(strings.ToUpper(file))[0] - 64)
}
func (b *Board) String() string {
var s = header
var ranks []int
if b.flipped {
ranks = []int{0, 1, 2, 3, 4, 5, 6, 7}
} else {
ranks = []int{7, 6, 5, 4, 3, 2, 1, 0}
}
for row, rank := range ranks {
for file := firstCol; file < dimensions; file++ {
if file == firstCol {
s += faintStyle.Render(fmt.Sprintf(" %d ", rank+1))
}
s += divider
if b.Grid[rank][file] == nil {
s += " "
} else {
s += b.Grid[rank][file].String()
}
if file == lastCol {
s += divider
}
}
if row != lastRow {
s += middle
}
}
return s + footer + faintStyle.Render(footerLabels)
}