QEUR23_ATTNS1: ゲーム2048のプログラムを「さくっと」つくる
~ またやるの? ~
QEU:FOUNDER : “久々に見てみましょう。QEUシステムのモジュール構成。今回からLLMを加えてみました。”
D先生 : “なるほどね・・・。でも、いま「私たちが立っている場所」って、Stable Diffusionを開発していた場所ですよね。”
QEU:FOUNDER : “ちょっと事情があり、LLMの開発は後回しします。強化学習にもどろう!ちょっと、2048ゲームをやり直してみたい。”
D先生 : “なんで・・・?今話題のATTENTION(の応用技術の開発)をやるんじゃなかったの?”
QEU:FOUNDER : “Attentionに切り込むために、強化学習から始めます。あとね、GPTにプログラムの生成を要求させてみて、どれだけプログラムの開発速度と質が上がるのかを確かめてもみたい。まずは、「ゲーム単体」をGPTに出してもらいましょう。”
プロンプト:「ゲーム2048(4x4)をテキスト表示で動くようなpythonプログラムを生成してください。」
D先生 : “うまく行きましたか?”
QEU:FOUNDER : “本当に驚いたんだけど、「マニュアル」付きでプログラムが出てきたよ。プログラムの出来は90%、ただし方向が上下逆だった・・・(笑)。これは、ボード配列の設定(配列番号+1=上)から見ても間違えそうなポイントなんだけどね・・・。そこらへんを、ちょっとだけ修正したプログラムは、こちら(↓)です。”
# 2048ゲームのロジック
import random
# ボードのサイズ
SIZE = 4
# ボードを初期化する関数
def init_board():
# ボードは二次元リストで表現する
board = [[0] * SIZE for _ in range(SIZE)]
# ランダムな位置に2か4を配置する
add_random_tile(board)
add_random_tile(board)
return board
# ランダムな位置に2か4を配置する関数
def add_random_tile(board):
# 空いているセルの座標をリストに格納する
empty_cells = []
for i in range(SIZE):
for j in range(SIZE):
if board[i][j] == 0:
empty_cells.append((i, j))
# 空いているセルがなければ何もしない
if not empty_cells:
return
# 空いているセルの中からランダムに選ぶ
i, j = random.choice(empty_cells)
# 10%の確率で4を、90%の確率で2を配置する
board[i][j] = 4 if random.random() < 0.1 else 2
# ボードを左にスライドする関数
def slide_left(board):
# 変化があったかどうかのフラグ
changed = False
# 各行について処理する
for row in board:
# まず0でないセルだけを抽出する
non_zero_cells = [cell for cell in row if cell != 0]
# 隣り合うセルが同じ値なら結合する
merged_cells = []
i = 0
while i < len(non_zero_cells):
if i + 1 < len(non_zero_cells) and non_zero_cells[i] == non_zero_cells[i + 1]:
merged_cells.append(non_zero_cells[i] * 2)
i += 2
else:
merged_cells.append(non_zero_cells[i])
i += 1
# 結合した後の行の長さが元の行の長さより短ければ、0で埋める
while len(merged_cells) < SIZE:
merged_cells.append(0)
# 元の行と異なれば、変化があったとする
if merged_cells != row:
changed = True
# 元の行を更新する
row[:] = merged_cells[:]
return changed
# ボードを右にスライドする関数(左にスライドした後に反転させる)
def slide_right(board):
reverse_board(board)
changed = slide_left(board)
reverse_board(board)
return changed
# ボードを上にスライドする関数(左に90度回転させた後に左にスライドし、元に戻す)
def slide_down(board):
rotate_board(board)
changed = slide_left(board)
rotate_board(board, -1)
return changed
# ボードを下にスライドする関数(右に90度回転させた後に左にスライドし、元に戻す)
def slide_up(board):
rotate_board(board, -1)
changed = slide_left(board)
rotate_board(board)
return changed
# ボードを反転させる関数(水平方向に反転)
def reverse_board(board):
for row in board:
row.reverse()
# ボードを回転させる関数(時計回りにn回90度回転)
def rotate_board(board, n=1):
n %= 4 # nを0から3の範囲に正規化する
for _ in range(n):
board[:] = list(map(list, zip(*board[::-1])))
# ボードが埋まっているかどうかを判定する関数
def is_full(board):
return all(cell != 0 for row in board for cell in row)
# ボードに動きがあるかどうかを判定する関数
def has_move(board):
# 空いているセルがあれば動きがある
if not is_full(board):
return True
# 隣り合うセルに同じ値があれば動きがある
for i in range(SIZE):
for j in range(SIZE):
cell = board[i][j]
if (i + 1 < SIZE and cell == board[i + 1][j]) or (j + 1 < SIZE and cell == board[i][j + 1]):
return True
# それ以外は動きがない
return False
# ボードをテキストで表示する関数
def print_board(board):
# 各セルの幅を揃えるために、最大桁数を求める
max_width = max(len(str(cell)) for row in board for cell in row)
# 各行について処理する
for row in board:
# セルの値を文字列に変換し、空白で埋める
cells = [str(cell).rjust(max_width) for cell in row]
# セルをパイプで区切って表示する
print("|" + "|".join(cells) + "|")
# メインの処理
def main():
# ボードを初期化する
board = init_board()
# ボードを表示する
print_board(board)
# ゲームが終了するまで繰り返す
while True:
# 入力を受け付ける
command = input("Enter direction (w, a, s, d) or q to quit: ")
# 入力がqなら終了する
if command == "q":
break
# 入力に応じてボードをスライドさせる
if command == "s":
changed = slide_down(board)
elif command == "a":
changed = slide_left(board)
elif command == "w":
changed = slide_up(board)
elif command == "d":
changed = slide_right(board)
else:
print("Invalid input")
continue
# ボードに変化があれば、ランダムな位置に新しいタイルを追加する
if changed:
add_random_tile(board)
# ボードを表示する
print_board(board)
else:
print("No move")
# ボードに動きがなければ、ゲームオーバーとする
if not has_move(board):
print("Game over")
break
# メインの処理を実行する
if __name__ == "__main__":
main()
C部長 : “GPTって、すごいんですね。じゃあ、強化学習のプログラムもGPTを使えば、すぐにできるでしょう?”
QEU:FOUNDER : “見た目はね・・・。でも、エラーが多すぎるのでやめました。部品(gym,pytorch,etc)のアップデートが激し過ぎて、結果としてGPTから出てくるプログラムが「ちぐはぐ」になっています。これだったら、古いバージョンでもいいので、「動作が保証されている(過去には動いていた)」プログラムを使う方がいいです。”
C部長 : “たたき台に何を使うんですか?”
QEU:FOUNDER : “小生が強化学習をやるときには、真っ先にC国の情報を優先します。お題は「DQN experience replay」です。なにしろ、あそこはロボティックス分野では「最先端の国」だからね。”
C部長 : “そんなにすごいん?”
D先生 : “こんなにすごいんですよ。ホラ・・・。”
QEU:FOUNDER : “おお・・・。小生が好きな「名画」が夜空に・・・。”
C部長 : “参りました・・・。”
QEU:FOUNDER : “今回は、機械学習での使用に耐えうるRTメトリックスの開発の完結編になります。これによって、LLMの開発を除くQEUシステムのモジュールが一応は「できあがり」になるんだよね。”
~ まとめ ~
C部長 : “最近、世の中が酷くなってきましたね。U国だけでなく、中東もひどいし・・・。”
QEU:FOUNDER : “一番ひどいのがJ国の中である件・・・。”
D先生 : “「日本スゴイ」の人たちの件ですね。“
QEU:FOUNDER : “前から不思議だったんです。あの人たち、ロシア支持にかかわらず、なぜか同時にイスラエルを支持なんです。そりゃ矛盾するだろうって・・・。”
D先生 : “そんな「細かな辻褄」なんて、どうでもいいんでしょう。 “
コメント
コメントを投稿