Skip to content

Commit

Permalink
feat: started board representation (wtf did i write??)
Browse files Browse the repository at this point in the history
  • Loading branch information
KrinjMaster committed Jan 8, 2024
1 parent aece38a commit f6ca5f0
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 1 deletion.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# krinj-mater

My chess engine built in Rust.

Goald:
[] A way to represent a board (pieces position, which turn is it, who can castle, en passant etc.)
176 changes: 176 additions & 0 deletions src/board.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
pub const DEFAULT_FEN_STRING: &str = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";

#[derive(Clone, Copy, Debug)]
pub enum Square {
None = 0b0000,
Empty = 0b0001,
WhitePawn = 0b00010,
WhiteKnight = 0b0011,
WhiteBishop = 0b0100,
WhiteRook = 0b0101,
WhiteQueen = 0b0110,
WhiteKing = 0b0111,
BlackPawn = 0b1000,
BlackKnight = 0b1001,
BlackBishop = 0b1010,
BlackRook = 0b1011,
BlackQueen = 0b1100,
BlackKing = 0b1101,
}

#[derive(Clone, Copy, Debug)]
pub enum Color {
White = 0b0000,
Black = 0b0001,
}

pub struct BoardState {
pub board: [[Square; 10]; 12],
pub to_move: Color,
pub white_king_side_castle: bool,
pub white_queen_side_castle: bool,
pub black_king_side_castle: bool,
pub black_queen_side_castle: bool,
pub en_passant: (u8, u8),
pub halfmove: u8,
pub fullmove: u8,
}

impl BoardState {
pub fn from_fen(fen_string: &str) -> Result<(), &str> {
let mut board = [[Square::None; 10]; 12];
let mut to_move: Color = Color::White;
let mut white_king_side_castle = false;
let mut white_queen_side_castle = false;
let mut black_king_side_castle = false;
let mut black_queen_side_castle = false;
let mut en_passant = (0, 0);
let mut halfmove = 0;
let mut fullmove = 0;

let fen: Vec<&str> = fen_string.split(" ").collect();
let mut row_index = 0;

if fen.len() != 6 {
return Err("Incorrect fen string! Check your notaion!");
}

for row in fen[0].split("/") {
let mut new_row: [Square; 10] = board[row_index + 2];
let mut position = 0;

for char in row.chars() {
match char {
'P' => new_row[position + 1] = Square::WhitePawn,
'N' => new_row[position + 1] = Square::WhiteKnight,
'B' => new_row[position + 1] = Square::WhiteBishop,
'R' => new_row[position + 1] = Square::WhiteRook,
'Q' => new_row[position + 1] = Square::WhiteQueen,
'K' => new_row[position + 1] = Square::WhiteKing,
'p' => new_row[position + 1] = Square::BlackPawn,
'n' => new_row[position + 1] = Square::BlackKnight,
'b' => new_row[position + 1] = Square::BlackBishop,
'r' => new_row[position + 1] = Square::BlackRook,
'q' => new_row[position + 1] = Square::BlackQueen,
'k' => new_row[position + 1] = Square::BlackKing,
_ => {
if char.is_numeric() {
for i in 0..char.to_digit(10).unwrap_or(0) {
new_row[(i).try_into().unwrap_or(1) + 1] = Square::Empty;
}
}
}
}
position += 1;
}

board[row_index + 2] = new_row;

row_index += 1;
}

// color to move
match fen[1] {
"b" => to_move = Color::Black,
"w" => to_move = Color::White,
_ => return Err("Incorrect move side!"),
}

// castling
for right in fen[2].chars() {
match right {
'K' => white_king_side_castle = true,
'Q' => white_queen_side_castle = true,
'k' => black_king_side_castle = true,
'q' => black_queen_side_castle = true,
'-' => continue,
_ => return Err("Incorrect castle right!"),
}
}

// en passant
match fen[3] {
"-" => en_passant = (-1, -1),
_ => {
if fen[3].len() != 2 {
return Err("Incorrect en passant position!");
}

let mut row = 0;
let mut column = 0;

match fen[3].chars().next().unwrap_or('i') {
'a' => column = 0,
'b' => column = 1,
'c' => column = 2,
'd' => column = 3,
'e' => column = 4,
'f' => column = 5,
'g' => column = 6,
'h' => column = 7,
_ => return Err("Incorrect en passant column position!"),
};

match fen[3].chars().last().unwrap_or('0') {
'1' => row = 0,
'2' => row = 1,
'3' => row = 2,
'4' => row = 3,
'5' => row = 4,
'6' => row = 5,
'7' => row = 6,
'8' => row = 7,
_ => return Err("Incorrect en passant row position!"),
};

en_passant = (row, column);
}
}

// halfmove
if fen[4].len() > 1 {
return Err("Incorrect halfmove count");
}

match fen[4].chars().next().unwrap_or('a').is_numeric() {
true => halfmove = fen[4].chars().next().unwrap().to_digit(10).unwrap_or(0),
false => return Err("Incorrect halfmove number!"),
}

// fullmove
if fen[5].len() > 1 {
return Err("Incorrect halfmove count");
}

match fen[5].chars().next().unwrap_or('a').is_numeric() {
true => fullmove = fen[5].chars().next().unwrap().to_digit(10).unwrap_or(0),
false => return Err("Incorrect halfmove number!"),
}

println!("{:?}", fen);

println!("board: {:?}\n to move: {:?}\n white q castle: {}\n white k castle: {}\n black q castle: {}\n black k castle: {}\nen passant: {:?}\n halfmove: {}\n fullmove: {}", board, to_move, white_queen_side_castle, white_king_side_castle, black_queen_side_castle, black_king_side_castle, en_passant, halfmove, fullmove);

Ok(())
}
}
6 changes: 5 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
use board::{BoardState, DEFAULT_FEN_STRING};

pub mod board;

fn main() {
println!("Hello, world!");
let _board = BoardState::from_fen(DEFAULT_FEN_STRING);
}

0 comments on commit f6ca5f0

Please sign in to comment.