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