Let's Move 是一項學習 Move 語言的激勵計畫,鼓勵更多的人學習 Move 語言
學習日誌 (alva-lin)
任務 4 - 完成一個遊戲的上鏈部署 (mainnet)#
任務
完成鏈遊相關知識的學習
完成隨機數的學習
完成如何存儲 Coin 在合約的學習
完成第一個遊戲合約部署主網
本次任務,我選擇了簡單的遊戲:石頭剪刀布,由單個玩家進行遊玩,與之對抗的電腦,使用隨機數來生成操作。隨機數的來源,使用全局時鐘
代碼#
module new_gaming::rock_paper_scissors {
use std::string::{Self, String};
use sui::clock::{Self, Clock};
use sui::event;
const EInvalidNumber: u64 = 1;
struct GamingResultEvent has copy, drop {
is_win: bool,
your_choice: String,
computer_choice: String,
result: String,
}
fun get_random_choice(clock: &Clock) : u8 {
((clock::timestamp_ms(clock) % 3) as u8)
}
fun map_choice_to_string(choice: u8) : String {
if (choice == 0) {
string::utf8(b"rock")
} else if (choice == 1) {
string::utf8(b"paper")
} else if (choice == 2) {
string::utf8(b"scissors")
} else {
string::utf8(b"Invalid")
}
}
public fun play(choice: u8, clock: &Clock) {
assert!(choice < 3, EInvalidNumber);
let computer_choice = get_random_choice(clock);
let (result, is_win) = if (
(choice == 0 && computer_choice == 1)
|| (choice == 1 && computer_choice == 2)
|| (choice == 2 && computer_choice == 0)
) {
(string::utf8(b"Win"), true)
} else if (choice == computer_choice) {
(string::utf8(b"Draw"), false)
} else {
(string::utf8(b"Lose"), false)
};
event::emit(GamingResultEvent {
result,
is_win,
your_choice: map_choice_to_string(choice),
computer_choice: map_choice_to_string(computer_choice),
});
}
}
隨機數#
代碼中使用了 sui::clock::Clock
時鐘,來作為隨機數。
我們可以找到對應的源碼 clock.move
,其中關於 Clock 有一段註釋。解釋了 Clock 是一個單例共享對象,為 Move 的調用提供時間。該對象的地址為 0x6
,只能由入口函數獨取(通過不可變引用訪問)。
Move 中,對象即地址,也就是說我們在需要傳入 Clock 時,直接使用它的地址 0x6
,就可以傳入 Clock 對象。
推送和調用#
我們跳過包的發布流程,直接調用方法
# 你可以直接使用我已經發布好的包
# export PACKAGE_ID=0xf968242b22a4f05b62847688c4071aa82c8c97c6a39f08b4b2f12cd7f662cdff
sui client call --gas-budget 7500000 --package $PACKAGE_ID --module rock_paper_scissors --function play --args 0 0x6
可以得到輸出,因為我直接將遊戲結果寫到事件中,所以可以清晰看出結果內容,多次調用方法,可以看到 computer_choice 的變化,同時 result 也會正確計算。
也可以直接使用 SuiScan 來查看本次交易的信息
# 交易 hash
Transaction Digest: 61QxmsdND2t9yCSGFYXPAGH3LRJH3gYb1TuggBpbuHFX
# 事件內容
╭──────────────────────────────────────────────────────────────────╮
│ Transaction Block Events │
├──────────────────────────────────────────────────────────────────┤
│ ┌── │
│ │ EventID: 61QxmsdND2t9yCSGFYXPAGH3LRJH3gYb1TuggBpbuHFX:0 │
│ │ PackageID: 0xf968242b2XXXXXXXXXXX662cdff │
│ │ Transaction Module: rock_paper_scissors │
│ │ Sender: 0xb31fcf5cXXXXXXXXa6965c57f48 │
│ │ EventType: 0xf9682....2cdff::rock_.._ssors::GamingResultEvent │
│ │ ParsedJSON: │
│ │ ┌─────────────────┬───────┐ │
│ │ │ computer_choice │ rock │ │
│ │ ├─────────────────┼───────┤ │
│ │ │ is_win │ false │ │
│ │ ├─────────────────┼───────┤ │
│ │ │ result │ Draw │ │
│ │ ├─────────────────┼───────┤ │
│ │ │ your_choice │ rock │ │
│ │ └─────────────────┴───────┘ │
│ └── │
╰──────────────────────────────────────────────────────────────────╯