DanielBarton446 / DanielBarton446/rust-go

[bug]: Captured Stones do not update adjacent chains' liberties

Open
#19 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Rust
Stars
1
Forks
0
PR merge metrics
No merged PRs in 30d

Description

### Describe the bug

Add the following unit test:
```rust
#[test]
fn dead_center_stone() {
let mut game: Game = Game::new_game(3, 3, Default::default());
game.make_move(0, 1).unwrap();
game.make_move(0, 0).unwrap();
game.make_move(1, 0).unwrap(); // capture corner
game.make_move(0, 2).unwrap();
game.make_move(1, 2).unwrap(); // capture corner
game.make_move(1, 1).unwrap(); // place center stone
game.make_move(2, 1).unwrap(); // capture center stone

dbg!("{}", &game.board);
dbg!("{:?}", &game.stone_groups.liberties);
let expected_board_state = vec![
vec![Stone::Empty, Stone::Black, Stone::Empty],
vec![Stone::Empty, Stone::Blac, Stone::Empty],
vec![Stone::Empty, Stone::Black, Stone::Empty],
];
assert_eq!(game.board.state, expected_board_state);
}

```

When running cargo test, we see:
```
failures:

---- game_logic::game::tests::dead_center_stone stdout ----
[src/game_logic/game.rs:289] "{}" = "{}"
[src/game_logic/game.rs:289] &game.board = Board {
state: [
[
Empty,
Empty,
Empty,
],
[
Black,
Empty,
Black,
],
[
Empty,
Black,
Empty,
],
],
width: 3,
height: 3,
}
[src/game_logic/game.rs:290] "{:?}" = "{:?}"
[src/game_logic/game.rs:290] &game.stone_groups.liberties = [
{},
{},
{},
{
6,
},
{},
{
8,
},
{},
{
6,
8,
},
{},
]
thread 'game_logic::game::tests::dead_center_stone' panicked at 'assertion failed: `(left == right)`
left: `[[Empty, Empty, Empty], [Black, Empty, Black], [Empty, Black, Empty]]`,
right: `[[Empty, Black, Empty], [Black, Empty, Empty], [Empty, Black, Empty]]`', src/game_logic/game.rs:296:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrac
```

What is happening here is that because the stone on index (1), or A2 had 2 stones on either side of it, threatening atari. However, these stones were captured which should have added back the liberties to the chain. This does not happen.

Because of this, we see that the A2 stone gets captured in this test as well as the center stone.

To resolve the issue, we need to:
1) On chain capture, for each stone in the chain, check immediate neighbors for opponent chains. Add the position back to the chain.

### Steps to reproduce

game.make_move(0, 1).unwrap();
game.make_move(0, 0).unwrap();
game.make_move(1, 0).unwrap(); // capture corner
game.make_move(0, 2).unwrap();
game.make_move(1, 2).unwrap(); // capture corner
game.make_move(1, 1).unwrap(); // place center stone
game.make_move(2, 1).unwrap(); // capture center stone

### Expected behavior

We expect not to lose the stone at A2 since A2 captured the corner stones which should open the liberties back up.

### Additional information

_No response_

### Operating system

Linux

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the dead_center_stone test and the capture logic in src/game_logic/game.rs, then run cargo test to reproduce the failure. Trace the captured chain's neighboring groups and their recorded liberties. Done means the test passes, the A2 stone remains on the board, and the center stone is captured as expected.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
game-dev
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.