|
|
@@ -43,7 +43,8 @@ pub fn start_game(_: &deck::Hand, mut players: &mut Vec<Player>) {
|
|
43
|
43
|
panic!("the players don't have the same number of cards")
|
|
44
|
44
|
}
|
|
45
|
45
|
}
|
|
46
|
|
- let mut starting_player_id = 1;
|
|
|
46
|
+ let mut starting_player_id = 0;
|
|
|
47
|
+ println!("===== Début de la partie ! =====");
|
|
47
|
48
|
for _ in 0..cards_per_player {
|
|
48
|
49
|
// For each round of the game
|
|
49
|
50
|
let mut cards_played: Heap = Vec::new();
|
|
|
@@ -54,33 +55,150 @@ pub fn start_game(_: &deck::Hand, mut players: &mut Vec<Player>) {
|
|
54
|
55
|
}
|
|
55
|
56
|
// Decide who has won
|
|
56
|
57
|
starting_player_id = winning_player(&mut cards_played);
|
|
|
58
|
+ let last_card_played = match cards_played.first() {
|
|
|
59
|
+ None => panic!("no card played this round"),
|
|
|
60
|
+ Some(card) => card,
|
|
|
61
|
+ };
|
|
|
62
|
+ println!(">>>>> Le joueur {} remporte le pli avec la carte {} ! <<<<<",
|
|
|
63
|
+ last_card_played.1,
|
|
|
64
|
+ last_card_played.0);
|
|
57
|
65
|
}
|
|
58
|
66
|
}
|
|
59
|
67
|
|
|
|
68
|
+// Keeps the order of the game but puts starting player first
|
|
60
|
69
|
fn sort_by_playing_order(mut players: &mut Vec<Player>, starting_player_id: i32) {
|
|
|
70
|
+ // Implementation via a sort with a complicated comparison function
|
|
|
71
|
+ // that assume that ids go from 0 to params::NUMBER_OF_PLAYERS-1
|
|
61
|
72
|
players.sort_by(|p1, p2| {
|
|
62
|
|
- (p1.id + starting_player_id % params::NUMBER_OF_PLAYERS as i32)
|
|
63
|
|
- .cmp(&(p2.id + starting_player_id % params::NUMBER_OF_PLAYERS as i32))
|
|
|
73
|
+ ((params::NUMBER_OF_PLAYERS as i32 + p1.id - starting_player_id) %
|
|
|
74
|
+ params::NUMBER_OF_PLAYERS as i32)
|
|
|
75
|
+ .cmp(&((params::NUMBER_OF_PLAYERS as i32 + p2.id - starting_player_id) %
|
|
|
76
|
+ params::NUMBER_OF_PLAYERS as i32))
|
|
64
|
77
|
});
|
|
65
|
78
|
}
|
|
66
|
79
|
|
|
67
|
80
|
fn play_card(player: &mut Player, cards_played: &mut Heap) {
|
|
68
|
|
- let valid_cards = valid_cards(&player.hand, cards_played);
|
|
|
81
|
+ let valid_cards = valid_cards(&player, cards_played);
|
|
69
|
82
|
let card = select_card(player, &valid_cards, cards_played);
|
|
70
|
83
|
player.hand.remove(&card);
|
|
71
|
84
|
cards_played.push((card, player.id));
|
|
|
85
|
+ println!("Le joueur {} joue {}.", player.id, card);
|
|
72
|
86
|
}
|
|
73
|
87
|
|
|
74
|
|
-fn valid_cards(hand: &deck::Hand, cards_played: &Heap) -> deck::Hand {
|
|
75
|
|
- unimplemented!();
|
|
|
88
|
+fn valid_cards(player: &Player, cards_played: &Heap) -> deck::Hand {
|
|
|
89
|
+ let valid_hand = player.hand.clone();
|
|
|
90
|
+ match cards_played.first() {
|
|
|
91
|
+ // If first to play then every card is valid
|
|
|
92
|
+ None => return valid_hand,
|
|
|
93
|
+ Some(&(card, _)) => {
|
|
|
94
|
+ match card {
|
|
|
95
|
+ // If fool played first you can play what you want
|
|
|
96
|
+ card::Card::Fool => {
|
|
|
97
|
+ let mut new_cards_played = cards_played.clone();
|
|
|
98
|
+ let _ = new_cards_played.remove(0);
|
|
|
99
|
+ return valid_cards(player, &new_cards_played);
|
|
|
100
|
+ }
|
|
|
101
|
+ // If it's a trump you can play only higher trumps,
|
|
|
102
|
+ // otherwise lower trumps, otherwise anything
|
|
|
103
|
+ card::Card::Trump(_) => {
|
|
|
104
|
+ let max_trump_played = max_trump(cards_played);
|
|
|
105
|
+ let higher_trumps: deck::Hand = valid_hand.iter()
|
|
|
106
|
+ .map(|&card| card.clone())
|
|
|
107
|
+ .filter(|&card| match card {
|
|
|
108
|
+ card::Card::Trump(this_trump) => max_trump_played < this_trump,
|
|
|
109
|
+ _ => false,
|
|
|
110
|
+ })
|
|
|
111
|
+ .collect();
|
|
|
112
|
+ if !higher_trumps.is_empty() {
|
|
|
113
|
+ return higher_trumps;
|
|
|
114
|
+ } else {
|
|
|
115
|
+ // Play a lower trump
|
|
|
116
|
+ let lower_trumps: deck::Hand = valid_hand.iter()
|
|
|
117
|
+ .map(|&card| card.clone())
|
|
|
118
|
+ .filter(|&card| match card {
|
|
|
119
|
+ card::Card::Trump(this_trump) => max_trump_played > this_trump,
|
|
|
120
|
+ _ => false,
|
|
|
121
|
+ })
|
|
|
122
|
+ .collect();
|
|
|
123
|
+ if !lower_trumps.is_empty() {
|
|
|
124
|
+ return lower_trumps;
|
|
|
125
|
+ } else {
|
|
|
126
|
+ // Play anaything
|
|
|
127
|
+ return valid_hand;
|
|
|
128
|
+ }
|
|
|
129
|
+ }
|
|
|
130
|
+ }
|
|
|
131
|
+ // If it's a face you can only play a face of the same suit, otherwise a trump,
|
|
|
132
|
+ // otherwise anything
|
|
|
133
|
+ card::Card::Face(card::Face { suit, symbol: _ }) => {
|
|
|
134
|
+ let same_suit_faces: deck::Hand = valid_hand.iter()
|
|
|
135
|
+ .map(|&card| card.clone())
|
|
|
136
|
+ .filter(|&card| match card {
|
|
|
137
|
+ card::Card::Face(card::Face { suit: this_suit, symbol: _ }) => {
|
|
|
138
|
+ suit == this_suit
|
|
|
139
|
+ }
|
|
|
140
|
+ _ => false,
|
|
|
141
|
+ })
|
|
|
142
|
+ .collect();
|
|
|
143
|
+ if !same_suit_faces.is_empty() {
|
|
|
144
|
+ return same_suit_faces;
|
|
|
145
|
+ } else {
|
|
|
146
|
+ // Play a trump
|
|
|
147
|
+ let trumps: deck::Hand = valid_hand.iter()
|
|
|
148
|
+ .map(|&card| card.clone())
|
|
|
149
|
+ .filter(|&card| match card {
|
|
|
150
|
+ card::Card::Trump(_) => true,
|
|
|
151
|
+ _ => false,
|
|
|
152
|
+ })
|
|
|
153
|
+ .collect();
|
|
|
154
|
+ if !trumps.is_empty() {
|
|
|
155
|
+ return trumps;
|
|
|
156
|
+ } else {
|
|
|
157
|
+ //Play anything
|
|
|
158
|
+ return valid_hand;
|
|
|
159
|
+ }
|
|
|
160
|
+ }
|
|
|
161
|
+ }
|
|
|
162
|
+ }
|
|
|
163
|
+ }
|
|
|
164
|
+ }
|
|
76
|
165
|
}
|
|
77
|
166
|
|
|
78
|
|
-fn select_card(player: &Player, valid_cards: &deck::Hand, cards_played: &Heap) -> card::Card {
|
|
79
|
|
- unimplemented!();
|
|
|
167
|
+// Returns the max trump in a heap of played cards, panics if no trump
|
|
|
168
|
+fn max_trump(cards_played: &Heap) -> card::Trump {
|
|
|
169
|
+ let mut max_trump: Option<card::Trump> = None;
|
|
|
170
|
+ for &(card, _) in cards_played.iter() {
|
|
|
171
|
+ match card {
|
|
|
172
|
+ card::Card::Trump(trump) => {
|
|
|
173
|
+ match max_trump {
|
|
|
174
|
+ None => max_trump = Some(trump),
|
|
|
175
|
+ Some(max) => {
|
|
|
176
|
+ if max < trump {
|
|
|
177
|
+ max_trump = Some(trump);
|
|
|
178
|
+ }
|
|
|
179
|
+ }
|
|
|
180
|
+ }
|
|
|
181
|
+ }
|
|
|
182
|
+ _ => (),
|
|
|
183
|
+ }
|
|
|
184
|
+ }
|
|
|
185
|
+ match max_trump {
|
|
|
186
|
+ None => panic!("no trump, cannot find max"),
|
|
|
187
|
+ Some(max) => max,
|
|
|
188
|
+ }
|
|
|
189
|
+}
|
|
|
190
|
+
|
|
|
191
|
+// Select a card to play among the valid cards
|
|
|
192
|
+fn select_card(_: &Player, valid_cards: &deck::Hand, _: &Heap) -> card::Card {
|
|
|
193
|
+ match valid_cards.iter().next() {
|
|
|
194
|
+ None => panic!("no valid card to play"),
|
|
|
195
|
+ Some(card) => card.clone(),
|
|
|
196
|
+ }
|
|
80
|
197
|
}
|
|
81
|
198
|
|
|
|
199
|
+// Determine who won the round
|
|
82
|
200
|
fn winning_player(cards: &mut Heap) -> i32 {
|
|
83
|
|
- cards.sort_by(|&(card1, _), &(card2, _)| card1.cmp(&card2));
|
|
|
201
|
+ cards.sort_by(|&(card1, _), &(card2, _)| card2.cmp(&card1));
|
|
84
|
202
|
match cards.first() {
|
|
85
|
203
|
Some(&(_, id)) => id,
|
|
86
|
204
|
None => panic!("no cards have been played"),
|