【Elixir/Phoenix】AI対戦4目並べを作る(AIの動作チェック編)で動作確認したAIの対戦相手を、GUIに組み込みます。
AI部分もGUI部分もElixirで記述されているので、簡単に組み込むことができます。
Nx/Axonのモジュールを追加
mix.exs
defp deps do
[
{:phoenix, "~> 1.7.0-rc.0", override: true},
{:phoenix_ecto, "~> 4.4"},
{:ecto_sql, "~> 3.6"},
{:ecto_sqlite3, ">= 0.0.0"},
{:phoenix_html, "~> 3.0"},
{:phoenix_live_reload, "~> 1.2", only: :dev},
{:phoenix_live_view, "~> 0.18.3"},
{:heroicons, "~> 0.5"},
{:floki, ">= 0.30.0", only: :test},
{:phoenix_live_dashboard, "~> 0.7.2"},
{:esbuild, "~> 0.5", runtime: Mix.env() == :dev},
{:tailwind, "~> 0.1.8", runtime: Mix.env() == :dev},
{:swoosh, "~> 1.3"},
{:finch, "~> 0.13"},
{:telemetry_metrics, "~> 0.6"},
{:telemetry_poller, "~> 1.0"},
{:gettext, "~> 0.20"},
{:jason, "~> 1.2"},
{:plug_cowboy, "~> 2.5"},
{:axon, "~> 0.2.0"},
{:exla, "~> 0.3.0"},
{:nx, "~> 0.3.0"},
]
end
DQNの処理ファイルを追加
lib/phx_gomoku/dqn.ex
lib/phx_gomoku/q_net.ex
gomoku-qnet-5x5-4-200k.axon
など、AI側の処理に必要なファイルを追加します。
イベントハンドラーの変更
lib/phx_gomoku_web/live/gomoku_live.ex
def handle_event("clicked", %{"x" => x, "y" => y}, socket) do
x = String.to_integer(x)
y = String.to_integer(y)
socket = socket
|> turn_human({y, x})
|> turn_ai()
{:noreply, socket}
end
turn_aiは、Dqn.get_action()を呼び出して得られた位置に石を置きます。
lib/phx_gomoku_web/live/gomoku_live.ex
def turn_ai(socket) when socket.assigns.ai_turn == socket.assigns.board.turn do
update(socket, :board, &turn_ai(&1, socket.assigns.q_net))
end
def turn_ai(socket) do
socket
end
def turn_ai(%Gomoku{done: true} = gomoku, _q_net) do
gomoku
end
def turn_ai(%Gomoku{done: false} = gomoku, q_net) do
pos = Dqn.get_action(gomoku, q_net)
Gomoku.put!(gomoku, pos)
end
まとめ
- 強化学習で作成した対戦相手と対戦できる、四目並べを作成する事が出来た。
- Liveviewの動的なHTMLのレンダリングにより、盤面の表示を簡単に行えた。
- 対戦相手部分がゲームエンジンと同じElixirで記述されているので、プロジェクトへのファイルコピーレベルで、結合できた。
- Javascript/Pythonを使う方法がありがちだが、Elixirだけでもできることを確認できた。
関連記事