iT邦幫忙

2023 iThome 鐵人賽

DAY 11
0
自我挑戰組

chatGPT 帶你從零開始寫 websocket 連線遊戲系列 第 11

D11 中場插播小功能 - 具有時間限制的行動

  • 分享至 

  • xImage
  •  

前言

在回合制卡牌遊戲中,為了避免玩家故意拖時間影響對手遊戲體驗,通常每回合都會要求在一定時間內完成。但究竟這樣的功能要怎麼在 python 內完成呢?各位看官們請接著看下去吧~

正篇

在 python 的 asyncio 出來之前,這個功能還真的想不到要怎麼實現,但自從有了 asyncio 之後,作這個功能就非常方便了。不囉嗦,直接上 code~

import asyncio

# 模擬一個可能需要一段時間的異步函數
async def long_running_function():
    await asyncio.sleep(10) # 可根據需要改成其他需要時間進行的操作
    return "Success" # 可根據需要改成自己要的回傳值

# 主協程
async def main():
    try:
        # 設定3秒的超時
        result = await asyncio.wait_for(long_running_function(), timeout=3)
        print(result)
    except asyncio.TimeoutError:
        print("Operation timed out!")

# 啟動主協程
asyncio.run(main())

裡面有幾個主要元素:

  1. 一個要等待的操作 (玩家回合行動) 上面的 long_running_function()
  2. 在主協程內使用 asyncio.wait_for(coro, timeout) 記得裡面的參數是 long_running_function() 而不是 long_running_function。筆者當初在接觸這邊的時候也以為這跟 callback_func 一樣是把函式當參數帶進去。但其實我們要帶入的是「呼叫 long_running_function() 產生的協程物件」,可以多看一些 asyncio 相關的小抄 (USD 1$) 幫助自己

同場加映 (js)

function withTimeout(ms, promise) {
    // 創建一個在特定時間後reject的promise
    let timeout = new Promise((resolve, reject) => {
        let timer = setTimeout(() => {
            clearTimeout(timer);
            reject(new Error('Operation timed out!'));
        }, ms);
    });

    // 使用Promise.race競賽兩個promises,返回首先完成的那個
    return Promise.race([
        promise,
        timeout
    ]);
}

// 模擬一個可能需要一段時間的函數
function longRunningFunction() {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve("Success");
        }, 5000);  // 此模擬函數將在5秒後完成
    });
}

// 主要呼叫
async function main() {
    try {
        let result = await withTimeout(3000, longRunningFunction()); // 設定3秒的超時
        console.log(result);
    } catch (error) {
        console.error(error.message);
    }
}

main();

這裡會發現 js 的實作相對比較簡潔,而且它的 Promise.race() 可以處理更多類型的 promise,不限於 sleep 類型的 promise。然後這邊的 withTimeout() 裡面也是 longRunningFunction(),多看一些範例之後就會記得要加 () 了

結語

今天插播一個其實也蠻重要的小功能,明天之後我們將會回頭把前面的一塊一塊小積木們組合成完整的專案功能,各位看官們敬請期待~


上一篇
D10 實現遊戲邏輯和回合控制
下一篇
D12 實作日 - 加個紀錄
系列文
chatGPT 帶你從零開始寫 websocket 連線遊戲31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言