pub struct PerPlayer<T, const P: usize> { /* private fields */ }Expand description
A collection that stores one element corresponding to each player in a game.
The type is parameterized by the type of elements T and the number of players in the game
P. For example, the type PerPlayer<f64, 3> contains exactly three f64 values, one for
each player in a three-player game.
The “const generic”
argument P is used to statically ensure that a PerPlayer collection contains the correct
number of elements for a given game, and to provide statically checked indexing into
PerPlayer collections.
§Dynamically checked indexing operations
The get and get_mut methods allow indexing into a
PerPlayer collection with plain usize indexes. They return references wrapped in an
Option type, which may be None if the index is too large for the number of players in the
game.
use t4t::PerPlayer;
let mut pp = PerPlayer::new(["klaatu", "barada", "nikto"]);
assert_eq!(pp.get(0), Some(&"klaatu"));
assert_eq!(pp.get(1), Some(&"barada"));
assert_eq!(pp.get(2), Some(&"nikto"));
assert_eq!(pp.get(3), None);
*pp.get_mut(0).unwrap() = "gort";
assert_eq!(pp.get(0), Some(&"gort"));§Statically checked indexing operations
The for_player and for_player_mut
methods allow indexing into a PerPlayer collection with indexes of type PlayerIndex. An
index of type PlayerIndex<P> is guaranteed to be in-range for a collection of type
PerPlayer<T, P>, that is, indexing operations into a PerPlayer collection are guaranteed
not to fail due to an index out-of-bounds error.
The Index and IndexMut traits are implemented using indexes of type PlayerIndex and
are synonymous with the for_player and for_player_mut methods, respectively.
Indexes can be constructed dynamically using the PlayerIndex::new constructor. While the
indexing operation cannot fail, constructing an index may fail if the index is out of
bounds, in which case the constructor will return None.
use t4t::PlayerIndex;
assert!(PlayerIndex::<3>::new(0).is_some());
assert!(PlayerIndex::<3>::new(1).is_some());
assert!(PlayerIndex::<3>::new(2).is_some());
assert!(PlayerIndex::<3>::new(3).is_none());When constructing indexes, often the value of P can be inferred from the type of the
PerPlayer collection it is used to index into.
use t4t::{PerPlayer, PlayerIndex};
let mut pp = PerPlayer::new(["klaatu", "barada", "nikto"]);
let p0 = PlayerIndex::new(0).unwrap();
let p1 = PlayerIndex::new(1).unwrap();
let p2 = PlayerIndex::new(2).unwrap();
assert_eq!(pp[p0], "klaatu");
assert_eq!(pp[p1], "barada");
assert_eq!(pp[p2], "nikto");
pp[p0] = "gort";
assert_eq!(pp[p0], "gort");Additionally, this module contains several submodules that predefine named indexes for all
players up to a player count of 16. For example, the indexes for three player games are
included in the for3 submodule.
use t4t::{for3, PerPlayer};
let mut pp = PerPlayer::new(["klaatu", "barada", "nikto"]);
assert_eq!(pp[for3::P0], "klaatu");
assert_eq!(pp[for3::P1], "barada");
assert_eq!(pp[for3::P2], "nikto");
pp[for3::P0] = "gort";
assert_eq!(pp[for3::P0], "gort");Implementations§
Source§impl<T, const P: usize> PerPlayer<T, P>
impl<T, const P: usize> PerPlayer<T, P>
Sourcepub fn generate<F: FnMut(PlayerIndex<P>) -> T>(gen_elem: F) -> Self
pub fn generate<F: FnMut(PlayerIndex<P>) -> T>(gen_elem: F) -> Self
Create a new per-player collection by calling the given function with each player index, collecting the results.
§Examples
use t4t::{for5, PerPlayer, PlayerIndex};
let squared = |index: PlayerIndex<5>| {
let val: usize = index.into();
val * val
};
let squares = PerPlayer::generate(squared);
assert_eq!(squares[for5::P0], 0);
assert_eq!(squares[for5::P1], 1);
assert_eq!(squares[for5::P2], 4);
assert_eq!(squares[for5::P3], 9);
assert_eq!(squares[for5::P4], 16);Sourcepub fn num_players(&self) -> usize
pub fn num_players(&self) -> usize
Get the number of players in the game, which corresponds to the number of elements in this collection.
Sourcepub fn get(&self, i: usize) -> Option<&T>
pub fn get(&self, i: usize) -> Option<&T>
Get a reference to the element corresponding to the ith player in the game. Returns
None if the index is out of range.
§Examples
use t4t::PerPlayer;
let mut pp = PerPlayer::new(["frodo", "sam", "merry", "pippin"]);
assert_eq!(pp.get(0), Some(&"frodo"));
assert_eq!(pp.get(1), Some(&"sam"));
assert_eq!(pp.get(2), Some(&"merry"));
assert_eq!(pp.get(3), Some(&"pippin"));
assert_eq!(pp.get(4), None);Sourcepub fn get_mut(&mut self, i: usize) -> Option<&mut T>
pub fn get_mut(&mut self, i: usize) -> Option<&mut T>
Get a mutable reference to the element corresponding to the ith player in the game.
Returns None if the index is out of range.
§Examples
use t4t::PerPlayer;
let mut pp = PerPlayer::new(["frodo", "sam", "merry", "pippin"]);
*pp.get_mut(1).unwrap() = "samwise";
*pp.get_mut(2).unwrap() = "meriadoc";
*pp.get_mut(3).unwrap() = "peregrin";
assert_eq!(pp.get(0), Some(&"frodo"));
assert_eq!(pp.get(1), Some(&"samwise"));
assert_eq!(pp.get(2), Some(&"meriadoc"));
assert_eq!(pp.get(3), Some(&"peregrin"));
assert_eq!(pp.get(4), None);Sourcepub fn for_player(&self, idx: PlayerIndex<P>) -> &T
pub fn for_player(&self, idx: PlayerIndex<P>) -> &T
Index into a PerPlayer collection with a PlayerIndex. This operation is statically
guaranteed not to fail.
§Examples
use t4t::{for4, PerPlayer};
let mut pp = PerPlayer::new(["frodo", "sam", "merry", "pippin"]);
assert_eq!(*pp.for_player(for4::P0), "frodo");
assert_eq!(*pp.for_player(for4::P1), "sam");
assert_eq!(*pp.for_player(for4::P2), "merry");
assert_eq!(*pp.for_player(for4::P3), "pippin");This method is used to implement the Index trait, which enables using the more concise
indexing syntax.
use t4t::{for4, PerPlayer};
let mut pp = PerPlayer::new(["frodo", "sam", "merry", "pippin"]);
assert_eq!(pp[for4::P0], "frodo");
assert_eq!(pp[for4::P1], "sam");
assert_eq!(pp[for4::P2], "merry");
assert_eq!(pp[for4::P3], "pippin");Sourcepub fn for_player_mut(&mut self, idx: PlayerIndex<P>) -> &mut T
pub fn for_player_mut(&mut self, idx: PlayerIndex<P>) -> &mut T
Index into a PerPlayer collection with PlayerIndex in a mutable context. This operation
is statically guaranteed not to fail.
§Examples
use t4t::{for4, PerPlayer};
let mut pp = PerPlayer::new(["frodo", "sam", "merry", "pippin"]);
*pp.for_player_mut(for4::P1) = "samwise";
*pp.for_player_mut(for4::P2) = "meriadoc";
*pp.for_player_mut(for4::P3) = "peregrin";
assert_eq!(*pp.for_player(for4::P0), "frodo");
assert_eq!(*pp.for_player(for4::P1), "samwise");
assert_eq!(*pp.for_player(for4::P2), "meriadoc");
assert_eq!(*pp.for_player(for4::P3), "peregrin");This method is used to implement the IndexMut trait, which enables using the more
concise indexing syntax.
use t4t::{for4, PerPlayer};
let mut pp = PerPlayer::new(["frodo", "sam", "merry", "pippin"]);
pp[for4::P1] = "samwise";
pp[for4::P2] = "meriadoc";
pp[for4::P3] = "peregrin";
assert_eq!(pp[for4::P0], "frodo");
assert_eq!(pp[for4::P1], "samwise");
assert_eq!(pp[for4::P2], "meriadoc");
assert_eq!(pp[for4::P3], "peregrin");Source§impl<T: Clone, const P: usize> PerPlayer<T, P>
impl<T: Clone, const P: usize> PerPlayer<T, P>
Sourcepub fn init_with(value: T) -> Self
pub fn init_with(value: T) -> Self
Create a new per-player collection where each element is initialized with the given cloneable value.
Sourcepub fn for_each<F: FnMut(&T)>(&self, f: F)
pub fn for_each<F: FnMut(&T)>(&self, f: F)
Execute a function for each element in a per-player collection.
§Examples
use t4t::PerPlayer;
let mut longest = "";
let pp = PerPlayer::new(["frodo", "sam", "merry", "pippin"]);
pp.for_each(|s| {
if s.len() > longest.len() {
longest = s;
}
});
assert_eq!(longest, "pippin");Sourcepub fn for_each_with_index<F: FnMut(PlayerIndex<P>, &T)>(&self, f: F)
pub fn for_each_with_index<F: FnMut(PlayerIndex<P>, &T)>(&self, f: F)
Execute a function for each element-index pair in a per-player collection.
§Examples
use t4t::{for4, PerPlayer};
let mut longest = "";
let mut longest_index = for4::P0;
let pp = PerPlayer::new(["frodo", "sam", "pippin", "merry"]);
pp.for_each_with_index(|i, s| {
println!("{}, {}, {}", i, s, s.len());
if s.len() > longest.len() {
println!("updating to {}, {}", i, s);
longest = s;
longest_index = i;
}
});
assert_eq!(longest, "pippin");
assert_eq!(longest_index, for4::P2);Sourcepub fn map<U, F: FnMut(T) -> U>(&self, f: F) -> PerPlayer<U, P>
pub fn map<U, F: FnMut(T) -> U>(&self, f: F) -> PerPlayer<U, P>
Map a function over all elements in a per-player collection, producing a new per-player collection.
§Examples
use t4t::PerPlayer;
let pp = PerPlayer::new(["frodo", "sam", "merry", "pippin"]);
let mut lengths = pp.map(|s| s.len());
assert_eq!(lengths, PerPlayer::new([5, 3, 5, 6]));
let mut firsts = pp.map(|s| s.chars().next().unwrap());
assert_eq!(firsts, PerPlayer::new(['f', 's', 'm', 'p']));Sourcepub fn map_with_index<U, F: FnMut(PlayerIndex<P>, T) -> U>(
&self,
f: F,
) -> PerPlayer<U, P>
pub fn map_with_index<U, F: FnMut(PlayerIndex<P>, T) -> U>( &self, f: F, ) -> PerPlayer<U, P>
Map a function over each element-index pair in a per-player collection, producing a new per-player collection.
§Examples
use t4t::PerPlayer;
let pp = PerPlayer::new(["frodo", "sam", "merry", "pippin"]);
let mut pairs = pp.map_with_index(|i, s| (i.as_usize(), s.len()));
assert_eq!(pairs, PerPlayer::new([(0, 5), (1, 3), (2, 5), (3, 6)]));
let mut nths = pp.map_with_index(|i, s| s.chars().nth(i.as_usize()).unwrap());
assert_eq!(nths, PerPlayer::new(['f', 'a', 'r', 'p']));Source§impl<T: Debug, const P: usize> PerPlayer<Option<T>, P>
impl<T: Debug, const P: usize> PerPlayer<Option<T>, P>
Sourcepub fn all_some(self) -> Option<PerPlayer<T, P>>
pub fn all_some(self) -> Option<PerPlayer<T, P>>
Converts a per-player collection of Option<T> values into a per-player collection of T
values if every element in the initial collection is Some; otherwise returns None.
§Examples
use t4t::PerPlayer;
assert_eq!(
PerPlayer::new([Some(3), Some(4), Some(5)]).all_some(),
Some(PerPlayer::new([3, 4, 5])),
);
assert_eq!(
PerPlayer::new([Some(3), None, Some(5)]).all_some(),
None,
);Source§impl<T, const P: usize> PerPlayer<T, P>
impl<T, const P: usize> PerPlayer<T, P>
Sourcepub fn iter(&self) -> <&[T; P] as IntoIterator>::IntoIter
pub fn iter(&self) -> <&[T; P] as IntoIterator>::IntoIter
An iterator over references to elements in the per-player collection.
Sourcepub fn iter_mut(&mut self) -> <&mut [T; P] as IntoIterator>::IntoIter
pub fn iter_mut(&mut self) -> <&mut [T; P] as IntoIterator>::IntoIter
An iterator over mutable references to elements in the per-player collection.
Trait Implementations§
Source§impl<'a, T, const P: usize> IntoIterator for &'a PerPlayer<T, P>
impl<'a, T, const P: usize> IntoIterator for &'a PerPlayer<T, P>
Source§impl<'a, T, const P: usize> IntoIterator for &'a mut PerPlayer<T, P>
impl<'a, T, const P: usize> IntoIterator for &'a mut PerPlayer<T, P>
Source§impl<T, const P: usize> IntoIterator for PerPlayer<T, P>
impl<T, const P: usize> IntoIterator for PerPlayer<T, P>
Source§impl<T: Ord, const P: usize> Ord for PerPlayer<T, P>
impl<T: Ord, const P: usize> Ord for PerPlayer<T, P>
1.21.0 · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
Source§impl<T: PartialOrd, const P: usize> PartialOrd for PerPlayer<T, P>
impl<T: PartialOrd, const P: usize> PartialOrd for PerPlayer<T, P>
impl<T: Copy, const P: usize> Copy for PerPlayer<T, P>
impl<T: Eq, const P: usize> Eq for PerPlayer<T, P>
impl<T, const P: usize> StructuralPartialEq for PerPlayer<T, P>
Auto Trait Implementations§
impl<T, const P: usize> Freeze for PerPlayer<T, P>where
T: Freeze,
impl<T, const P: usize> RefUnwindSafe for PerPlayer<T, P>where
T: RefUnwindSafe,
impl<T, const P: usize> Send for PerPlayer<T, P>where
T: Send,
impl<T, const P: usize> Sync for PerPlayer<T, P>where
T: Sync,
impl<T, const P: usize> Unpin for PerPlayer<T, P>where
T: Unpin,
impl<T, const P: usize> UnwindSafe for PerPlayer<T, P>where
T: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more