| Crates.io | secondbest |
| lib.rs | secondbest |
| version | 0.6.0 |
| created_at | 2025-05-19 12:45:45.461562+00 |
| updated_at | 2025-07-06 12:51:49.300161+00 |
| description | A Rust library for implementing the Second Best strategy game |
| homepage | https://smooth-pudding.hatenablog.com/ |
| repository | https://github.com/mat-der-D/secondbest |
| max_upload_size | |
| id | 1679689 |
| size | 130,527 |
secondbest is a Rust library for implementing the "Second Best" strategy game. This library
provides a complete implementation of the game rules, board representation, and game state management.
"Second Best" is a strategic board game played on 8 positions arranged in a circle. Players take turns placing pieces of their color (Black or White) or moving pieces already on the board. The game features a unique mechanic where a player can declare "second best" after their opponent's move, forcing the opponent to choose a different action.
The unique feature of this game is the "second best" declaration:
A player wins when they achieve one of the following:
Note: Winning conditions are only checked after all "second best" declarations have been used.
The library is organized into several modules:
board: Core board representation and operations
BitBoard: Low-level bit manipulation for efficient board state representationBoard: High-level API for board manipulationPosition: Enumeration of the 8 board positions (N, NE, E, SE, S, SW, W, NW)Color: Player colors (B for Black, W for White)Action: Game actions (Put or Move)game: Game state management
Game: Main game state controllerGameResult: Game outcome representationerror: Error handling
use secondbest::prelude::*;
// Create a new game
let mut game = Game::new();
// Apply actions (place pieces and move them)
game.apply_action(Action::Put(Position::N, Color::B)).unwrap();
game.apply_action(Action::Put(Position::S, Color::W)).unwrap();
// Check game state
if game.can_declare_second_best() {
game.declare_second_best().unwrap();
}
// Check for a winner
match game.result() {
GameResult::Finished { winner } => println!("Winner: {:?}", winner),
GameResult::InProgress => println!("Game still in progress"),
}
For lower-level control, you can work directly with the Board API:
use secondbest::prelude::*;
let mut board = Board::default();
// Place pieces
board.put(Position::N, Color::B).unwrap();
// Check board state
let pieces_at_north = board.get_pieces_at(Position::N);
let black_piece_count = board.count_pieces(Color::B);
// Check for winning conditions
if board.lines_up(Color::B) {
println!("Black has won!");
}
The library provides detailed error types for various operations:
use secondbest::prelude::*;
use secondbest::error::GameError;
let mut game = Game::new();
let result = game.apply_action(Action::Put(Position::N, Color::B));
match result {
Ok(()) => println!("Action applied successfully"),
Err(GameError::IllegalAction(_)) => println!("Illegal action"),
Err(GameError::GameAlreadyOver) => println!("Game is already over"),
Err(GameError::BoardError(_)) => println!("Board error occurred"),
Err(_) => println!("Other error occurred"),
}
License: MIT OR Apache-2.0