Skip to content

Commit

Permalink
some random work with chess AI
Browse files Browse the repository at this point in the history
  • Loading branch information
TeemuKoivisto committed Mar 4, 2024
1 parent a65af35 commit b03bf9d
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 21 deletions.
42 changes: 22 additions & 20 deletions crates/wasm/src/ai.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use std::cmp::{max, min};
use std::{
cmp::{max, min},
collections::HashMap,
};
use wasm_bindgen::prelude::*;

use crate::board::Board;
Expand All @@ -21,8 +24,8 @@ pub fn compute_ai(board: &mut Board, ai_number: u32, search_depth: i32) -> bool
let perf = web_sys::window().unwrap().performance().unwrap();

let t0 = perf.now();
let empty = board.get_empty_indices();
for (cx, cy) in empty.clone() {
let empty = board.get_empty_cells();
for (_, (cx, cy)) in empty.clone().into_iter() {
let value = minimax(
cx,
cy,
Expand Down Expand Up @@ -57,7 +60,7 @@ pub fn minimax(
x: u32,
y: u32,
board: &mut Board,
empty_cells: Vec<(u32, u32)>,
mut empty_cells: &HashMap<u32, (u32, u32)>,
depth: i32,
is_maximizing: bool,
alpha: i32,
Expand All @@ -66,6 +69,7 @@ pub fn minimax(
human_player: u32,
) -> i32 {
board.set_cell_owner(&x, &y, player);
empty_cells.remove(&(&x + &y * 5));
let won = board.update_cell_adjancies(x, y, player);
let mut value: i32 = 0;
let mut ended = true;
Expand Down Expand Up @@ -93,16 +97,17 @@ pub fn minimax(
value = -10000000;
let mut alph = alpha;
let pl = if player == 2 { 1 } else { 2 };
let empty: Vec<(u32, u32)> = empty_cells
.into_iter()
.filter(|(cx, cy)| cx != &x || cy != &y)
.collect();
for (cx, cy) in &empty {
// let empty: Vec<(u32, u32)> = empty_cells
// .into_iter()
// .filter(|(cx, cy)| cx != &x || cy != &y)
// .collect();
let empty = empty_cells.clone();
for (_, (cx, cy)) in empty_cells.into_iter() {
value = max(
value,
minimax(

Check failure on line 108 in crates/wasm/src/ai.rs

View workflow job for this annotation

GitHub Actions / push_to_registry

arguments to this function are incorrect
*cx,
*cy,
cx,
cy,
board,
empty.clone(),
depth - 1,
Expand All @@ -114,7 +119,7 @@ pub fn minimax(
),
);
alph = max(alph, value);
board.set_cell_owner(cx, cy, 0);
board.set_cell_owner(&cx, &cy, 0);
if beta <= alpha {
break;
}
Expand All @@ -123,16 +128,13 @@ pub fn minimax(
value = 10000000;
let mut bet = beta;
let pl = if player == 2 { 1 } else { 2 };
let empty: Vec<(u32, u32)> = empty_cells
.into_iter()
.filter(|(cx, cy)| cx != &x || cy != &y)
.collect();
for (cx, cy) in &empty {
let empty = empty_cells.clone();
for (_, (cx, cy)) in empty_cells.into_iter() {
value = min(
value,
minimax(

Check failure on line 135 in crates/wasm/src/ai.rs

View workflow job for this annotation

GitHub Actions / push_to_registry

arguments to this function are incorrect
*cx,
*cy,
cx,
cy,
board,
empty.clone(),
depth - 1,
Expand All @@ -144,7 +146,7 @@ pub fn minimax(
),
);
bet = min(bet, value);
board.set_cell_owner(cx, cy, 0);
board.set_cell_owner(&cx, &cy, 0);
if beta <= alpha {
break;
}
Expand Down
24 changes: 23 additions & 1 deletion crates/wasm/src/board.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use js_sys::Array;
use std::collections::HashMap;
use std::ops::{Index, IndexMut};
use std::slice::Iter;
use wasm_bindgen::prelude::*;
Expand Down Expand Up @@ -48,6 +49,8 @@ pub struct Board {
available: u32,
in_row: u32,
cells: Vec<BoardCell>,
empty_cells: Vec<u8>,
code: String,
}

#[wasm_bindgen]
Expand Down Expand Up @@ -93,6 +96,16 @@ impl Board {
.collect()
}

pub fn get_empty_cells(&self) -> HashMap<u32, (u32, u32)> {
let mut map = HashMap::new();
for c in self.cells.iter() {
if c.owner == 0 {
map.insert(c.x + c.y * self.size, (c.x, c.y));
}
}
map
}

pub fn clone_cells(&self) -> Vec<BoardCell> {
self.cells.clone()
}
Expand Down Expand Up @@ -222,12 +235,16 @@ impl Board {
}

pub fn set_cell_owner(&mut self, x: &u32, y: &u32, player: u32) {
self.cells[(x + y * self.size) as usize].owner = player;
let idx = (x + y * self.size) as usize;
self.cells[idx].owner = player;
if player != 0 {
self.available -= 1;
self.empty_cells[idx] = 1;
} else {
self.available += 1;
self.empty_cells[idx] = 0;
}
// self.code = std::str::from_utf8(&self.empty_cells).unwrap().to_string()
}
}

Expand All @@ -236,6 +253,7 @@ impl Board {
#[wasm_bindgen(constructor)]
pub fn new(size: u32, in_row: u32) -> Self {
let mut cells = Vec::new();
let mut empty_cells = Vec::new();
for y in 0..size {
for x in 0..size {
cells.push(BoardCell {
Expand All @@ -249,13 +267,17 @@ impl Board {
right_diag: 0,
},
});
empty_cells.push(0)
}
}
let code = std::str::from_utf8(&empty_cells).unwrap().to_string();
Self {
size,
available: size * size,
in_row,
cells,
empty_cells,
code,
}
}

Expand Down
77 changes: 77 additions & 0 deletions crates/wasm/src/empty_cells.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use std::collections::HashSet;

use wasm_bindgen::prelude::*;

use crate::board::Board;

#[wasm_bindgen]
extern "C" {
fn alert(s: &str);
// Use `js_namespace` here to bind `console.log(..)` instead of just `log(..)`
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}

pub struct EmptyCells {
size: u32,
start: u32,
// end: u32, // ?
board: u128,
cells: Vec<(u32, u32)>,
mapping: HashSet<usize>
}

impl EmptyCells {
pub fn new(board: &Board) -> Self {
let mut val = 0 as u128;
let mut i = 0;
let mut start = 0;
let mut cells = Vec::new();
for c in board.clone_cells() {
if c.owner == 0 {
if start == 0 && i > 0 {
start = i;
}
val = val << 1;
cells.push((c.x, c.y));
} else {
val = val << 0;
}
i += 1;
}
Self {
size: i / 2,
start,
cells,
mapping: HashSet::new(),
board: val
}
}

pub fn copy_with_cell_selected(&self, x: u32, y: u32, empty: bool) -> Vec<usize> {
let mut created = Vec::with_capacity(self.mapping.len());
for key in self.mapping.into_iter() {
if empty || x + y * self.size != key as u32 {
created.push(key);
}
}
created
}

pub fn create_empty_vec(&self) -> Vec<usize> {
let mut created = Vec::with_capacity(self.mapping.len());
for key in self.mapping.into_iter() {
created.push(key);
}
created
}

pub fn set_empty(&mut self, x: u32, y: u32, player: u32) {
let idx = (x + y * self.size) as usize;
if player == 0 {
self.mapping.insert(idx);
} else {
self.mapping.remove(&idx);
}
}
}
1 change: 1 addition & 0 deletions crates/wasm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod ai;
pub mod board;
// pub mod empty_cells;
1 change: 1 addition & 0 deletions packages/chess/src/board.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ interface BoardOptions {}
export class Board {
size = 8
cells: Square[] = []
castleable: [boolean, boolean] = [true, true]

constructor(opts?: BoardOptions) {
const cells: Square[] = []
Expand Down

0 comments on commit b03bf9d

Please sign in to comment.