0.2.3 |
|
---|---|
0.2.2 |
|
0.2.0 |
|
0.1.4 |
|
0.1.0 |
|
#38 in #game-state
26KB
465 行
holochain_turn_based_game
通用 Holochain 引擎混合,用于在您的 Holochain 应用中创建基于回合制的游戏。这些游戏具有有限数量的玩家,其中每个玩家依次进行回合。
这是对该引擎先前版本的更新,可在 https://github.com/holochain-devcamp/generic-game 中找到,由 https://github.com/willemolding 编码。
此混合程序针对 hdk v0.0.100
构建,并在 crates: https://crates.io/crates/holochain_turn_based_game 上发布。
文档
在此处可以找到此混合程序的文档:https://docs.rs/holochain-turn-based-game。
安装
将以下内容添加到您的 zome cargo toml 中。
holochain_turn_based_game = "0.2"
设置
我们将按照顺序执行所有步骤以创建或转换游戏,以井字棋为例(您可以在 example-dna
中找到完整的 hApp 示例)。
1. 创建您的游戏状态结构
您需要创建一个表示游戏在任何时间点的状态的 struct
。这个结构将不会被提交为条目,因此您不需要在 DHT 方面进行优化。
#[derive(Clone, Debug, Serialize, Deserialize, DefaultJson)]
pub struct Piece {
pub x: usize,
pub y: usize,
}
#[derive(Clone, Debug, Serialize, Deserialize, DefaultJson)]
pub struct TicTacToe {
pub player_1: Vec<Piece>,
pub player_2: Vec<Piece>,
}
2. 创建您的移动类型
接下来,我们必须创建一个表示玩家在回合中可以执行的所有可能的移动的移动类型。这通常是一个枚举,概述了所有不同的移动类型,并包含了关于移动的所有必要信息。此结构将 会 以序列化形式提交到 DHT,因此请确保不要加载太多冗余信息。
#[derive(Clone, Debug, Serialize, Deserialize, DefaultJson)]
pub enum TicTacToeMove {
Place(Piece),
Resign,
}
3. 实现 Game 特性
接下来,我们需要指定我们游戏的行为。这是通过实现 Game
特性来完成的
impl Game<TicTacToeMove> for TicTacToe {
// The minimum number of players that must participate for the game to be valid
// Return None if there is no limit
fn min_players() -> Option<usize> {
Some(2)
}
// The maximum number of players that must participate for the game to be valid
// Return None if there is no limit
fn max_players() -> Option<usize> {
Some(2)
}
// Constructs the initial state for the game
fn initial(players: &Vec<AgentPubKeyB64>) -> Self {
...
}
// Applies the move to the game object, transforming it
// If the move is invalid, it should return an error
fn apply_move(&mut self, game_move: &M, players: &Vec<AgentPubKeyB64>, author_index: usize) -> ExternResult<()> {
...
}
// Gets the winner for the game
fn get_winner(
&self,
players: &Vec<AgentPubKeyB64>,
) -> Option<AgentPubKeyB64> {
...
}
}
从现在开始,在调用库中的大多数函数时,我们需要提供游戏和移动结构作为类型参数,以便库可以执行其函数。
4. 添加游戏和移动条目定义
use holochain_turn_based_game::prelude::*;
entry_defs![GameMoveEntry::entry_def(), GameEntry::entry_def()];
5. 从 zome 的 init
中调用 init 函数
use holochain_turn_based_game::prelude::*;
#[hdk_extern]
pub fn init(_: ()) -> ExternResult<InitCallbackResult> {
init_turn_based_games()
}
玩一个游戏
1. 创建游戏
要创建游戏,请调用 create_game
函数
#[hdk_extern]
fn create_game(rival: AgentPubKeyB64) -> ExternResult<EntryHashB64> {
let hash = holochain_turn_based_game::prelude::create_game(vec![
rival,
agent_info()?.agent_latest_pubkey.into(),
])?;
Ok(hash)
}
玩家在向量中的顺序将决定他们移动的顺序。
2. 进行移动
要创建移动,请调用 create_move
函数
#[derive(Serialize, Deserialize, Debug)]
struct PlacePieceInput {
game_hash: EntryHashB64,
previous_move_hash: Option<EntryHashB64>,
x: usize,
y: usize,
}
#[hdk_extern]
fn place_piece(
PlacePieceInput {
game_hash,
previous_move_hash,
x,
y,
}: PlacePieceInput,
) -> ExternResult<EntryHashB64> {
let game_move = TicTacToeMove::Place(Piece { x, y });
let move_hash = holochain_turn_based_game::prelude::create_move(
game_hash,
previous_move_hash,
game_move,
)?;
Ok(move_hash)
}
3. 获取游戏状态
要获取游戏条目,请调用 get_game
#[hdk_extern]
fn get_game(game_hash: EntryHashB64) -> ExternResult<GameEntry> {
holochain_turn_based_game::prelude::get_game(game_hash)
}
要获取游戏中完成的移动,请调用 get_game_moves
#[hdk_extern]
fn get_moves(game_hash: EntryHashB64) -> ExternResult<Vec<MoveInfo>> {
holochain_turn_based_game::prelude::get_game_moves(game_hash)
}
要获取游戏的胜者,请调用 get_game_winner
#[hdk_extern]
fn get_winner(game_hash: EntryHashB64) -> ExternResult<Option<AgentPubKeyB64>> {
let winner = holochain_turn_based_game::prelude::get_game_winner::<TicTacToe, TicTacToeMove>(
game_hash,
)?;
Ok(winner)
}
依赖项
~5-11MB
~110K SLoC