Xây dựng trò chơi cờ bàn bằng TensorFlow Agents và Flutter

1. Trước khi bắt đầu

Bước đột phá đáng kinh ngạc của AlphaGoAlphaStar đã cho thấy tiềm năng của việc sử dụng công nghệ học máy để xây dựng các tác nhân trò chơi ở cấp độ siêu nhân. Việc xây dựng một trò chơi nhỏ dựa trên học máy là một bài tập thú vị để học các kỹ năng cần thiết nhằm tạo ra những tác nhân trò chơi mạnh mẽ.

Trong lớp học lập trình này, bạn sẽ tìm hiểu cách tạo một trò chơi cờ bàn bằng cách sử dụng:

  • TensorFlow Agent để huấn luyện một tác nhân trò chơi bằng phương pháp học tăng cường
  • TensorFlow Serving để phân phát mô hình
  • Flutter để tạo ứng dụng trò chơi cờ bàn nhiều nền tảng

Điều kiện tiên quyết

  • Kiến thức cơ bản về cách phát triển Flutter bằng Dart
  • Kiến thức cơ bản về học máy bằng TensorFlow, chẳng hạn như huấn luyện so với triển khai
  • Kiến thức cơ bản về Python, thiết bị đầu cuối và Docker

Kiến thức bạn sẽ học được

  • Cách huấn luyện một tác nhân Nhân vật không phải người chơi (NPC) bằng TensorFlow Agents
  • Cách phân phát mô hình đã huấn luyện bằng TensorFlow Serving
  • Cách xây dựng một trò chơi cờ bàn trên nhiều nền tảng bằng Flutter

Bạn cần có

2. Trò chơi Plane Strike

Trò chơi mà bạn xây dựng trong lớp học lập trình này có tên là “Plane Strike”, một trò chơi cờ bàn nhỏ dành cho 2 người chơi, tương tự như trò chơi cờ bàn “Battleship” (Chiến hạm). Các quy tắc rất đơn giản:

  • Người chơi sẽ đấu với một tác nhân NPC được huấn luyện bằng công nghệ học máy. Người chơi có thể bắt đầu trò chơi bằng cách nhấn vào ô bất kỳ trên bảng của tác nhân.
  • Khi bắt đầu trò chơi, người chơi là con người và tác nhân mỗi người có một đối tượng 'máy bay' (8 ô màu xanh lục tạo thành một 'máy bay' như bạn có thể thấy trong bàn cờ của người chơi là con người trong ảnh động bên dưới) trên bàn cờ của riêng họ; những 'máy bay' này được đặt ngẫu nhiên và chỉ người sở hữu bàn cờ mới nhìn thấy, còn đối thủ thì không.
  • Người chơi và tác nhân lần lượt tấn công vào một ô trên bảng của nhau. Người chơi có thể nhấn vào bất kỳ ô nào trên bảng của tác nhân, trong khi tác nhân sẽ tự động đưa ra lựa chọn dựa trên dự đoán của một mô hình học máy. Ô được chọn sẽ chuyển sang màu đỏ nếu đó là ô "máy bay" ("trúng"); nếu không, ô đó sẽ chuyển sang màu vàng ("trượt").
  • Người nào đạt được 8 ô màu đỏ trước sẽ thắng trò chơi; sau đó, trò chơi sẽ được khởi động lại với các bảng mới.

Sau đây là một ví dụ về lối chơi của trò chơi:

77cead530c5a4aff.gif

3. Thiết lập môi trường phát triển Flutter

Để phát triển bằng Flutter, bạn cần có 2 phần mềm để hoàn tất lớp học lập trình này: Flutter SDKmột trình chỉnh sửa.

Bạn có thể chạy lớp học lập trình này bằng bất kỳ thiết bị nào sau đây:

  • Trình mô phỏng iOS (bạn cần cài đặt các công cụ Xcode).
  • Trình mô phỏng Android (cần thiết lập trong Android Studio).
  • Một trình duyệt (bạn cần có Chrome để gỡ lỗi).
  • Dưới dạng ứng dụng máy tính cho Windows, Linux hoặc macOS. Bạn phải phát triển trên nền tảng mà bạn dự định triển khai. Vì vậy, nếu muốn phát triển một ứng dụng máy tính cho Windows, bạn phải phát triển trên Windows để truy cập vào chuỗi bản dựng thích hợp. Có những yêu cầu cụ thể theo hệ điều hành được đề cập chi tiết trên docs.flutter.dev/desktop.

