أنشِئ لعبة لوحية مع TensorFlow Agents وFlutter

1. قبل البدء

أظهر الإنجاز المذهل الذي حقّقته AlphaGo وAlphaStar إمكانية استخدام تعلُّم الآلة لإنشاء وكلاء ألعاب بمستوى خارق. إنّها تجربة ممتعة لإنشاء لعبة صغيرة مستنِدة إلى تعلُّم الآلة لاكتساب المهارات اللازمة لإنشاء وكلاء ألعاب فعّالين.

في هذا الدرس التطبيقي حول الترميز، ستتعرّف على كيفية إنشاء لعبة لوحية باستخدام:

  • وكيل TensorFlow لتدريب وكيل لعبة باستخدام التعلّم التعزيزي
  • ‫منصة TensorFlow للعرض لعرض النموذج
  • ‫Flutter لإنشاء تطبيق ألعاب لوحية من عدّة منصات

المتطلبات الأساسية

  • معرفة أساسية بتطوير تطبيقات Flutter باستخدام Dart
  • معرفة أساسية بتعلُّم الآلة باستخدام TensorFlow، مثل التدريب مقابل النشر
  • معرفة أساسية بلغة Python والأوامر الطرفية وDocker

أهداف الدورة التعليمية

  • كيفية تدريب وكيل شخصية غير قابلة للعب (NPC) باستخدام TensorFlow Agents
  • كيفية عرض النموذج المدرَّب باستخدام منصة TensorFlow للعرض
  • كيفية إنشاء لعبة لوحية متوافقة مع عدّة منصات باستخدام Flutter

المتطلبات

2. The Plane Strike Game

اسم اللعبة التي ستنشئها في هذا الدرس التطبيقي حول الترميز هو "ضربة جوية"، وهي لعبة لوحية صغيرة لشخصَين تشبه اللعبة اللوحية "بارجة". القواعد بسيطة للغاية:

  • يلعب اللاعب البشري ضدّ شخصية غير قابلة للعب تم تدريبها باستخدام تقنية تعلُّم الآلة. يمكن للاعب البشري بدء اللعبة من خلال النقر على أي خلية في لوحة اللاعب الآلي.
  • في بداية اللعبة، يملك اللاعب البشري والوكيل كائن "طائرة" (8 خلايا خضراء تشكّل "طائرة" كما يظهر في لوحة اللاعب البشري في الصورة المتحركة أدناه) على لوحتيهما. يتم وضع هذه "الطائرات" بشكل عشوائي ولا يراها سوى مالكو اللوحة، وتكون مخفية عن الخصوم.
  • يتناوب اللاعب البشري والوكيل على ضرب إحدى خلايا لوحة كل منهما. يمكن للاعب البشري النقر على أي خلية في لوحة الوكيل، بينما يتخذ الوكيل القرار تلقائيًا استنادًا إلى توقّعات نموذج تعلُّم الآلة. يتحوّل لون الخلية التي تم استهدافها إلى الأحمر إذا كانت خلية "طائرة" (إصابة)، وإلى الأصفر إذا لم تكن كذلك (خطأ).
  • يفوز اللاعب الذي يحصل على 8 خلايا حمراء أولاً، ثم تتم إعادة تشغيل اللعبة بلوحات جديدة.

في ما يلي عيّنة من طريقة اللعب:

77cead530c5a4aff.gif

3- إعداد بيئة تطوير Flutter

لتطوير تطبيقات Flutter، تحتاج إلى برنامجَين لإكمال هذا الدرس التطبيقي حول الترميز، وهما حزمة تطوير البرامج (SDK) الخاصة بمنصة Flutter ومحرِّر.

يمكنك تشغيل الدرس العملي باستخدام أيّ من الأجهزة التالية:

  • محاكي iOS (يتطلّب تثبيت أدوات Xcode)
  • محاكي Android (يتطلّب الإعداد في "استوديو Android")
  • متصفّح (يجب استخدام Chrome لتصحيح الأخطاء).
  • كتطبيق سطح مكتب على Windows أو Linux أو macOS يجب أن يتم التطوير على النظام الأساسي الذي تخطّط للنشر عليه. لذا، إذا أردت تطوير تطبيق Windows لسطح المكتب، يجب أن يتم التطوير على Windows للوصول إلى سلسلة الإنشاء المناسبة. هناك متطلبات خاصة بنظام التشغيل يتم تناولها بالتفصيل على الرابط docs.flutter.dev/desktop.

