الآن بعد أن أصبح لديك عنصر لعبة في جدولك، يمكنك معرفة كيفية محاكاة لاعب يقوم بحركة في لعبة قيد التقدم.
هناك طريقتان يمكنك من خلالهما التعامل مع هذه العملية. في الطريقة الأولى، يمكنك استرداد العنصر باستخدام واجهة برمجة تطبيقات GetItem. بعد ذلك، ستقوم بتحديث عنصر اللعبة في تطبيقك وفقًا للحركة التي قام بها اللاعب. وأخيرًا، يمكنك استبدال العنصر الموجود في DynamoDB باستخدام واجهة برمجة تطبيقات PutItem. رغم فاعلية هذا الخيار، إلا أنه يتطلب طلبات متعددة لجدول DynamoDB ويخاطر باستبدال أي تغييرات حدثت بين جلب عنصر اللعبة وإعادة كتابته.
الطريقة الثانية لمعالجة هذه العملية هي استخدام استدعاء واجهة برمجة التطبيقات UpdateItem في DynamoDB. باستخدام واجهة برمجة تطبيقات UpdateItem، يمكنك تحديث عنصر 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 SDK وإنشاء مثيل DynamoDB Document Client.
وبعد ذلك، يمكنك تحديد طريقة تسمى performMove. تتشابه هذه الطريقة مع طريقة داخلية سيتم استخدامها في التطبيق الخاص بك عندما يطلب أحد المستخدمين القيام بحركة. يقوم البرنامج النصي بتجميع المعلمات لاستدعاء واجهة برمجة تطبيقات UpdateItem. أولًا، يغير سمتين في اللعبة -- آخر مستخدم يقوم بحركة، وعدد العناصر في الكومة التي تم تغييرها.
بعد ذلك، تقوم معلمات واجهة برمجة تطبيقات UpdateItem بتقديم بعض التأكيدات حول الحالة الحالية للعبة. يتم تقييم ConditionExpression قبل تحديث العنصر لتأكيد أن العنصر قيد الحالة المطلوبة. وستقوم أنت بإجراء التأكيدات الثلاثة التالية في تعبير حالتك:
- أن المستخدم الذي يطلب إجراء حركة هو أحد المستخدمين الموجودين في اللعبة؛
- أن الدور الحالي من نصيب المستخدم الذي يطلب إجراء الحركة؛
- أن الكومة التي يتم تغييرها لها قيمة حالية أعلى من القيمة التي يتم تغييرها إليها.
وأخيرًا، أن تشير المعلمات إلى ReturnValue من ALL_NEW، ما يعني أن DynamoDB تُرجع العنصر بالكامل بعد تحديث قيمه. بمجرد القيام بذلك، يمكن لتطبيقك تقييم اللعبة لمعرفة ما إذا كان هناك فائز.
يوجد في أسفل الملف مثالًا على كيفية استدعاء هذه الطريقة في التطبيق الخاص بك. يمكنك تنفيذ البرنامج النصي باستخدام الأمر التالي:
وستظهر النتيجة التالية في الوحدة الطرفية:
Updated game: { heap2: 4,
heap1: 3,
heap3: 5,
gameId: '5b5ee7d8',
user2: 'theseconduser',
user1: 'myfirstuser',
lastMoveBy: 'theseconduser' }
يمكنك ملاحظة أن الكتابة كانت ناجحة وتم تحديث اللعبة.
حاول تشغيل البرنامج النصي مرة أخرى في محطتك الطرفية. وستظهر النتيجة التالية:
فشلت طلباتك المشروطة هذه المرة. كان المستخدم صاحب طلب theseconduser -- هو آخر لاعب تحرك. علاوة على ذلك، فإن الكومة المتغيرة -- heap1 -- كانت تحمل بالفعل القيمة 3، ما يعني أن المستخدم لم يغير أي شيء. لهذا السبب، تم رفض الطلب.