- Web Engineer
- アウトバウンド営業
- Webエンジニア(経験者)
- Other occupations (18)
- Development
- Business
はじめに
Unityなどで対戦ゲームを作っている時に、「対戦相手のAIをどうするか」ということで頭を悩ませた経験はありませんか?
ゲームのAIは「⚪︎⚪︎なら××する」というような条件分岐の処理をたくさん書いたり、ゲームの状況を表す変数を用意し、その変数に従って行動を分岐させるというようにして実装することが多いと思いますが、複雑な処理を実装するのは大変です。また、ゲームの種類によっては状況の分岐が膨大になり過ぎて書き切れなかったり、そもそもどのような処理を書くべきなのかが分からなくなってしまうこともあります。
そうなると「AIの行動パターン作成を自動化できないか?」という発想が出てきます。人間の力では難しいことは機械に任せてしまおうというわけです。
しかしそんなことは本当に可能なのかと思われる方もいらっしゃるでしょう。結論から言えば可能です。
では何を使えば可能になるのでしょうか?それこそが機械学習の一分野、強化学習です。
強化学習とは何か
Wikipediaによると、強化学習の定義は以下の通りとなっております。
ある環境内における知的エージェントが、現在の状態を観測し、得られる収益(累積報酬)を最大化するために、どのような行動をとるべきかを決定する機械学習の一分野である。強化学習は、教師あり学習、教師なし学習と並んで、3つの基本的な機械学習パラダイムの一つである。
引用元:強化学習 - Wikipedia
つまり強化学習とは、行動主体(ゲームのAI)が環境(ゲームの状況)を把握した上で最適な行動は何かを決定するための技術です。
今回のケースは「AIの行動パターンの作成を自動化したい」ということですから、まさにぴったりな技術と言えるでしょう。
次に、この強化学習を使ってAIの行動パターン作成を自動化するための準備を行っていきます。
ゲームの作成
まずはゲームを開発しましょう。AIを作るといっても、学習するための環境(=ゲーム)がなければ始まりません。
今回作成したゲームの概要は以下です。なお、ゲームの作成にはpygameを使いました。
- このゲームは対戦型のシューティングゲームです。自分のエネルギー(1Pは画面下部、2Pは画面上部に表示)がなくなったら負けになります。
- このゲームでは、威力小(青色)・威力中(緑色)・威力大(赤色)の3種類の弾を撃つことができます。自分の発射した弾が相手に到達すると、その弾の威力に応じて相手のエネルギーが減ります。ただし、弾を撃つと自分のエネルギーも威力に応じて減ってしまいます。
- 自分の発射した弾が相手の弾にぶつかると、ぶつかった弾の威力に応じて弾が弱体化します。威力が同じ弾がぶつかった時は対消滅し、威力が異なる時は威力が高い弾が残り、消えた方の弾の威力に応じて弱体化します。
- エネルギーは時間経過で回復します。また、残りエネルギーに応じてバーの色は多い方から順に緑、黄色、赤色に変化します。また、無敵状態中は残りエネルギーに関わらずバーの色は青色になります。
- 画面上を移動するUFOに自分の弾を当てると、一定時間無敵状態になります。また、同様にエイリアンに自分の弾を当てると、当てた数に応じて自分の弾の威力が上がります。
実際のゲーム画面は以下のようになります。ゲーム本体のコードは主にGame.pyにて実装しております。
それでは、今回のゲーム作成において、pygameによるゲーム開発の特徴的な部分と工夫した点について説明していきます。pygameはUnityなどのゲームエンジンと比べると抽象度の高い処理をあまり提供していないため、その分の処理を自分で実装する必要があります。そういった違いにも注目していただければと思います。
① ゲームループについて
pygameでは、メインループを以下のように自分で書く必要があります。
def main():
start() #初期化処理
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
pygame.display.update() #画面の更新
update() #ゲーム本体の処理
上記のソースコードで注目して欲しいのは3行目のwhile True:
と5行目のif文です。
まずはwhile True:
から説明します。
どんなプログラムにも共通することですが、プログラム内の処理が全て完了するとそのプログラムは基本的にすぐ終了します。このゲームプログラムも例外ではありません。しかし画面が一瞬だけ表示されてすぐ消えてしまってはゲームになりません。そのため、ゲームを表示し続けられるように何の操作をしていなくてもゲーム中は「処理が続いている」という形にする必要があります。
そこで登場するのがwhile True:
の無限ループで、これにより処理中の状態を維持しています。また同時に、無限ループの中で画面やゲーム本体の処理を実行することでプレイヤーの操作やゲームの状態の変化がすぐ反映されるようになります。
5〜7行目のif文はゲームを終了できるようにするためのものです。このプログラムは先ほど説明したwhile True:
の無限ループによって処理中の状態を維持しているのですが、while True:
はwhile文の処理継続条件を常に満たすため、そのままでは「×」ボタンのクリックなど通常の方法でのプログラム終了ができなくなってしまいます。処理中の状態を維持したいとはいっても、終了させられないのでは困ってしまいます。そこで5行目のif文によって、ユーザーが「×」ボタンをクリックするなどプログラム終了の命令が出た時はプログラムを終了できるようにしています。
②フレームレートへの対応
このゲームはPythonと必要なモジュールを導入していればどのようなPCでも遊ぶことができますが、PCと一言に言っても事務作業用の安価なものからハイスペックなゲーミングPCまで性能には幅があり、同じゲームをプレイしていてもフレームレート(1秒あたりの画面の更新回数≒メインループの実行回数)には差があります。その上、同じPCでも他に実行しているプログラムなど条件の違いによってもフレームレートには差が発生します。
そのため、フレームレートを無視して「メインループの関数が実行される度に右に10ピクセルずつ移動」というような処理をしてしまうと、PCの性能や状態によってゲームのスピード感が全く異なるものになってしまい、ゲームとして成り立たなくなってしまいます。
pygameではpygame.time.Clock
クラスのtick
関数でフレームレートの対応を行っています。tick
関数の引数にフレームレート数を指定することでフレームレートをコントロールでき、例えばtick(30)
とするとフレームレートが30を超えそうになった時に処理を遅らせることで最大フレームレートが30になるように調整します。
…
記事の続きは下のURLをクリック!
https://rightcode.co.jp/blogs/46543
エンジニア積極採用中です!
現在、WEBエンジニア、モバイルエンジニア、デザイナー、営業などを積極採用中です!
採用ページはこちら:https://rightcode.co.jp/recruit
社員の声や社風などを知りたい方はこちら:https://rightcode.co.jp/blogs?category=life
社長と一杯飲みながらお話しませんか?(転職者向け)
特設ページはこちら: https://rightcode.co.jp/gohan-sake-president-talk
もっとワクワクしたいあなたへ
現在、ライトコードでは「WEBエンジニア」「モバイルエンジニア」「ゲームエンジニア」、「デザイナー」「WEBディレクター」「営業」などを積極採用中です!
ライトコードは技術力に定評のある受託開発をメインにしているIT企業です。
有名WEBサービスやアプリの受託開発などの企画、開発案件が目白押しの状況です。
- もっと大きなことに挑戦したい!
- エンジニアとしてもっと成長したい!
- モダンな技術に触れたい!
現状に満足していない方は、まずは、エンジニアとしても第一線を走り続ける弊社代表と気軽にお話してみませんか?
ネット上では、ちょっとユルそうな会社に感じると思いますが(笑)、
実は技術力に定評があり、沢山の実績を残している会社ということをお伝えしたいと思っております。
- ライトコードの魅力を知っていただきたい!
- 社風や文化なども知っていただきたい!
- 技術に対して熱意のある方に入社していただきたい!
一度、【Wantedly内の弊社ページ】や【コーポレートサイト】をのぞいてみてください。