=== 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(agentWins200): #>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