1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use boolinator::Boolinator;
pub trait Direction: Sized + From<usize> + Into<usize> {
type Directions: Iterator<Item = Self>;
fn directions() -> Self::Directions;
fn inv(self) -> Self {
let mut n: usize = self.into();
n += Self::total() / 2;
n %= Self::total();
n.into()
}
fn total() -> usize {
Self::directions().count()
}
#[inline]
fn chooser(sigmoids: impl Iterator<Item = f32>) -> Option<(Self, float_ord::FloatOrd<f32>)> {
sigmoids
.map(float_ord::FloatOrd)
.enumerate()
.max_by_key(|&(_, n)| n)
.and_then(|(ix, value)| (value.0 > 0.5).as_some((ix.into(), value)))
}
#[inline]
fn chooser_slice(sigmoids: &[f32]) -> Option<(Self, float_ord::FloatOrd<f32>)> {
Self::chooser(sigmoids.iter().cloned())
}
#[inline]
fn turn_clockwise(self) -> Self {
let mut n: usize = self.into();
n += Self::total() - 1;
n %= Self::total();
n.into()
}
#[inline]
fn turn_counterclockwise(self) -> Self {
let mut n: usize = self.into();
n += 1;
n %= Self::total();
n.into()
}
}
pub trait Neighborhood<T>: std::iter::FromIterator<T> {
type Direction: Direction;
type Iter: Iterator<Item = T>;
type DirIter: Iterator<Item = (Self::Direction, T)>;
fn new<F: FnMut(Self::Direction) -> T>(dir_map: F) -> Self;
fn iter(self) -> Self::Iter;
fn dir_iter(self) -> Self::DirIter;
}
pub trait GetNeighbors<'a, Idx, Neighbors> {
fn get_neighbors(&'a self, index: Idx) -> Neighbors;
}
pub trait TakeMoveDirection<Idx, Dir, Move> {
unsafe fn take_move_direction(&self, ix: Idx, dir: Dir) -> Move;
}
pub trait TakeMoveNeighbors<Idx, MoveNeighbors> {
unsafe fn take_move_neighbors(&self, ix: Idx) -> MoveNeighbors;
}