changes
This commit is contained in:
parent
2c241948f7
commit
351953450a
46
Cargo.lock
generated
46
Cargo.lock
generated
@ -44,31 +44,6 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
|
||||
dependencies = [
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.13.0"
|
||||
@ -188,7 +163,6 @@ dependencies = [
|
||||
"lazy_static",
|
||||
"num",
|
||||
"rand",
|
||||
"rayon",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
@ -256,26 +230,6 @@ dependencies = [
|
||||
"zerocopy 0.8.17",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
|
||||
@ -14,5 +14,4 @@ either = "1.13"
|
||||
lazy_static = "1.5.0"
|
||||
num = "0.4"
|
||||
rand = "0.9"
|
||||
rayon = "1.10"
|
||||
static_assertions = "1.1"
|
||||
|
||||
10
src/agent.rs
10
src/agent.rs
@ -14,7 +14,7 @@ pub struct ManualAgent {
|
||||
}
|
||||
|
||||
impl Agent for ManualAgent {
|
||||
fn next_move(&mut self, _: &Board) -> Option<(usize, usize)> {
|
||||
fn next_move(&mut self, board: &Board) -> Option<(usize, usize)> {
|
||||
let stdin = io::stdin();
|
||||
let mut input = String::new();
|
||||
println!("Your turn! ('Skip' to skip)");
|
||||
@ -34,8 +34,12 @@ impl Agent for ManualAgent {
|
||||
.and_then(|x| -> Option<[usize; 2]> { x.try_into().ok() })
|
||||
.map(|x| (x[0], x[1]));
|
||||
|
||||
if got.is_some() {
|
||||
return got;
|
||||
if let Some(got) = got {
|
||||
if board.possible_moves(self.color).all(|x| x != got) {
|
||||
println!("Invalid move! Try again.");
|
||||
continue;
|
||||
}
|
||||
return Some(got);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
12
src/board.rs
12
src/board.rs
@ -233,12 +233,16 @@ impl Board {
|
||||
fill
|
||||
}
|
||||
|
||||
pub fn count(&self, piece: Piece) -> usize {
|
||||
match piece {
|
||||
Piece::Black => self.black_board.count(),
|
||||
Piece::White => self.white_board.count(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns (White score, Black score)
|
||||
pub fn get_score(&self) -> (usize, usize) {
|
||||
(
|
||||
self.white_board.count() as usize,
|
||||
self.black_board.count() as usize,
|
||||
)
|
||||
(self.count(Piece::White), self.count(Piece::Black))
|
||||
}
|
||||
|
||||
pub fn game_winner(&self, turn: Piece) -> Option<Piece> {
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
use crate::{agent::Agent, board::Board, piece::Piece};
|
||||
use rayon::prelude::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Move {
|
||||
@ -33,7 +32,7 @@ struct Move {
|
||||
|
||||
impl Move {
|
||||
fn compute_self_value(&self, agent_color: Piece, depth: usize) -> i64 {
|
||||
let mut self_value = self.captured as i64;
|
||||
let mut self_value = self.board.count(agent_color) as i64;
|
||||
|
||||
if self.winner == Some(!agent_color) {
|
||||
// if this board results in the opponent winning, MAJORLY negatively weigh this move
|
||||
@ -43,8 +42,6 @@ impl Move {
|
||||
} else if self.winner == Some(agent_color) {
|
||||
// results in a win for the agent
|
||||
self_value = i64::MAX;
|
||||
} else if self.color != agent_color {
|
||||
self_value = -self_value;
|
||||
}
|
||||
|
||||
self_value / depth as i64
|
||||
@ -87,24 +84,24 @@ impl FutureMoves {
|
||||
color: Piece,
|
||||
remaining_depth: usize,
|
||||
) {
|
||||
if remaining_depth == 0 {
|
||||
return;
|
||||
self.current_depth += remaining_depth;
|
||||
let mut next_nodes: Vec<usize> = nodes.collect();
|
||||
|
||||
let mut next_color = !color;
|
||||
|
||||
for _ in 0..remaining_depth {
|
||||
next_nodes = next_nodes
|
||||
.into_iter()
|
||||
.flat_map(|node_idx| {
|
||||
self.generate_children(
|
||||
Some(node_idx),
|
||||
&self.arena[node_idx].board.clone(),
|
||||
next_color,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
next_color = !next_color;
|
||||
}
|
||||
|
||||
let next_color = !color;
|
||||
|
||||
let next_nodes: Vec<usize> = nodes
|
||||
.flat_map(|node_idx| {
|
||||
self.generate_children(
|
||||
Some(node_idx),
|
||||
&self.arena[node_idx].board.clone(),
|
||||
next_color,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
self.current_depth += 1;
|
||||
self.extend_layers(next_nodes.into_iter(), next_color, remaining_depth - 1);
|
||||
}
|
||||
|
||||
fn generate_children(
|
||||
@ -225,9 +222,9 @@ impl FutureMoves {
|
||||
let mut index_map = vec![None; self.arena.len()];
|
||||
|
||||
// PERF: reverse iterator to avoid unneeded `memcpy`s when deconstructing the Arena
|
||||
for (old_idx, keep) in retain.iter().enumerate().rev() {
|
||||
for (old_idx, keep) in retain.into_iter().enumerate().rev() {
|
||||
let mut node = self.arena.remove(old_idx);
|
||||
if *keep {
|
||||
if keep {
|
||||
index_map[old_idx] = Some(new_arena.len());
|
||||
|
||||
node.parent = node.parent.and_then(|p| index_map[p]);
|
||||
|
||||
@ -60,7 +60,7 @@ impl Game {
|
||||
// Lets the player try again if the move is invalid
|
||||
// Now we dont need to restart the game if we mess up
|
||||
Err(err) => {
|
||||
println!("Invalid move by Player {}: {}. Try again.", player_i, err);
|
||||
panic!("Invalid move by Player {}: {}. Try again.", player_i, err);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user