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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//! Rock-paper-scissors and related games.
use *;
/// A move in rock-paper-scissors-style game.
/// The classic [rock-paper-scissors](https://en.wikipedia.org/wiki/Rock_paper_scissors) game.
///
/// The moves are related as follows:
///
/// - `Rock` beats `Scissors`
/// - `Scissors` beats `Paper`
/// - `Paper` beats `Rock`
///
/// A winning move is awarded `1`, a losing move is awarded `-1`, and ties are awarded `0`.
///
/// # Examples
/// ```
/// use t4t::*;
/// use t4t_games::rps;
///
/// let rps = rps::rock_paper_scissors();
/// assert!(rps.is_zero_sum());
/// ```
/// Rock-paper-scissors extended with two news moves: fire and water.
///
/// In this version of the game, `Rock`, `Paper`, and `Scissors` are related to each other as in
/// the basic game. Additionally:
///
/// - `Fire` beats `Rock`, `Paper`, and `Scissors`, but loses to `Water`
/// - `Water` beats `Fire`, but loses to `Rock`, `Paper`, and `Scissors`
///
/// # Examples
/// ```
/// use t4t::*;
/// use t4t_games::rps;
///
/// let fw = rps::fire_water();
/// assert!(fw.is_zero_sum());
/// ```
/// An N-player version of rock-paper-scissors.
///
/// Each player is assigned a utility value that is computed by counting the number of players that
/// the player beat subtracted by the number of players that beat the player. For example, playing
/// `Rock` will give a utility value equal to the number of `Scissors` moves played by other
/// players minus the number of `Paper` moves played by other players.
///
/// # Examples
///
/// ```
/// use t4t::*;
/// use t4t_games::rps;
///
/// // 10-player rock-paper-scissors.
/// let rps10: Normal<rps::Move, i64, 10> = rps::big_rock_paper_scissors();
/// assert!(rps10.is_zero_sum());
///
/// // 1000-player rock-paper-scissors!
/// let rps1000: Normal<rps::Move, i64, 1000> = rps::big_rock_paper_scissors();
/// ```
///
/// Note that `rps1000` demonstrates that `Normal` can represent extremely large games---this game
/// has a payoff table with `3^1000` entries! Such large games can be represented and played
/// without issue, but any function that iterates over the outcomes (such as
/// [`is_zero_sum`](t4t::Normal::is_zero_sum) or any solution concept), will leave you waiting
/// beyond the heat death of the universe.