Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste

some:vier_gewinnt

Code vom 02.04.2020

Hierbei spielt ein selbstlernender Agent gegen einen anderen selbstlernenden Agenten oder gegen einen Gegner, der einen Zug vorausschauen kann. Auch nach längerer Lernzeit gewinnt der Agent nur wenige Spiele, ungefähr 10%, gegen diesen Gegner.

import random
import numpy as np
from collections import deque
from keras.models import Sequential
from keras.layers import Dense, Dropout, Conv2D, MaxPooling2D, Flatten, BatchNormalization
from keras.optimizers import Adam
from keras.regularizers import l2
import keras
 
def ViergewinntAnfangsmatrix():
    #game_state[x,0,0] greift auf die Zeile zu
    #game_state[0,x,0] greift auf die Spalte
    #game_state[0,0,x] greift auf das zu benutzende Feld zu (x=0/1 sind Spieler; x=2 zeigt leere Felder)
    game_state = np.zeros_like(np.arange(42*3).reshape(6,7,3))
    for i in range(7):
        for ii in range(6):
            game_state[ii,i,2]=1
    return game_state
 
def matrixTransponieren(state,which):#Macht aus der 3 Dimensionalen Matrix, eine 2 dimensionale
    game = np.copy(state)
    matrix = game.transpose()
    m = matrix[which].transpose()
    return m
 
def printGame(state):#Gibt den Spielzustand in 2D zurück, 0 = leeres Feld, 1 = Spieler 1, 2 = Spieler 2
    game = np.copy(state)
    Spieler1 = matrixTransponieren(game,0)
    Spieler2 = matrixTransponieren(game,1)
    return (Spieler1+Spieler2*2)
 
 
def actionkorrigieren(state,action):#Sucht einen gueltigen Zug, wenn ein illegaler Zug gemacht worden ist.
    game = np.copy(state)
    Moeglichkeiten = matrixTransponieren(game,2)
    if(Moeglichkeiten[0,action]==1):#gueltiger Zug
        return action
    for x in range(7):
        if(x+action+1>6):
            action = action - 7
        if(Moeglichkeiten[0,x+action+1] == 1):
            return action+x+1
 
 
 
def check_array(reihe):
    #Prüft ob in einem Array 4 in einer Reihe sind
    a = np.copy(reihe)
    for i in range(len(a)-3):
        b=sum(a[i:i+4])   
        if (b== 4): return 4
 
def checkgewonnen(game_state,player):
    #Prüft ob jemand gewonnen hat
    state = np.copy(game_state)
    state_matrix = matrixTransponieren(state,player)
   #Wenn return 0, hat player 1 gewonnen...
   #Spalte
    for i in range(7):#Durch die vielen for-Schleifen geht hier etwas Zeit verloren
        a=check_array(state_matrix[:6, i:i+1].reshape(6,))
        if(a==4):return 1
 
    #Diagonalen:
    for i in range(3): 
        a=check_array(np.diagonal(state_matrix, i+1))
        if(a==4):return 1
        a=check_array(np.diagonal(state_matrix, -i))
        if(a==4):return 1
        a=check_array(np.fliplr(state_matrix).diagonal(i+1))
        if(a==4):return 1
        a=check_array(np.fliplr(state_matrix).diagonal(-i))
        if(a==4):return 1
 
    #Zeile: 
    for i in range(6):
        a=check_array(state_matrix[i:i+1].reshape(7,))
        if(a==4):return 1       
    return None
 
def unentschieden(game_state):
    state = np.copy(game_state)
    Drawstate = matrixTransponieren(state,2) 
    for i in range(7):  
        if(Drawstate[0,i] == 1):
           return 0
    return 1 
 