4. طريقة الإعداد

لتنزيل الرمز البرمجي لهذا الدرس التطبيقي حول الترميز، اتّبِع الخطوات التالية:

  1. انتقِل إلى مستودع GitHub الخاص بهذا الدرس التطبيقي حول الترميز.
  2. انقر على الرمز > تنزيل ملف zip لتنزيل كل الرمز البرمجي لهذا الدرس التطبيقي حول الترميز.

2cd45599f51fb8a2.png

  1. فك ضغط ملف ZIP الذي تم تنزيله لفتح مجلد جذر codelabs-main يحتوي على جميع الموارد التي تحتاج إليها.

في هذا الدرس التطبيقي حول الترميز، تحتاج فقط إلى الملفات الموجودة في الدليل الفرعي tfagents-flutter/ في المستودع، والذي يحتوي على مجلدات متعددة:

  • يحتوي المجلّدان step0 وstep6 على الرمز الأولي الذي ستستند إليه في كل خطوة من خطوات هذا الدرس التطبيقي حول الترميز.
  • يحتوي المجلد finished على الرمز البرمجي المكتمل لنموذج التطبيق النهائي.
  • يحتوي كل مجلد على مجلد فرعي backbend يتضمّن رمز الخلفية، ومجلد فرعي frontend يتضمّن رمز واجهة Flutter الأمامية.

5- تنزيل التبعيات للمشروع

الخلفية

افتح الوحدة الطرفية وانتقِل إلى المجلد الفرعي tfagents-flutter. نفِّذ ما يلي:

pip install -r requirements.txt

الواجهة الأمامية

  1. في VS Code، انقر على ملف > فتح مجلد، ثم اختَر المجلد step0 من رمز المصدر الذي نزّلته سابقًا.
  2. افتح ملف step0/frontend/lib/main.dart. إذا ظهر لك مربّع حوار VS Code يطلب منك تنزيل الحِزم المطلوبة لتطبيق المبتدئين، انقر على الحصول على الحِزم (Get packages).
  3. إذا لم يظهر لك مربع الحوار هذا، افتح نافذة الأوامر ثم نفِّذ الأمر flutter pub get في المجلد step0/frontend.

7ada07c300f166a6.png

6. الخطوة 0: تشغيل تطبيق البداية

  1. افتح ملف step0/frontend/lib/main.dart في VS Code، وتأكَّد من إعداد "محاكي Android" أو "محاكي iOS" بشكل صحيح وظهورهما في شريط الحالة.

على سبيل المثال، إليك ما يظهر عند استخدام هاتف Pixel 5 مع Android Emulator:

9767649231898791.png

في ما يلي ما يظهر عند استخدام iPhone 13 مع iOS Simulator:

95529e3a682268b2.png

  1. انقر على a19a0c68bc4046e6.png بدء تصحيح الأخطاء.

تشغيل التطبيق واستكشافه

سيتم تشغيل التطبيق على Android Emulator أو iOS Simulator. واجهة المستخدم بسيطة جدًا. يتوفّر لوحا ألعاب، ويمكن للاعب البشري النقر على أي خلية في لوحة البرنامج في الأعلى كموضع ضربة. ستدرّب وكيلًا ذكيًا على توقّع مكان الضربة تلقائيًا استنادًا إلى لوحة اللاعب البشري.

في الخلفية، سيرسل تطبيق Flutter رقعة اللعب الحالية للاعب البشري إلى الخلفية، التي تشغّل نموذج تعلُّم تعزيزي وتعرض موضع الخلية المتوقّع ضربها بعد ذلك. ستعرض الواجهة الأمامية النتيجة في واجهة المستخدم بعد تلقّي الردّ.

734ab3d48a1133e1.png 15cba2e741149c95.png

إذا نقرت على أي خلية في لوحة الوكيل الآن، لن يحدث أي شيء لأنّ التطبيق لا يمكنه التواصل مع الخلفية بعد.

7. الخطوة 1: إنشاء بيئة Python في TensorFlow Agents

