パーソナルブログメモリ

a = [1, 1]
for _ in "*" * 999: a += [sum(a[-2:])]
print(a)

Python 150行で機械学習

2018-06-14 | プログラムをマスター計画2020
3目並べなら機械学習できそう。

やってみるとできました。


機械学習
データを分析して
判別に優位な特徴を見つけだす。
本来膨大なデータが必要。
ざっくりこんな認識しかありません。

教師としてはランダムプレイヤーと
詰めの一手だけ打つランダマー

ランダマーにも負けなくなります。
機械学習したもの同士で戦わせると
ほぼ引き分けます。

引分のデータは計算にいれてませんが、
引き分けます。

最後数局、表示させていますが、
えっ!?という手もあります。



import random
#機械学習
#教えるルールは手番と開いている所におけるのみ
#勝利判定外側で
#局面で勝った回数と負けた回数は記憶
#局面データ 000000000三目ならべ 自分、手番
#データ連想記憶 局面 先手勝ち、後手勝ち

class PlayerRandom:
    #def __init__(self):
    def think(self,bd,tb):
        r=random.randint(0,8)
        if bd[r]=="0":
            return bd[:r]+str(tb)+bd[r+1:]
        else:
            return self.think(bd,tb)
    def result(self,bd,w):
        pass

class PlayerRandomA:
    #def __init__(self):
    def think(self,bd,tb):
        for r in range(9):
            if bd[r]=="0":
                if checkWin(bd[:r]+str(tb)+bd[r+1:])==tb:
                    return bd[:r]+str(tb)+bd[r+1:]
        r=random.randint(0,8)
        if bd[r]=="0":
            return bd[:r]+str(tb)+bd[r+1:]
        else:
            return self.think(bd,tb)
    def result(self,bd,w):
        pass

class PlayerStudy:
    def __init__(self):
        self.db={}
        self.gbd=[]
    def think(self,bd,tb):
        self.gbd.append(bd)
        br=-1
        bs=0.5
        for r in range(9):
            if bd[r]=="0":
                b=bd[:r]+str(tb)+bd[r+1:]
                if b in self.db:
                    w1,w2,dr=self.db[b]
                    if tb==1:
                        if w2==0:
                            score=1
                        else:
                            score=w1/w2
                    if tb==2:
                        if w1==0:
                            score=1
                        else:
                            score=w2/w1
                    if score>bs:
                        bs=score
                        br=r
        if br>=0:
            b=bd[:br]+str(tb)+bd[br+1:]
            self.gbd.append(b)
            return b
        while True:
            r=random.randint(0,8)
            if bd[r]=="0":
                b=bd[:r]+str(tb)+bd[r+1:]
                self.gbd.append(b)
                return b
    def result(self,bd,w):
        if self.gbd[len(self.gbd)-1]!=bd:
            self.gbd.append(bd)
        self.dictMarge(w)
    def dictMarge(self,w):
        for k in self.gbd:
            if k in self.db:
                w1,w2,dr=self.db[k]
                if w==1: w1+=1
                if w==2: w2+=1
                if w==-1: dr+=1
                self.db[k]=(w1,w2,dr)
            else:
                if w==1:self.db[k]=(1,0,0)
                if w==2:self.db[k]=(0,1,0)
                if w==-1:self.db[k]=(0,0,1)
        del self.gbd[:]

def getBd(bd,p):
    s=""
    for i in range(len(p)):
        s+=bd[int(p[i])]
    if s.count("1")==len(p):return 1
    if s.count("2")==len(p):return 2
    return 0

def printbd(bd):
    b=bd.replace("0",".")
    b=b.replace("1","O")
    b=b.replace("2","X")
    print(b[0:3])
    print(b[3:6])
    print(b[6:9])
    print("")

def checkWin(bd):
    arr=["012","345","678","036","147","258","048","246"]
    for a in arr:
        w=getBd(bd,a)
        if w>0:return w
    if bd.count("0")==0:return -1
    return 0

def game(p1,p2,show):
    bd="000000000"
    tb=1
    overSw=0
    while True:
        if tb==1:bd=p1.think(bd,tb)
        if tb==2:bd=p2.think(bd,tb)
        if show==1:
            printbd(bd)
        w=checkWin(bd)
        if w!=0:
            p1.result(bd,w)
            p2.result(bd,w)
            return w
        tb+=1
        if tb>2:tb=1

def repaetGame(p1,p2,times,show):
    wa=[0,0,0]
    for i in range(times):
        w=game(p1,p2,show)
        if w==-1:w=0
        wa[w]+=1
    print(wa)#引分、先手勝ち、後手勝ち

p0=PlayerRandom()
p1=PlayerRandomA()
p2=PlayerStudy()
p3=PlayerStudy()

repaetGame(p0,p2,20000,0)
repaetGame(p1,p3,20000,0)
repaetGame(p2,p3,10000,0)
repaetGame(p2,p3,5,1)
repaetGame(p1,p3,5,1)


最新の画像もっと見る

コメントを投稿

ブログ作成者から承認されるまでコメントは反映されません。