def naechsterSchritt(game_state, action, player,Zug):
    #Hier wird ein Zug durchgeführt
    #Das reward-System muss noch überarbeitet werden
    state = np.copy(game_state)
    Moeglichkeiten = matrixTransponieren(state,2)
    if(Moeglichkeiten[0,action]!=1):#ungueltiger Zug
        reward = -1
        done = 1
    else:
        amWeitestenUnten = 5
        while(Moeglichkeiten[amWeitestenUnten,action]!=1 and amWeitestenUnten > 0):#Sucht die passende Zeile
            amWeitestenUnten=amWeitestenUnten-1
        state[amWeitestenUnten,action,player]=1
        state[amWeitestenUnten,action,2]=0
        if(unentschieden(state)):
            #reward=0.25
            reward = 110
            done=1
        else:
            ende=checkgewonnen(state,player)
            if(ende==None):
                #reward=(0.004*Zug)
                reward = 3**(Zug/10)
                done=0
                return state, reward, done
            #reward=1-(Zug*0.002)
            reward=1000-(Zug*5)
            done=1
    return state, reward, done
 
 
class Agent:
    def __init__(self, state_size, action_size):
        self.state_size = state_size
        self.action_size = action_size
        self.memory = deque(maxlen=3000) #Erinnerungen
        self.memory_of_Wins = deque(maxlen=3000)
        self.memory_of_Loss = deque(maxlen=3000)
        self.gamma = 1.0   # discount rate
        self.epsilon = 1.0  # exploration rate
        self.epsilon_min = 0.01
        self.epsilon_decay = 0.9999 #War 0.999
        self.learning_rate = 0.0001 #War 0.001
        self.input_shape = (6,7,3)
        self.reg=l2(0.0001) #War 0.0005
        self.kernel_I="he_normal"
        self.model = self._build_model() #NN wird gebaut
 
    def _build_model(self):
        model = Sequential()
        model.add(Conv2D(16, (5, 5), strides=(2, 2), padding="valid",kernel_initializer=self.kernel_I, kernel_regularizer=self.reg, input_shape=self.input_shape))
		#here we stack two CONV layers on top of each other where
		#each layerswill learn a total of 32 (3x3) filters
        model.add(Conv2D(32, (3, 3), padding="same", kernel_initializer=self.kernel_I, kernel_regularizer=self.reg, activation='relu'))
        model.add(BatchNormalization())
        model.add(Conv2D(32, (3, 3), strides=(2, 2), padding="same", kernel_initializer=self.kernel_I, kernel_regularizer=self.reg, activation='relu'))
        model.add(BatchNormalization())
        model.add(Dropout(0.25))
        model.add(Conv2D(64, (3, 3), padding="same", kernel_initializer=self.kernel_I, kernel_regularizer=self.reg, activation='relu'))
        model.add(BatchNormalization())
        model.add(Conv2D(64, (3, 3), strides=(2, 2), padding="same", kernel_initializer=self.kernel_I, kernel_regularizer=self.reg, activation='relu'))
        model.add(BatchNormalization())
        model.add(Dropout(0.25))
        # increase the number of filters again, this time to 128
        model.add(Conv2D(128, (3, 3), padding="same", kernel_initializer=self.kernel_I, kernel_regularizer=self.reg, activation='relu'))
        model.add(BatchNormalization())
        model.add(Conv2D(128, (3, 3), strides=(2, 2), padding="same", kernel_initializer=self.kernel_I, kernel_regularizer=self.reg, activation='relu'))
        model.add(BatchNormalization())
        model.add(Dropout(0.25))
        model.add(Flatten())
        model.add(Dense(512, kernel_initializer=self.kernel_I, activation='relu'))
        model.add(BatchNormalization())
        model.add(Dropout(0.5))
		# softmax classifier
        model.add(Dense(self.action_size, activation='softmax'))
        model.compile(loss="categorical_crossentropy", optimizer=Adam(lr=self.learning_rate), metrics=["accuracy"])
 
        return model#Dieses NN muss wahrscheinlich auch noch angepasst werden
 
    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 rememberWins(self, state, action, reward, next_state, done):#Erinnerungsmöglichkeit
        # merkt sich alle bisher durchlaufenen Zustände
        self.memory_of_Wins.append((state, action, reward, next_state, done))
    def rememberLoss(self, state, action, reward, next_state, done):#Erinnerungsmöglichkeit
        # merkt sich alle bisher durchlaufenen Zustände
        self.memory_of_Loss.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.reshape(1,6,7,3))#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.reshape(1,6, 7, 3))))
            target_f = self.model.predict(state.reshape(1,6, 7, 3))
            target_f[0][action] = target 
            # Filtering out states and targets for training
            states.append(state.reshape(6, 7, 3))
            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
 
    def replayWins(self, batch_size):
        minibatch = random.sample(self.memory_of_Wins, batch_size)
        states, targets_f = [], []
        for state, action, reward, next_state, done in minibatch:
            target = reward #Reward-Anpassung
            target_f = self.model.predict(state.reshape(1,6, 7, 3))
            target_f[0][action] = target 
            # Filtering out states and targets for training
            states.append(state.reshape(6, 7, 3))
            targets_f.append(target_f[0])
        history = self.model.fit(np.array(states), np.array(targets_f), epochs=2, verbose=0)
        # Keeping track of loss
        loss = history.history['loss'][0]
        if self.epsilon > self.epsilon_min:
            self.epsilon *= self.epsilon_decay
        return loss
 
    def replayLoss(self, batch_size):
        minibatch = random.sample(self.memory_of_Loss, batch_size)
        states, targets_f = [], []
        for state, action, reward, next_state, done in minibatch:
            target = reward #Reward-Anpassung
            target_f = self.model.predict(state.reshape(1,6, 7, 3))
            target_f[0][action] = target 
            # Filtering out states and targets for training
            states.append(state.reshape(6, 7, 3))
            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) 
 