الهدف الأساسي من هذا الدرس التطبيقي حول الترميز هو تصميم وكيل يتعلّم من خلال التفاعل مع بيئة. على الرغم من أنّ لعبة Plane Strike بسيطة نسبيًا ويمكن إنشاء قواعد يدوية لعنصر التحكّم غير البشري، يمكنك استخدام التعلّم المعزّز لتدريب وكيل حتى تتمكّن من اكتساب المهارات وإنشاء وكلاء بسهولة لألعاب أخرى في المستقبل.

في الإعداد العادي للتعلم المعزّز (RL)، يتلقّى الوكيل ملاحظة في كل خطوة زمنية ويختار إجراءً. يتم تطبيق الإجراء على البيئة، وتُرجع البيئة مكافأة وملاحظة جديدة. يدرّب البرنامج سياسة لاختيار الإجراءات التي تزيد من مجموع المكافآت إلى أقصى حدّ، ويُعرف ذلك أيضًا بالعائد. ومن خلال لعب اللعبة مرات عديدة، يتمكّن البرنامج من تعلُّم الأنماط وتحسين مهاراته لإتقان اللعبة. لصياغة لعبة Plane Strike كمشكلة تعلّم معزّز، فكِّر في حالة اللوحة على أنّها الملاحظة، وموضع الضربة على أنّه الإجراء، وإشارة الإصابة/الخطأ على أنّها المكافأة.

bc5da07bc45062f4.png

لتدريب وكيل الشخصية غير القابلة للعب، يمكنك الاستفادة من TensorFlow Agents، وهي مكتبة موثوقة وقابلة للتطوير وسهلة الاستخدام لتعزيز التعلّم في TensorFlow.

تُعدّ مكتبة TF Agents خيارًا رائعًا للتعلّم المعزّز لأنّها تتضمّن مجموعة كبيرة من الجلسات التدريبية والأمثلة والمستندات الشاملة لمساعدتك في البدء. يمكنك استخدام TF Agents لحلّ مشاكل التعلّم المعزّز الواقعية والمعقّدة مع إمكانية التوسّع وتطوير خوارزميات جديدة للتعلّم المعزّز بسرعة. يمكنك التبديل بسهولة بين البرامج والخيارات المختلفة للتجربة. كما أنّه تم اختباره جيدًا ويسهل إعداده.

تتوفّر العديد من بيئات الألعاب المُنشأة مسبقًا والمضمّنة في OpenAI Gym (مثل ألعاب Atari) وMujuco وغيرها، والتي يمكن أن تستفيد منها حزمة TF Agents بسهولة. ولكن بما أنّ لعبة Plane Strike هي لعبة مخصّصة بالكامل، عليك أولاً تنفيذ بيئة جديدة من البداية.

لتنفيذ بيئة TF Agents Python، عليك تنفيذ الطرق التالية:

class YourGameEnv(py_environment.PyEnvironment):

  def __init__(self):
    """Initialize environment."""


  def action_spec(self):
    """Return action_spec."""


  def observation_spec(self):
    """Return observation_spec."""


  def _reset(self):
    """Return initial_time_step."""


  def _step(self, action):
    """Apply action and return new time_step."""

أهمها الدالة _step() التي تتلقّى إجراءً وتعرض عنصر time_step جديدًا. في لعبة Plane Strike، لديك لوحة لعب. وعندما يصل موضع ضربة جديد، يحدّد النظام البيئي ما يلي استنادًا إلى حالة لوحة اللعب:

  • الشكل الذي يجب أن يبدو عليه لوحة الألعاب بعد ذلك (هل يجب أن يتغير لون الخلية إلى الأحمر أو الأصفر، بالنظر إلى الموقع المخفي للطائرة؟)
  • ما هي المكافأة التي يجب أن يحصل عليها اللاعب مقابل هذا الموضع (مكافأة إصابة الهدف أو عقوبة عدم إصابته)؟
  • هل يجب إنهاء اللعبة (هل فاز أحد؟)
  • أضِف الرمز التالي إلى الدالة _step() في الملف _planestrike_py_environment.py:
if self._hit_count == self._plane_size:
    self._episode_ended = True
    return self.reset()

if self._strike_count + 1 == self._max_steps:
    self.reset()
    return ts.termination(
        np.array(self._visible_board, dtype=np.float32), UNFINISHED_GAME_REWARD
    )

