前回、浮動小数点数演算を使わないQ学習アルゴリズムを実装しました。次にこれをゲームボーイ用にビルドしていきます。
実装
Q学習をゲームボーイ用にビルド
ゲームボーイ用のmain関数は以下のようになります。PC版との違いは、乱数シードの設定関数がinitrand
という関数に変わっている点と、ファイル保存機能がないことだけです。驚くべきことに、GBDKにはprintf
が実装されており、ゲームボーイ特有の入出力を一切記述することなく文字の表示が可能です。
#include <stdio.h> #include <stdlib.h> #include "config.h" #include "mountaincar.h" #include "qlearning.h" int main() { QLearningState *q_state = QLearningStateCreate(); for (int epoch = 0; epoch < 1000; epoch++) { initrand((unsigned int)epoch); // GBDKにおける乱数のシード設定関数 for (int i = 0; i < 100; i++) { TrainEpisode(q_state); } // fix test case initrand((unsigned int)1); int32_t total_reward = 0; for (int i = 0; i < 10; i++) { uint8_t steps; total_reward += TestEpisode(q_state, &steps); } printf("%d,Avg:%d\n", epoch, total_reward / 10); } return 0; }
ビルドは、GBDKに含まれるlcc.exe
で行います。エミュレータで動作するROMファイルが出力されます。
lcc.exe -o mountaincar.gb gb_main.c mountaincar.c qlearning.c
エミュレータで実行した際の画面を示します。
ゴールに到達できず終了した場合の報酬は-25600です。これより大きな値が表示されたということは、ゴールに到達できたことを示します。これにより、ゲームボーイ上で学習が動作することが確認できました。エミュレータでは、実機の速度(60fps)に合わせて実行するほかに、PCのスペックが許す限り高速に実行することも可能です。画面例では2111fps出ており、実機の35倍の速度で動作確認をすることができます。
報酬が表示されるだけでは面白くないので、次回、車の動きを画面に表示するための実装を進めていきます。