51 lines
1.2 KiB
Go
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
|
|
}
|