self._strike_count += 1
action_x = action // self._board_size
action_y = action % self._board_size
# Hit
if self._hidden_board[action_x][action_y] == HIDDEN_BOARD_CELL_OCCUPIED:
    # Non-repeat move
    if self._visible_board[action_x][action_y] == VISIBLE_BOARD_CELL_UNTRIED:
        self._hit_count += 1
        self._visible_board[action_x][action_y] = VISIBLE_BOARD_CELL_HIT
        # Successful strike
        if self._hit_count == self._plane_size:
            # Game finished
            self._episode_ended = True
            return ts.termination(
                np.array(self._visible_board, dtype=np.float32),
                FINISHED_GAME_REWARD,
            )
        else:
            self._episode_ended = False
            return ts.transition(
                np.array(self._visible_board, dtype=np.float32),
                HIT_REWARD,
                self._discount,
            )
    # Repeat strike
    else:
        self._episode_ended = False
        return ts.transition(
            np.array(self._visible_board, dtype=np.float32),
            REPEAT_STRIKE_REWARD,
            self._discount,
        )
# Miss
else:
    # Unsuccessful strike
    self._episode_ended = False
    self._visible_board[action_x][action_y] = VISIBLE_BOARD_CELL_MISS
    return ts.transition(
        np.array(self._visible_board, dtype=np.float32),
        MISS_REWARD,
        self._discount,

8. الخطوة 2: تدريب وكيل اللعبة باستخدام TensorFlow Agents

بعد إعداد بيئة TF Agents، يمكنك تدريب وكيل اللعبة. في هذا الدرس التطبيقي حول الترميز، ستستخدم وكيل REINFORCE. ‫REINFORCE هي خوارزمية تدرّج السياسة في التعلّم المعزّز. تتمثّل الفكرة الأساسية في تعديل مَعلمات الشبكة العصبية للسياسة استنادًا إلى إشارات المكافآت التي يتم جمعها أثناء اللعب، وذلك لكي تتمكّن شبكة السياسة من زيادة العائد إلى أقصى حد في عمليات اللعب المستقبلية.

  • أولاً، عليك إنشاء مثيل لبيئات التدريب والتقييم. أضِف الرمز التالي إلى الدالة train_agent() في الملف step2/backend/training.py:
train_py_env = planestrike_py_environment.PlaneStrikePyEnvironment(
    board_size=BOARD_SIZE, discount=DISCOUNT, max_steps=BOARD_SIZE**2
)
eval_py_env = planestrike_py_environment.PlaneStrikePyEnvironment(
    board_size=BOARD_SIZE, discount=DISCOUNT, max_steps=BOARD_SIZE**2
)

train_env = tf_py_environment.TFPyEnvironment(train_py_env)
eval_env = tf_py_environment.TFPyEnvironment(eval_py_env)
  • بعد ذلك، عليك إنشاء وكيل تعلّم معزّز سيتم تدريبه. في هذا الدرس التطبيقي حول الترميز، ستستخدم وكيل REINFORCE، وهو وكيل مستند إلى السياسات. أضِف هذا الرمز مباشرةً أسفل الرمز أعلاه:
actor_net = tfa.networks.Sequential(
    [
        tfa.keras_layers.InnerReshape([BOARD_SIZE, BOARD_SIZE], [BOARD_SIZE**2]),
        tf.keras.layers.Dense(FC_LAYER_PARAMS, activation="relu"),
        tf.keras.layers.Dense(BOARD_SIZE**2),
        tf.keras.layers.Lambda(lambda t: tfp.distributions.Categorical(logits=t)),
    ],
    input_spec=train_py_env.observation_spec(),
)

optimizer = tf.keras.optimizers.Adam(learning_rate=LEARNING_RATE)

train_step_counter = tf.Variable(0)

tf_agent = reinforce_agent.ReinforceAgent(
    train_env.time_step_spec(),
    train_env.action_spec(),
    actor_network=actor_net,
    optimizer=optimizer,
    normalize_returns=True,
    train_step_counter=train_step_counter,
)
  • أخيرًا، درِّب الوكيل في حلقة التدريب. في حلقة التكرار، عليك أولاً جمع بضع حلقات من اللعب في المخزن المؤقت، ثم تدريب البرنامج باستخدام البيانات المخزّنة مؤقتًا. أضِف الرمز التالي إلى الدالة train_agent() في الملف step2/backend/training.py:
# Collect a few episodes using collect_policy and save to the replay buffer.
collect_episode(
    train_py_env,
    collect_policy,
    COLLECT_EPISODES_PER_ITERATION,
    replay_buffer_observer,
)

# Use data from the buffer and update the agent's network.
iterator = iter(replay_buffer.as_dataset(sample_batch_size=1))
trajectories, _ = next(iterator)
tf_agent.train(experience=trajectories)
replay_buffer.clear()
  • يمكنك الآن بدء التدريب. في نافذة الوحدة الطرفية، انتقِل إلى المجلد step2/backend على جهاز الكمبيوتر ونفِّذ الأمر التالي:
python training.py

يستغرق التدريب من 8 إلى 12 ساعة، وذلك حسب إعدادات الأجهزة (لا يلزمك إكمال التدريب بالكامل لأنّه يتم توفير نموذج مُدرَّب مسبقًا في step3). في هذه الأثناء، يمكنك تتبُّع مستوى التقدّم باستخدام TensorBoard. افتح نافذة طرفية جديدة، وانتقِل إلى المجلد step2/backend على الكمبيوتر ونفِّذ الأمر التالي:

tensorboard --logdir tf_agents_log/

tf_agents_log هو المجلد الذي يحتوي على سجلّ التدريب. في ما يلي مثال على عملية تدريب:

33e12e2b387c063a.png 8488632ccf43348a.png

يمكنك ملاحظة أنّ متوسط مدة الحلقة ينخفض ومتوسط العائد يزداد مع تقدّم التدريب. يمكنك أن تفهم بشكل بديهي أنّه إذا كان العنصر الذكي أكثر ذكاءً ويقدّم توقّعات أفضل، سيصبح طول اللعبة أقصر وسيجمع العنصر المزيد من المكافآت. وهذا منطقي لأنّ الوكيل يريد إنهاء اللعبة في خطوات أقل لتقليل الخصم الكبير على المكافآت في الخطوات اللاحقة.

بعد اكتمال التدريب، يتم تصدير النموذج المدرَّب إلى المجلد policy_model.

9- الخطوة 3: تفعيل النموذج المدرَّب باستخدام منصة TensorFlow للعرض

بعد تدريب وكيل اللعبة، يمكنك نشره باستخدام منصة TensorFlow للعرض.

  • في نافذة الوحدة الطرفية، انتقِل إلى المجلد step3/backend على جهاز الكمبيوتر وابدأ منصة TensorFlow للعرض باستخدام Docker:
docker run -t --rm -p 8501:8501 -p 8500:8500 -v "$(pwd)/backend/policy_model:/models/policy_model" -e MODEL_NAME=policy_model tensorflow/serving

ينزّل Docker تلقائيًا صورة منصة TensorFlow للعرض أولاً، ويستغرق ذلك دقيقة واحدة. بعد ذلك، من المفترض أن تبدأ منصة TensorFlow للعرض. يجب أن يبدو السجلّ على النحو التالي: مقتطف الرمز هذا:

2022-05-30 02:38:54.147771: I tensorflow_serving/model_servers/server.cc:89] Building single TensorFlow model file config:  model_name: policy_model model_base_path: /models/policy_model
2022-05-30 02:38:54.148222: I tensorflow_serving/model_servers/server_core.cc:465] Adding/updating models.
2022-05-30 02:38:54.148273: I tensorflow_serving/model_servers/server_core.cc:591]  (Re-)adding model: policy_model
2022-05-30 02:38:54.262684: I tensorflow_serving/core/basic_manager.cc:740] Successfully reserved resources to load servable {name: policy_model version: 123}
2022-05-30 02:38:54.262768: I tensorflow_serving/core/loader_harness.cc:66] Approving load for servable version {name: policy_model version: 123}
2022-05-30 02:38:54.262787: I tensorflow_serving/core/loader_harness.cc:74] Loading servable version {name: policy_model version: 123}
2022-05-30 02:38:54.265010: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:38] Reading SavedModel from: /models/policy_model/123
2022-05-30 02:38:54.277811: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:90] Reading meta graph with tags { serve }
2022-05-30 02:38:54.278116: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:132] Reading SavedModel debug info (if present) from: /models/policy_model/123
2022-05-30 02:38:54.280229: I external/org_tensorflow/tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2022-05-30 02:38:54.332352: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:206] Restoring SavedModel bundle.
2022-05-30 02:38:54.337000: I external/org_tensorflow/tensorflow/core/platform/profile_utils/cpu_utils.cc:114] CPU Frequency: 2193480000 Hz
2022-05-30 02:38:54.402803: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:190] Running initialization op on SavedModel bundle at path: /models/policy_model/123
2022-05-30 02:38:54.410707: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:277] SavedModel load for tags { serve }; Status: success: OK. Took 145695 microseconds.
2022-05-30 02:38:54.412726: I tensorflow_serving/servables/tensorflow/saved_model_warmup_util.cc:59] No warmup data file found at /models/policy_model/123/assets.extra/tf_serving_warmup_requests
2022-05-30 02:38:54.417277: I tensorflow_serving/core/loader_harness.cc:87] Successfully loaded servable version {name: policy_model version: 123}
2022-05-30 02:38:54.419846: I tensorflow_serving/model_servers/server_core.cc:486] Finished adding/updating models
2022-05-30 02:38:54.420066: I tensorflow_serving/model_servers/server.cc:367] Profiler service is enabled
2022-05-30 02:38:54.428339: I tensorflow_serving/model_servers/server.cc:393] Running gRPC ModelServer at 0.0.0.0:8500 ...
[warn] getaddrinfo: address family for nodename not supported
2022-05-30 02:38:54.431620: I tensorflow_serving/model_servers/server.cc:414] Exporting HTTP/REST API at:localhost:8501 ...
[evhttp_server.cc : 245] NET_LOG: Entering the event loop ...