4. Bắt đầu thiết lập

Cách tải mã xuống cho lớp học lập trình này:

  1. Chuyển đến kho lưu trữ GitHub cho lớp học lập trình này.
  2. Nhấp vào Code > Download zip (Mã > Tải xuống tệp ZIP) để tải tất cả mã cho lớp học lập trình này xuống.

2cd45599f51fb8a2.png

  1. Giải nén tệp zip đã tải xuống để giải nén một thư mục gốc codelabs-main có tất cả tài nguyên bạn cần.

Đối với lớp học lập trình này, bạn chỉ cần các tệp trong thư mục con tfagents-flutter/ trong kho lưu trữ. Thư mục này chứa nhiều thư mục:

  • Các thư mục step0 đến step6 chứa mã khởi đầu mà bạn sẽ dùng để tạo cho từng bước trong lớp học lập trình này.
  • Thư mục finished chứa mã hoàn chỉnh cho ứng dụng mẫu đã hoàn thành.
  • Mỗi thư mục đều chứa một thư mục con backbend (chứa mã phụ trợ) và một thư mục con frontend (chứa mã giao diện người dùng Flutter)

5. Tải các phần phụ thuộc cho dự án xuống

Phụ trợ

Mở cửa sổ dòng lệnh và chuyển đến thư mục con tfagents-flutter. Chạy lệnh sau:

pip install -r requirements.txt

Giao diện người dùng

  1. Trong VS Code, hãy nhấp vào File > Open folder (Tệp > Mở thư mục), sau đó chọn thư mục step0 trong mã nguồn mà bạn đã tải xuống trước đó.
  2. Mở tệp step0/frontend/lib/main.dart. Nếu bạn thấy hộp thoại VS Code xuất hiện và nhắc bạn tải các gói cần thiết cho ứng dụng khởi đầu xuống, hãy nhấp vào Get packages (Tải gói xuống).
  3. Nếu bạn không thấy hộp thoại này, hãy mở thiết bị đầu cuối rồi chạy lệnh flutter pub get trong thư mục step0/frontend.

7ada07c300f166a6.png

6. Bước 0: Chạy ứng dụng khởi đầu

  1. Mở tệp step0/frontend/lib/main.dart trong VS Code, đảm bảo rằng Trình mô phỏng Android hoặc Trình mô phỏng iOS được thiết lập đúng cách và xuất hiện trên thanh trạng thái.

Ví dụ: sau đây là những gì bạn thấy khi sử dụng Pixel 5 với Trình mô phỏng Android:

9767649231898791.png

Sau đây là những gì bạn thấy khi sử dụng iPhone 13 với Trình mô phỏng iOS:

95529e3a682268b2.png

  1. Nhấp vào a19a0c68bc4046e6.png Bắt đầu gỡ lỗi.

Chạy và khám phá ứng dụng

Ứng dụng sẽ chạy trên Trình mô phỏng Android hoặc Trình mô phỏng iOS. Giao diện người dùng khá đơn giản. Có 2 bảng trò chơi; người chơi có thể nhấn vào bất kỳ ô nào trong bảng của tác nhân ở trên cùng làm vị trí tấn công. Bạn sẽ huấn luyện một tác nhân thông minh để tự động dự đoán vị trí cần đánh dựa trên bàn cờ của người chơi.

Trong quá trình này, ứng dụng Flutter sẽ gửi bàn cờ hiện tại của người chơi đến phần phụ trợ. Phần phụ trợ này chạy một mô hình học tăng cường và trả về vị trí ô dự đoán để đánh tiếp theo. Giao diện người dùng sẽ hiển thị kết quả trong giao diện người dùng sau khi nhận được phản hồi.

734ab3d48a1133e1.png 15cba2e741149c95.png

Nếu bạn nhấp vào ô bất kỳ trên bảng của tác nhân, sẽ không có gì xảy ra vì ứng dụng chưa thể giao tiếp với phần phụ trợ.

