separate optimization levels
This commit is contained in:
		
							
								
								
									
										2
									
								
								wasm/o-x-rust/Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								wasm/o-x-rust/Cargo.lock
									
									
									
										generated
									
									
									
								
							@@ -25,7 +25,7 @@ dependencies = [
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "o-x-rust"
 | 
			
		||||
version = "0.0.7"
 | 
			
		||||
version = "0.0.8"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "wasm-bindgen",
 | 
			
		||||
]
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ description = "Noughts and crosses WASM algorithms"
 | 
			
		||||
repository = "https://git.koval.net/cyclane/game-algorithms/src/branch/main/wasm/o-x-rust"
 | 
			
		||||
license = "GNU GPLv3"
 | 
			
		||||
readme = "README.md"
 | 
			
		||||
version = "0.0.7"
 | 
			
		||||
version = "0.0.8"
 | 
			
		||||
edition = "2021"
 | 
			
		||||
 | 
			
		||||
[lib]
 | 
			
		||||
 
 | 
			
		||||
@@ -35,20 +35,53 @@ pub fn get_turn(me: u8, other: u8, first: bool, empty: usize) -> u8 {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[wasm_bindgen]
 | 
			
		||||
pub fn get_score(me: u8, other: u8, first: bool, board: &[u8]) -> f64 {
 | 
			
		||||
	let (outcomes, score) = sub_get_score(me, other, first, board);
 | 
			
		||||
pub fn o0_get_score(me: u8, other: u8, first: bool, board: &[u8]) -> f64 {
 | 
			
		||||
	let winner = find_winner(board);
 | 
			
		||||
	if winner != 0 {
 | 
			
		||||
		return if winner == me { 1.0 } else { -1.0 };
 | 
			
		||||
	}
 | 
			
		||||
	let empty = count_empty(board);
 | 
			
		||||
	if empty == 0 {
 | 
			
		||||
		return 0.0;
 | 
			
		||||
	}
 | 
			
		||||
	let mut score = 0.0;
 | 
			
		||||
	for i in 0..9 {
 | 
			
		||||
		if board[i] != 0 {
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		let copy = &mut [0u8; 9];
 | 
			
		||||
		copy.copy_from_slice(board);
 | 
			
		||||
		copy[i] = get_turn(me, other, first, empty);
 | 
			
		||||
		score += o0_get_score(me, other, first, copy);
 | 
			
		||||
	}
 | 
			
		||||
	score
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[wasm_bindgen]
 | 
			
		||||
pub fn o1d_get_score(me: u8, other: u8, first: bool, board: &[u8]) -> f64 {
 | 
			
		||||
	let (outcomes, score) = o1_sub_get_score(me, other, first, board, 2, 2, 1);
 | 
			
		||||
	score as f64 / outcomes as f64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[wasm_bindgen]
 | 
			
		||||
pub fn o1nd_get_score(me: u8, other: u8, first: bool, board: &[u8]) -> f64 {
 | 
			
		||||
	let (outcomes, score) = o1_sub_get_score(me, other, first, board, 1, 1, 0);
 | 
			
		||||
	score as f64 / outcomes as f64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// outcomes, winning outcomes
 | 
			
		||||
pub fn sub_get_score(me: u8, other: u8, first: bool, board: &[u8]) -> (i32, i32) {
 | 
			
		||||
// m: Total outcomes multiplier
 | 
			
		||||
// w: Win winning outcome score
 | 
			
		||||
// d: Draw winning outcome score
 | 
			
		||||
// (loose = 0)
 | 
			
		||||
pub fn o1_sub_get_score(me: u8, other: u8, first: bool, board: &[u8], m: i32, w: i32, d: i32) -> (i32, i32) {
 | 
			
		||||
	let winner = find_winner(board);
 | 
			
		||||
	if winner != 0 {
 | 
			
		||||
		return if winner == me { (1, 1) } else { (1, 0) };
 | 
			
		||||
		return if winner == me { (m, w) } else { (m, 0) };
 | 
			
		||||
	}
 | 
			
		||||
	let empty = count_empty(board);
 | 
			
		||||
	if empty == 0 {
 | 
			
		||||
		return (1, 0);
 | 
			
		||||
		return (m, d);
 | 
			
		||||
	}
 | 
			
		||||
	let mut score = 0;
 | 
			
		||||
	let mut outcomes = 0;
 | 
			
		||||
@@ -59,15 +92,33 @@ pub fn sub_get_score(me: u8, other: u8, first: bool, board: &[u8]) -> (i32, i32)
 | 
			
		||||
		let copy = &mut [0u8; 9];
 | 
			
		||||
		copy.copy_from_slice(board);
 | 
			
		||||
		copy[i] = get_turn(me, other, first, empty);
 | 
			
		||||
		let (sub_outcomes, sub_score) = sub_get_score(me, other, first, copy);
 | 
			
		||||
		let (sub_outcomes, sub_score) = o1_sub_get_score(me, other, first, copy, m, w, d);
 | 
			
		||||
		outcomes += sub_outcomes;
 | 
			
		||||
		score += sub_score;
 | 
			
		||||
	}
 | 
			
		||||
	(outcomes, score)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Optimization levels: o0, o1d, o1nd, o2
 | 
			
		||||
// o0: minmax without optimizations
 | 
			
		||||
// o1d: minmax with ratio optimization including draws
 | 
			
		||||
// o1nd: minmax with ratio optimization excluding draws (draw = loose)
 | 
			
		||||
#[wasm_bindgen]
 | 
			
		||||
pub fn predict(me: u8, other: u8, first: bool, board: &[u8]) -> usize {
 | 
			
		||||
pub fn get_score(me: u8, other: u8, first: bool, board: &[u8], optimization_level: &str) -> f64 {
 | 
			
		||||
	match optimization_level {
 | 
			
		||||
		"o0" => o0_get_score(me, other, first, board),
 | 
			
		||||
		"o1d" => o1d_get_score(me, other, first, board),
 | 
			
		||||
		"o1nd" => o1nd_get_score(me, other, first, board),
 | 
			
		||||
		_ => 0.0
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Optimization levels: o0, o1d, o1nd, o2
 | 
			
		||||
// o0: minmax without optimizations
 | 
			
		||||
// o1d: minmax with ratio optimization including draws
 | 
			
		||||
// o1nd: minmax with ratio optimization excluding draws (draw = loose)
 | 
			
		||||
#[wasm_bindgen]
 | 
			
		||||
pub fn predict(me: u8, other: u8, first: bool, board: &[u8], optimization_level: &str) -> usize {
 | 
			
		||||
	let (mut max_p, mut max_s) = (0, f64::MIN);
 | 
			
		||||
	let empty = count_empty(board);
 | 
			
		||||
	if empty == 0 {
 | 
			
		||||
@@ -80,7 +131,7 @@ pub fn predict(me: u8, other: u8, first: bool, board: &[u8]) -> usize {
 | 
			
		||||
		let copy = &mut [0u8; 9];
 | 
			
		||||
		copy.copy_from_slice(board);
 | 
			
		||||
		copy[i] = get_turn(me, other, first, empty);
 | 
			
		||||
		let score = get_score(me, other, first, copy);
 | 
			
		||||
		let score = get_score(me, other, first, copy, optimization_level);
 | 
			
		||||
		if score > max_s {
 | 
			
		||||
			(max_p, max_s) = (i, score);
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user