يمكنك إرسال طلب نموذجي إلى نقطة النهاية للتأكّد من أنّها تعمل على النحو المتوقّع:

curl -d '{"signature_name":"action","instances":[{"0/discount":0.0,"0/observation":[[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,     0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]],"0/reward":0.0,"0/step_type":0}]}'     -X POST http://localhost:8501/v1/models/policy_model:predict

ستعرض نقطة النهاية موضعًا متوقّعًا 45، وهو (5, 5) في وسط اللوحة (إذا كنت مهتمًا بمعرفة السبب، يمكنك محاولة معرفة لماذا يُعدّ وسط اللوحة تخمينًا جيدًا لموضع الضربة الأولى).

{
    "predictions": [45]
}

هذا كل شيء! لقد أنشأت بنجاح نظامًا خلفيًا لتوقّع موضع الضربة التالية لشخصية غير قابلة للعب.

10. الخطوة 4: إنشاء تطبيق Flutter لنظامَي التشغيل Android وiOS

الخادم الخلفي جاهز. يمكنك البدء في إرسال طلبات إليه لاسترداد توقّعات موضع الضربة من تطبيق Flutter.

  • أولاً، عليك تحديد فئة تتضمّن المدخلات التي تريد إرسالها. أضِف الرمز التالي إلى ملف step4/frontend/lib/game_agent.dart:
class Inputs {
  final List<double> _boardState;
  Inputs(this._boardState);

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['0/discount'] = [0.0];
    data['0/observation'] = [_boardState];
    data['0/reward'] = [0.0];
    data['0/step_type'] = [0];
    return data;
  }
}

يمكنك الآن إرسال الطلب إلى منصة TensorFlow للعرض لإجراء التوقّعات.

  • أضِف الرمز التالي إلى الدالة predict() في الملف step4/frontend/lib/game_agent.dart:
var flattenedBoardState = boardState.expand((i) => i).toList();
final response = await http.post(
  Uri.parse('http://$server:8501/v1/models/policy_model:predict'),
  body: jsonEncode(<String, dynamic>{
    'signature_name': 'action',
    'instances': [Inputs(flattenedBoardState)]
  }),
);

if (response.statusCode == 200) {
  var output = List<int>.from(
      jsonDecode(response.body)['predictions'] as List<dynamic>);
  return output[0];
} else {
  throw Exception('Error response');
}

بعد أن يتلقّى التطبيق الردّ من الخلفية، عليك تعديل واجهة مستخدم اللعبة لعرض مستوى التقدّم فيها.

  • أضِف الرمز التالي إلى الدالة _gridItemTapped() في الملف step4/frontend/lib/main.dart:
