LoginSignup
0
1

特殊な条件下でのハイ&ローゲーム(Hi-Lo)を行うAIモデル

Last updated at Posted at 2024-04-15

目次

1.ハイ&ロー(Hi-Lo)とは何か
2.使用したライブラリと手法
3.今回の特殊な条件
4.Q学習のプログラム
5.今後の展望

※ミスなどがありましたら報告願います

1. ハイ&ロー(Hi-Lo)とは何か

ハイ&ローは、トランプを用いるカードゲームで、名前の通り、高い(high)か低い(low)かを当てる単純なゲームです。
単純なだけに細かい所で色々ルールが派生したり違ったりすることもあります。
最近では、オンラインカジノサイトなどで有名なため、知っている方も多いと思います。
今回は、オンラインカジノでのハイ&ローのルールを採用していきます。

手順

1.jokerを除いた52枚のトランプをよくシャッフルし、山札を裏向きにしておく
2.ディーラーが山札の一番上を表にして前に置く
3.プレイヤーは次に山札から出るカードが今開示されているカードより高い(high)か低い(low)かを予想する
(カードの大きさは、小さい順に2,3,4,5,6,7,8,9,10,J,Q,K,A)
4.ディーラーは伏せられていたカードを開示する
5.(1)予想が正しかった場合は、オッズ表(リンクにあるものをそのまま使っています)に基づきディーラーがプレイヤーに報酬を支払う
(2)予想が外れた場合は、ディーラーがプレイヤーの賭け金額を没収
6.先ほど開示されたカードをもとに次のカードの予想を行う
7.52枚のカードがなくなるまで1→6を繰り返す

<注>カジノサイトによってはカードを3枚出して戻すというところもあります。

※手順をお借りしたサイト
https://www.casino-winnersclub.com/high-low.php#haiandorono_liure (このサイトのオッズ表です)
https://edgegram.hatenablog.jp/entry/2018/09/05/172349

使用したライブラリ

使用した言語はpythonです。環境にJupyter Notebookを使用しました。

- python 3

次にライブラリを紹介しましょう。

- numpy as np
- pandas as pd

pandasはデータをまとめるために使用しました。別にimportしなくても構いません

使用した手法

AIとは言ってもいくつかの手法のもとに成り立っています。
今回は、正解のデータがあるわけでもなく、明確な目的は所持金額を増やすことだけなので強化学習を使用。
強化学習の基本とされている「Q学習」を使用しました。もちろんε-greedy法はありです。

今回の特殊な条件

・今回はわかりやすいようにカードの大きい順を変えます。
本来:(2,3,4,5,6,7,8,9,10,J,Q,K,A)
今回:(A,2,3,4,5,6,7,8,9,10,J,Q,K)
・数字が同じだった場合について"Same"という選択肢のあるものや、"High"に含めるもの、"Low"に含めるものがありますが、今回"Same"は"High"に含めるものを採用します。
・スート(マーク)による大小(例:♠>❤など)はなしです。
・バーストはなしです
・賭けられる金額は1です。(読者の皆さんが変えて遊んでみてください)

Q学習のプログラム

Qテーブルの定義

base_Q_table
num_actions = 2
num_total_values = 13
num_remaining_cards = 52 
q_table_shape = (num_actions, num_total_values, num_remaining_cards)
q_table = np.ones(q_table_shape)

残りのカードの枚数が学習に大事なので三次元によるQ学習になっています。

オッズ表を定義

Odds_dict
odds_dict = {
    1: (1.00, 13.4),
    2: (1.04, 6.30),
    3: (1.10, 4.20),
    4: (1.30, 3.30),
    5: (1.45, 2.70),
    6: (2.10, 1.50),
    7: (1.80, 1.80),
    8: (1.50, 2.10),
    9: (2.70, 1.45),
    10: (3.30, 1.30),
    11: (4.20, 1.10),
    12: (6.30, 1.04),
    13: (13.4, 1.00)
}

ゲームをプレイする関数

play_game
def play_game(initial_bet, epsilon):
    global bet
    global total
    global remaining_cards

    deck = list(range(1, 14)) * 4  # AからKまでのジョーカー抜きのデッキ
    np.random.shuffle(deck)

    # カードの初期状態
    total = deck.pop()  # 初めに開示されるカード
    action = 1  # 初期アクション
    reward = 0  # 報酬の初期化

    while deck:
        # カードを引く前に状態を取得
        state = (action, total-1, len(deck))

        # ε-greedy法に基づいて次のアクションを決定
        if np.random.rand() < epsilon:
            next_action = np.random.randint(2)  # ランダムに行動を選択
        else:
            next_action = 1 if q_table[1, total-1, len(deck)] > q_table[0, total-1, len(deck)] else 0  # Q値が最大となる行動を選択

        # カードを引く
        next_card = deck.pop()

        # 次の状態の取得
        next_state = (next_action, next_card-1, len(deck))

        # プレイヤーの予測に基づいて勝敗判定
        next_card_value = q_table[:, total-1, len(deck)]
        max_next_card_value = next_card_value[next_action]

        if (action == 1 and next_card >= total):
            reward = initial_bet * odds_dict[total][0]
        elif (action == 0 and next_card < total):
            reward = initial_bet * odds_dict[total][1]
        else:
            reward = -initial_bet

        # Q値の更新
        q_table[state] = (1 - alpha) * q_table[state] + alpha * (reward + gamma * max_next_card_value)

        # カードを更新
        total = next_card
        action = next_action

    return reward

学習率、回数、εの値

learning_rate
epochs = 100000
bet = 1
epsilon = 0.1 
alpha = 0.1
gamma = 0.9

alphaとgammaを書き忘れてました。すみません(2024/05/17)

モデルの作成

making_model
print(q_table)
for _ in range(epochs):
    reward = play_game(bet, epsilon)
    if _ % 100 == 0:
        print(q_table)
print(q_table)

今後の展望

今度は、安全手をなるべく多くとれるように、もう一つの有名なものであるSARSAを行いたいと思います。また、賭け金を予測に基づいて変動させるAIを作ることもよいかと思います。

0
1
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
1