Subscribed unsubscribe Subscribe Subscribe

最中限AIその2

ちょいちょい書き直してみた。
どうしても分岐が多くなって見にくくなる。。。
なんとなく自分が勝負するときに考えてることを実現させようとは思ってるんだけど、なんとも難しい。

# -*- encoding: utf-8 -*-

from saichugen import Player
from saichugenlib import *

class MyAI(Player):
    name = "MyAI"
    def __init__(self, hand):
        hand.sort()
        self.hand = hand
    def play(self, info):
        handstr = map(to_str, self.hand)
        # 未知カードから自分の手持ちを取り除く
        import copy
        self.unknowns = copy.copy(info['unknowns'])
        for i in self.hand:
            self.unknowns.remove(i)

        my_game_score = info['game_score'][0]
        my_round_score = info['round_score'][0]

        round_strategy = ''
        # 1,2ラウンド目の戦略:とりあえず点は取らない方向で
        if info['iround'] < 2:
            round_strategy = 'lose'
        # 3-5ラウンド目の戦略:状況を見極める
        if info['iround'] >= 2 :
            if my_game_score < get_mid(info['game_score']):
                round_strategy = 'win'
            elif my_game_score > get_mid(info['game_score']):
                round_strategy = 'lose'
            else:
                if my_game_score < get_top(info['game_score']):
                    round_strategy = 'win'
                else:
                    round_strategy = 'lose'

        # 現在のターンの戦略
        turn_strategy = ''
        if round_strategy == 'win':
            if my_round_score < get_mid(info['round_score']):
                turn_strategy = 'win'
            elif my_round_score > get_mid(info['round_score']):
                turn_strategy = 'lose'
            else:
                if my_round_score < get_top(info['round_score']):
                    turn_strategy = 'win'
                else:
                    turn_strategy = 'lose'
        elif round_strategy == 'lose':
            if my_round_score < get_mid(info['round_score']):
                turn_strategy = 'lose'
            elif my_round_score > get_mid(info['round_score']):
                turn_strategy = 'win'
            else:
                if my_round_score < get_top(info['round_score']):
                    turn_strategy = 'lose'
                else:
                    turn_strategy = 'win'
        elif round_strategy == 'keep':
            turn_strategy = ''

        # 手持ちカードのそれぞれを出したときの得点率を計算
        a = []
        for i in self.hand:
            lt = 0
            gt = 0
            for j in self.unknowns:
                if j < i:
                    lt += 1
                else:
                    gt += 1
            a.append(lt * gt)
        # 得点率の平均を算出
        ave = 1.0 * sum(a) / len(a)

        from random import choice
        if turn_strategy == '':
            return self.hand.pop(choice(range(len(self.hand))))
        # 戦略に従った選択
        # 得点すべきときには得点率が平均以上のものから選択
        # 得点すべきでないときには得点率が平均以下のものから選択
        flg = 0
        if turn_strategy == 'win':
            flg = 1
        elif turn_strategy == 'lose':
            flg = -1
        recommend = []
        for i in range(len(a)):
            if (a[i] - ave) * flg > 0:
                recommend.append(i)
        if len(recommend) == 0:
            recommend = range(len(a))

        return self.hand.pop(choice(recommend))

def get_top(*xs):
    if len(xs) == 1: xs = xs[0]
    assert len(xs) == 3
    return sorted(xs)[2]

ランダムAIと10000回対戦を何度かやらせてみた結果:

[989, -418, -571]
[935, -562, -373]
[746, -436, -310]
[1050, -477, -573]
[1005, -474, -531]

お。悪くない。勝ちやすい傾向にあるのは確かだ。
とは言え、実際にオンラインで勝っているヒトたちの平均値は0.5〜0.8くらい。今のこのAIは0.1にようやく届くか、という程度だ。
まだまだ分岐を増やして行けば少しは近づくかな?それとももっと別のアイデアが必要になってくるのだろうか?
そもそもまだ自分でも勝つための作戦がよく分かってないしなぁ…