Benutzer-Werkzeuge

Webseiten-Werkzeuge


ws1920:selbstlernender_gegner

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen gezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
ws1920:selbstlernender_gegner [2020/03/26 17:36]
benbaute
ws1920:selbstlernender_gegner [2020/04/03 13:10] (aktuell)
benbaute
Zeile 1: Zeile 1:
-**Selbstlernender Gegner**+===== Selbstlernender Gegner ​=====
  
-**VierGewinnt** +VierGewinnt\\ 
-**Tic Tac Toe**+Tic Tac Toe
  
-**Überblick**+=== Überblick ​===
  
 Wir, Ben und Gohjan haben uns mit dem Thema auseinadergesetzt,​ wie man einer künstlichen Intelligenz Spiele beibringen kann. Dafür haben wir uns für Vier gewinnt entschieden,​ da Vier gewinnt ein relativ simples Spielprinzip hat, aber durch z.B. Zwickmühlen trotzdem ziemlich komlex ist und so der Computer auch viel zu lernen hat. Dafür haben wir uns zuerst mit Tic Tac Toe beschäftigt,​ da dies ein vergleichbares Spielprinzip hat, aber wesentlich weniger mögliche Zustände hat und so einfacher zu erlernen ist. Wir, Ben und Gohjan haben uns mit dem Thema auseinadergesetzt,​ wie man einer künstlichen Intelligenz Spiele beibringen kann. Dafür haben wir uns für Vier gewinnt entschieden,​ da Vier gewinnt ein relativ simples Spielprinzip hat, aber durch z.B. Zwickmühlen trotzdem ziemlich komlex ist und so der Computer auch viel zu lernen hat. Dafür haben wir uns zuerst mit Tic Tac Toe beschäftigt,​ da dies ein vergleichbares Spielprinzip hat, aber wesentlich weniger mögliche Zustände hat und so einfacher zu erlernen ist.
  
-**Code** +=== Code ===
-[[pagename|Tic Tac Toe]] +
-[[pagename|Vier gewinnt]]+
  
-**Dokumentation** +[[some:Tic Tac Toe]]
-[[pagename|Dokumentation]]+
  
 +[[some:Vier gewinnt]]
  
 +=== Dokumentation ===
  
-**Hinweise von Stefan Born** +[[pagename|Dokumentation]]
-Für das Spiel fällt mir zweierlei ein: +
- +
-Tic-Tac-Toe hat einen so kleinen Zustandsraum,​ dass man das Spiel '​lösen',​ also mit einem Backtracking-Algorithmus einen optimalen Zug finden kann.  So ähnlich kann man es noch bis etwa zur Größe von '​Mühle'​ machen, dann geht das nicht mehr. +
- +
-Für komplexere Spiele wird man so etwas wie 'deep Q-Learning'​ brauchen. einige Quellen u.a. das Buch von Sutton und Barto über Reinforcemen Learning, dass die grundlegenden Ideen von Reinforcement Learning +
-gut erklärt. +
- +
-**Protokoll für den 21.11.2019** +
- +
-Wir haben uns mit einem Backtracking-Algorithmus auseinander gesetzt und teilweise versucht ihn anzuwenden und außerdem ein TicTacToe Spiel anhand der Turtle angefangen zu Programmieren. ​  +
- +
-**Protokoll für den 28.11.2019** +
- +
-Heute haben wir mit der Turtle erflogreich ein TicTacToe-Spiel programmiert welches zwei Spieler gegeneinander spielen lässt und uns mit dem Thema "​Reinforcement Learning"​ auseinander gesetzt. +
- +
-**Protokoll für den 05.12.2019** +
- +
-Anfangs infomierten wir uns noch in Bezug zu "​Reinforcement Learning"​ und einigten uns recht schnell darauf den Gegner mit Q-Learning zu entwickeln. Daraufhin haben wir uns mit der Methode intensiver beschäftigt und auch schon einen ersten Plan mithilfe des Buches von Richard S. Sutton "​Reinforcement Learning An Introduction second edition"​ für den Spieler vom Tic-Tac-Toe-Spiel aufgestellt. +
-Reinforcemts Learning funktioniert indem ein "​Agent"​ auf seine Umgebung reagiert und für seine Handlung belohnt oder bestraft wird. Er handelt entweder zufällig oder in dem Interesse eine Aktion durchzuführen,​ welche die größte Belohnung gibt. Beide Handlungsmöglichkeiten sind wichtig, da der Agent auch durch schlechte Aktionen dazulernt. Um den Computer dazu zu bringen so zu lernen, werden wir es mit der q-Formel versuchen, welche anhand seiner Aktionen die Bewertung für die Aktionen, die anfangs noch sehr ungenau sind, spezialisiert. +
-In den nächsten Stunden werden wir uns dann damit beschäftigen wie man das auch in die Tat umsetzen kann. +
- +
-**Protokoll für den 19.12.2019** +
- +
-Eine Woche vor Weihnachten haben wir nun einen selbstlernendem Gegner, den wir im Internet gefunden haben (https://​github.com/​agrawal-rohit/​playing-games-with-python/​blob/​master/​Tic%20Tac%20Toe/​training_(AIvsAI)_ReinforcementLearning.py),​ versucht in Bens TikTakToe Spiel einzubauen. Außerdem haben wir schon angefangen den Computer aus dem Internet zu analysieren und auf ein "vier gewinnt"​ Spiel zu übertragen. +
-Für die nächsten Wochen haben wir uns vorgenommen,​ zum einen ein "vier gewinnt"​ Spiel mit der Turtle zu schreiben, dass sich ähnlich wie Bens TicTacToe-Spiel verhält und zum anderen den Computeer weiter zu analysieren und  anfangen ein AI für  ein "vier gewinnt"​ zu schreiben.  +
-Bens TicTacToe-Spiel:​ +
-import turtle as t +
-import numpy as np +
-tttmatrix=np.zeros(9) +
-tttmatrix=tttmatrix.reshape((3,​ 3)) +
-kreuz = 0 +
-Anzahl = 0 +
-spielende = 10 +
-siegkreuz = 0 +
-siegkreis = 0 +
-keinsieg = 0 +
-start = t.Turtle() +
-start.speed(0) +
-def neuanfang():​ +
-    global spielende +
-    global siegkreis +
-    global siegkreuz +
-    global keinsieg +
-    global tttmatrix +
-    global Anzahl +
-    if(spielende!=10):​ +
-        start.up() +
-        start.clear() +
-        start.setx(-2) +
-        start.hideturtle() +
-        start.write(siegkreuz) +
-        start.sety(start.ycor()+2) +
-        start.write(siegkreis) +
-        start.sety(start.ycor()+2) +
-        start.write(keinsieg) +
-        start.goto(0,​0) +
-        tttmatrix=0 +
-        tttmatrix=np.zeros(9) +
-        tttmatrix=tttmatrix.reshape((3,​ 3)) +
-        spielende = 10 +
-        t.clear() +
-        Anzahl = 0 +
-     +
-     +
-def kreismalen(t):​ +
-    t.up() +
-    t.right(90) +
-    t.forward(4) +
-    t.left(90) +
-    t.down() +
-    t.circle(4) +
-     +
-def kreuzmalen(t):​ +
-    t.left(45) +
-    t.forward(5) +
-    t.backward(10) +
-    t.forward(5) +
-    t.left(90) +
-    t.forward(5) +
-    t.backward(10) +
-    t.forward(5) +
-    t.right(135) +
-def tttfeld():​ +
-    """​ +
-    Malt ein 3x3 Feld. +
-    """​ +
-    t.setworldcoordinates(0,​30,​30,​0) +
-    spalten = t.Turtle() +
-    spalten.left(90) +
-    zeilen = t.Turtle() +
-    spalten.speed(0) +
-    zeilen.speed(0) +
-    spalten.hideturtle() +
-    zeilen.hideturtle() +
-    for i in range(4): +
-        spalten.setx(i*10) +
-        zeilen.sety(i*10) +
-        spalten.forward(30) +
-        zeilen.forward(30) +
-        spalten.sety(0) +
-        zeilen.setx(0) +
-    zeilen.goto(0,​0) +
-    spalten.goto(0,​0) +
-    zeilen.up() +
-    zeilen.setx(-3) +
-    zeilen.write("​Siege von Kreuz:",​ align="​right"​) +
-    zeilen.sety(zeilen.ycor()+2) +
-    zeilen.write("​Siege von Kreis:",​ align="​right"​) +
-    zeilen.sety(zeilen.ycor()+2) +
-    zeilen.write("​Unentschieden:",​ align="​right"​) +
-    zeilen.goto(0,​0) +
-    zeilen.down() +
-     +
-def ende(): +
-    zeile = np.sum(tttmatrix,​ axis=1) +
-    spalte = np.sum(tttmatrix,​ axis=0) +
-    diagonale1 = tttmatrix[0, 0]+tttmatrix[1, 1]+tttmatrix[2,​ 2] +
-    diagonale2 = tttmatrix[2,​ 0]+tttmatrix[1,​ 1]+tttmatrix[0,​ 2] +
-    if(3 in zeile or 3 in spalte or 3==diagonale1 or 3==diagonale2):​ +
-        return 1 +
-    elif(-3 in zeile or -3 in spalte or -3==diagonale1 or -3==diagonale2):​ +
-        return -1 +
-    else: +
-        return 0 +
-def malen(x, y): +
-    global kreuz +
-    global Anzahl +
-    global spielende +
-    global siegkreis +
-    global siegkreuz +
-    global keinsieg +
-    global tttmatrix +
-    if(x <=10): +
-        spalte = 0 +
-    if(x >10 and x <=20): +
-        spalte = 1 +
-    if(x >20 and x <=30): +
-        spalte = 2 +
-    if(y <=10): +
-        zeile = 0 +
-    if(y >10 and y <=20): +
-        zeile = 1 +
-    if(y >20 and y <=30): +
-        zeile = 2 +
-    t.up() +
-    t.setx(spalte*10+5) +
-    t.sety(zeile*10+5) +
-    t.down() +
-    if(tttmatrix[zeile,​ spalte]==0 and spielende==10):​ +
-        Anzahl = Anzahl + 1 +
-        if(kreuz==0):​ +
-            kreuzmalen(t) +
-            kreuz =  1 +
-            tttmatrix[zeile,​ spalte]=1 +
-            if(ende()==1):​ +
-                t.up() +
-                t.goto(15,​15) +
-                t.write("​Kreuz hat gewonnen",​ align="​center",​ font=("​Arial",​ 32, "​normal"​)) +
-                spielende = 1 +
-                siegkreuz = siegkreuz +1 +
-                t.down() +
-        else: +
-            kreismalen(t) ​  +
-            kreuz = 0 +
-            tttmatrix[zeile,​ spalte]=-1 +
-            if(ende()==-1):​ +
-                t.up() +
-                t.goto(15,​15) +
-                t.write("​Kreis hat gewonnen",​ align="​center",​ font=("​Arial",​ 32, "​normal"​)) +
-                spielende = -1 +
-                siegkreis = siegkreis +1 +
-                t.down() +
-        if(Anzahl==9 and ende()==0):​ +
-            t.up() +
-            t.goto(15,​15) +
-            t.write("​Unentschieden",​ align="​center",​ font=("​Arial",​ 32, "​normal"​)) +
-            spielende = 0 +
-            keinsieg = keinsieg +1 +
-            t.down() +
-tttfeld() +
-t.speed(0) +
-t.hideturtle() +
-screen=t.Screen() +
-screen.onclick(t.goto) +
-screen.onclick(malen) +
-screen.onkeypress(neuanfang,​ "​space"​) +
-screen.listen() +
-t.mainloop() +
-t.exitonclick()  +
- +
-09.01.2020:​ +
-Nicht funktionierender Code mit selbstlernendem Gegner: +
-<​code>​ +
- +
-import turtle as t +
-import numpy as np +
-from math import inf as infinity +
-import itertools +
-import random +
- +
- +
-def play_move(state,​ player, block_num):​ +
-    if state[int((block_num-1)/​3)][(block_num-1)%3] is ' ': +
-        state[int((block_num-1)/​3)][(block_num-1)%3] = player +
-        if(player == '​X'​):​ +
-            printX(int((block_num-1)/​3),​ (block_num-1)%3) +
-        else: +
-            print0(int((block_num-1)/​3),​ (block_num-1)%3) +
- +
-def copy_game_state(state):​ +
-    new_state = [[' ','​ ','​ '​],​['​ ','​ ','​ '​],​['​ ','​ ','​ ']] +
-    for i in range(3): +
-        for j in range(3): +
-            new_state[i][j] = state[i][j] +
-    return new_state +
- +
-def check_current_state(game_state): ​    +
-    # Check horizontals +
-    if (game_state[0][0] == game_state[0][1] and game_state[0][1] == game_state[0][2] and game_state[0][0] is not ' '): +
-        return game_state[0][0],​ "​Done"​ +
-    if (game_state[1][0] == game_state[1][1] and game_state[1][1] == game_state[1][2] and game_state[1][0] is not ' '): +
-        return game_state[1][0],​ "​Done"​ +
-    if (game_state[2][0] == game_state[2][1] and game_state[2][1] == game_state[2][2] and game_state[2][0] is not ' '): +
-        return game_state[2][0],​ "​Done"​ +
-     +
-    # Check verticals +
-    if (game_state[0][0] == game_state[1][0] and game_state[1][0] == game_state[2][0] and game_state[0][0] is not ' '): +
-        return game_state[0][0],​ "​Done"​ +
-    if (game_state[0][1] == game_state[1][1] and game_state[1][1] == game_state[2][1] and game_state[0][1] is not ' '): +
-        return game_state[0][1],​ "​Done"​ +
-    if (game_state[0][2] == game_state[1][2] and game_state[1][2] == game_state[2][2] and game_state[0][2] is not ' '): +
-        return game_state[0][2],​ "​Done"​ +
-     +
-    # Check diagonals +
-    if (game_state[0][0] == game_state[1][1] and game_state[1][1] == game_state[2][2] and game_state[0][0] is not ' '): +
-        return game_state[1][1],​ "​Done"​ +
-    if (game_state[2][0] == game_state[1][1] and game_state[1][1] == game_state[0][2] and game_state[2][0] is not ' '): +
-        return game_state[1][1],​ "​Done"​ +
-     +
-    # Check if draw +
-    draw_flag = 0 +
-    for i in range(3): +
-        for j in range(3): +
-            if game_state[i][j] is ' ': +
-                draw_flag = 1 +
-    if draw_flag is 0: +
-        return None, "​Draw"​ +
-     +
-    return None, "Not Done"​ +
- +
-def comstarts():​ +
-    global playerChoice +
-    newGame('​O'​) +
-    playerChoice = 0 +
-     +
-def playerstarts():​ +
-    global playerChoice +
-    newGame('​X'​) +
-    playerChoice = 1 +
-     +
-def newGame(player_choice):​ +
-    global NoWin +
-    global WinsPlayer +
-    global WinsCom +
-    if(check_current_state(game_state)== "​Done"​ or NoWin == 0 and WinsPlayer == 0 and WinsCom == 0): +
-        start.up() +
-        start.clear() +
-        start.setx(-2) +
-        start.hideturtle() +
-        start.write(WinsPlayer) +
-        start.sety(start.ycor()+2) +
-        start.write(WinsCom) +
-        start.sety(start.ycor()+2) +
-        start.write(NoWin) +
-        t.clear() +
-        if(player_choice == '​O'​):​ +
-            block_choice = getBestMove(game_state,​ players[0]) +
-            play_move(game_state ,​players[0],​ block_choice) +
-             +
- +
-def wheretogo(x,​ y): +
-    '''​ +
-    prüft, wo der Spieler hinklickt und gibt je nachdem eine Zahl zwischen 1 und 9 zurück. +
-    '''​ +
-    global game_state +
-    if(x > 0 and x <=10): +
-        spalte = 1 +
-    if(x >10 and x <=20): +
-        spalte = 2 +
-    if(x >20 and x <=30): +
-        spalte = 3 +
-    if(y > 0 and y <=10): +
-        zeile = 0 +
-    if(y >10 and y <=20): +
-        zeile = 1 +
-    if(y >20 and y <=30): +
-        zeile = 2 +
-    block_choice = 3*zeile +spalte +
-    if(game_state[int((block_choice-1)/​3)][(block_choice-1)%3] == ' '): +
-        t.up() +
-        t.setx((spalte-1)*10+5) +
-        t.sety(zeile*10+5) +
-        game(block_choice) +
-     +
- +
-def printX(zeile,​ spalte): +
-    t.up() +
-    t.setx(spalte*10+5) +
-    t.sety(zeile*10+5) +
-    t.down() +
-    t.left(45) +
-    t.forward(5) +
-    t.backward(10) +
-    t.forward(5) +
-    t.left(90) +
-    t.forward(5) +
-    t.backward(10) +
-    t.forward(5) +
-    t.right(135) +
-    t.up() +
-     +
-def print0(zeile,​ spalte): +
-    t.up() +
-    t.setx(spalte*10+5) +
-    t.sety(zeile*10+5) +
-    t.down() +
-    t.up() +
-    t.right(90) +
-    t.forward(4) +
-    t.left(90) +
-    t.down() +
-    t.circle(4) +
-    t.up() +
- +
-def tttfeld():​ +
-    """​ +
-    Malt ein 3x3 Feld. +
-    """​ +
-    t.setworldcoordinates(0,​30,​30,​0) +
-    spalten = t.Turtle() +
-    spalten.left(90) +
-    zeilen = t.Turtle() +
-    spalten.speed(0) +
-    zeilen.speed(0) +
-    spalten.hideturtle() +
-    zeilen.hideturtle() +
-    for i in range(4): +
-        spalten.setx(i*10) +
-        zeilen.sety(i*10) +
-        spalten.forward(30) +
-        zeilen.forward(30) +
-        spalten.sety(0) +
-        zeilen.setx(0) +
-    zeilen.goto(0,​0) +
-    spalten.goto(0,​0) +
-    zeilen.up() +
-    zeilen.setx(-3) +
-    zeilen.write("​Siege vom Spieler:",​ align="​right"​) +
-    zeilen.sety(zeilen.ycor()+2) +
-    zeilen.write("​Siege vom Computer:",​ align="​right"​) +
-    zeilen.sety(zeilen.ycor()+2) +
-    zeilen.write("​Unentschieden:",​ align="​right"​) +
-    zeilen.goto(0,​0) +
-    zeilen.goto(31,​15) +
-    zeilen.write("​Wer soll anfangen? Du(X) oder der Computer(O)?",​ align="​left",​ font=("​Arial",​ 8, "​normal"​)) +
-    zeilen.down() +
-     +
-     +
-     +
-def update_state_value(curr_state_idx,​ next_state_idx,​ learning_rate):​ +
-    new_value = state_values_for_AI[curr_state_idx] + learning_rate*(state_values_for_AI[next_state_idx] ​ - state_values_for_AI[curr_state_idx]) +
-    state_values_for_AI[curr_state_idx] = new_value +
- +
-def getBestMove(state,​ player): +
-    '''​ +
-    Reinforcement Learning Algorithm +
-    ''' ​    +
-    moves = [] +
-    curr_state_values = [] +
-    empty_cells = [] +
-    for i in range(3): +
-        for j in range(3): +
-            if state[i][j] is ' ': +
-                empty_cells.append(i*3 + (j+1)) +
-     +
-    for empty_cell in empty_cells:​ +
-        moves.append(empty_cell) +
-        new_state = copy_game_state(state) +
-        #​play_move(new_state,​ player, empty_cell) +
-        next_state_idx = list(states_dict.keys())[list(states_dict.values()).index(new_state)] +
-        curr_state_values.append(state_values_for_AI[next_state_idx]) +
-             +
-    best_move_idx = np.argmax(curr_state_values) +
-    best_move = moves[best_move_idx] +
-    return best_move +
- +
-def game(block_choice):​ +
-    global NoWin +
-    global WinsPlayer +
-    global WinsCom +
-    global game_state +
-    global playerChoice +
-    current_player_idx=playerChoice +
-     +
-    current_state = "Not Done" ​  +
-    winner = None +
-    if current_player_idx == 0: +
-        player_choice = '​X'​ +
-    else:  +
-        player_choice = '​O'​ +
-    curr_state_idx = list(states_dict.keys())[list(states_dict.values()).index(game_state)] +
-    if current_player_idx == 0: #Mensch macht ersten Zug +
-        play_move(game_state ,​players[current_player_idx],​ block_choice) +
-        current_player_idx = 1  +
-        block_choice = getBestMove(game_state,​ players[current_player_idx]) +
-        play_move(game_state ,​players[current_player_idx],​ block_choice) +
-         +
-    else:   #​Computer macht ersten Zug +
-        play_move(game_state ,​players[current_player_idx],​ block_choice) +
-        current_player_idx = 0 +
-        block_choice = getBestMove(game_state,​ players[current_player_idx]) +
-        play_move(game_state ,​players[current_player_idx],​ block_choice) +
-         +
-    print(game_state) +
-    winner, current_state = check_current_state(game_state) +
-    if winner is not None: +
-        t.up() +
-        t.goto(15,​15) +
-        if(str(winner) == player_choice):​ +
-            WinsPlayer = WinsPlayer +1 +
-            t.write("​Du hast gewonnen",​ align="​center",​ font=("​Arial",​ 32, "​normal"​)) +
-        else: +
-            WinsCom = WinsCom +1 +
-            t.write("​Du hast verloren",​ align="​center",​ font=("​Arial",​ 32, "​normal"​)) +
-        t.goto(40,​15) +
-        t.write("​Wer soll anfangen? Du(X) oder der Computer(O)?",​ align="​left",​ font=("​Arial",​ 8, "​normal"​)) +
-    if current_state is "​Draw":​ +
-        NoWin = NoWin +1 +
-        t.up() +
-        t.goto(15,​15) +
-        t.write("​Unentschieden",​ align="​center",​ font=("​Arial",​ 30, "​normal"​)) +
-        t.goto(40,​15) +
-        t.write("​Wer soll anfangen? Du(X) oder der Computer(O)?",​ align="​left",​ font=("​Arial",​ 8, "​normal"​)) +
-# PLaying +
- +
-# Initialize state values +
-player = ['​X','​O','​ '] +
-states_dict = {} +
-all_possible_states = [[list(i[0:​3]),​list(i[3:​6]),​list(i[6:​10])] for i in itertools.product(player,​ repeat = 9)] +
-n_states = len(all_possible_states) # 2 players, 9 spaces +
-n_actions = 9   # 9 spaces +
-state_values_for_AI = np.full((n_states),​0.0) +
-print("​n_states = %i \nn_actions = %i"​%(n_states,​ n_actions)) +
- +
-for i in range(n_states):​ +
-    states_dict[i] = all_possible_states[i] +
-    winner, _ = check_current_state(states_dict[i]) +
-    if winner == '​O': ​  # AI won +
-        state_values_for_AI[i] = 1 +
-    elif winner == '​X': ​  # AI lost +
-        state_values_for_AI[i] = -1 +
- +
- +
- +
- +
- +
-start = t.Turtle()  +
-start.speed(0) +
-t.speed(0) +
-t.hideturtle() +
-screen=t.Screen() +
-WinsPlayer = 0 +
-WinsCom = 0 +
-NoWin = 0 +
-playerChoice = 0 +
-game_state = [[' ','​ ','​ '], +
-              [' ','​ ','​ '], +
-              [' ','​ ','​ ']] +
-players = ['​X','​O'​] +
- +
-current_state = "Not Done"​ +
-tttfeld() +
- +
- +
-#LOAD TRAINED STATE VALUES +
-state_values_for_AI = np.loadtxt('​trained_state_values_O.txt',​ dtype=np.float64) +
- +
- +
- +
-screen.onclick(wheretogo) +
-screen.onkeypress(comstarts,​ "​o"​) +
-screen.onkeypress(playerstarts,​ "​x"​) +
-screen.listen() +
-t.mainloop() +
- +
-t.exitonclick() +
-</​code>​ +
- +
-**Protokoll für den 23.1.2020** +
-Wir haben angefangen eine Funkiton zu schreiben um die umgebung eines neu gesetzten Stein zu prüfen und festzustellen ob dadurch eine Prtei gewinnt.  +
-Funktion zum checken von jedem Array: +
-def Summe(self, zeile, spalte): #muss noch mit der umgebung verknüpft werden +
-        for i in range(len(a)-3):​ +
-            b=a[i:​i+4] +
-            if (sum(b)== 4 or sum(b)==-4):​ +
-                return sum(b)  +
-                 +
-Spalte: a=board[:6, s-1:​s] ​    ​Diagonale:​ a=np.diagonal(board,​ s-z) Zeile: a=board[:1] #für die Zeile +
- +
-**Protokoll für den 06.02.2020** +
-Training Algorithmus fertig +
-Funktion fertig - Wissen ob 4 in einer Reihe sind +
- +
-Problem: Anzahl möglicher Zustände über 10 hoch 20 +
-D.h. das Programm läuft so noch nicht  +
- +
- +
- +
- +
- +
-Kommentierte Version des Codes mit dem NN: +
- +
- +
-import random +
-import gym +
-import numpy as np +
-from collections import deque +
-from keras.models import Sequential +
-from keras.layers import Dense, Dropout +
-from keras.optimizers import Adam +
-import keras +
- +
- +
-def ViergewinntAnfangsmatrix():​ +
-    #​game_state[x,​0,​0] greift auf das zu benutzende Feld zu (x=0/1 sind Spiele; x=2 zeigt leere Felder) +
-    #​game_state[0,​x,​0] greift auf die Zeile zu +
-    #​game_state[0,​0,​x] greift auf die Spalte zu +
-    game_state = np.zeros_like(np.arange(42*3).reshape(3,​6,​7)) +
-    game_state[2]=1 +
-    return game_state +
- +
-def check_array(a):​ +
-    #Prüft ob in einem Array 4 in einer Reihe sind +
-    for i in range(len(a)-3):​ +
-        b=sum(a[i:​i+4]) ​   +
-        if (b== 4): return 4 +
- +
-def checkgewonnen(game_state):​ +
-    #Prüft ob jemand gewonnen hat +
-    Winstate = game_state[0] +
-    Losestate = game_state[1] +
-    Drawstate = game_state[2]  +
-   #​Spalte +
-    for i in range(7): +
-        a=check_array(Winstate[:​6,​ i:​i+1].reshape(6,​)) +
-        b=check_array(Losestate[:​6,​ i:​i+1].reshape(6,​)) +
-        if(a==4):​return "​Win"​ +
-        if(b==4):​return "​Lose"​ +
-     +
-    #​Diagonalen:​ +
-    for i in range(3):  +
-        a=check_array(np.diagonal(Winstate,​ i+1)) +
-        b=check_array(np.diagonal(Losestate,​ i+1)) +
-        if(a==4):​return "​Win"​ +
-        if(b==4):​return "​Lose"​ +
-        a=check_array(np.diagonal(Winstate,​ -i)) +
-        b=check_array(np.diagonal(Losestate,​ -i)) +
-        if(a==4):​return "​Win"​ +
-        if(b==4):​return "​Lose"​ +
-        a=check_array(np.fliplr(Winstate).diagonal(i+1)) +
-        b=check_array(np.fliplr(Losestate).diagonal(i+1)) +
-        if(a==4):​return "​Win"​ +
-        if(b==4):​return "​Lose"​ +
-        a=check_array(np.fliplr(Winstate).diagonal(-i)) +
-        b=check_array(np.fliplr(Losestate).diagonal(-i)) +
-        if(a==4):​return "​Win"​ +
-        if(b==4):​return "​Lose"​ +
-       +
-    #Zeile:  +
-    for i in range(6): +
-        a=check_array(Winstate[i:​i+1].reshape(7,​)) +
-        b=check_array(Losestate[i:​i+1].reshape(7,​)) +
-        if(a==4):​return "​Win"​ +
-        if(b==4):​return "​Lose"​ +
-    # Check if draw +
-    for i in range(7): ​  +
-        if(Drawstate[0,​i] == 1): +
-           ​return None +
-    return "​Draw"​ +
- +
- +
- +
-class Agent: +
-    def __init__(self,​ state_size, action_size):​ +
-        self.state_size = state_size +
-        self.action_size = action_size +
-        self.memory = deque(maxlen=2000) #​Erinnerungen +
-        self.gamma = 1.0   # discount rate +
-        self.epsilon = 1.0  # exploration rate +
-        self.epsilon_min = 0.01 +
-        self.epsilon_decay = 0.999 +
-        self.learning_rate = 0.001 +
-        self.model = self._build_model() #NN wird gebaut +
- +
-    def _build_model(self):​ +
-        # Einfaches NN  +
-        #Müssen weitere Layer hinzugefügt werden, da 4gewinnt komplexer ist? +
-        model = Sequential() #Standard komplett vernetztes NN +
-        model.add(Dense(48,​ input_dim=self.state_size,​ activation='​relu',​  +
-                        kernel_regularizer=keras.regularizers.l2(0.00001)))#​Input muss angepasst werden +
-        model.add(Dropout(0.3)) # Soll "​Overfitting"​ vermeiden +
-        model.add(Dense(24,​ activation='​relu',​ kernel_regularizer=keras.regularizers.l2(0.00001)))#​Hidden-Layer +
-        model.add(Dense(self.action_size,​ activation='​linear'​))#​Output im Bezug auf mögliche Aktionen (hier 7) +
-        model.compile(loss='​mse',​ +
-                      optimizer=Adam(lr=self.learning_rate)) #​Erstellung +
-        return model +
- +
-    def remember(self,​ state, action, reward, next_state, done):#​Erinnerungsmöglichkeit +
-        # merkt sich alle bisher durchlaufenen Zustände +
-        self.memory.append((state,​ action, reward, next_state, done)) +
- +
-    def act(self, state): +
-        # epsilon-greedy:​ off-policy oder policy +
-         +
-        if np.random.rand() <= self.epsilon:#​Zufällige Aktion +
-            return random.randrange(self.action_size) +
-        act_values = self.model.predict(state)#​Vorhersage des NN +
-        return np.argmax(act_values[0]) ​ # returns action +
- +
-    def replay(self,​ batch_size):​ +
-        # baut den Vektor der Q-Werte aus  +
-        # als reward zum Zeitpunkt t + gamma*max(moegliche rewards zum Zeitpunkt t+1) +
-        #prüft ob ein Zug gut war? +
-        minibatch = random.sample(self.memory,​ batch_size) +
-        states, targets_f = [], [] +
-        for state, action, reward, next_state, done in minibatch:​ +
-            target = reward #​Reward-Anpassung +
-            if not done: +
-                target = (reward + self.gamma * +
-                          np.amax(self.model.predict(next_state)[0])) +
-            target_f = self.model.predict(state) +
-            target_f[0][action] = target  +
-            # Filtering out states and targets for training +
-            states.append(state[0]) +
-            targets_f.append(target_f[0]) +
-        history = self.model.fit(np.array(states),​ np.array(targets_f),​ epochs=1, verbose=0) +
-        # Keeping track of loss +
-        loss = history.history['​loss'​][0] +
-        if self.epsilon > self.epsilon_min:​ +
-            self.epsilon *= self.epsilon_decay +
-        return loss +
- +
-    #laden und speichern des NN +
-    def load(self, name): +
-        self.model.load_weights(name) +
- +
-    def save(self, name): +
-        self.model.save_weights(name) +
-         +
-         +
-         +
-# Lernen:  +
- +
-#  EPISODES mal durchspielen,​ bis der Mast umfaellt +
- +
- +
- +
- +
-EPISODES = 10 +
- +
- +
-env = gym.make('​CartPole-v1'​) +
-#4gewinnt einfuegen +
- +
- +
-#state_size = env.observation_space.shape[0] +
-state_size = 7 #Für die 7 Möglichkeiten die es gibt einen Stein zu platzieren +
-#​Spielfeld?​ +
- +
- +
-action_size = env.action_space.n +
-#Wird 7 sein, solange keine Spalte voll ist +
- +
- +
-agent = Agent(state_size,​ action_size) +
-done = False +
-batch_size = 32#Muss eventuell auch angepasst werden +
- +
-for e in range(EPISODES):​ +
-    state = env.reset() +
-    #eigene Reset Funktion +
-     +
-    state = np.reshape(state,​ [1, state_size])#​Erzeugt einen Array, der den Zustand repräsentiert +
-    cum_reward = 0 +
-    for time in range(500):#​Zeit braucht man nicht bei 4 gewinnt, ersetzen mit max Spiellänge +
-        #​env.render() +
-        action = agent.act(state)#​Auswahl der möglichen Aktionen +
-        next_state, reward, done, _ = env.step(action)#​Ausführung dieser Aktion +
-        reward = reward/​(abs(next_state[0])+1.)**2 if not done else -10 #Anpssung des rewards-System +
-        cum_reward += reward +
-        next_state = np.reshape(next_state,​ [1, state_size])#nächsten Zustand herbei führen +
-        agent.remember(state,​ action, reward, next_state, done)#​merken +
-        state = next_state +
-        if done: +
-            print(("​episode:​ {}/{}, score: {}, e: {:​.2}"#​Score sollte nicht abhängig von Anzahl Züge, sondern von gewonenen/​verloren sein +
-                  .format(e, EPISODES, time, agent.epsilon))) +
-            break +
-        if len(agent.memory) > batch_size:​ +
-            loss = agent.replay(batch_size) +
-            # Logging training loss and actual reward every 10 timesteps +
-            if time % 10 == 0: +
-                print(("​episode:​ {}/{}, time: {}, cumulative reward: {:.4f}, loss: {:​.4f}"​.format(e,​ EPISODES, time, cum_reward, loss)))  +
- +
-agent.save("​qlearning_cartpole.weights"​) +
- +
- +
-# Testen des gelernten Modells mit leichten Störungen, um die Stabilität zu sehen. Mit Visualisierung +
-#​Funktioniert hier nicht so richtig+
  
-#2 Ai's gegeneinander spielen lassen?+[[some:​Bericht]]
  
-agent.load("​qlearning_cartpole.weights"​)#​gemerkte Entscheidungen laden, um damit gute Züge machen zu können 
  
-import time  as ti #Zeit braucht man nicht 
-for e in range(1000):#​Von hier 
-    state = env.reset() 
-    state[0] = state[0] + np.random.randn()*0.1 
-    state[1] = state[1] + np.random.randn()*0.1 
-    state[2] = state[2] + np.random.randn()*0.1 
-    state[3] = state[3] + np.random.randn()*0.1 
-    env.env.state = state 
-    state = np.reshape(state,​ [1, state_size]) 
-    for time in range(2000):#​bis hier muss komplett ersetzt werden 
-        ​ 
-        env.render()#​Nicht Zeit abhängig, braucht man also nicht 
-        agent.epsilon = 0# Setzt Zufallshandlung auf 0 
-        action = agent.act(state) 
-        next_state, reward, done, _ = env.step(action) 
-        next_state = np.reshape(next_state,​ [1, state_size]) 
-        state = next_state#​Spielt einen Zug durch 
-        if done: 
-            print("​Duration:​ ", time) 
-            break 
-            ​ 
-    else: 
-        print("​Volle Zeit"​)#​Hier wichtig ob Gewonnen/​Verloren/​Unentschieden?​ 
ws1920/selbstlernender_gegner.1585240601.txt.gz · Zuletzt geändert: 2020/03/26 17:36 von benbaute