現在您的資料表中有一個遊戲項目,您可以學習如何模擬玩家移動進行中的遊戲。
您可以透過兩種方式處理此操作。.第一種方法是,使用 GetItem API 擷取項目。然後,您根據玩家的移動來更新應用程式中的遊戲項目。最後,使用 PutItem API 取代 DynamoDB 中的現有項目。儘管此選項有效,但它需要對 DynamoDB 資料表申請多次請求,並有可能覆寫在擷取和重寫遊戲項目之間發生的任何變更。
處理此操作的第二種方法是,在 DynamoDB 中使用 UpdateItem API 呼叫。使用 UpdateItem API,您可以透過單一請求就地更新 DynamoDB 項目。您指定要變更的項目、要變更的屬性以及要在該項目上主張的任何條件。這是變更項目的慣用方式,因為它不需要多次呼叫資料庫。
在 scripts/ 目錄中,有一個名為 performMove.js 的檔案,其包含如下內容:
const AWS = require('aws-sdk')
const documentClient = new AWS.DynamoDB.DocumentClient()
const performMove = async ({ gameId, user, changedHeap, changedHeapValue }) => {
if (changedHeapValue < 0 ) {
throw new Error('Cannot set heap value below 0')
}
const params = {
TableName: 'turn-based-game',
Key: {
gameId: gameId
},
UpdateExpression: `SET lastMoveBy = :user, ${changedHeap} = :changedHeapValue`,
ConditionExpression: `(user1 = :user OR user2 = :user) AND lastMoveBy <> :user AND ${changedHeap} > :changedHeapValue`,
ExpressionAttributeValues: {
':user': user,
':changedHeapValue': changedHeapValue,
},
ReturnValues: 'ALL_NEW'
}
try {
const resp = await documentClient.update(params).promise()
console.log('Updated game: ', resp.Attributes)
} catch (error) {
console.log('Error updating item: ', error.message)
}
}
performMove({ gameId: '5b5ee7d8', user: 'theseconduser', changedHeap: 'heap1', changedHeapValue: 3 })
該指令碼有點複雜,因此請逐步進行操作。
與之前的指令碼一樣,您要匯入 AWS 開發套件並建立一個 DynamoDB 文件用戶端執行個體。
然後,您可將方法定義為 performMove。此方法類似於當使用者請求移動時在應用程式中使用的內部方法。該指令碼為 UpdateItem API 呼叫組合參數。首先,它變更了遊戲的兩個屬性 - 要移動的最後一個使用者,以及在變更的堆積中的元素數量。
然後,UpdateItem API 參數會對遊戲的目前狀態作出一些聲明。請先求取 ConditionExpression 的值,然後更新項目,以確認該項目處於所需狀態之前。您將在條件表達式中進行以下三種聲明:
- 請求執行移動的使用者是遊戲中兩個使用者中的一個;
- 目前回合屬於請求執行移動的使用者;
- 變更的堆積的目前值高於要變更的堆積的目前值。
最後,參數聲明 ReturnValue 為 ALL_NEW,這意味著 DynamoDB 在更新其值之後會傳回整個項目。有鑒於此,您的應用程式就可以評估遊戲,查看是否有獲勝者。
該檔案的底部顯示了如何在應用程式中呼叫此方法的範例。使用以下命令執行指令碼:
Updated game: { heap2: 4,
heap1: 3,
heap3: 5,
gameId: '5b5ee7d8',
user2: 'theseconduser',
user1: 'myfirstuser',
lastMoveBy: 'theseconduser' }
您可以看到寫入成功並且遊戲已更新。
嘗試在終端機中再次執行指令碼。您應會看到以下輸出:
此次,您的條件請求失敗了。正在請求的使用者 -- theseconduser -- 是最近移動的玩家。此外,變更的堆積 -- heap1 -- 已有數值 3,這表示使用者未進行任何變更。因此,該請求被拒絕。