게시판VLM을 이용한 테트리스 학습예제 소스

예제 소스

VLM을 이용한 테트리스 학습 · 파일 31개

moe_macro_policy.py

from __future__ import annotations

from dataclasses import dataclass

import numpy as np


@dataclass(frozen=True)
class ExpertWeights:
    # Larger is better; we convert metrics to a single score.
    # cleared: +, holes/bump/height: -
    w_cleared: float = 3.0
    w_holes: float = -0.8
    w_bump: float = -0.03
    w_height: float = -0.10
    w_game_over: float = -100.0


@dataclass(frozen=True)
class GateConfig:
    # weights for experts A..D in the final score
    gate_a_holes: float = 1.0
    gate_b_lines: float = 1.0
    gate_c_bump: float = 1.0
    gate_d_height: float = 1.0


def _expert_a_min_holes(cleared, holes, bump, height, game_over) -> float:
    return (-holes) + (-100.0 * game_over) + (0.5 * cleared)


def _expert_b_max_lines(cleared, holes, bump, height, game_over) -> float:
    return (10.0 * cleared) + (-0.2 * holes) + (-100.0 * game_over)


def _expert_c_min_bumpiness(cleared, holes, bump, height, game_over) -> float:
    return (-bump) + (-0.3 * holes) + (1.0 * cleared) + (-100.0 * game_over)


def _expert_d_min_height(cleared, holes, bump, height, game_over) -> float:
    return (-height) + (-0.3 * holes) + (1.5 * cleared) + (-100.0 * game_over)


def choose_macro_action_moe(micro_env, gate: GateConfig = GateConfig()) -> int:
    """
    Choose macro action (rot,col) using 4 experts + simple gating.
    Requires C API function tetris_eval_macro_candidates.
    """
    h = micro_env._h
    dll = micro_env._lib._dll
    w = int(dll.tetris_board_width(h))
    n = 4 * w
    buf = (np.zeros((n, 6), dtype=np.int32)).reshape(-1)
    ptr = buf.ctypes.data_as(np.ctypeslib.ctypes.POINTER(np.ctypeslib.ctypes.c_int))
    written = int(dll.tetris_eval_macro_candidates(h, ptr, n))
    if written <= 0:
        return 0

    m = buf.reshape(n, 6)[:written]
    cleared = m[:, 0].astype(np.float32)
    holes = m[:, 1].astype(np.float32)
    bump = m[:, 2].astype(np.float32)
    height = m[:, 3].astype(np.float32)
    go = m[:, 4].astype(np.float32)

    a = np.array([_expert_a_min_holes(c, ho, bu, he, g) for c, ho, bu, he, g in zip(cleared, holes, bump, height, go)], dtype=np.float32)
    b = np.array([_expert_b_max_lines(c, ho, bu, he, g) for c, ho, bu, he, g in zip(cleared, holes, bump, height, go)], dtype=np.float32)
    c = np.array([_expert_c_min_bumpiness(c1, ho, bu, he, g) for c1, ho, bu, he, g in zip(cleared, holes, bump, height, go)], dtype=np.float32)
    d = np.array([_expert_d_min_height(c1, ho, bu, he, g) for c1, ho, bu, he, g in zip(cleared, holes, bump, height, go)], dtype=np.float32)

    final = (
        gate.gate_a_holes * a
        + gate.gate_b_lines * b
        + gate.gate_c_bump * c
        + gate.gate_d_height * d
    )
    return int(np.argmax(final))


__all__ = ["GateConfig", "ExpertWeights", "choose_macro_action_moe"]