Expand description
This crate provides functionality for creating software related to the tafl family of board games. It includes structs, enums and traits that encapsulate game data and logic, helpful to build games, AIs, etc. It is not a goal of this crate to provide any concrete implementations of game clients or AIs.
§Getting started
As a starting point, you will likely want to use the following structs if you are implementing a game engine or similar:
rules::Ruleset: Specifies the rules for the game.game::logic::GameLogic: Keeps a copy of the game rules, and implements the logic required to assess the validity and outcome of a given move. The data stored in this struct is expected to be static over the course of a single game. It does not keep information about the current game state, but rather, its methods take a reference to that state as necessary.game::state::GameState: Keeps track of the current state of the game - that is, all the data that changes frequently, such as positions of pieces on the board, which side is to play, etc. The aim is to minimise the memory footprint of this data and avoid heap allocations so that game state can be copied and passed around efficiently.game::Game: This struct contains aGameLogicand aGameState, and also contains a couple ofVecs which keep track of previous moves (to allow move history to be shown to the user) and previous game states (to allow move undoing). Therefore, it is a helpful struct when building a game client, for example.
You can roll your own ruleset and starting board setup, or you can choose from one of the common
variants which are included in the preset::rules and preset::boards modules.
§Board state
Board state, and other collections of pieces and tiles, are generally implemented using
bitfields (integers). Larger boards require larger integer types to be able to display
the board state. For example, a 7x7 board can be represented using u64s, but an 11x11 board
would require u128s.
In addition, board state generally uses a separate bitfield for each side and
piece type that can be placed on the board. Therefore, for variants which support a wider range
of pieces, more bitfields are required. To allow different board sizes and piece sets
to be represented, while also allowing state for smaller, simpler games to be represented
efficiently, hnefatafl uses a number of different traits and structs to represent board state.
Some of the key traits and structs used to store game state are described below:
bitfield::BitFieldis a trait allowing access to a bitfield and basic conversions betweenTiles and bit indices. It is implemented on a number of different integer types. It is kind of the building block of the other structs and traits used to represent board state.collections::TileSetis a struct that represents a set ofTileson a board. It is generic overBitField.collections::PieceMapis a trait allowing mapping of tiles to the pieces (if any) that occupy them.PieceMaphas an associated typeBitFieldwhich is the bitfield type used to represent the board state. Several of the collections returned by functions onPieceMapare generic over that type.collections::BasicPieceMapis a struct that implementsPieceMapusingTileSets to represent the “basic” pieces: attacking soldiers, defending soldiers and defending king.board::state::BoardStateis a trait allowing access to the board state. It has two associated types:BitFieldandPieceMap(each of which is constrained by the trait of the same name) which are used to store and represent board state internally.board::state::BasicBoardStateis a struct that implementsBoardStatefor basic pieces. It is generic overBitFieldand uses aBasicPieceMapto store state internally.game::state::GameStateis a struct that represents the current state of a game. It is generic overBoardState, and includes both board state and other game state, such as the player whose turn it is.game::Gameis a struct that represents a game. It groups together state, rules and history. It is generic overBoardState.
To reduce the complexity of having to deal with generics and associated types for simple use
cases, some concrete implementations of these traits are provided. These are found in the
aliases module. So, for example, if you just want to play a game on a 7x7 board, you can use
a SmallBasicGame instead of a Game<BasicBoardState<u64>>.
§Serialization
If compiled with the serde feature, the structs in this crate may be serialised and
deserialized using the serde crate.
Modules§
- aliases
- Type aliases for concrete implementations of generic structs. This module contains some concrete implementations of various generic structs for ease of use. The general naming convention used is:
- bitfield
- An implementation of a bitfield, used to hold board state.
- board
- Code relating to the board, including board state and geometry.
- collections
- Code relating to collections of pieces and tiles.
- error
- Errors used elsewhere in the crate.
- game
- Code for implementing a game, including game logic and state.
- pieces
- Code relating to game pieces.
- play
- Code relating to “plays” (ie, game moves).
- preset
- Pre-defined rulesets and board positions.
- rules
- Code for defining game rules.
- tiles
- Code relating to board tiles and coordinates.
Macros§
- basic_
piecemap - Create a new
BasicPieceMapwith the given placed pieces. The first argument is theBitFieldimplementation to use. - impl_
bitfield - Implement the
BitFieldtrait for the given integer type. First argument should be the type to implement the trait for; the second should be the byte value to use forBitField::ROW_WIDTH. This macro is for use with the standard library integer types. - impl_
bitfield_ bigint - Implement the
BitFieldtrait for the given integer type. First argument should be the type to implement the trait for; the second should be the byte value to use forBitField::ROW_WIDTH. This macro is for use with the big integer types provided by theprimitive_typescrate. It implements the trait in a way that works with the methods exposed by these types. Trying to use this macro on other types (or, conversely, trying to use thecrate::impl_bitfield!macro on theprimitive_typestypes) could result in weird and difficult to debug errors like stack overflows. - tileset
- Creates a
TileSetcontaining the arguments, similar tovec!.