Compare commits
1 Commits
60b65e3eec
...
dev
Author | SHA1 | Date | |
---|---|---|---|
6d415468e0
|
@@ -1,5 +1,6 @@
|
||||
use glib::ExitCode;
|
||||
use rdraught::draughts::DraughtsGame;
|
||||
use rdraught_ui;
|
||||
|
||||
fn main() -> ExitCode {
|
||||
let game = DraughtsGame::default();
|
||||
|
@@ -6,7 +6,7 @@ use gtk4::glib::{MainContext, Propagation};
|
||||
use gtk4::{self as gtk, gdk::ffi::GDK_BUTTON_PRIMARY};
|
||||
use gtk4::{Application, DrawingArea, prelude::*};
|
||||
use rdraught::{
|
||||
DraughtsBoard, DraughtsGame, Move, Piece, Player, Position, RDraughtApplication,
|
||||
DraughtsBoard, DraughtsGame, Error, Move, Piece, Player, Position, RDraughtApplication,
|
||||
RectangularBoard,
|
||||
};
|
||||
use rsvg::SvgHandle;
|
||||
@@ -473,17 +473,17 @@ fn create_game_window(
|
||||
let mut rd_app = rd.borrow_mut();
|
||||
println!("Applied move: {:?}", mv);
|
||||
rd_app.apply_move(mv).unwrap();
|
||||
// let game_copy = rd_app.game().clone();
|
||||
// thread::spawn(move || {
|
||||
// if let (Some(mv), analyzed_moves) =
|
||||
// game_copy.get_best_move(10)
|
||||
// {
|
||||
// println!(
|
||||
// "Next best move: {:?}, analyzed moves: {}",
|
||||
// mv, analyzed_moves
|
||||
// );
|
||||
// }
|
||||
// });
|
||||
let game_copy = rd_app.game().clone();
|
||||
thread::spawn(move || {
|
||||
if let (Some(mv), analyzed_moves) =
|
||||
game_copy.get_best_move(10)
|
||||
{
|
||||
println!(
|
||||
"Next best move: {:?}, analyzed moves: {}",
|
||||
mv, analyzed_moves
|
||||
);
|
||||
}
|
||||
});
|
||||
move_applied = true;
|
||||
break;
|
||||
}
|
||||
|
@@ -12,7 +12,7 @@ pub trait RectangularBoard {
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct DraughtsBoard {
|
||||
data: [u8; (POSITIONS * BITS_PER_POSITION).div_ceil(8)],
|
||||
data: [u8; (POSITIONS * BITS_PER_POSITION + 7) / 8],
|
||||
}
|
||||
|
||||
impl DraughtsBoard {
|
||||
@@ -38,23 +38,23 @@ impl DraughtsBoard {
|
||||
let index = offset_bits / 8;
|
||||
let remainder = offset_bits % 8;
|
||||
let mut value = 0;
|
||||
value |= (self.data[index] >> remainder) & 7;
|
||||
value = value | ((self.data[index] >> remainder) & 7);
|
||||
if remainder > 5 {
|
||||
let written_bits = 8 - remainder;
|
||||
value |= (self.data[index + 1] & (7 >> written_bits)) << written_bits
|
||||
value = value | ((self.data[index + 1] & (7 >> written_bits)) << written_bits)
|
||||
}
|
||||
Piece::from_repr(value as usize).unwrap()
|
||||
}
|
||||
|
||||
pub fn new<T: FnMut(Position) -> Piece>(mut cb: T) -> DraughtsBoard {
|
||||
let mut result = DraughtsBoard {
|
||||
data: [0u8; (POSITIONS * BITS_PER_POSITION).div_ceil(8)],
|
||||
data: [0u8; (POSITIONS * BITS_PER_POSITION + 7) / 8],
|
||||
};
|
||||
for i in 0..DraughtsBoard::rows() {
|
||||
for j in 0..DraughtsBoard::columns() {
|
||||
if (i + j) % 2 == 0 {
|
||||
let position = Position::new(i as u8, j as u8).unwrap();
|
||||
let piece = cb(position);
|
||||
let piece = cb(position.clone());
|
||||
result.set(position, piece);
|
||||
}
|
||||
}
|
||||
@@ -254,6 +254,12 @@ pub struct DraughtsGame {
|
||||
next_move: Player,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SerializedDraughtsGame {
|
||||
data: Vec<u8, 24>,
|
||||
next_move: Player,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Error {
|
||||
WrongPlayer,
|
||||
@@ -349,7 +355,8 @@ impl DraughtsGame {
|
||||
} else {
|
||||
return Err(Error::WrongPlayer);
|
||||
}
|
||||
} else if self.next_move == player {
|
||||
} else {
|
||||
if self.next_move == player {
|
||||
self.board.apply_move(mv)?;
|
||||
// Check if more captures are available for the current piece
|
||||
if self
|
||||
@@ -363,6 +370,7 @@ impl DraughtsGame {
|
||||
self.next_turn();
|
||||
} else {
|
||||
return Err(Error::WrongPlayer);
|
||||
}
|
||||
};
|
||||
let end = mv.get_end_position();
|
||||
//Promote pawns that reach the last row
|
||||
@@ -511,6 +519,68 @@ impl DraughtsGame {
|
||||
}
|
||||
}
|
||||
|
||||
impl SerializedDraughtsGame {
|
||||
fn serialize(position: Position, piece: Piece) -> u8 {
|
||||
let p = position.row() * 4 + position.col() / 2;
|
||||
p << 3 | piece as u8
|
||||
}
|
||||
|
||||
fn deserialize(byte: u8) -> Result<(Position, Piece), Error> {
|
||||
let index = byte >> 3;
|
||||
let row = index >> 2;
|
||||
let col = ((index - (row << 2)) % 4) * 2 + (row % 2);
|
||||
let pos = Position::new(row, col)?;
|
||||
Ok((
|
||||
pos,
|
||||
Piece::from_repr((byte & 7) as usize).ok_or(Error::InvalidPiece)?,
|
||||
))
|
||||
}
|
||||
|
||||
fn from(
|
||||
DraughtsGame { board, next_move }: &DraughtsGame,
|
||||
) -> Result<SerializedDraughtsGame, Error> {
|
||||
let mut data = Vec::<u8, 24>::new();
|
||||
for i in 0..DraughtsBoard::rows() {
|
||||
for j in 0..DraughtsBoard::columns() {
|
||||
let p = Position::new(i as u8, j as u8)?;
|
||||
let piece = board.get_piece(&p);
|
||||
if piece != Piece::NoPiece {
|
||||
data.push(Self::serialize(p, piece)).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(SerializedDraughtsGame {
|
||||
data,
|
||||
next_move: *next_move,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DraughtsGame> for SerializedDraughtsGame {
|
||||
fn from(DraughtsGame { board, next_move }: DraughtsGame) -> Self {
|
||||
let mut data = Vec::<u8, 24>::new();
|
||||
for i in 0..DraughtsBoard::rows() {
|
||||
for j in 0..DraughtsBoard::columns() {
|
||||
let p = Position::new(i as u8, j as u8).unwrap();
|
||||
let piece = board.get_piece(&p);
|
||||
if piece != Piece::NoPiece {
|
||||
data.push(Self::serialize(p, piece)).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
SerializedDraughtsGame {
|
||||
data,
|
||||
next_move: next_move,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<DraughtsGame> for SerializedDraughtsGame {
|
||||
fn into(self) -> DraughtsGame {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MoveIterator<'a> {
|
||||
board: &'a DraughtsBoard,
|
||||
position: Position,
|
||||
@@ -672,12 +742,44 @@ mod std {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub use std::*;
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(feature = "std")]
|
||||
mod tests {
|
||||
extern crate std;
|
||||
use super::{DraughtsBoard, Piece, Position};
|
||||
use super::{
|
||||
DraughtsBoard, DraughtsGame, Move, MoveDirection, Piece, Player, Position,
|
||||
SerializedDraughtsGame,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
#[test]
|
||||
fn test_serialize_deserialize_piece() {
|
||||
for (pos, piece) in [
|
||||
(Position::new(4u8, 2u8), Piece::SimpleRedPawn),
|
||||
(Position::new(0u8, 6u8), Piece::CrownedRedPawn),
|
||||
(Position::new(1u8, 7u8), Piece::SimpleWhitePawn),
|
||||
(Position::new(2u8, 4u8), Piece::CrownedWhitePawn),
|
||||
(Position::new(3u8, 5u8), Piece::SimpleRedPawn),
|
||||
(Position::new(6u8, 2u8), Piece::CrownedRedPawn),
|
||||
(Position::new(7u8, 7u8), Piece::SimpleWhitePawn),
|
||||
(Position::new(7u8, 1u8), Piece::CrownedWhitePawn),
|
||||
(Position::new(6u8, 6u8), Piece::SimpleRedPawn),
|
||||
(Position::new(4u8, 6u8), Piece::CrownedRedPawn),
|
||||
(Position::new(6u8, 6u8), Piece::SimpleWhitePawn),
|
||||
(Position::new(4u8, 6u8), Piece::CrownedWhitePawn),
|
||||
] {
|
||||
let pos = pos.unwrap();
|
||||
let serialized = SerializedDraughtsGame::serialize(pos, piece);
|
||||
let (deserialized_pos, deserialized_piece) =
|
||||
SerializedDraughtsGame::deserialize(serialized).unwrap();
|
||||
assert_eq!(piece, deserialized_piece);
|
||||
assert_eq!(pos, deserialized_pos);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create() {
|
||||
@@ -721,7 +823,7 @@ mod tests {
|
||||
#[cfg(feature = "std")]
|
||||
mod ai_tests {
|
||||
extern crate std;
|
||||
use super::{DraughtsGame, Move, MoveDirection, Piece, Player, Position};
|
||||
use super::{DraughtsBoard, DraughtsGame, Move, MoveDirection, Piece, Player, Position};
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[test]
|
||||
|
@@ -1,4 +1,6 @@
|
||||
#![no_std]
|
||||
#[macro_use]
|
||||
extern crate strum;
|
||||
|
||||
mod constants;
|
||||
pub mod draughts;
|
||||
|
@@ -117,9 +117,9 @@ impl Mul<(i32, i32)> for Position {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Position> for u8 {
|
||||
fn from(pos: Position) -> Self {
|
||||
(8 - 1 - pos.row()) * (POSITIONS_PER_ROW as u8) + pos.col() / 2
|
||||
impl Into<u8> for Position {
|
||||
fn into(self) -> u8 {
|
||||
(8 - 1 - self.row()) * (POSITIONS_PER_ROW as u8) + self.col() / 2
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user