Data update
This commit is contained in:
parent
4bb20c9b71
commit
cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions
|
|
@ -0,0 +1,2 @@
|
|||
(require 'chess)
|
||||
(chess-pos-to-fen (chess-fischer-random-position))
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
-- Seed the random number generator with the current system time
|
||||
math.randomseed(os.time())
|
||||
|
||||
-- Define a `Helper` table to store utility functions
|
||||
local Helper = {}
|
||||
|
||||
-- Create a 1D table (array) filled with the same value
|
||||
--- @param len number number of elements
|
||||
--- @param val any value to fill each element with
|
||||
function Helper.newFilledTable(len, val)
|
||||
local t = {}
|
||||
|
||||
for i = 1, len do
|
||||
t[i] = val
|
||||
end
|
||||
|
||||
return t
|
||||
end
|
||||
|
||||
-- Create a 2D table (rows x cols) initialized with a given value
|
||||
---@param rows number number of rows
|
||||
---@param cols number number of columns
|
||||
---@param init any initial value for each cell
|
||||
function Helper.new2D(rows, cols, init)
|
||||
local b = {}
|
||||
|
||||
for r = 1, rows do
|
||||
b[r] = {}
|
||||
for c = 1, cols do
|
||||
b[r][c] = init
|
||||
end
|
||||
end
|
||||
|
||||
return b
|
||||
end
|
||||
|
||||
-- Compare two tables element by element for equality
|
||||
-- Works only for flat 1D arrays
|
||||
function Helper.tablesEqual(tbl1, tbl2)
|
||||
if #tbl1 ~= #tbl2 then
|
||||
error("Tables must have equal length")
|
||||
end
|
||||
if #tbl1 == 0 and #tbl2 == 0 then
|
||||
return true
|
||||
end
|
||||
|
||||
for i = 1, #tbl1 do
|
||||
if tbl1[i] ~= tbl2[i] then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-- Initialise an 8x8 chess board (empty, filled with nils)
|
||||
local board = Helper.new2D(8, 8, nil)
|
||||
|
||||
-- Place white and black kings randomly on the board
|
||||
-- Ensures:
|
||||
-- 1. They are not on the same square
|
||||
-- 2. They are not adjacent (Chebyshev distance > 1)
|
||||
local function placeKings(board)
|
||||
local attempts = 0
|
||||
|
||||
while true do
|
||||
attempts = attempts + 1
|
||||
if attempts > 10000 then
|
||||
error("Failed to place kings after many attempts")
|
||||
end
|
||||
|
||||
-- Random row and column for each king
|
||||
local wr = math.random(1, 8)
|
||||
local wc = math.random(1, 8)
|
||||
local br = math.random(1, 8)
|
||||
local bc = math.random(1, 8)
|
||||
local skip1 = false
|
||||
local skip2 = false
|
||||
|
||||
-- Ensure kings are not on the same square
|
||||
if wr == br and wc == bc then
|
||||
skip1 = true
|
||||
end
|
||||
|
||||
if not skip1 then
|
||||
-- Check Chebyshev distance (max of row/col difference)
|
||||
local dr = math.abs(wr-br)
|
||||
local dc = math.abs(wc-bc)
|
||||
local chebyshev = (dr > dc) and dr or dc
|
||||
|
||||
-- Skip if kings are adjacent
|
||||
if chebyshev <= 1 then
|
||||
skip2 = true
|
||||
end
|
||||
|
||||
-- Place kings if squares are empty and valid
|
||||
if not skip2 then
|
||||
if not board[wr][wc] and not board[br][bc] then
|
||||
board[wr][wc] = "K" -- White king
|
||||
board[br][bc] = "k" -- Black king
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Populate the board with a given set of pieces
|
||||
---@param board table board
|
||||
---@param pieces string string of piece characters (e.g. "PPPPPPPP")
|
||||
---@param isPawn boolean boolean, true if placing pawns (to avoid ranks 1 and 8)
|
||||
local function populate(board, pieces, isPawn)
|
||||
local piecesAmount = #pieces
|
||||
|
||||
for i = 1, piecesAmount do
|
||||
local pieceChar = pieces:sub(i, i)
|
||||
local attempts = 0
|
||||
|
||||
while true do
|
||||
attempts = attempts + 1
|
||||
if attempts > 5000 then
|
||||
error("Failed to place piece "..pieceChar)
|
||||
end
|
||||
|
||||
-- Choose a random square
|
||||
local r = math.random(1, 8)
|
||||
local c = math.random(1, 8)
|
||||
|
||||
if board[r][c] then
|
||||
-- Skip if already occupied
|
||||
else
|
||||
-- Prevent pawns on promotion ranks (1 or 8)
|
||||
if isPawn and (r == 1 or r == 8) then
|
||||
else
|
||||
board[r][c] = pieceChar
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Convert the board into Forsyth-Edwards Notation (FEN)
|
||||
-- Only encodes piece placement and default values for side-to-move, castling, etc.
|
||||
local function toFENFormat(board)
|
||||
local result = ""
|
||||
|
||||
-- Loop through ranks 8 to 1 (FEN goes top-down)
|
||||
for r = 8, 1, -1 do
|
||||
local emptyCount = 0
|
||||
|
||||
for c = 1, 8 do
|
||||
local row = board[r]
|
||||
local ch = row and row[c]
|
||||
|
||||
if not ch then
|
||||
-- Count consecutive empty squares
|
||||
emptyCount = emptyCount + 1
|
||||
else
|
||||
-- Insert number for empty squares, then piece
|
||||
if emptyCount > 0 then
|
||||
result = result .. tostring(emptyCount)
|
||||
emptyCount = 0
|
||||
end
|
||||
result = result .. tostring(ch)
|
||||
end
|
||||
end
|
||||
|
||||
-- Handle trailing empty squares in row
|
||||
if emptyCount > 0 then
|
||||
result = result .. tostring(emptyCount)
|
||||
end
|
||||
|
||||
-- Add rank separator except for last row
|
||||
if r > 1 then
|
||||
result = result .. "/"
|
||||
end
|
||||
end
|
||||
|
||||
-- Append default FEN suffix ("w - - 0 1")
|
||||
return result .. " w - - 0 1"
|
||||
end
|
||||
|
||||
-- Main function --
|
||||
|
||||
placeKings(board)
|
||||
populate(board, "PPPPPPPP", true)
|
||||
populate(board, "pppppppp", true)
|
||||
populate(board, "RNBQBNR", false)
|
||||
populate(board, "rnbqbnr", false)
|
||||
|
||||
print(toFENFormat(board))
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
import rand
|
||||
import math
|
||||
|
||||
const nul = u8(0)
|
||||
|
||||
struct Game {
|
||||
mut:
|
||||
grid [][]u8 = [][]u8{len: 8, init: []u8{len: 8, init: nul}}
|
||||
}
|
||||
|
||||
fn (mut gme Game) create_fen() string {
|
||||
gme.place_kings()
|
||||
gme.place_pieces("PPPPPPPP", true)
|
||||
gme.place_pieces("pppppppp", true)
|
||||
gme.place_pieces("RNBQBNR", false)
|
||||
gme.place_pieces("rnbqbnr", false)
|
||||
return gme.to_fen()
|
||||
}
|
||||
|
||||
fn (mut gme Game) place_kings() {
|
||||
for {
|
||||
r1 := rand.intn(8) or {0}
|
||||
c1 := rand.intn(8) or {0}
|
||||
r2 := rand.intn(8) or {0}
|
||||
c2 := rand.intn(8) or {0}
|
||||
if r1 != r2 && math.abs(r1 - r2) > 1 && math.abs(c1 - c2) > 1 {
|
||||
gme.grid[r1][c1] = `K`
|
||||
gme.grid[r2][c2] = `k`
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut gme Game) place_pieces(pieces string, is_pawn bool) {
|
||||
num_to_place := rand.intn(pieces.len) or {0}
|
||||
mut rir, mut cir := 0, 0
|
||||
for nal in 0 .. num_to_place {
|
||||
rir = 0
|
||||
cir = 0
|
||||
for {
|
||||
rir = rand.intn(8) or {0}
|
||||
cir = rand.intn(8) or {0}
|
||||
if gme.grid[rir][cir] == nul && !(is_pawn && (rir == 0 || rir == 7)) { break }
|
||||
}
|
||||
gme.grid[rir][cir] = pieces[nal]
|
||||
}
|
||||
}
|
||||
|
||||
fn (gme Game) to_fen() string {
|
||||
mut fen := ""
|
||||
mut count_empty := 0
|
||||
for rir in 0 .. 8 {
|
||||
for cir in 0 .. 8 {
|
||||
ch := gme.grid[rir][cir]
|
||||
print(if ch == nul { "." } else { ch.ascii_str() } + " ")
|
||||
if ch == nul { count_empty++ }
|
||||
else {
|
||||
if count_empty > 0 {
|
||||
fen += count_empty.str()
|
||||
count_empty = 0
|
||||
}
|
||||
fen += ch.ascii_str()
|
||||
}
|
||||
}
|
||||
if count_empty > 0 {
|
||||
fen += count_empty.str()
|
||||
count_empty = 0
|
||||
}
|
||||
fen += "/"
|
||||
println("")
|
||||
}
|
||||
fen += " w - - 0 1"
|
||||
return fen
|
||||
}
|
||||
|
||||
fn main() {
|
||||
mut game := Game{}
|
||||
println(game.create_fen())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue