[PYTHON] Une histoire de compétition avec un ami dans Othello AI Preparation

Il y a combien d'années AlphaGo a-t-il remporté le Champion du Monde de Go (il y a trois ans ^ 1)? De nos jours, diverses méthodes ont été développées et il semble que les IA se combattent souvent.

Donc, cette fois, je vais me battre contre l'IA faite par mon ami N et le mien (qu'est-ce que les centaines de millions de bières?).

Je vais l'écrire comme une série comme un journal, alors merci.

Attaché

J'ai créé un lien en jouant contre un ami cette fois. C'est

** Ne cherchez pas du tout **

Alpha Zero, le successeur d'Alpha Go, a gagné en force grâce à une méthode ^ 1 qui combine la recherche arborescente Monte Carlo et l'apprentissage profond, mais la moitié est intentionnellement rejetée. La raison de ce type de liaison est que mes amis créent l'IA en utilisant une méthode axée sur la recherche. Il s'agit d'une composition de soi-disant exploration vs apprentissage profond.

Ensuite, comment faire de l'IA consiste à jouer à un jeu basé sur des nombres aléatoires et des modèles générés et à laisser l'IA apprendre les informations de la partition musicale. Le modèle fera de son mieux pour récupérer les fonctionnalités nécessaires pour gagner.

Préparation

Lors de la création d'Othello AI, la première chose dont vous avez besoin est de définir des règles et de gérer les informations du tableau pour faire Othello lui-même. Donc, dans cette section préparatoire, je voudrais expliquer la situation au moment où ils ont été faits.

Tout d’abord, je voudrais dire quelque chose.

** Enregistrez tout moyen d'accélération autre que l'algorithme **

Je n'ai pas prêté beaucoup d'attention à l'accélération du jeu Othello lui-même (je pensais que c'était un niveau d'erreur car c'est un tableau 8 * 8), mais maintenant que j'ai déjà commencé à apprendre, la lecture est douce. Fait écho à la situation actuelle. J'ai une idée claire de l'accélération, alors j'espère pouvoir également écrire sur cet article.

Initialiser, déplacer

othello.py


def othelloInit():
    board = np.zeros((8,8))
    board[4-1][4-1]=1
    board[5-1][5-1]=1
    board[4-1][5-1]=-1
    board[5-1][4-1]=-1
    board=board.astype(np.int32)
    return board

def othelloMove(board,move):
    if type(move)==int:
        return -1
    tempBoard=othelloMovable(board,move)
    if type(tempBoard) ==np.ndarray:
        return tempBoard
    else:   
        return 0



J'écrirai tout sur le système de jeu d'Othello dans othello.py. othelloInit () renvoie le premier état de la carte d'Othello (l'état où les pièces noires et blanches sont placées à l'état réversible uniquement au milieu) au format numpy.ndarray.

De plus, comme les informations de la carte sont directement placées dans le modèle, elles ne sont pas classifiées.

othelloMove () met à jour les informations de la carte en fonction des informations de la variable de déplacement. Vérifie s'il peut être mis à jour avec othelloMovable (), renvoie 0 sinon, et des informations sur la carte si possible.

Peux-tu bouger?

othello.py


def othelloBlank(board,move):#0 si gratuit, 1 si non gratuit
    k=(board[move[0]][move[1]])*(board[move[0]][move[1]])

    return k
def othelloMovable(Board,Move):#Juge s'il est en mouvement, renvoie les informations du tableau après le placement si possible, 0 sinon
    board=Board.copy()
    move=copy.deepcopy(Move)
    old_board=board.copy()
    if move[0]<0:
        move[0]=0
    elif move[0]>=8:
        move[0]=7
    if move[1]<0:
        move[1]=0
    elif move[1]>=8:
        move[1]=7
    if othelloBlank(board,move)==1:
        return 0
    for i in range(1,9):
        
        #print("ColorCheck:"+str(ColorCheck(board,move,i))+" i:"+str(i))
        if ColorCheck(board,move,i)==-1:
            if i==1:#Vers le haut
                #print("i:"+str(i))
                check=1
                for k in range(move[1],8):#Vérification de la masse, y compris vous-même
                    
                    if k==move[1]:#J'ai déjà vérifié, alors passe
                        pass
                    else:
                        #print([move[0],k])
                        temp=ColorCheck(board,[move[0],k],i)#Contrôle de masse
                        #print("Check:"+str(check))
                        if temp==-1:#Augmentez le nombre si votre adversaire
                        
                            check=check+1
                        elif temp==1 and check>0:#Si vous êtes vous-même, inversez, sauf lorsque la case de l'adversaire n'est jamais apparue
                            
                            check=check*-1
                        else:#Exclure car il ne s'inverse pas
                            
                            break
                    if check<0:#La valeur négative peut être laissée
                        
                        for c in range(0,(check*-1)+1):#Déterminez la cellule à modifier en vous référant à la valeur de comptage.
                            board[move[0]][c+move[1]]=1
                        break
            elif i==2:#En haut à droite
                #print("i:"+str(i))
                temp_move=max(move)
                check=1
                for k in range(temp_move,8):#Vérification de la masse, y compris vous-même
                    
                    if k==temp_move:#J'ai déjà vérifié, alors passe
                        pass
                    else:
                        temp=ColorCheck(board,[move[0]+k-temp_move,move[1]+k-temp_move],i)#Contrôle de masse
                        #print("Check:"+str(check))
                        if temp==-1:#Augmentez le nombre si votre adversaire
                            check=check+1
                        elif temp==1 and check>0:#Si vous êtes vous-même, inversez, sauf lorsque la case de l'adversaire n'est jamais apparue
                            check=check*-1
                        else:#Exclure car il ne s'inverse pas
                            
                            break
                    if check<0:#La valeur négative peut être laissée
                        for c in range(0,(check*-1)+1):#Déterminez la cellule à modifier en vous référant à la valeur de comptage.
                            board[c+move[0]][c+move[1]]=1
                        break
            elif i==3:#droite
                #print("i:"+str(i))
                check=1
                for k in range(move[0],8):#Vérification de la masse, y compris vous-même
                    
                    if k==move[0]:#J'ai déjà vérifié, alors passe
                        pass
                    else:
                        temp=ColorCheck(board,[k,move[1]],i)#Contrôle de masse
                        #print("Check:"+str(check))
                        if temp==-1:#Augmentez le nombre si votre adversaire
                          
                            check=check+1
                        elif temp==1 and check>0:#Si vous êtes vous-même, inversez, sauf lorsque la case de l'adversaire n'est jamais apparue
                            
                            check=check*-1
                        else:#Exclure car il ne s'inverse pas
                            
                            break
                    if check<0:#La valeur négative peut être laissée
                        for c in range(0,(check*-1)+1):#Déterminez la cellule à modifier en vous référant à la valeur de comptage.
                            board[move[0]+c][move[1]]=1
                        break
            elif i==4:#En bas à droite
                #print("i:"+str(i))
                temp_move=max(move[0],7-move[1])
                check=1
                for k in range(temp_move,8):#Vérification de la masse, y compris vous-même
                    
                    if k==temp_move:#J'ai déjà vérifié, alors passe
                        pass
                    else:
                        temp=ColorCheck(board,[move[0]+k-temp_move,move[1]-k+temp_move],i)#Contrôle de masse
                        #print("Check:"+str(check))
                        if temp==-1:#Augmentez le nombre si votre adversaire
                            check=check+1
                        elif temp==1 and check>0:#Si vous êtes vous-même, inversez, sauf lorsque la case de l'adversaire n'est jamais apparue
                            check=check*-1
                        else:#Exclure car il ne s'inverse pas
                            
                            break
                    if check<0:#La valeur négative peut être laissée
                        for c in range(0,(check*-1)+1):#Déterminez la cellule à modifier en vous référant à la valeur de comptage.
                            board[c+move[0]][-c+move[1]]=1
                        break
            elif i==5:#en dessous de
                #print("i:"+str(i))
                check=1
                for k in range(move[1],0,-1):#Vérification de la masse, y compris vous-même
                    
                    if k==move[1]:#J'ai déjà vérifié, alors passe
                        pass
                    else:
                        temp=ColorCheck(board,[move[0],k],i)#Contrôle de masse
                        #print("Check:"+str(check))
                        if temp==-1:#Augmentez le nombre si votre adversaire
                            check=check+1
                        elif temp==1 and check>0:#Si vous êtes vous-même, inversez, sauf lorsque la case de l'adversaire n'est jamais apparue
                            check=check*-1
                        else:#Exclure car il ne s'inverse pas
                            
                            break
                    if check<0:#La valeur négative peut être laissée
                        for c in range(0,(check*-1)+1):#Déterminez la cellule à modifier en vous référant à la valeur de comptage.
                            board[move[0]][-c+move[1]]=1
                        break
            elif i==6:#En bas à gauche
                #print("i:"+str(i))
                temp_move=min(move)
                check=1
                for k in range(temp_move,0,-1):#Vérification de la masse, y compris vous-même
                    
                    if k==temp_move:#J'ai déjà vérifié, alors passe
                        pass
                    else:
                        temp=ColorCheck(board,[move[0]+k-temp_move,move[1]+k-temp_move],i)#Contrôle de masse
                        #print("Check:"+str(check))
                        if temp==-1:#Augmentez le nombre si votre adversaire
                            check=check+1
                        elif temp==1 and check>0:#Si vous êtes vous-même, inversez, sauf lorsque la case de l'adversaire n'est jamais apparue
                            check=check*-1
                        else:#Exclure car il ne s'inverse pas
                            
                            break
                    if check<0:#La valeur négative peut être laissée
                        for c in range(0,(check*-1)+1):#Déterminez la cellule à modifier en vous référant à la valeur de comptage.
                            board[-c+move[0]][-c+move[1]]=1
                        break
            elif i==7:#la gauche
                #print("i:"+str(i))
                check=1
                for k in range(move[0],0,-1):#Vérification de la masse, y compris vous-même
                    
                    if k==move[0]:#J'ai déjà vérifié, alors passe
                        pass
                    else:
                        temp=ColorCheck(board,[k,move[1]],i)#Contrôle de masse
                        #print("Check:"+str(check))
                        if temp==-1:#Augmentez le nombre si votre adversaire
                            check=check+1
                        elif temp==1 and check>0:#Si vous êtes vous-même, inversez, sauf lorsque la case de l'adversaire n'est jamais apparue
                            check=check*-1
                        else:#Exclure car il ne s'inverse pas
                           
                            break
                            
                    if check<0:#La valeur négative peut être laissée
                        for c in range(0,(check*-1)+1):#Déterminez la cellule à modifier en vous référant à la valeur de comptage.
                            board[move[0]-c][move[1]]=1
                        break
            elif i==8:#en haut à gauche
                #print("i:"+str(i))
                temp_move=max(7-move[0],move[1])
                check=1
                for k in range(temp_move,8):#Vérification de la masse, y compris vous-même
                    
                    if k==temp_move:#J'ai déjà vérifié, alors passe
                        pass
                    else:
                        
                        temp=ColorCheck(board,[move[0]-k+temp_move,move[1]+k-temp_move],i)#Contrôle de masse
                        #print("Check:"+str(check))
                        if temp==-1:#Augmentez le nombre si votre adversaire
                            check=check+1
                        elif temp==1 and check>0:#Si vous êtes vous-même, inversez, sauf lorsque la case de l'adversaire n'est jamais apparue
                            check=check*-1
                        else:#Exclure car il ne s'inverse pas
                            
                            break
                    if check<0:#La valeur négative peut être laissée
                        for c in range(0,(check*-1)+1):#Déterminez la cellule à modifier en vous référant à la valeur de comptage.
                            board[-c+move[0]][c+move[1]]=1
                        break
    if np.allclose(board,old_board):
        #print("Je ne peux pas le mettre")
        return 0
    return board

longue... othelloBlank () vérifie s'il est libre sur le plateau en fonction des informations de déplacement. Je ne voulais pas utiliser le branchement, donc je le calcule et le renvoie de force.

othelloMovable () vérifie si elle est dans une règle (s'il y a une pièce à retourner) basée sur les informations de déplacement. C'est juste long. Je l'ai écrit dans la tension de minuit, et je sens que je pensais m'être amélioré même avec cela à ce moment-là, mais il semble que c'est la cause de la lenteur.

L'AS-tu fait? Et d'autres

othello.py


def othelloEndCheck(board):#Découvrez s'il y a un autre endroit où aller. Renvoie 1 s'il peut être placé, 0 s'il ne peut pas être placé.
    for i in range(0,8):
        for n in range(0,8):
            #print([i,n])
            if type(othelloMovable(board,[i,n]))==np.ndarray:
                #print("Nope")
                return 1
    return 0

def ColorCheck(board,axis,way):#Le haut commence 1 dans le sens des aiguilles d'une montre et réserve jusqu'à 8. 0 est omnidirectionnel. Si hors bord-2,Si l'autre partie-Renvoie 1, 0 pour les blancs, 1 pour lui-même.
    if way==1:
        if axis[1]>=7:
            return -2
        else:
            #print("ColorCheck")
            #print(board[axis[0]][axis[1]+1])
            return board[axis[0]][axis[1]+1]
    elif way==2:
        if axis[0]>=7 or axis[1]>=7:
            return -2
        else:
            return board[axis[0]+1][axis[1]+1]
    elif way==3:
        if axis[0]>=7:
            return -2
        else:
            return board[axis[0]+1][axis[1]]
    elif way==4:
        if axis[0]>=7 or axis[1]<=0:
            return -2
        else:
            return board[axis[0]+1][axis[1]-1]       
    elif way==5:
        if axis[1]<=0:
            return -2
        else:
            return board[axis[0]][axis[1]-1]
    elif way==6:
        if axis[1]<=0 or axis[0]<=0:
            return -2
        else:
            return board[axis[0]-1][axis[1]-1]
    elif way==7:
        if axis[0]<=0:
            return -2
        else:
            return board[axis[0]-1][axis[1]]
    elif way==8:
        if axis[0]<=0 or axis[1]>=7:
            return -2
        else:
            return board[axis[0]-1][axis[1]+1]


    return 0

C'est aussi long ... othelloEndCheck () vérifie s'il y a d'autres mouvements. Renvoie 1 si vous pouvez l'atteindre, 0 si vous ne pouvez pas l'atteindre.

ColorCheck () renvoie la couleur des cadres environnants en fonction des informations de déplacement (pourquoi seulement vous n'avez pas othello?). Je n'ai pas utilisé toutes les directions dans le commentaire, donc je ne l'ai pas encore implémenté.

Celui qui affiche quelque chose

othello.py


def othelloReverse(Board):
    board=Board.copy()
    #print("reversing")
    board=board*-1
    return board

def othelloShow(board):
    for i in reversed(range(0,8)):#y
        #print("i:"+str(i))
        for k in range(0,8):#x
            if board[k][i]==-1:
                print("○",end=" ")
            elif board[k][i]==1:
                print("●",end=" ")
            elif board[k][i]==0:
                print("■",end=" ")
        print("")
        print("")
    #print(board[7])
    return 0

othelloReverse () retourne la couleur du tableau. En d'autres termes, les première et deuxième attaques sont remplacées. En conséquence, le côté frappant sera toujours 1 sur les données du tableau.

othelloShow () montre l'état du tableau. C'est un peu gênant de faire le coin inférieur gauche (0,0). À l'avenir, j'aimerais utiliser la méthode gui en utilisant des pygames pour plus de commodité.

Résumé

** Celui qui est définitivement sur le net est le plus rapide. ** **

Je ne suis pas une personne qui sait beaucoup faire de la programmation compétitive, et je ne suis pas un passionné de programmation, donc je ne peux pas penser à un algorithme qui puisse être fait plus rapidement.

Et après avoir fait tout cela, j'ai été choqué de savoir comment accélérer ...

J'espère vous voir la prochaine fois dans l'édition de construction de modèles.

Recommended Posts

Une histoire de compétition avec un ami dans Othello AI Preparation
Une histoire sur l'apprentissage automatique avec Kyasuket
Une histoire sur l'implémentation d'un écran de connexion avec django
Une histoire remplie de valeurs absolues de numpy.ndarray
Histoire de l'utilisation du jeton logiciel de Resona avec 1Password
Une histoire de prédiction du taux de change avec Deep Learning
L'histoire de la création d'une partition de type Hanon avec Python
Une histoire d'essayer un monorepo (Golang +) Python avec Bazel
Une histoire qui reflète l'activité Discord dans Slack Status
L'histoire de la gestion de theano avec TSUBAME 2.0
Une histoire sur un débutant Linux passant LPIC101 en une semaine
Une histoire sur la façon de spécifier un chemin relatif en python.
Une histoire sur l'installation de matplotlib à l'aide de pip avec une erreur
Une histoire sur un amateur faisant une rupture de bloc avec python (kivy) ②
[Note] Une histoire sur la tentative de remplacer une méthode de classe avec deux barres inférieures dans la série Python 3.
Une histoire sur la façon de traiter le problème CORS
Apprentissage automatique Une histoire sur des personnes qui ne sont pas familiarisées avec GBDT utilisant GBDT en Python
Une histoire sur un amateur faisant une rupture de bloc avec python (kivy) ①
Une histoire sur la création d'une courte chanson par hasard avec Sudachi Py
[Django] Une histoire sur le fait de rester coincé dans un marais en essayant de valider un zip avec un formulaire [TDD]
Une histoire sur la tentative d'implémentation de variables privées en Python.
Une histoire sur une tragédie qui se passe en échangeant des commandes dans le chat
Une histoire à propos d'un débutant en python coincé avec aucun module nommé'ttp.server '
Une histoire sur tout, de la collecte de données au développement d'IA et à la publication d'applications Web en Python (3. développement d'IA)
Une histoire sur l'ajout d'une API REST à un démon créé avec Python
Une histoire sur une erreur de construction dans une bibliothèque partagée qui fait référence à libusb
Une histoire sur le développement d'un type logiciel avec Firestore + Python + OpenAPI + Typescript
Une histoire rafraîchissante sur Slice en Python
Remarque à propos de get_scorer de sklearn
Une histoire de mauvaise humeur sur Slice en Python
Faisons l'IA d'Othello avec Chainer-Part 1-
L'histoire de l'utilisation de la réduction de Python
Faisons l'IA d'Othello avec Chainer-Part 2-
L'histoire d'un capteur de stationnement en 10 minutes avec le kit de démarrage GrovePi +
[Petite histoire] Comment enregistrer des graphiques matplotlib dans un lot avec Jupyter
Une histoire sur l'automatisation du mahjong en ligne (Jakutama) avec OpenCV et l'apprentissage automatique
[Mémorandum] Une histoire sur l'essai du didacticiel OpenCV (reconnaissance faciale) dans un environnement Windows
Livre en spirale en Python! Python avec un livre en spirale! (Chapitre 14 ~)
Une histoire sur un remodelage magique qui met Lubuntu dans un Chromebook
Dessinez un cœur en rubis avec PyCall
[Facile] Reconnaissance automatique AI avec une webcam!
Une histoire sur Python pop and append
Faisons une IA à trois yeux avec Pylearn 2
Une histoire que moi, un débutant en programmation, j'ai créé une application de cartographie d'efficacité commerciale avec GeoDjango
[Note] Une histoire sur l'impossibilité de percer le proxy avec pip
Une histoire déroutante avec deux façons d'implémenter XGBoost en Python + notes générales
Une histoire sur la création d'un environnement IDE avec WinPython sur un ancien système d'exploitation Windows.
Une histoire qui est devenue bleu clair en 4 mois après avoir démarré AtCoder avec python
Échapper à l'environnement virtuel de Python ~ Une histoire sur le fait d'être piégé dans un environnement virtuel que j'ai créé ~
J'ai essayé de créer un chargeur de démarrage x86 qui peut démarrer vmlinux avec Rust