Draw initial board

This commit is contained in:
ekzyis 2024-09-18 03:15:24 +02:00
parent e26f553cc6
commit f1ab0c2af4
31 changed files with 246 additions and 0 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

153
chess/board.go Normal file
View File

@ -0,0 +1,153 @@
package chess
import (
"fmt"
"image"
"image/draw"
"image/png"
"log"
"os"
)
type Board struct {
tiles [8][8]*Piece
}
func NewBoard() *Board {
board := &Board{}
board.mustSetPiece(Rook, Light, "a1")
board.mustSetPiece(Knight, Light, "b1")
board.mustSetPiece(Bishop, Light, "c1")
board.mustSetPiece(Queen, Light, "d1")
board.mustSetPiece(King, Light, "e1")
board.mustSetPiece(Bishop, Light, "f1")
board.mustSetPiece(Knight, Light, "g1")
board.mustSetPiece(Rook, Light, "h1")
board.mustSetPiece(Pawn, Light, "a2")
board.mustSetPiece(Pawn, Light, "b2")
board.mustSetPiece(Pawn, Light, "c2")
board.mustSetPiece(Pawn, Light, "d2")
board.mustSetPiece(Pawn, Light, "e2")
board.mustSetPiece(Pawn, Light, "f2")
board.mustSetPiece(Pawn, Light, "g2")
board.mustSetPiece(Pawn, Light, "h2")
board.mustSetPiece(Rook, Dark, "a8")
board.mustSetPiece(Knight, Dark, "b8")
board.mustSetPiece(Bishop, Dark, "c8")
board.mustSetPiece(Queen, Dark, "d8")
board.mustSetPiece(King, Dark, "e8")
board.mustSetPiece(Bishop, Dark, "f8")
board.mustSetPiece(Knight, Dark, "g8")
board.mustSetPiece(Rook, Dark, "h8")
board.mustSetPiece(Pawn, Dark, "a7")
board.mustSetPiece(Pawn, Dark, "b7")
board.mustSetPiece(Pawn, Dark, "c7")
board.mustSetPiece(Pawn, Dark, "d7")
board.mustSetPiece(Pawn, Dark, "e7")
board.mustSetPiece(Pawn, Dark, "f7")
board.mustSetPiece(Pawn, Dark, "g7")
board.mustSetPiece(Pawn, Dark, "h7")
return board
}
func (b *Board) Save(filename string) error {
var (
file *os.File
img *image.RGBA
piece *Piece
bg *image.Uniform
rect image.Rectangle
p = image.Point{0, 0}
err error
)
if file, err = os.Create(filename); err != nil {
return err
}
defer file.Close()
img = image.NewRGBA(image.Rect(0, 0, 1024, 1024))
for yi := 0; yi < 8; yi++ {
for xi := 0; xi < 8; xi++ {
rect = image.Rect(xi*128, yi*128, (xi*128)+128, (yi*128)+128)
bg = image.NewUniform(getTileColor(xi, yi))
draw.Draw(img, rect, bg, p, draw.Src)
piece = b.tiles[xi][yi]
if piece != nil {
draw.Draw(img, rect, piece.Image, p, draw.Over)
}
}
}
return png.Encode(file, img)
}
func (b *Board) SetPiece(name PieceName, color Color, position string) error {
var (
piece *Piece
x int
y int
err error
)
if len(position) != 2 {
return fmt.Errorf("invalid position: %s", position)
}
if piece, err = NewPiece(name, color); err != nil {
return err
}
if x, y, err = getXY(position); err != nil {
return err
}
b.tiles[x][y] = piece
return nil
}
func (b *Board) mustSetPiece(name PieceName, color Color, position string) {
if err := b.SetPiece(name, color, position); err != nil {
log.Fatalf("cannot set piece %s: %v", name, err)
}
}
func getXY(position string) (int, int, error) {
var (
posX rune
posY rune
x int
y int
)
runes := []rune(position)
posX = runes[0]
posY = runes[1]
if posX < 'a' && posX > 'h' {
return -1, -1, fmt.Errorf("invalid posX: %s", position)
}
if posY < '1' && posY > '8' {
return -1, -1, fmt.Errorf("invalid posY: %s", position)
}
// image origin (0,0) is at top-left corner (a8)
x = int(posX - 'a')
y = int('8' - posY)
return x, y, nil
}
func getTileColor(x, y int) Color {
if x%2 == y%2 {
return Light
} else {
return Dark
}
}

73
chess/piece.go Normal file
View File

@ -0,0 +1,73 @@
package chess
import (
"fmt"
"image"
"image/color"
"image/png"
"os"
"golang.org/x/image/draw"
)
type Piece struct {
Name PieceName
Color color.Color
Image image.Image
}
type PieceName string
const (
Pawn PieceName = "p"
Knight PieceName = "n"
Bishop PieceName = "b"
Rook PieceName = "r"
Queen PieceName = "q"
King PieceName = "k"
)
type Color color.Color
var (
Light Color = color.RGBA{240, 217, 181, 255}
Dark Color = color.RGBA{181, 136, 99, 255}
)
func NewPiece(name PieceName, color Color) (*Piece, error) {
var (
colorSuffix string
path string
file *os.File
img image.Image
dst *image.RGBA
err error
)
colorSuffix = "l"
if color == Light {
colorSuffix = "l"
} else if color == Dark {
colorSuffix = "d"
} else {
return nil, fmt.Errorf("invalid color: %v", color)
}
path = fmt.Sprintf("assets/1024px-Chess_%s%st45.svg.png", name, colorSuffix)
if file, err = os.Open(path); err != nil {
return nil, err
}
defer file.Close()
if img, err = png.Decode(file); err != nil {
return nil, err
}
// source image for each piece is 1024x1024 and board is 8x8
// so we need to scale each piece down to 128x128 (1024/8)
dst = image.NewRGBA(image.Rect(0, 0, 128, 128))
draw.CatmullRom.Scale(dst, dst.Rect, img, img.Bounds(), draw.Over, nil)
return &Piece{Name: name, Color: color, Image: dst}, nil
}

5
go.mod Normal file
View File

@ -0,0 +1,5 @@
module github.com/ekzyis/sn-chess
go 1.23.0
require golang.org/x/image v0.20.0

2
go.sum Normal file
View File

@ -0,0 +1,2 @@
golang.org/x/image v0.20.0 h1:7cVCUjQwfL18gyBJOmYvptfSHS8Fb3YUDtfLIZ7Nbpw=
golang.org/x/image v0.20.0/go.mod h1:0a88To4CYVBAHp5FXJm8o7QbUl37Vd85ply1vyD8auM=

13
main.go Normal file
View File

@ -0,0 +1,13 @@
package main
import (
"github.com/ekzyis/sn-chess/chess"
)
func main() {
var (
b = chess.NewBoard()
)
b.Save("board.png")
}