#holochain #game #turn #game-state #player #generic #dht

已撤销 holochain_turn_based_game

Holochain 通用库,用于构建基于回合制的游戏,包含 DHT 验证动作

0.2.3 2021年5月14日
0.2.2 2021年5月14日
0.2.0 2021年4月9日
0.1.4 2020年6月12日
0.1.0 2020年4月25日

#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