/// ### The problem
for k in 0..np {
if k == index {
gs.players[k].body_mut().clear();
gs.players[k].body_mut().push(new_head);
} else if gs.players[k].body().is_empty() {
panic!("Broken invariant");
} else {
let head = *gs.players[k].head().expect("Broken invariant");
// let cells = &gs.field.cells;
gs.players[k].body_mut().retain(|ref p| {
// remove the points from the body if they are owned by someone else
match gs.field.cells[p.0 as usize][p.1 as usize] {
Cell::Owned(_) => false,
_ => true
}
});
// just in case
if gs.players[k].body().is_empty() {
gs.players[k].body_mut().push(head);
}
}
}
/*
We get the error:
```
error[E0502]: cannot borrow `gs` as immutable because `gs.players` is also borrowed as mutable
--> src/model.rs:723:49
|
723 | gs.players[k].body_mut().retain(|ref p| {
| ---------- ^^^^^^^ immutable borrow occurs here
| |
| mutable borrow occurs here
724 | // remove the points from the body if they are owned by someone else
725 | match gs.field.cells[p.0 as usize][p.1 as usize] {
| -- borrow occurs due to use of `gs` in closure
...
729 | });
| - mutable borrow ends here
*/
/// ### Fix
for k in 0..np {
if k == index {
gs.players[k].body_mut().clear();
gs.players[k].body_mut().push(new_head);
} else if gs.players[k].body().is_empty() {
panic!("Broken invariant");
} else {
let head = *gs.players[k].head().expect("Broken invariant");
// make the closure to refer only the part of the game state, not the whole one
let cells = &gs.field.cells;
gs.players[k].body_mut().retain(|ref p| {
// remove the points from the body if they are owned by someone else
match cells[p.0 as usize][p.1 as usize] {
Cell::Owned(_) => false,
_ => true
}
});
// just in case
if gs.players[k].body().is_empty() {
gs.players[k].body_mut().push(head);
}
}
}
Comments