
ML-Agentsでブロック崩しのAIを作ってみた【機械学習】【Unity】
こんにちは。youtuberのこーじ様に憧れて最近ML-Agentsの勉強を始めました。今回、ブロック崩しのAIを作ってみたので記事にしました。
参考文献
この本を参考にしました。
Unityではじめる機械学習・強化学習 Unity ML-Agents実践ゲームプログラミング | 布留川 英一, 佐藤 英一 |本 | 通販 | Amazon
完成形
AIが勝手にブロック崩しをプレイしてくれます。動画はこちら
ブロック崩しAI
育成方法

まず、本に従って上図のようなゲームを作成しました。これによりボールを落とさずに跳ね返すAIを作成できます。これを1時間ほど学習させて、跳ね返すAIを作成します。

拡張する形で、ブロック崩しを作成しました。
システム
基本的には、普通のブロック崩しと同じシステム。
初期状態:ブロックが5×3個配置され、ボールと板は中心に配置。
ブロックが全部破壊されたらクリアとし、ゲームリセットする。
ボールを跳ね返せなかったらゲームリセットする。
ステップ数5000とし、それを超えたらリセットする。
最後のステップ数は、時間がかかりすぎてしまった場合、ゲームクリアできなかったとみなしました。
報酬
与える報酬は以下の通りにしました。
$$
\begin{array}{|c|c|}
落下 & -2.0 \\ \hline
ブロックにボールが当たる & +1.0 \\ \hline
時間経過 & -0.0005 \\ \hline
ボールと当たる & +0.1 \\ \hline
全消し & +2.0 \\ \hline
\end{array}
$$
落下したら大きなペナルティを与えます。落下の回数が多かったので、途中でペナルティの値を増やしました。また、早めに全消ししてほしいので時間経過により微小のペナルティを与えています。ボールを跳ね返せたときに少しの報酬、ボールがブロックに当たった時、全消しした時には大きな報酬を与え、なるべく早くゲームクリアするようにしました。
観察
観察させたものは以下の通りです。
ボールのx座標
ボールのz座標
ボールのx座標の速度
ボールのz座標の速度
板のx座標
のこりブロック数
ボールの位置、方向と板の位置を観察することで、跳ね返せるようにしています。
結果

202回プレイさせてみたところ、150回全消しすることができました。成功率は約74.3パーセント。跳ね返すことができなかったというよりかは途中で無限ループに陥ってしまい、失敗になるケースが多かったです。

角を角ばらないようにすることで無限ループ回数は減りましたが、それでもまだループしてしまうようです。
もっとたくさん学習させればもっと強くなると思います。
プログラム(一部)
本の拡張部分は公開できませんが、参考になればうれしいです。
ブロックのプレファブを受け取って、配置するプログラムです。色をランダムにつけれるようにしました。
public GameObject Blocks;
private Color[] colors = new Color[]{
Color.red,
Color.green,
Color.yellow,
Color.cyan,
Color.black,
};
public void ResetBlocks(){
Vector3 startPosition = new Vector3(-4, 3, 2.0f);
float width = 2.0f;
float height = 1.0f;
float depth = 0.5f;
foreach( var block in activeBlocks ){
Destroy(block);
}
for( int i = 0; i < 5; i++ ){
for( int j = 0; j < 3; j++ ){
Vector3 newPosition = new Vector3(startPosition.x + i * width,
0.5f, startPosition.z + j * depth + 2.0f);
GameObject newBlock = Instantiate(Blocks, newPosition,
Quaternion.identity);
activeBlocks.Add(newBlock);
ChangeBlockColor(newBlock);
}
}
}
void ChangeBlockColor(GameObject block){
Renderer blockRenderer = block.GetComponent<Renderer>();
Color randomColor = colors[Random.Range(0, colors.Length)];
blockRenderer.material.color = randomColor;
}
便利アイテムDiscreteActions
DiscreteActionsを用いることで、信号を離散的に制御できます!
今回は、
1 : 右へ移動
2 : 左へ移動
というようにしてプログラムを組みました。
終わりに
見ていただきありがとうございます。ML-Agentsを使えば、いろんなことができそうなのでこれからも勉強頑張ります。