7. Bước 1: Tạo môi trường Python TensorFlow Agents

Mục tiêu chính của lớp học lập trình này là thiết kế một tác nhân học hỏi bằng cách tương tác với môi trường. Mặc dù trò chơi Plane Strike tương đối đơn giản và bạn có thể tạo các quy tắc theo cách thủ công cho tác nhân NPC, nhưng bạn sẽ sử dụng phương pháp học tăng cường để huấn luyện một tác nhân. Nhờ đó, bạn sẽ học được các kỹ năng và có thể dễ dàng tạo tác nhân cho các trò chơi khác trong tương lai.

Trong chế độ cài đặt Học tăng cường (RL) tiêu chuẩn, tác nhân nhận được một thông tin quan sát ở mỗi bước thời gian và chọn một hành động. Hành động này được áp dụng cho môi trường và môi trường sẽ trả về một phần thưởng và một trạng thái quan sát mới. Tác nhân huấn luyện một chính sách để chọn các hành động nhằm tối đa hoá tổng phần thưởng, còn được gọi là lợi nhuận. Bằng cách chơi trò chơi nhiều lần, tác nhân có thể học được các mẫu và trau dồi kỹ năng để thành thạo trò chơi. Để xây dựng trò chơi Plane Strike dưới dạng một vấn đề RL, hãy coi trạng thái của bảng là thông tin quan sát, vị trí tấn công là hành động và tín hiệu trúng/trượt là phần thưởng.

bc5da07bc45062f4.png

Để huấn luyện tác nhân NPC, bạn tận dụng TensorFlow Agents, một thư viện học tăng cường đáng tin cậy, có khả năng mở rộng và dễ sử dụng cho TensorFlow.

TF Agents rất phù hợp cho việc học tăng cường vì có một bộ lớp học lập trình, ví dụ và tài liệu phong phú để giúp bạn bắt đầu. Bạn có thể sử dụng TF Agents để giải quyết các vấn đề RL phức tạp và thực tế với khả năng mở rộng, đồng thời nhanh chóng phát triển các thuật toán RL mới. Bạn có thể dễ dàng chuyển đổi giữa các tác nhân và thuật toán khác nhau để thử nghiệm. Ngoài ra, ứng dụng này đã được kiểm thử kỹ lưỡng và dễ định cấu hình.

Có nhiều môi trường trò chơi được tạo sẵn trong OpenAI Gym (ví dụ: trò chơi Atari), Mujuco, v.v. mà TF Agents có thể dễ dàng tận dụng. Nhưng vì trò chơi Plane Strike là một trò chơi tuỳ chỉnh hoàn chỉnh, nên trước tiên bạn cần triển khai một môi trường mới từ đầu.

