Initial commit
commit
9825def253
@ -0,0 +1,2 @@
|
|||||||
|
*.fiar
|
||||||
|
__pycache__
|
@ -0,0 +1,43 @@
|
|||||||
|
import fiar
|
||||||
|
import nn
|
||||||
|
import lib
|
||||||
|
|
||||||
|
game = fiar.FIAR();
|
||||||
|
nn = lib.loadSingle(0)
|
||||||
|
|
||||||
|
def declareWinner():
|
||||||
|
game.printField();
|
||||||
|
print("And the winner is P", game.proveWinner(), "!")
|
||||||
|
|
||||||
|
def isnumber(val):
|
||||||
|
try:
|
||||||
|
val = int(val)
|
||||||
|
return True
|
||||||
|
except ValueError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
while True:
|
||||||
|
game.printField();
|
||||||
|
|
||||||
|
player_input = input("P1, where do you put your stone? ")
|
||||||
|
|
||||||
|
while not (isnumber(player_input) and 7 >= int(player_input) >= 1):
|
||||||
|
player_input = input("P1, your input has to be a number between 1 and 7! New input: ")
|
||||||
|
|
||||||
|
try:
|
||||||
|
game.setStone(int(player_input)-1, 1)
|
||||||
|
except OverflowError:
|
||||||
|
print("This Column is already full, maybe try again next time...")
|
||||||
|
|
||||||
|
if(game.proveWinner()):
|
||||||
|
declareWinner()
|
||||||
|
break
|
||||||
|
|
||||||
|
# --------------- #
|
||||||
|
|
||||||
|
game = lib.nextNNmove(nn, game, 2);
|
||||||
|
|
||||||
|
if(game.proveWinner()):
|
||||||
|
declareWinner()
|
||||||
|
break
|
@ -0,0 +1,51 @@
|
|||||||
|
import fiar
|
||||||
|
|
||||||
|
game = fiar.FIAR();
|
||||||
|
|
||||||
|
def declareWinner():
|
||||||
|
game.printField();
|
||||||
|
print("And the winner is P", game.proveWinner(), "!")
|
||||||
|
|
||||||
|
|
||||||
|
def isnumber(val):
|
||||||
|
try:
|
||||||
|
val = int(val)
|
||||||
|
return True
|
||||||
|
except ValueError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
while True:
|
||||||
|
game.printField();
|
||||||
|
|
||||||
|
player_input = input("P1, where do you put your stone? ")
|
||||||
|
|
||||||
|
while not (isnumber(player_input) and 7 >= int(player_input) >= 1):
|
||||||
|
player_input = input("P1, your input has to be a number between 1 and 7! New input: ")
|
||||||
|
|
||||||
|
try:
|
||||||
|
game.setStone(int(player_input)-1, 1);
|
||||||
|
except OverflowError:
|
||||||
|
print("This Column is already full, maybe try again next time...")
|
||||||
|
|
||||||
|
if(game.proveWinner()):
|
||||||
|
declareWinner()
|
||||||
|
break
|
||||||
|
|
||||||
|
# --------------- #
|
||||||
|
|
||||||
|
game.printField();
|
||||||
|
|
||||||
|
player_input = input("P2, where do you put your stone? ")
|
||||||
|
|
||||||
|
while not (isnumber(player_input) and 7 >= int(player_input) >= 1):
|
||||||
|
player_input = input("P2, your input has to be a number between 1 and 7! New input: ")
|
||||||
|
|
||||||
|
try:
|
||||||
|
game.setStone(int(player_input)-1, 2);
|
||||||
|
except OverflowError:
|
||||||
|
print("This Column is already full, maybe try again next time...")
|
||||||
|
|
||||||
|
if(game.proveWinner()):
|
||||||
|
declareWinner()
|
||||||
|
break
|
@ -0,0 +1,121 @@
|
|||||||
|
class FIAR():
|
||||||
|
def __init__(self, height=6, width=7):
|
||||||
|
self.height = height # y
|
||||||
|
self.width = width # x
|
||||||
|
self.field = []
|
||||||
|
# field[x][y]
|
||||||
|
for x in range(width):
|
||||||
|
col = []
|
||||||
|
for y in range(height):
|
||||||
|
col.append(None)
|
||||||
|
self.field.append(col)
|
||||||
|
|
||||||
|
def getTransformedField(self):
|
||||||
|
output = []
|
||||||
|
for col in self.field:
|
||||||
|
output += col
|
||||||
|
return output
|
||||||
|
|
||||||
|
def printField(self):
|
||||||
|
redBG = "\33[41m"
|
||||||
|
greenBG = "\33[42m"
|
||||||
|
clearBG = "\33[0m"
|
||||||
|
dashes = (self.width * 2)+1
|
||||||
|
print("-" * dashes)
|
||||||
|
for y in range(self.height, -1, -1):
|
||||||
|
for x in range(self.width):
|
||||||
|
if y == self.height:
|
||||||
|
print("|" + str(x+1), end='')
|
||||||
|
elif self.field[x][y] == 1:
|
||||||
|
print("|" + redBG + "x" + clearBG, end='')
|
||||||
|
elif self.field[x][y] == 2:
|
||||||
|
print("|" + greenBG+"o" + clearBG, end='')
|
||||||
|
else:
|
||||||
|
print("|" + " ", end='')
|
||||||
|
print("|")
|
||||||
|
print("-" * dashes)
|
||||||
|
|
||||||
|
def setStone(self, col, player):
|
||||||
|
if(col in list(range(self.width))):
|
||||||
|
has_set = False
|
||||||
|
for i in range(self.height):
|
||||||
|
if self.field[col][i] == None:
|
||||||
|
self.field[col][i] = player
|
||||||
|
has_set = True
|
||||||
|
break
|
||||||
|
if not has_set:
|
||||||
|
raise OverflowError
|
||||||
|
else:
|
||||||
|
raise IndexError
|
||||||
|
|
||||||
|
def proveWinner(self):
|
||||||
|
# Tie:
|
||||||
|
tie = True
|
||||||
|
for x in range(self.width):
|
||||||
|
if(self.field[x][self.height-1] == None):
|
||||||
|
tie = False
|
||||||
|
break
|
||||||
|
if tie:
|
||||||
|
return 3
|
||||||
|
|
||||||
|
# Horizontal:
|
||||||
|
for y in range(self.height):
|
||||||
|
for x in range(self.width-3):
|
||||||
|
if self.field[x][y] != None:
|
||||||
|
first = self.field[x][y]
|
||||||
|
isWinner = True
|
||||||
|
|
||||||
|
for i in range(1, 4):
|
||||||
|
if self.field[x+i][y] != first:
|
||||||
|
isWinner = False
|
||||||
|
break
|
||||||
|
|
||||||
|
if isWinner:
|
||||||
|
return first
|
||||||
|
|
||||||
|
# Vertical:
|
||||||
|
for x in range(self.width):
|
||||||
|
for y in range(self.height-3):
|
||||||
|
if self.field[x][y] != None:
|
||||||
|
first = self.field[x][y]
|
||||||
|
isWinner = True
|
||||||
|
|
||||||
|
for i in range(1, 4):
|
||||||
|
if self.field[x][y+i] != first:
|
||||||
|
isWinner = False
|
||||||
|
break
|
||||||
|
|
||||||
|
if isWinner:
|
||||||
|
return first
|
||||||
|
|
||||||
|
# Diagonal Up:
|
||||||
|
for x in range(self.width-3):
|
||||||
|
for y in range(self.height-3):
|
||||||
|
if self.field[x][y] != None:
|
||||||
|
first = self.field[x][y]
|
||||||
|
isWinner = True
|
||||||
|
|
||||||
|
for i in range(1, 4):
|
||||||
|
if self.field[x+i][y+i] != first:
|
||||||
|
isWinner = False
|
||||||
|
break
|
||||||
|
|
||||||
|
if isWinner:
|
||||||
|
return first
|
||||||
|
|
||||||
|
# Diagonal Down:
|
||||||
|
for x in range(3, self.width):
|
||||||
|
for y in range(self.height-3):
|
||||||
|
if self.field[x][y] != None:
|
||||||
|
first = self.field[x][y]
|
||||||
|
isWinner = True
|
||||||
|
|
||||||
|
for i in range(1, 4):
|
||||||
|
if self.field[x-i][y+i] != first:
|
||||||
|
isWinner = False
|
||||||
|
break
|
||||||
|
|
||||||
|
if isWinner:
|
||||||
|
return first
|
||||||
|
|
||||||
|
return False
|
@ -0,0 +1,58 @@
|
|||||||
|
import nn
|
||||||
|
import pickle
|
||||||
|
|
||||||
|
networks_filename = "networks.fiar"
|
||||||
|
|
||||||
|
def nextNNmove(network, game, player):
|
||||||
|
flatfield = game.getTransformedField()
|
||||||
|
player1 = []
|
||||||
|
player2 = []
|
||||||
|
for spot in flatfield:
|
||||||
|
if spot == 1:
|
||||||
|
player1.append(1)
|
||||||
|
player2.append(0)
|
||||||
|
elif spot == 2:
|
||||||
|
player1.append(0)
|
||||||
|
player2.append(1)
|
||||||
|
else:
|
||||||
|
player1.append(0)
|
||||||
|
player2.append(0)
|
||||||
|
|
||||||
|
out = network.calculateOutput(player1+player2)
|
||||||
|
preferences = []
|
||||||
|
for i in range(len(out)):
|
||||||
|
maxI = 0
|
||||||
|
maxVal = -20
|
||||||
|
for j in range(len(out)):
|
||||||
|
if out[j] > maxVal:
|
||||||
|
maxVal = out[j]
|
||||||
|
maxI = j
|
||||||
|
out[maxI] = -20
|
||||||
|
preferences.append(maxI)
|
||||||
|
|
||||||
|
for val in preferences:
|
||||||
|
try:
|
||||||
|
game.setStone(val, player)
|
||||||
|
except OverflowError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
return game
|
||||||
|
|
||||||
|
def createAndSave(num):
|
||||||
|
nets = []
|
||||||
|
for i in range(num):
|
||||||
|
nets.append(nn.NN(84, 168, 168, 84, 84, 42, 7))
|
||||||
|
saveAll(nets)
|
||||||
|
|
||||||
|
def saveAll(nets):
|
||||||
|
with open(networks_filename, 'wb') as networks_file:
|
||||||
|
pickle.dump(nets, networks_file)
|
||||||
|
|
||||||
|
def loadAll():
|
||||||
|
with open(networks_filename, 'rb') as networks_file:
|
||||||
|
nets = pickle.load(networks_file)
|
||||||
|
return nets
|
||||||
|
|
||||||
|
def loadSingle(num):
|
||||||
|
return loadAll()[num]
|
@ -0,0 +1,40 @@
|
|||||||
|
import numpy as np
|
||||||
|
|
||||||
|
class NN():
|
||||||
|
score = 0
|
||||||
|
|
||||||
|
def __init__(self, *args):
|
||||||
|
self.layers = args
|
||||||
|
self.synapses = []
|
||||||
|
for i in range(len(self.layers)-1):
|
||||||
|
self.synapses.append(np.random.normal(scale=1,size=(self.layers[i], self.layers[i+1])))
|
||||||
|
|
||||||
|
def calculateOutput(self, input):
|
||||||
|
layerInput = input
|
||||||
|
|
||||||
|
for synapseLayer in self.synapses:
|
||||||
|
layerInput = np.dot(layerInput, synapseLayer)
|
||||||
|
layerInput = self.sigmoid(layerInput)
|
||||||
|
|
||||||
|
return layerInput
|
||||||
|
|
||||||
|
def sigmoid(self, s):
|
||||||
|
#print("Arr:", arr)
|
||||||
|
#s = np.array(arr)
|
||||||
|
# activation function
|
||||||
|
res = 1 / (1 + np.exp(-s))
|
||||||
|
#print("Res:", res)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def getSynapses(self):
|
||||||
|
return self.synapses
|
||||||
|
|
||||||
|
def setSynapses(self, synapses):
|
||||||
|
self.synapses = synapses
|
||||||
|
|
||||||
|
def mutate(self, val):
|
||||||
|
mut_arr = []
|
||||||
|
for i in range(len(self.layers)-1):
|
||||||
|
mut_arr.append(np.random.normal(scale=val,size=(self.layers[i], self.layers[i+1])))
|
||||||
|
self.synapses = np.add(self.synapses, mut_arr)
|
||||||
|
return mut_arr
|
@ -0,0 +1,2 @@
|
|||||||
|
numpy
|
||||||
|
pickle
|
@ -0,0 +1,63 @@
|
|||||||
|
import lib, fiar
|
||||||
|
|
||||||
|
nets = lib.loadAll()
|
||||||
|
gen = 0
|
||||||
|
|
||||||
|
def NvN(net1, net2, printField=False):
|
||||||
|
game = fiar.FIAR();
|
||||||
|
|
||||||
|
while True:
|
||||||
|
game = lib.nextNNmove(net1, game, 1);
|
||||||
|
if(game.proveWinner()):
|
||||||
|
break
|
||||||
|
game = lib.nextNNmove(net2, game, 2);
|
||||||
|
if(game.proveWinner()):
|
||||||
|
break
|
||||||
|
|
||||||
|
if printField:
|
||||||
|
game.printField()
|
||||||
|
print(net1.synapses[0][0][0])
|
||||||
|
print()
|
||||||
|
|
||||||
|
return game.proveWinner()
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
gen += 1
|
||||||
|
print("Gen:", gen)
|
||||||
|
|
||||||
|
# Reset the nets' score:
|
||||||
|
for net in nets:
|
||||||
|
net.score = 0
|
||||||
|
|
||||||
|
# Let the nets play against each other:
|
||||||
|
for i in range(len(nets)):
|
||||||
|
for j in range(i+1, len(nets)):
|
||||||
|
|
||||||
|
|
||||||
|
winner = NvN(nets[i], nets[j], i==0 and j==1)
|
||||||
|
#print("Net1:",i,"Net2:",j)
|
||||||
|
#print("Winner:",winner)
|
||||||
|
if(winner == 1):
|
||||||
|
nets[i].score += 1
|
||||||
|
if(winner == 2):
|
||||||
|
nets[j].score += 1
|
||||||
|
|
||||||
|
winner = NvN(nets[j], nets[i])
|
||||||
|
#print("Net1:",i,"Net2:",j)
|
||||||
|
#print("Winner:",winner)
|
||||||
|
if(winner == 1):
|
||||||
|
nets[i].score += 1
|
||||||
|
if(winner == 2):
|
||||||
|
nets[j].score += 1
|
||||||
|
|
||||||
|
# Sort the nets by their score:
|
||||||
|
nets.sort(key=lambda x: x.score, reverse=True)
|
||||||
|
for i in range(int(len(nets)/3)):
|
||||||
|
nets[i+int(len(nets)/3)] = nets[i];
|
||||||
|
nets[i+int(len(nets)/3)].mutate(0.001);
|
||||||
|
nets[i+int(len(nets)/3*2)] = nets[i];
|
||||||
|
nets[i+int(len(nets)/3*2)].mutate(0.1);
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("Saving all Data...")
|
||||||
|
lib.saveAll(nets)
|
Loading…
Reference in New Issue