split_from and diag use iterators not vectors
This commit is contained in:
parent
bd5cc2ea52
commit
13f5b29dac
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -152,6 +152,7 @@ dependencies = [
|
|||||||
name = "othello"
|
name = "othello"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"either",
|
||||||
"num",
|
"num",
|
||||||
"rand",
|
"rand",
|
||||||
"rayon",
|
"rayon",
|
||||||
|
|||||||
@ -8,6 +8,7 @@ edition = "2021"
|
|||||||
debug = true
|
debug = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
either = "1.13.0"
|
||||||
num = "0.4"
|
num = "0.4"
|
||||||
rand = "0.9"
|
rand = "0.9"
|
||||||
rayon = "1.10"
|
rayon = "1.10"
|
||||||
|
|||||||
@ -151,7 +151,7 @@ impl Board {
|
|||||||
chains.extend(j_chain.map(|range| range.into_iter().map(|j| (i, j)).collect()));
|
chains.extend(j_chain.map(|range| range.into_iter().map(|j| (i, j)).collect()));
|
||||||
|
|
||||||
// handle diagonals
|
// handle diagonals
|
||||||
chains.extend(diag(i, j, 0, 0, BOARD_SIZE - 1, BOARD_SIZE - 1));
|
chains.extend(diag(i, j, 0, 0, BOARD_SIZE - 1, BOARD_SIZE - 1).map(Iterator::collect));
|
||||||
|
|
||||||
let mut fill: Vec<(usize, usize)> = Vec::with_capacity(chains.iter().map(Vec::len).sum());
|
let mut fill: Vec<(usize, usize)> = Vec::with_capacity(chains.iter().map(Vec::len).sum());
|
||||||
|
|
||||||
|
|||||||
@ -248,7 +248,7 @@ pub struct ComplexAgent {
|
|||||||
|
|
||||||
impl ComplexAgent {
|
impl ComplexAgent {
|
||||||
pub fn new(color: Piece) -> Self {
|
pub fn new(color: Piece) -> Self {
|
||||||
const MAX_DEPTH: usize = 6;
|
const MAX_DEPTH: usize = 7;
|
||||||
Self {
|
Self {
|
||||||
color,
|
color,
|
||||||
future_moves: FutureMoves::new(color, MAX_DEPTH),
|
future_moves: FutureMoves::new(color, MAX_DEPTH),
|
||||||
|
|||||||
58
src/misc.rs
58
src/misc.rs
@ -1,31 +1,38 @@
|
|||||||
|
use either::Either;
|
||||||
use std::{iter::Rev, ops::RangeInclusive};
|
use std::{iter::Rev, ops::RangeInclusive};
|
||||||
|
|
||||||
pub fn split_from<T>(min: T, max: T, x: T) -> [Vec<T>; 2]
|
pub fn split_from<T>(min: T, max: T, x: T) -> [impl Iterator<Item = T> + Clone; 2]
|
||||||
where
|
where
|
||||||
T: num::Integer + Copy,
|
T: num::Integer + Copy,
|
||||||
RangeInclusive<T>: Iterator<Item = T> + DoubleEndedIterator,
|
RangeInclusive<T>: Iterator<Item = T> + DoubleEndedIterator,
|
||||||
Rev<RangeInclusive<T>>: Iterator<Item = T>,
|
Rev<RangeInclusive<T>>: Iterator<Item = T>,
|
||||||
{
|
{
|
||||||
// check that x is in range
|
let in_range = (x >= min) && (x <= max);
|
||||||
if min > x || x > max {
|
|
||||||
return [const { Vec::new() }; 2];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// RangeInclusive (1..=0), has 0 elements
|
||||||
|
let base = Either::Right(T::one()..=T::zero());
|
||||||
[
|
[
|
||||||
if x > min + T::one() {
|
if in_range && x > min + T::one() {
|
||||||
(min..=(x - T::one())).rev().collect()
|
Either::Left((min..=(x - T::one())).rev())
|
||||||
} else {
|
} else {
|
||||||
Vec::new()
|
base.clone()
|
||||||
},
|
},
|
||||||
if x + T::one() < max {
|
if in_range && x + T::one() < max {
|
||||||
((x + T::one())..=max).collect()
|
Either::Right((x + T::one())..=max)
|
||||||
} else {
|
} else {
|
||||||
Vec::new()
|
base
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn diag<T>(i: T, j: T, min_i: T, min_j: T, max_i: T, max_j: T) -> [Vec<(T, T)>; 4]
|
pub fn diag<T>(
|
||||||
|
i: T,
|
||||||
|
j: T,
|
||||||
|
min_i: T,
|
||||||
|
min_j: T,
|
||||||
|
max_i: T,
|
||||||
|
max_j: T,
|
||||||
|
) -> [impl Iterator<Item = (T, T)>; 4]
|
||||||
where
|
where
|
||||||
T: num::Integer + Copy,
|
T: num::Integer + Copy,
|
||||||
RangeInclusive<T>: Iterator<Item = T> + DoubleEndedIterator,
|
RangeInclusive<T>: Iterator<Item = T> + DoubleEndedIterator,
|
||||||
@ -34,13 +41,7 @@ where
|
|||||||
let i_chains = split_from(min_i, max_i, i);
|
let i_chains = split_from(min_i, max_i, i);
|
||||||
let j_chains = split_from(min_j, max_j, j);
|
let j_chains = split_from(min_j, max_j, j);
|
||||||
|
|
||||||
[(0, 0), (1, 1), (1, 0), (0, 1)].map(|(a, b)| {
|
[(0, 0), (1, 1), (1, 0), (0, 1)].map(|(a, b)| i_chains[a].clone().zip(j_chains[b].clone()))
|
||||||
i_chains[a]
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.zip(j_chains[b].clone())
|
|
||||||
.collect()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -49,15 +50,24 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn split_test() {
|
fn split_test() {
|
||||||
assert_eq!(split_from(0, 6, 2), [vec![1, 0], vec![3, 4, 5, 6]]);
|
assert_eq!(
|
||||||
|
split_from(0, 6, 2).map(Iterator::collect::<Vec<usize>>),
|
||||||
|
[vec![1, 0], vec![3, 4, 5, 6]]
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(split_from(0, 6, 0), [vec![], vec![1, 2, 3, 4, 5, 6]]);
|
assert_eq!(
|
||||||
|
split_from(0, 6, 0).map(Iterator::collect::<Vec<usize>>),
|
||||||
|
[vec![], vec![1, 2, 3, 4, 5, 6]]
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(split_from(0, 6, 6), [vec![5, 4, 3, 2, 1, 0], vec![]]);
|
assert_eq!(
|
||||||
|
split_from(0, 6, 6).map(Iterator::collect::<Vec<usize>>),
|
||||||
|
[vec![5, 4, 3, 2, 1, 0], vec![]]
|
||||||
|
);
|
||||||
|
|
||||||
// test out-of-bounds and also generics
|
// test out-of-bounds and also generics
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
split_from::<i16>(-1i16, 4i16, 10i16),
|
split_from::<i16>(-1i16, 4i16, 10i16).map(Iterator::collect::<Vec<i16>>),
|
||||||
[const { Vec::new() }; 2]
|
[const { Vec::new() }; 2]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -65,7 +75,7 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn diag_test() {
|
fn diag_test() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
diag(2, 3, 0, 0, 7, 7),
|
diag(2, 3, 0, 0, 7, 7).map(Iterator::collect::<Vec<(usize, usize)>>),
|
||||||
[
|
[
|
||||||
vec![(1, 2), (0, 1)],
|
vec![(1, 2), (0, 1)],
|
||||||
vec![(3, 4), (4, 5), (5, 6), (6, 7)],
|
vec![(3, 4), (4, 5), (5, 6), (6, 7)],
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user