Để triển khai môi trường Python của TF Agents, bạn cần triển khai các phương thức sau:

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."""

Quan trọng nhất là hàm _step(). Hàm này nhận một thao tác và trả về một đối tượng time_step mới. Trong trường hợp trò chơi Plane Strike, bạn có một bảng trò chơi; khi có một vị trí tấn công mới, dựa trên điều kiện của bảng trò chơi, môi trường sẽ xác định:

  • Bảng trò chơi sẽ có dạng như thế nào tiếp theo (ô có nên đổi màu thành đỏ hoặc vàng không, dựa trên vị trí máy bay bị che khuất?)
  • Người chơi sẽ nhận được phần thưởng gì cho vị trí đó (phần thưởng khi trúng hoặc hình phạt khi trượt?)
  • Trò chơi có kết thúc không (có ai thắng không?)
  • Thêm mã sau vào hàm _step() trong tệp _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. Bước 2: Huấn luyện tác nhân trò chơi bằng TensorFlow Agents

Khi đã thiết lập môi trường TF Agents, bạn có thể huấn luyện tác nhân trò chơi. Trong lớp học lập trình này, bạn sẽ sử dụng một tác nhân REINFORCE. REINFORCE là một thuật toán độ dốc chính sách trong RL. Ý tưởng cơ bản của thuật toán này là điều chỉnh các tham số mạng nơ-ron chính sách dựa trên các tín hiệu phần thưởng được thu thập trong quá trình chơi, để mạng chính sách có thể tối đa hoá lợi nhuận trong các lượt chơi sau này.

  • Trước tiên, bạn cần khởi tạo môi trường huấn luyện và đánh giá. Thêm mã này vào hàm train_agent() trong tệp 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)
  • Tiếp theo, bạn cần tạo một tác nhân học tăng cường sẽ được huấn luyện. Trong lớp học lập trình này, bạn sẽ sử dụng tác nhân REINFORCE (một tác nhân dựa trên chính sách). Thêm mã này ngay bên dưới mã ở trên:
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,
)
  • Cuối cùng, hãy huấn luyện tác nhân trong vòng lặp huấn luyện. Trong vòng lặp, trước tiên, bạn thu thập một vài tập chơi trò chơi vào một vùng đệm, sau đó huấn luyện tác nhân bằng dữ liệu được đệm. Thêm mã này vào hàm train_agent() trong tệp 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()
  • Bây giờ, bạn có thể bắt đầu quá trình huấn luyện. Trong thiết bị đầu cuối, hãy chuyển đến thư mục step2/backend trên máy tính rồi chạy:
python training.py

Quá trình huấn luyện mất từ 8 đến 12 giờ để hoàn tất, tuỳ thuộc vào cấu hình phần cứng của bạn (bạn không cần tự mình hoàn tất toàn bộ quá trình huấn luyện vì một mô hình được huấn luyện trước đã có sẵn trong step3). Trong thời gian chờ đợi, bạn có thể theo dõi tiến trình bằng TensorBoard. Mở một cửa sổ dòng lệnh mới, chuyển đến thư mục step2/backend trên máy tính rồi chạy:

tensorboard --logdir tf_agents_log/

tf_agents_log là thư mục chứa nhật ký huấn luyện. Một lần chạy huấn luyện mẫu sẽ có dạng như sau:

33e12e2b387c063a.png 8488632ccf43348a.png

Bạn có thể thấy rằng độ dài tập trung bình giảm và lợi nhuận trung bình tăng lên khi quá trình huấn luyện diễn ra. Bạn có thể hiểu một cách trực quan rằng nếu tác nhân thông minh hơn và đưa ra dự đoán chính xác hơn, thì thời lượng trò chơi sẽ ngắn hơn và tác nhân sẽ thu thập được nhiều phần thưởng hơn. Điều này hợp lý vì tác nhân muốn hoàn thành trò chơi trong ít bước hơn để giảm thiểu việc chiết khấu phần thưởng lớn ở các bước sau.

Sau khi quá trình huấn luyện hoàn tất, mô hình đã huấn luyện sẽ được xuất sang thư mục policy_model.

9. Bước 3: Triển khai mô hình đã huấn luyện bằng TensorFlow Serving

Giờ đây, sau khi huấn luyện tác nhân trò chơi, bạn có thể triển khai tác nhân đó bằng TensorFlow Serving.

  • Trong thiết bị đầu cuối, hãy chuyển đến thư mục step3/backend trên máy tính rồi khởi động TensorFlow Serving bằng 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

Trước tiên, Docker sẽ tự động tải hình ảnh TensorFlow Serving xuống. Quá trình này mất một phút. Sau đó, TensorFlow Serving sẽ bắt đầu. Nhật ký sẽ có dạng như đoạn mã sau:

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 ...

Bạn có thể gửi một yêu cầu mẫu đến điểm cuối để đảm bảo điểm cuối hoạt động như mong đợi:

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

Điểm cuối sẽ trả về một vị trí dự đoán 45, là (5, 5) ở giữa bảng (nếu tò mò, bạn có thể thử tìm hiểu lý do tại sao tâm của bảng là một lựa chọn tốt cho vị trí tấn công đầu tiên).

{
    "predictions": [45]
}

Vậy là xong! Bạn đã tạo thành công một phần phụ trợ để dự đoán vị trí tấn công tiếp theo cho tác nhân NPC.

10. Bước 4: Tạo ứng dụng Flutter cho Android và iOS

Phần phụ trợ đã sẵn sàng. Bạn có thể bắt đầu gửi yêu cầu đến dịch vụ này để truy xuất thông tin dự đoán vị trí chạm từ ứng dụng Flutter.

  • Trước tiên, bạn cần xác định một lớp bao bọc các thông tin đầu vào cần gửi. Thêm mã này vào tệp 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;
  }
}

Giờ đây, bạn có thể gửi yêu cầu đến TensorFlow Serving để đưa ra dự đoán.

  • Thêm mã này vào hàm predict() trong tệp 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');
}

Sau khi ứng dụng nhận được phản hồi từ phần phụ trợ, bạn sẽ cập nhật giao diện người dùng của trò chơi để phản ánh tiến trình của trò chơi.

  • Thêm mã này vào hàm _gridItemTapped() trong tệp 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(() {});

Chạy ứng dụng

  1. Nhấp vào a19a0c68bc4046e6.png Start debugging (Bắt đầu gỡ lỗi) rồi đợi ứng dụng tải.
  2. Nhấn vào ô bất kỳ trên bảng của đặc vụ để bắt đầu trò chơi.

852942d0de299c1f.png 6ae3601470c8e33a.png

11. Bước 5: Bật ứng dụng Flutter cho các nền tảng máy tính

Ngoài Android và iOS, Flutter còn hỗ trợ các nền tảng máy tính, bao gồm Linux, Mac và Windows.

Linux

  1. Đảm bảo rằng thiết bị mục tiêu được đặt thành 86cba523de82b4f9.png trong thanh trạng thái của VSCode.
  2. Nhấp vào a19a0c68bc4046e6.png Start debugging (Bắt đầu gỡ lỗi) rồi đợi ứng dụng tải.
  3. Nhấp vào ô bất kỳ trên bảng của đặc vụ để bắt đầu trò chơi.

48594c7c0a589733.png

Mac

  1. Đối với máy Mac, bạn cần thiết lập các quyền thích hợp vì ứng dụng sẽ gửi yêu cầu HTTP đến phần phụ trợ. Vui lòng tham khảo bài viết Quyền và Hộp cát ứng dụng để biết thêm thông tin chi tiết.

Thêm mã này vào step4/frontend/macOS/Runner/DebugProfile.entitlementsstep4/frontend/macOS/Runner/Release.entitlements tương ứng:

<key>com.apple.security.network.client</key>
<true/>
  1. Đảm bảo rằng thiết bị mục tiêu được đặt thành eb4b0b5563824138.png trong thanh trạng thái của VSCode.
  2. Nhấp vào a19a0c68bc4046e6.png Start debugging (Bắt đầu gỡ lỗi) rồi đợi ứng dụng tải.
  3. Nhấp vào ô bất kỳ trên bảng của đặc vụ để bắt đầu trò chơi.

55a5de3674194e89.png

Windows

  1. Đảm bảo rằng thiết bị mục tiêu được đặt thành 9587be1bb375bc0f.png trong thanh trạng thái của VSCode.
  2. Nhấp vào a19a0c68bc4046e6.png Start debugging (Bắt đầu gỡ lỗi) rồi đợi ứng dụng tải.
  3. Nhấp vào ô bất kỳ trên bảng của đặc vụ để bắt đầu trò chơi.

41d9f87d84c5e755.png

12. Bước 6: Bật ứng dụng Flutter cho nền tảng web

Một việc khác bạn có thể làm là thêm tính năng hỗ trợ web vào ứng dụng Flutter. Theo mặc định, nền tảng web sẽ tự động được bật cho các ứng dụng Flutter, vì vậy, bạn chỉ cần chạy ứng dụng đó.

  1. Đảm bảo thiết bị mục tiêu được đặt thành 71db93efa928d15d.png trong thanh trạng thái của VSCode.
  2. Nhấp vào a19a0c68bc4046e6.png Start debugging (Bắt đầu gỡ lỗi) rồi đợi ứng dụng tải trong trình duyệt Chrome.
  3. Nhấp vào ô bất kỳ trên bảng của đặc vụ để bắt đầu trò chơi.

fae7490304e28dfe.png

13. Xin chúc mừng

Bạn đã tạo một ứng dụng trò chơi cờ bàn có tác nhân dựa trên học máy để chơi với người chơi là con người!

Tìm hiểu thêm