Skip to content

Commit f9fce0b

Browse files
committed
Implementing tile flipping
1 parent 846702c commit f9fce0b

File tree

1 file changed

+37
-8
lines changed

1 file changed

+37
-8
lines changed

examples/reversi/board.rs

+37-8
Original file line numberDiff line numberDiff line change
@@ -87,26 +87,54 @@ impl Board {
8787
self.valid_moves.contains(position)
8888
}
8989

90-
pub fn play_piece(&mut self, pos: Position) {
90+
/// Returns the tiles that were flipped
91+
pub fn play_piece(&mut self, pos: Position) -> Vec<Position> {
9192
if self.is_valid_move(&pos) {
9293
assert!(self[pos.0][pos.1].is_none(), "Valid move was not an empty tile!");
9394
self.tiles[pos.0][pos.1] = Some(self.current);
94-
self.flip_tiles(pos);
95+
let flipped = self.flip_tiles(pos);
9596

9697
self.current = self.current.other();
9798

9899
//TODO: When nested method calls are enabled, this can be done in one line
99100
// Link: https://github.com/rust-lang/rust/issues/44100
100101
let current = self.current;
101102
self.update_valid_moves(current);
103+
flipped
102104
}
103105
else {
104106
unreachable!("Game should check for whether a valid move was used before playing it");
105107
}
106108
}
107109

108-
fn flip_tiles(&mut self, start: Position) {
109-
unimplemented!()
110+
fn flip_tiles(&mut self, (row, col): Position) -> Vec<Position> {
111+
let piece = self.current;
112+
assert_eq!(self.tiles[row][col], Some(piece));
113+
let other = piece.other();
114+
let rows = self.tiles.len() as isize;
115+
let cols = self.tiles[0].len() as isize;
116+
117+
let mut flipped = Vec::new();
118+
for (adj_row, adj_col) in self.adjacent_positions((row, col)) {
119+
if self.tiles[adj_row][adj_col] == Some(other)
120+
&& self.find_piece((row, col), (adj_row, adj_col), piece) {
121+
// Perform flips
122+
let delta_row = adj_row as isize - row as isize;
123+
let delta_col = adj_col as isize - col as isize;
124+
let mut curr_row = adj_row as isize;
125+
let mut curr_col = adj_col as isize;
126+
while curr_row >= 0 && curr_row < rows && curr_col >= 0 && curr_col < cols {
127+
let current = &mut self.tiles[curr_row as usize][curr_col as usize];
128+
if *current == Some(other) {
129+
*current = Some(piece);
130+
flipped.push((curr_row as usize, curr_col as usize));
131+
}
132+
curr_row += delta_row;
133+
curr_col += delta_col;
134+
}
135+
}
136+
}
137+
flipped
110138
}
111139

112140
fn update_valid_moves(&mut self, piece: Piece) {
@@ -151,17 +179,18 @@ impl Board {
151179
/// finds piece AND only encounters piece.other() along the way.
152180
fn find_piece(&self, pos: Position, (target_row, target_col): Position, piece: Piece) -> bool {
153181
let other = piece.other();
182+
let rows = self.tiles.len() as isize;
183+
let cols = self.tiles[0].len() as isize;
154184

155185
let delta_row = target_row as isize - pos.0 as isize;
156186
let delta_col = target_col as isize - pos.1 as isize;
157187

158188
let mut curr_row = target_row as isize + delta_row;
159189
let mut curr_col = target_col as isize + delta_col;
160-
while curr_row >= 0 && curr_row < self.tiles.len() as isize
161-
&& curr_col >= 0 && curr_col < self.tiles[0].len() as isize {
190+
while curr_row >= 0 && curr_row < rows && curr_col >= 0 && curr_col < cols {
162191
let current = self.tiles[curr_row as usize][curr_col as usize];
163-
curr_row = curr_row + delta_row;
164-
curr_col = curr_col + delta_col;
192+
curr_row += delta_row;
193+
curr_col += delta_col;
165194
if current == Some(other) {
166195
continue;
167196
}

0 commit comments

Comments
 (0)