int agentAction =
    await _policyGradientAgent.predict(_playerVisibleBoardState);
_agentActionX = agentAction ~/ _boardSize;
_agentActionY = agentAction % _boardSize;
if (_playerHiddenBoardState[_agentActionX][_agentActionY] ==
    hiddenBoardCellOccupied) {
  // Non-repeat move
  if (_playerVisibleBoardState[_agentActionX][_agentActionY] ==
      visibleBoardCellUntried) {
    _agentHitCount++;
  }
  _playerVisibleBoardState[_agentActionX][_agentActionY] =
      visibleBoardCellHit;
} else {
  _playerVisibleBoardState[_agentActionX][_agentActionY] =
      visibleBoardCellMiss;
}
setState(() {});

تشغيلها

  1. انقر على a19a0c68bc4046e6.png بدء تصحيح الأخطاء ثم انتظِر حتى يتم تحميل التطبيق.
  2. انقر على أي خلية في لوحة العميل لبدء اللعبة.

852942d0de299c1f.png 6ae3601470c8e33a.png

11. الخطوة 5: تفعيل تطبيق Flutter لمنصات أجهزة الكمبيوتر

بالإضافة إلى Android وiOS، يتوافق Flutter أيضًا مع أنظمة التشغيل على أجهزة الكمبيوتر، بما في ذلك Linux وMac وWindows.

Linux

  1. تأكَّد من ضبط جهاز الاختبار على 86cba523de82b4f9.png في شريط الحالة في VSCode.
  2. انقر على a19a0c68bc4046e6.png بدء تصحيح الأخطاء ثم انتظِر حتى يتم تحميل التطبيق.
  3. انقر على أي خلية في لوحة العميل الافتراضي لبدء اللعبة.

48594c7c0a589733.png

Mac

  1. بالنسبة إلى أجهزة Mac، عليك إعداد الأذونات المناسبة لأنّ التطبيق سيرسل طلبات HTTP إلى الخلفية. يُرجى الرجوع إلى مقالة الأذونات وبيئة الاختبار المعزولة للتطبيق للحصول على مزيد من التفاصيل.

أضِف هذا الرمز إلى step4/frontend/macOS/Runner/DebugProfile.entitlements وstep4/frontend/macOS/Runner/Release.entitlements على التوالي:

<key>com.apple.security.network.client</key>
<true/>
  1. تأكَّد من ضبط جهاز الاختبار على eb4b0b5563824138.png في شريط الحالة في VSCode.
  2. انقر على a19a0c68bc4046e6.png بدء تصحيح الأخطاء ثم انتظِر حتى يتم تحميل التطبيق.
  3. انقر على أي خلية في لوحة العميل الافتراضي لبدء اللعبة.

55a5de3674194e89.png

Windows

  1. تأكَّد من ضبط جهاز الاختبار على 9587be1bb375bc0f.png في شريط الحالة في VSCode.
  2. انقر على a19a0c68bc4046e6.png بدء تصحيح الأخطاء ثم انتظِر حتى يتم تحميل التطبيق.
  3. انقر على أي خلية في لوحة العميل الافتراضي لبدء اللعبة.

41d9f87d84c5e755.png

12. الخطوة 6: تفعيل تطبيق Flutter لمنصة الويب

يمكنك أيضًا إضافة إمكانية استخدام تطبيق Flutter على الويب. يتم تلقائيًا تفعيل منصة الويب لتطبيقات Flutter، لذا كل ما عليك فعله هو تشغيلها.

  1. تأكَّد من ضبط جهاز الاختبار على 71db93efa928d15d.png في شريط الحالة في VSCode.
  2. انقر على a19a0c68bc4046e6.png بدء تصحيح الأخطاء، ثم انتظِر حتى يتم تحميل التطبيق في متصفّح Chrome.
  3. انقر على أي خلية في لوحة العميل الافتراضي لبدء اللعبة.

fae7490304e28dfe.png

13. تهانينا

لقد أنشأت تطبيقًا للعبة لوحية يتضمّن وكيلًا مستندًا إلى تعلُّم الآلة للعب ضد لاعب بشري.

مزيد من المعلومات