1
0
mirror of https://github.com/maaslalani/gambit.git synced 2024-11-28 08:38:36 +02:00

feat: (de)serialize boards

This commit is contained in:
Maas Lalani 2021-11-27 18:02:13 -05:00
parent ec63525eb6
commit a9baeeae24
No known key found for this signature in database
GPG Key ID: F53774FA051C052A
6 changed files with 107 additions and 47 deletions

View File

@ -41,11 +41,78 @@ func (b *Board) Move(from, to string) {
p.Position = toPos
}
func (b *Board) Init(pieces []*Piece) {
for _, piece := range pieces {
p := piece
b.Grid[piece.Position[0]-1][piece.Position[1]-1] = p
// 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 {

8
board.txt Normal file
View File

@ -0,0 +1,8 @@
RNBQKBNR
PPPPPPPP
........
........
........
........
pppppppp
rnbqkbnr

23
board_test.go Normal file
View File

@ -0,0 +1,23 @@
package main
import "testing"
func TestSerialize(t *testing.T) {
positions := `RNBQKB.R
PPPP.PPP
.....N..
....P...
....p...
..n.....
pppp.ppp
r.bqkbnr`
board := Deserialize(positions)
serialized := Serialize(board)
if positions != serialized {
t.Log("want: " + positions)
t.Log("got: " + serialized)
t.Fatal("Board was not equivalent to deserialization and serialization")
}
}

View File

@ -1,15 +1,19 @@
package main
import (
_ "embed"
"log"
"strings"
tea "github.com/charmbracelet/bubbletea"
)
//go:embed board.txt
var initialBoard string
func main() {
m := model{}
m.Board.Init(append(WhitePieces(), BlackPieces()...))
m.Board = *Deserialize(string(initialBoard))
p := tea.NewProgram(m, tea.WithMouseAllMotion())
if err := p.Start(); err != nil {
log.Fatal(err)

View File

@ -83,35 +83,3 @@ func NewPiece(piece piece, position position, color color) *Piece {
Color: color,
}
}
func InitialPieces(color color) []*Piece {
var pieces []*Piece
var (
pawnRank int
backRank int
)
if color == White {
backRank, pawnRank = 1, 2
} else {
backRank, pawnRank = 8, 7
}
for i := 1; i <= 8; i++ {
pieces = append(pieces, NewPiece(Pawn, position{pawnRank, i}, color))
}
for i, p := range []piece{Rook, Knight, Bishop, Queen, King, Bishop, Knight, Rook} {
pieces = append(pieces, NewPiece(p, position{backRank, i + 1}, color))
}
return pieces
}
func BlackPieces() []*Piece {
return InitialPieces(Black)
}
func WhitePieces() []*Piece {
return InitialPieces(White)
}

View File

@ -25,13 +25,3 @@ func TestPosition(t *testing.T) {
}
}
}
func TestInitialPieces(t *testing.T) {
whitePieces := InitialPieces(White)
blackPieces := InitialPieces(Black)
if len(whitePieces) != 16 || len(blackPieces) != 16 {
t.Logf("got %d white pieces", len(whitePieces))
t.Logf("got %d black pieces", len(blackPieces))
t.Fatal("set should have 16 pieces per color")
}
}