class Gegner:#Dadurch das dies eine extra Klasse ist, können einfach verschiedene NN`s benutzt werden
    #Dabei ist die Klasse eigentlich komplett glcih, bis auf das unterschiedliche NN
    def __init__(self, state_size, action_size):
        self.state_size = state_size
        self.action_size = action_size
        self.memory = deque(maxlen=3000) #Erinnerungen
        self.memory_of_Wins = deque(maxlen=3000)
        self.memory_of_Loss = deque(maxlen=3000)
        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.input_shape = (6,7,3)
        self.model = self._build_model() #NN wird gebaut
 
    def _build_model(self):
        #https://adventuresinmachinelearning.com/keras-tutorial-cnn-11-lines/ 
        model = Sequential() #Standard komplett vernetztes NN
        model.add(Conv2D(32, kernel_size=(3,3), strides=(1, 1), padding='same',
                 activation='relu',  input_shape=self.input_shape))
        model.add(MaxPooling2D(pool_size=(1, 1), strides=(1, 1)))
        model.add(Conv2D(64, (5, 5), padding='same', activation='relu'))
        model.add(MaxPooling2D(pool_size=(2, 2)))
        model.add(Flatten())
        model.add(Dense(1000, activation='relu'))
        model.add(Dense(self.action_size, activation='softmax'))
        model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.SGD(lr=self.learning_rate),
              metrics=['accuracy'])
        return model#Dieses NN muss wahrscheinlich auch noch angepasst werden
 
    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 rememberWins(self, state, action, reward, next_state, done):#Erinnerungsmöglichkeit
        # merkt sich alle bisher durchlaufenen Zustände
        self.memory_of_Wins.append((state, action, reward, next_state, done))
    def rememberLoss(self, state, action, reward, next_state, done):#Erinnerungsmöglichkeit
        # merkt sich alle bisher durchlaufenen Zustände
        self.memory_of_Loss.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.reshape(1,6,7,3))#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.reshape(1,6, 7, 3))))
            target_f = self.model.predict(state.reshape(1,6, 7, 3))
            target_f[0][action] = target 
            # Filtering out states and targets for training
            states.append(state.reshape(6, 7, 3))
            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
 
    def replayWins(self, batch_size):
        minibatch = random.sample(self.memory_of_Wins, batch_size)
        states, targets_f = [], []
        for state, action, reward, next_state, done in minibatch:
            target = reward #Reward-Anpassung
            target_f = self.model.predict(state.reshape(1,6, 7, 3))
            target_f[0][action] = target 
            # Filtering out states and targets for training
            states.append(state.reshape(6, 7, 3))
            targets_f.append(target_f[0])
        history = self.model.fit(np.array(states), np.array(targets_f), epochs=2, verbose=0)
        # Keeping track of loss
        loss = history.history['loss'][0]
        if self.epsilon > self.epsilon_min:
            self.epsilon *= self.epsilon_decay
        return loss
 
    def replayLoss(self, batch_size):
        minibatch = random.sample(self.memory_of_Loss, batch_size)
        states, targets_f = [], []
        for state, action, reward, next_state, done in minibatch:
            target = reward #Reward-Anpassung
            target_f = self.model.predict(state.reshape(1,6, 7, 3))
            target_f[0][action] = target 
            # Filtering out states and targets for training
            states.append(state.reshape(6, 7, 3))
            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)      
 
 
class randomGegner:
    def __init__(self, state_size, action_size):
        self.state_size = state_size
        self.action_size = action_size
    def act(self, state, zug):
        emptycells = []
        game = np.copy(state)
        Moeglichkeiten = matrixTransponieren(game,2)
        for x in range(7):
                if(Moeglichkeiten[0,x] == 1):
                    emptycells.append(x)
        for i in range(7):
            if(Moeglichkeiten[0,i] == 1):
                nextState, reward, done = naechsterSchritt(game, i, 1, zug)
                if(done ==1 and reward>200):#>0.5
                    return i
        for y in range(7):
            if(Moeglichkeiten[0,y] == 1):
                nextState, reward, done = naechsterSchritt(game, y, 0, zug)
                if(done ==1 and reward>200):#>0.5
                    return y
        action = random.choice(emptycells)
        return (action)
 
class randomAgent:
    def __init__(self, state_size, action_size):
        self.state_size = state_size
        self.action_size = action_size
    def act(self, state, zug):
        emptycells = []
        game = np.copy(state)
        Moeglichkeiten = matrixTransponieren(game,2)
        for x in range(7):
                if(Moeglichkeiten[0,x] == 1):
                    emptycells.append(x)
        for i in range(7):
            if(Moeglichkeiten[0,i] == 1):
                nextState, reward, done = naechsterSchritt(game, i, 0, zug)
                if(done ==1 and reward>200):
                    return i
        for y in range(7):
            if(Moeglichkeiten[0,y] == 1):
                nextState, reward, done = naechsterSchritt(game, y, 1, zug)
                if(done ==1 and reward>200):
                    return y
        action = random.choice(emptycells)
        return (action)
 
 
 
 
 
 
 
# Lernen: 
 
#  EPISODES mal durchspielen, bis der Mast umfaellt
 
 
 
Ep = 10000
EPISODES = 50
 
#state_size = env.observation_space.shape[0]
state_size = 126 #Für die 3 Matrizen (Spieler1,Spieler2, mögliche Züge) * das Brett
#Spielfeld?
 
 
action_size = 7 #7Mögliche Züge
#Wird 7 sein, solange keine Spalte voll ist
 
zufälligerGegner = int(input("Trainieren mit einem zufälligem Gegner(1) oder mit einem Selbstlernendem Gegner(0)?\n"))
if(zufälligerGegner==0):
 
    agent = Agent(state_size, action_size)
    gegner = Gegner(state_size, action_size)#Spielt gegen sich selber
    player = 0#agent fängt an zu spielen
    agentWins = 0
    gegnerWins = 0
    agentFails = 0
    gegnerFails = 0
    zuegeGesamt = 0
    gegner.load("Gegner3D.weights")
    agent.load("agent3D.weights")
    AnzahlUnentschieden = 0
    done = False
    batch_size = 32#Muss eventuell auch angepasst werden
    cum_reward = 0
    cum_reward_gegner = 0
    for i in range(Ep):    
        for e in range(EPISODES):
            state = ViergewinntAnfangsmatrix()
            player = 0
            #state = env.reset()
            #eigene Reset Funktion
 
            #state = np.reshape(state, [1, state_size])#Erzeugt einen Array, der den Zustand repräsentiert
            #for time in range(500):#Zeit braucht man nicht bei 4 gewinnt, ersetzen mit max Spiellänge
            zuege = 0
            while(zuege<42):
                #env.render()
                if(zuege%2==0):
                    action_Agent = agent.act(state)#Auswahl der möglichen Aktionen
                    next_state, reward, done = naechsterSchritt(state,action_Agent,player,zuege)#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_Agent, reward, next_state, done)#merken
                    player = 1
                    if(reward<0):agentFails = agentFails +1
                    if(reward>0.5): 
                        agentWins = agentWins +1
                        agent.rememberWins(state, action_Agent, reward, next_state, done)
                        gegner.rememberLoss(state, action_Agent, 0.01*zuege-1, next_state, done)
                else:#Spielt gegen sich selbst
                    action_Gegner = gegner.act(state)
                    next_state, reward, done = naechsterSchritt(state,action_Gegner,player,zuege)
                    cum_reward_gegner += reward
                    #next_state = np.reshape(next_state, [1, state_size])
                    gegner.remember(state, action_Gegner, reward, next_state, done)
                    player = 0
                    if(reward<0):gegnerFails = gegnerFails +1
                    if(reward>0.5):
                        gegnerWins = gegnerWins +1
                        gegner.rememberWins(state, action_Gegner, reward, next_state, done)
                        agent.rememberLoss(state, action_Agent, 0.01*zuege-1, next_state, done)
 
                    if(zuege==41 and reward<0.5):AnzahlUnentschieden+=1
 
 
                state = np.copy(next_state)
                if(done==1 and (EPISODES*i+e)%50==0):print("Spielende:\n",printGame(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)))
                   # print(("episode: {}/{}, score: {}, e: {:.2}"
                          #.format(e, EPISODES, zuege, agent.epsilon)))
 
                 #   break
                if (len(agent.memory) > batch_size and zuege%5==0):
                    loss = agent.replay(batch_size)
                if (len(gegner.memory) > batch_size and zuege%5==0):
                    loss_gegner = gegner.replay(batch_size)
 
                if (len(agent.memory_of_Wins) > batch_size and zuege%5==0):
                    loss_Wins = agent.replayWins(batch_size)
                if (len(gegner.memory_of_Wins) > batch_size and zuege%5==0):
                    loss_gegner_Wins = gegner.replayWins(batch_size)
 
                if (len(agent.memory_of_Loss) > batch_size and zuege%5==0):
                    loss_Loss = agent.replayLoss(batch_size)
                if (len(gegner.memory_of_Loss) > batch_size and zuege%5==0):
                    loss_gegner_Loss = gegner.replayLoss(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))) 
                if(done):
                    zuegeGesamt = zuegeGesamt + zuege + 1
                    break
                zuege = zuege + 1
        print(("\nepisode: {}/{}, Züge pro Spiel: {:.1f}, \nWinsTotal:{}, LossTotal:{}, DrawsTotal:{}, \nIllegalMove-A: {}, IllegalMove-G: {}, cumulative reward: {:.2f}, cum_Gegner: {:.2f}\n".format((EPISODES*i+e+1),(Ep*EPISODES), (zuegeGesamt/((EPISODES)*(i+1))), agentWins, gegnerWins, AnzahlUnentschieden, agentFails, gegnerFails, cum_reward, cum_reward_gegner)))
 
        agent.save("agent2D7Mal7.weights")
        gegner.save("Gegner2D7Mal7.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?
        gegner.load("Gegner2D7Mal7.weights")
        agent.load("agent2D7Mal7.weights")#gemerkte Entscheidungen laden, um damit gute Züge machen zu können
 
else:
    agent = Agent(state_size, action_size)
    gegner = randomGegner(state_size, action_size)
    random_Agent = randomAgent(state_size, action_size)
    player = 0#agent fängt an zu spielen
    agentWins = 0
    gegnerWins = 0
    agentFails = 0
    gegnerFails = 0
    zuegeGesamt = 0
    loss = 555
    loss_Wins = 555
    loss_Loss = 555
    #agent.load("agent673.weights")
    AnzahlUnentschieden = 0
    done = False
    batch_size = 500#Muss eventuell auch angepasst werden
    cum_reward = 0
    cum_reward_gegner = 0
    AnzahlSpiele = 1
    eingabe = int(input("Sollen bevor der Agent die Züge wählt, schon vorher Spielsituationen simuliert werden, sodass der Agent auch mit gewonennen Spielständen  üben kann?Ja(1)/Nein(0)\n"))
    if(eingabe == 1):
        eingabe = int(input("Wie viele gewonnene Spielstände?(Zwischen 500 und 550 ist sinvoll.)"))
        while(agentWins<eingabe):
                state = ViergewinntAnfangsmatrix()
                player = 0
                #state = env.reset()
                #eigene Reset Funktion
 
                #state = np.reshape(state, [1, state_size])#Erzeugt einen Array, der den Zustand repräsentiert
                #for time in range(500):#Zeit braucht man nicht bei 4 gewinnt, ersetzen mit max Spiellänge
                zuege = 0
                while(zuege<42):
                    #env.render()
                    if(zuege%2==0):
                        action_Agent = random_Agent.act(state,zuege)#Auswahl der möglichen Aktionen
                        next_state, reward, done = naechsterSchritt(state,action_Agent,player,zuege)#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_Agent, reward, next_state, done)
                        player = 1
                        if(reward<0):agentFails = agentFails +1
                        if(reward>200): #>0.5
                            agentWins = agentWins +1
                            agent.rememberWins(state, action_Agent, reward, next_state, done)
                    else:#Spielt gegen sich selbst
                        action_Gegner = gegner.act(state,zuege)
                        next_state, reward, done = naechsterSchritt(state,action_Gegner,player,zuege)
                        cum_reward_gegner += reward
                        player = 0
                        if(reward<0):
                            gegnerFails = gegnerFails +1
                        if(reward>200):#0.5
                            gegnerWins = gegnerWins +1
                            #agent.rememberLoss(state, action_Agent, 0.01*zuege-1, next_state, done)
                            #agent.rememberLoss(state, action_Agent, 4*zuege-1000, next_state, done)
 
                        if(zuege==41 and reward<200):AnzahlUnentschieden+=1#<0.5
 
                    state = np.copy(next_state)
                    if(done==1 and agentWins > 499 and(agentWins)%10==0): print(("\nZüge pro Spiel: {:.1f}, \nWinsTotal:{}, LossTotal:{}, DrawsTotal:{}, \nloss: {:.1f}, LossWins: {:.1f}, LossLoss: {:.1f}\n".format((zuegeGesamt/AnzahlSpiele), agentWins, gegnerWins, AnzahlUnentschieden, loss, loss_Wins, loss_Loss)))
 
                    #if (len(agent.memory) > batch_size and len(agent.memory_of_Wins) > batch_size and len(agent.memory_of_Loss) > batch_size and zuege%15==0):
                     #   loss = agent.replay(batch_size)
                      #  loss_Wins = agent.replayWins(batch_size)
                       # loss_Loss = agent.replayLoss(batch_size)
 
                    if(done):
                        zuegeGesamt = zuegeGesamt + zuege + 1
                        AnzahlSpiele = AnzahlSpiele +1
                        break
                    zuege = zuege + 1
 
        print(eingabe, "Wins gemerkt\n")
    player = 0#agent fängt an zu spielen
    agentWins = 0
    gegnerWins = 0
    agentFails = 0
    gegnerFails = 0
    zuegeGesamt = 0
    agent.load("agentNight.weights")
    AnzahlUnentschieden = 0
    done = False
    batch_size = 32#Muss eventuell auch angepasst werden
    cum_reward = 0
    cum_reward_gegner = 0
    for i in range(Ep):    
        for e in range(EPISODES):
            state = ViergewinntAnfangsmatrix()
            player = 0
            #state = env.reset()
            #eigene Reset Funktion
 
            #state = np.reshape(state, [1, state_size])#Erzeugt einen Array, der den Zustand repräsentiert
            #for time in range(500):#Zeit braucht man nicht bei 4 gewinnt, ersetzen mit max Spiellänge
            zuege = 0
            while(zuege<42):
                #env.render()
                if(zuege%2==0):
                    action_Agent = agent.act(state)#Auswahl der möglichen Aktionen
                    action_Korrigiert = actionkorrigieren(state,action_Agent)
                    next_state, reward, done = naechsterSchritt(state,action_Korrigiert,player,zuege)#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_Agent, reward, next_state, done)#merken
                    player = 1
                    if(reward<0):agentFails = agentFails +1
                    if(reward>200):#>0.5 
                        agentWins = agentWins +1
                        agent.rememberWins(state, action_Agent, reward, next_state, done)
                else:#Spielt gegen sich selbst
                    action_Gegner = gegner.act(state,zuege)
                    next_state, reward, done = naechsterSchritt(state,action_Gegner,player,zuege)
                    cum_reward_gegner += reward
                    player = 0
                    if(reward<0): 
                        gegnerFails = gegnerFails +1
                    if(reward>200):#0.5
                        gegnerWins = gegnerWins +1
                        #agent.rememberLoss(state, action_Agent, 0.01*zuege-1, next_state, done)
                       # agent.rememberLoss(state, action_Agent, 4*zuege-1000, next_state, done)
 
                    if(zuege==41 and reward<200):AnzahlUnentschieden+=1#<0.5
 
                state = np.copy(next_state)
                if(done==1 and (EPISODES*i+e)%50==0):print("Spielende:\n",printGame(state))
 
 
                 #   break
                if (len(agent.memory) > batch_size and len(agent.memory_of_Wins) > batch_size and zuege%5==0):#and len(agent.memory_of_Loss) > batch_size
                    loss = agent.replay(batch_size)
                    loss_Wins = agent.replayWins(batch_size)
                    #loss_Loss = agent.replayLoss(batch_size)
 
                if(done):
                    zuegeGesamt = zuegeGesamt + zuege + 1
                    break
                zuege = zuege + 1
        print(("\nepisode: {}/{}, Züge pro Spiel: {:.1f}, \nWinsTotal:{}, LossTotal:{}, DrawsTotal:{}, \ncumulative reward: {:.2f}, cum_Gegner: {:.2f}, \nloss: {:.1f}, LossWins: {:.1f}\n".format((EPISODES*i+e+1),(Ep*EPISODES), (zuegeGesamt/((EPISODES)*(i+1))), agentWins, gegnerWins, AnzahlUnentschieden, cum_reward, cum_reward_gegner, loss, loss_Wins)))
        #print(("\nepisode: {}/{}, Züge pro Spiel: {:.1f}, \nWinsTotal:{}, LossTotal:{}, DrawsTotal:{}, \nIllegalMove-A: {}, IllegalMove-G: {}, cumulative reward: {:.2f}, cum_Gegner: {:.2f}, \nloss: {:.1f}, LossWins: {:.1f}, LossLoss: {:.1f}\n".format((EPISODES*i+e+1),(Ep*EPISODES), (zuegeGesamt/((EPISODES)*(i+1))), agentWins, gegnerWins, AnzahlUnentschieden, agentFails, gegnerFails, cum_reward, cum_reward_gegner, loss, loss_Wins, loss_Loss)))
        agent.save("agentNight.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?
        agent.load("agentNight.weights")#gemerkte Entscheidungen laden, um damit gute Züge mache
 
some/vier_gewinnt.txt · Zuletzt geändert: 2020/04/03 15:55 von benbaute