0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

チュートリアルStep3

Last updated at Posted at 2024-10-04

スクリーンショット 2024-10-09 22.05.09.png

puyopuyo.gif
 ぷよぷよプログラミングAI学習システムは、中高生の自己調整学習に向けて開発されました。
 どうやって、Chromebookで、10分で、素敵な人工知能を作れるのでしょうか?
 秘密は、3つ。
 1 jupyter liteで、webクライアントがpythonコードを実行
 2 超軽量な機械学習フレームワークdezeroを採用
 3 ぷよぷよのstageとactionがコンパクト

Github&X

ぷよぷよプログラミングAI学習用まとめ

チュートリアルまとめ

Step3 Action選択肢と衝突判定

3 衝突判定をして、Action選択肢を探る。

 どこにpuyoを移動させて、回転させるかという選択肢は、幅6 x 回転4 -2 = 22 の可能性があるようにも見えますが、他のpuyoと衝突するかもしれないので、衝突判定が必要です。

step2で作った、set_puyo_to_boardを改造して、衝突判定の関数を作ります。

def check_collision(board, puyo):
   rot = puyo.rotation
   if rot == 0 and puyo.x == 5:
      return True
   if rot == 2 and puyo.x == 0:
      return True
   if puyo.y >= 12:
      return True
   if puyo.y == 11 and rot == 3 :
      return True
   if board[puyo.y, puyo.x] > 0 :
      return True
   if not( rot == 1) and board[puyo.y + puyo.dy[rot], puyo.x + puyo.dx[rot]] > 0:
      return True
   return False

この関数は、そのブロックがboardの中に入っているか、逆に言えば、はみ出ていないか判定もしています。

check_collisionを使って、actionの選択肢をリスト化します。

actionの選択肢は、スタートする列の位置と回転数をリストとして出力します。

import numpy as np
from puyo_utils import *

def create_action_list(board):
    puyo2 = Puyopuyo()
    res = []
    for rot in range(4):
        for pos1 in range(6):
            puyo2.x = pos1
            puyo2.rotation = rot
            if not check_collision(board, puyo2):   
                res.append([pos1, rot])
    return res

action_list は、numpyではないので、少し注意が必要です。
それでは、使ってみましょう。

board = utils.create_sample_board()
action_list=create_action_list(board)

print(action_list)

[[0, 0], [1, 0], [2, 0], [3, 0], [4, 0], [0, 1], [1, 1], [2, 1], [3, 1], [4, 1], [5, 1], [1, 2], [2, 2], [3, 2], [4, 2], [5, 2], [0, 3], [1, 3], [2, 3], [3, 3], [4, 3], [5, 3]]

action_listは厳密には、ぷよの横移動と回転可能性が完全には保証されていません。実ゲームでどこまで応用可能かはやってみてからの調整が必要です。

これらの関数も使いたいので、puyo_utilsに保存しておきます。

%%writefile puyo_utils.py
import numpy as np
import random

class CFG:
    Height = 12
    Width = 6


class Puyopuyo:
    def __init__(self):
        self.x = 2
        self.y = 0
        self.dx = [1,  0, -1, 0]
        self.dy = [0, -1,  0, 1]
        self.centerPuyo = random.randint(1,4)
        self.movablePuyo = random.randint(1,4)
        self.rotation = 1    


class utils:
    def create_sample_board(height=CFG.Height, width=CFG.Width):
        sample_list = np.arange(width)
        random.shuffle(sample_list)
        board = np.zeros(height * width, dtype = np.int32).reshape(height, width)

        for j in range(width):
            if sample_list[j]:
                for i in range(sample_list[j]):
                    board[height - 1 - i, j] = random.randint(1, 4)

        return board

    def create_new_puyo(board):
        new_puyo = Puyopuyo()
        done = False
        if board[2, 0] > 0:
            done = True
        return new_puyo, done    

    def set_puyo_to_board(board, puyo):
        new_board = np.copy(board)
        new_board[puyo.y, puyo.x ] = puyo.centerPuyo
        puyo_dy = puyo.y + puyo.dy[puyo.rotation]
        puyo_dx = puyo.x + puyo.dx[puyo.rotation]
        if puyo_dy >= 0:
            new_board[puyo_dy, puyo_dx ] = puyo.movablePuyo
        return new_board

    def check_collision(board, puyo):
        rot = puyo.rotation
        if rot == 0 and puyo.x == 5:
            return True
        if rot == 2 and puyo.x == 0:
            return True
        if puyo.y >= 12:
            return True
        if puyo.y == 11 and rot == 3 :
            return True
        if board[puyo.y, puyo.x] > 0 :
            return True
        if not( rot == 1) and board[puyo.y + puyo.dy[rot], puyo.x + puyo.dx[rot]] > 0:
            return True
        return False
    

    def create_action_list(board):
        puyo2 = Puyopuyo()
        res = []
        for rot in range(4):
            for pos1 in range(6):
                puyo2.x = pos1
                puyo2.rotation = rot
                if not utils.check_collision(board, puyo2):   
                    res.append([pos1, rot])
        return res

Overwriting puyo_utils.py
  • class utils : 関数をまとめて、utilsにしました。名前がぶつからないようにします。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?