Files

51 lines
1.2 KiB
Go

package display
import (
"fmt"
"strings"
)
// BoardFromFEN renders a FEN's piece placement in the server's ASCII board
// format (files on the first and last lines, ranks at both ends of a row,
// "." for an empty square), so RenderBoard colors it the same way.
func BoardFromFEN(fen string) (string, error) {
fields := strings.Fields(fen)
if len(fields) == 0 {
return "", fmt.Errorf("empty FEN")
}
rows := strings.Split(fields[0], "/")
if len(rows) != 8 {
return "", fmt.Errorf("FEN has %d ranks, want 8", len(rows))
}
var b strings.Builder
b.WriteString(" a b c d e f g h\n")
for i, row := range rows {
rank := byte('8' - i)
b.WriteByte(rank)
b.WriteByte(' ')
files := 0
for _, c := range row {
switch {
case c >= '1' && c <= '8':
for n := 0; n < int(c-'0'); n++ {
b.WriteString(". ")
}
files += int(c - '0')
case strings.ContainsRune("pnbrqkPNBRQK", c):
b.WriteRune(c)
b.WriteByte(' ')
files++
default:
return "", fmt.Errorf("invalid FEN character %q", c)
}
}
if files != 8 {
return "", fmt.Errorf("rank %c has %d files, want 8", rank, files)
}
b.WriteByte(rank)
b.WriteByte('\n')
}
b.WriteString(" a b c d e f g h")
return b.String(), nil
}