pub struct Board { /* private fields */ }
Expand description
Represents an Othello board and provides convenient functions to manipulate it.
The board is represented by two bitboards, one for black and one for white. Each bitboard is a 64-bit unsigned integer, where each bit encodes if a stone for that player exists on that space. As can be seen in the graphic below, MSB denotes A1 while LSB denotes H8.
A B C D E F G H
+----+----+----+----+----+----+----+----+
1 | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 |
+----+----+----+----+----+----+----+----+
2 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 |
+----+----+----+----+----+----+----+----+
3 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
+----+----+----+----+----+----+----+----+
4 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
+----+----+----+----+----+----+----+----+
5 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
+----+----+----+----+----+----+----+----+
6 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
+----+----+----+----+----+----+----+----+
7 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 |
+----+----+----+----+----+----+----+----+
8 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
+----+----+----+----+----+----+----+----+
Implementations§
source§impl Board
impl Board
sourcepub fn standard() -> Self
pub fn standard() -> Self
Returns a board with the standard opening position configured.
If W
denotes white and B
denotes black, this is the opening
position:
ABCDEFGH
+--------+
1 |........|
2 |........|
3 |........|
4 |...WB...|
5 |...BW...|
6 |........|
7 |........|
8 |........|
+--------+
§Examples
use magpie::othello::Board;
let board = Board::standard();
assert_eq!(60, board.empty_squares().count_set());
sourcepub fn is_valid(&self) -> bool
pub fn is_valid(&self) -> bool
Evaluates if the board is in a consistent state
Consistency is defined as whether or not multiple stones occupy the same square.
§Examples
use magpie::othello::{Board, Stone};
let mut board = Board::empty();
// The board should be valid
assert!(board.is_valid());
// Here multiple stones are placed on the same
// squares, which is not valid
board.place_stone_unchecked(Stone::Black, u64::MAX.into());
board.place_stone_unchecked(Stone::White, u64::MAX.into());
assert!(!board.is_valid());
sourcepub fn place_stone_unchecked(&mut self, stone: Stone, pos: Bitboard)
pub fn place_stone_unchecked(&mut self, stone: Stone, pos: Bitboard)
Places stones in the specified positions.
Multiple stones may be placed at once, but no other stones will be flipped as during normal play. No restrictions are placed on the number or position of the pieces which may result in an invalid board where multiple stones occupy the same square. It is the responsibility of the caller to ensure that the board remains consistent.
remove_stone_unchecked
may be of use as well.
§Examples
use magpie::othello::{Board, Stone};
let mut board = Board::empty();
let pos = 1_u64.try_into().unwrap();
board.place_stone_unchecked(Stone::Black, pos);
assert_ne!(board, Board::empty());
sourcepub fn remove_stone_unchecked(&mut self, stone: Stone, pos: Bitboard)
pub fn remove_stone_unchecked(&mut self, stone: Stone, pos: Bitboard)
Removes stones in the specified positions.
Multiple stones may be removed at once.
place_stone_unchecked
may be of use as well.
§Examples
use magpie::othello::{Board, Stone};
let mut board = Board::standard();
let black_stones = board.bits_for(Stone::Black);
let white_stones = board.bits_for(Stone::White);
board.remove_stone_unchecked(Stone::Black, black_stones);
board.remove_stone_unchecked(Stone::White, white_stones);
assert_eq!(board, Board::empty());
sourcepub fn play(&mut self, stone: Stone, pos: Position)
pub fn play(&mut self, stone: Stone, pos: Position)
Places a stone in the specified position and updates the board accordingly.
It is the responsibility of the caller to ensure that the move is legal. Playing an illegal move will result in undefined behavior.
§Examples
use magpie::othello::{Board, Stone};
let mut board = Board::standard();
let player = Stone::Black;
let pos = board
.moves_for(player)
.hot_bits()
.next()
.unwrap();
board.play(Stone::Black, pos);
assert_ne!(board, Board::standard());
sourcepub fn bits_for(&self, stone: Stone) -> Bitboard
pub fn bits_for(&self, stone: Stone) -> Bitboard
Returns the bitboard representation of the specified player.
§Examples
use magpie::othello::{Board, Stone};
let board = Board::standard();
let black = board.bits_for(Stone::Black);
let white = board.bits_for(Stone::White);
// The two bitboards do not intersect
assert_eq!(0, black & white);
// They do contain the same number of stones
assert_eq!(black.count_set(), white.count_set());
sourcepub fn is_legal_move(&self, stone: Stone, pos: Position) -> bool
pub fn is_legal_move(&self, stone: Stone, pos: Position) -> bool
Checks whether or not a move is valid for the specified player.
§Examples
use magpie::othello::{Board, Stone};
let board = Board::standard();
let pos = 1_u64.try_into().unwrap();
assert!(!board.is_legal_move(Stone::Black, pos));
sourcepub fn moves_for(&self, stone: Stone) -> Bitboard
pub fn moves_for(&self, stone: Stone) -> Bitboard
Calculates and returns the set of all legal moves for the specified player.
§Examples
use magpie::othello::{Board, Stone};
let board = Board::standard();
let stone = Stone::Black;
assert_eq!(4, board.moves_for(stone).count_set());
sourcepub fn empty_squares(&self) -> Bitboard
pub fn empty_squares(&self) -> Bitboard
Returns the set of all empty squares on the board.
§Examples
use magpie::othello::Board;
let board = Board::standard();
assert_eq!(60, board.empty_squares().count_set());
sourcepub fn stone_at(&self, pos: Position) -> Option<Stone>
pub fn stone_at(&self, pos: Position) -> Option<Stone>
Queries the board at the specified position for the presence of a stone.
§Examples
use magpie::othello::{Board, Stone};
let board = Board::standard();
let pos = 0x8000000.try_into().unwrap();
assert_eq!(Some(Stone::White), board.stone_at(pos));
sourcepub fn display(&self) -> BoardDisplay<'_>
pub fn display(&self) -> BoardDisplay<'_>
Trait Implementations§
source§impl PartialEq for Board
impl PartialEq for Board
source§impl TryFrom<(Bitboard, Bitboard)> for Board
impl TryFrom<(Bitboard, Bitboard)> for Board
source§fn try_from(stones: (Bitboard, Bitboard)) -> Result<Self, Self::Error>
fn try_from(stones: (Bitboard, Bitboard)) -> Result<Self, Self::Error>
Returns a board built from the two specified bitboards.
Returns an error if the two bitboards intersect.
§Examples
use magpie::othello::{Board, Stone};
let board = Board::standard();
let black = board.bits_for(Stone::Black);
let white = board.bits_for(Stone::White);
// Quite a contrived example
let board = Board::try_from((black, white));
assert_eq!(Ok(Board::standard()), board);
§type Error = OthelloError
type Error = OthelloError
source§impl TryFrom<(u64, u64)> for Board
impl TryFrom<(u64, u64)> for Board
source§fn try_from(stones: (u64, u64)) -> Result<Self, Self::Error>
fn try_from(stones: (u64, u64)) -> Result<Self, Self::Error>
Returns a board built from the two specified bitboards.
Returns an error if the two bitboards intersect.
§Examples
use magpie::othello::{Board, Stone};
let board = Board::standard();
let black = board.bits_for(Stone::Black);
let white = board.bits_for(Stone::White);
// Quite a contrived example
let board = Board::try_from((black, white));
assert_eq!(Ok(Board::standard()), board);