## Vara Network 链上游戏案例 <img src="https://hackmd.io/_uploads/ByRqBZKbR.png" width="640" alt="GEAR"> ### Racing Cars https://racing.vara.network --- <img src="https://hackmd.io/_uploads/S1m9BbY-C.png" width="1200" alt="GEAR"> --- <img src="https://hackmd.io/_uploads/HkktUbKWA.png" width="1200" alt="GEAR"> --- <img src="https://hackmd.io/_uploads/ryAJw-F-A.png" width="1200" alt="GEAR"> --- ## 游戏实例 (GameInstance) ``` pub struct Game { pub cars: BTreeMap<ActorId, Car>, pub car_ids: Vec<ActorId>, pub current_turn: u8, pub state: GameState, pub result: Option<GameResult>, pub current_round: u32, pub last_time_step: u64, } ``` 向入口函数发送消息更新游戏状态: - Init: `In<GameInit>` - Handle: `InOut<GameAction, Result<GameReply, GameError>>` --- ## 初始状态 (Init) ``` #[no_mangle] extern fn init() { let init_msg: GameInit = msg::load().expect("Unable to load the message"); unsafe { CONTRACT = Some(Contract { admins: vec![msg::source()], config: init_msg.config, games: HashMap::with_capacity(20_000), msg_id_to_game_id: HashMap::with_capacity(5_000), ..Default::default() }); } } ``` --- ## 游戏动作 ``` #[derive(Encode, Decode, TypeInfo, Debug)] pub enum StrategyAction { BuyAcceleration, BuyShell, Skip, } ``` --- ``` impl Game { pub fn buy_acceleration(&mut self) { let car_id = self.get_current_car_id(); let car = self.cars.get_mut(&car_id).expect("Get Car: Can't be None"); car.speed = car.speed.saturating_add(DEFAULT_SPEED); car.car_actions.push(RoundAction::Accelerated); } pub fn buy_shell(&mut self) { let car_id = self.get_current_car_id(); let shelled_car_id = self.find_car_to_shell(&car_id); self.cars.entry(shelled_car_id).and_modify(|car| { let new_speed = car.speed.saturating_sub(DEFAULT_SPEED); car.speed = new_speed.max(DEFAULT_SPEED); car.car_actions.push(RoundAction::SlowedDown); }); } ``` --- ## 更新状态 ``` pub fn update_positions(&mut self, config: &Config) { ... } ``` --- ## 玩家逻辑 ``` impl Game { fn player_move( &mut self, msg_src: &ActorId, strategy_move: StrategyAction, ) -> Result<GameReply, GameError> { let game = self.get_game(msg_src); if game.state != GameState::PlayerAction { return Err(GameError::NotPlayerTurn); } match strategy_move { StrategyAction::BuyAcceleration => { game.buy_acceleration(); } StrategyAction::BuyShell => { game.buy_shell(); } StrategyAction::Skip => {} } ... } ``` --- ## 机器人算法 car-1: 一直加速 car-2: 加权随机 car-3: 按位置决定操作 --- ## 状态清理 游戏结束一分钟后自动清理链上状态 ``` fn send_messages(account: &ActorId, config: &Config) { msg::send_with_gas_delayed( exec::program_id(), GameAction::RemoveGameInstance { account_id: *account, }, config.gas_to_remove_game, 0, config.time_interval, ) .expect("Error in sending message"); } ``` --- ## References https://wiki.gear-tech.io/docs/examples/Gaming/racingcars/ https://wiki.gear-tech.io/docs/developing-contracts/interactions-between-programs/ https://github.com/gear-foundation/dapps/tree/master/contracts/car-races --- # Questions <img src="https://hackmd.io/_uploads/SyK8P72d2.jpg" width="240" alt="GEAR"> <img src="https://hackmd.io/_uploads/By_kgE3_2.png" width="240" alt="VARA"> 课后答疑频道: https://t.me/Gear_CN
{"title":"Racing Cars","slideOptions":"{\"theme\":\"dark\",\"spotlight\":{\"enabled\":false},\"width\":1600,\"height\":900}","description":"Racing Cars","image":"https://hackmd.io/_uploads/HJRhVbYZ0.png","contributors":"[{\"id\":\"94262fbf-81ae-4ed7-933c-561a41bd977a\",\"add\":8257,\"del\":4536}]"}
    164 views