Works...
This commit is contained in:
parent
5ba277a2aa
commit
f9a5ba1964
@ -2,6 +2,7 @@ import time
|
|||||||
import random
|
import random
|
||||||
import threading
|
import threading
|
||||||
import torch
|
import torch
|
||||||
|
from math import sqrt
|
||||||
#from multiprocessing import Event
|
#from multiprocessing import Event
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from threading import Event
|
from threading import Event
|
||||||
@ -86,12 +87,13 @@ class State(ABC):
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
# improveMe
|
# improveMe
|
||||||
def getPriority(self, score):
|
def getPriority(self, score, cascadeMemory=None):
|
||||||
# Used for ordering the priority queue
|
# Used for ordering the priority queue
|
||||||
# Priority should not change for the same root
|
# Priority should not change for the same root
|
||||||
# Lower prioritys get worked on first
|
# Lower prioritys get worked on first
|
||||||
# Higher generations should have higher priority
|
# Higher generations should have higher priority
|
||||||
return score + self.generation*0.5
|
# Higher cascadeMemory (more influence on higher-order-scores) should have lower priority
|
||||||
|
return score + self.generation*0.5 - cascadeMemory*0.35
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def checkWin(self):
|
def checkWin(self):
|
||||||
@ -142,10 +144,14 @@ class Node():
|
|||||||
self._scores = [None]*self.state.playersNum
|
self._scores = [None]*self.state.playersNum
|
||||||
self._strongs = [None]*self.state.playersNum
|
self._strongs = [None]*self.state.playersNum
|
||||||
self._alive = True
|
self._alive = True
|
||||||
|
self._cascadeMemory = 0 # Used for our alternative to alpha-beta pruning
|
||||||
|
|
||||||
def kill(self):
|
def kill(self):
|
||||||
self._alive = False
|
self._alive = False
|
||||||
|
|
||||||
|
def revive(self):
|
||||||
|
self._alive = True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def childs(self):
|
def childs(self):
|
||||||
if self._childs == None:
|
if self._childs == None:
|
||||||
@ -159,26 +165,28 @@ class Node():
|
|||||||
newNode = Node(self.state.mutate(action), self.universe, self, action)
|
newNode = Node(self.state.mutate(action), self.universe, self, action)
|
||||||
self._childs.append(self.universe.merge(newNode))
|
self._childs.append(self.universe.merge(newNode))
|
||||||
|
|
||||||
@property
|
def getStrongFor(self, player):
|
||||||
def strongs(self):
|
if self._strongs[player]!=None:
|
||||||
return self._strongs
|
return self._strongs[player]
|
||||||
|
else:
|
||||||
|
return self.getScoreFor(player)
|
||||||
|
|
||||||
def _pullStrong(self): # Currently Expecti-Max
|
def _pullStrong(self): # Currently Expecti-Max
|
||||||
strongs = [None]*self.playersNum
|
strongs = [None]*self.playersNum
|
||||||
for p in range(self.playersNum):
|
for p in range(self.playersNum):
|
||||||
cp = self.state.curPlayer
|
cp = self.state.curPlayer
|
||||||
if cp == p: # P owns the turn; controlls outcome
|
if cp == p: # P owns the turn; controlls outcome
|
||||||
best = 10000000
|
best = 1000000000
|
||||||
for c in self.childs:
|
for c in self.childs:
|
||||||
if c._strongs[cp] < best:
|
if c.getStrongFor(p) < best:
|
||||||
best = c._strongs[p]
|
best = c.getStrongFor(p)
|
||||||
strongs[p] = best
|
strongs[p] = best
|
||||||
else:
|
else:
|
||||||
scos = [(c._strongs[cp], c._strongs[p]) for c in self.childs]
|
scos = [(c.getStrongFor(p), c.getStrongFor(cp)) for c in self.childs]
|
||||||
scos.sort(key=lambda x: x[0])
|
scos.sort(key=lambda x: x[1])
|
||||||
betterHalf = scos[:max(3,int(len(scos)/2))]
|
betterHalf = scos[:max(3,int(len(scos)/3))]
|
||||||
myScores = [bh[1] for bh in betterHalf]
|
myScores = [bh[0]**2 for bh in betterHalf]
|
||||||
strongs[p] = sum(myScores)/len(myScores)
|
strongs[p] = sqrt(myScores[0]*0.75 + sum(myScores)/(len(myScores)*4))
|
||||||
update = False
|
update = False
|
||||||
for s in range(self.playersNum):
|
for s in range(self.playersNum):
|
||||||
if strongs[s] != self._strongs[s]:
|
if strongs[s] != self._strongs[s]:
|
||||||
@ -186,21 +194,32 @@ class Node():
|
|||||||
break
|
break
|
||||||
self._strongs = strongs
|
self._strongs = strongs
|
||||||
if update:
|
if update:
|
||||||
self.parent._pullStrong()
|
if self.parent!=None:
|
||||||
|
cascade = self.parent._pullStrong()
|
||||||
|
else:
|
||||||
|
cascade = 2
|
||||||
|
self._cascadeMemory = self._cascadeMemory/2 + cascade
|
||||||
|
return cascade + 1
|
||||||
|
self._cascadeMemory /= 2
|
||||||
|
return 0
|
||||||
|
|
||||||
def forceStrong(self, depth=3):
|
def forceStrong(self, depth=3):
|
||||||
if depth==0:
|
if depth==0:
|
||||||
self.strongDecay()
|
self.strongDecay()
|
||||||
else:
|
else:
|
||||||
for c in self.childs:
|
if len(self.childs):
|
||||||
c.forceStrong(depth-1)
|
for c in self.childs:
|
||||||
|
c.forceStrong(depth-1)
|
||||||
|
else:
|
||||||
|
self.strongDecay()
|
||||||
|
|
||||||
def strongDecay(self):
|
def strongDecay(self):
|
||||||
if self._strongs == [None]*self.playersNum:
|
if self._strongs == [None]*self.playersNum:
|
||||||
if not self.scoresAvaible():
|
if not self.scoresAvaible():
|
||||||
self._calcScores()
|
self._calcScores()
|
||||||
self._strongs = self._scores
|
self._strongs = self._scores
|
||||||
self.parent._pullStrong()
|
return self.parent._pullStrong()
|
||||||
|
return None
|
||||||
|
|
||||||
def getSelfScore(self):
|
def getSelfScore(self):
|
||||||
return self.getScoreFor(self.curPlayer)
|
return self.getScoreFor(self.curPlayer)
|
||||||
@ -219,6 +238,12 @@ class Node():
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def strongScoresAvaible(self):
|
||||||
|
for p in self._strongs:
|
||||||
|
if p==None:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def _calcScores(self):
|
def _calcScores(self):
|
||||||
for p in range(self.state.playersNum):
|
for p in range(self.state.playersNum):
|
||||||
self._calcScore(p)
|
self._calcScore(p)
|
||||||
@ -307,9 +332,10 @@ class Runtime():
|
|||||||
return
|
return
|
||||||
bot = c=='bot'
|
bot = c=='bot'
|
||||||
if bot:
|
if bot:
|
||||||
|
self.head.forceStrong(7)
|
||||||
opts = []
|
opts = []
|
||||||
for c in self.head.childs:
|
for c in self.head.childs:
|
||||||
opts.append((c, c.getStrongScore(self.head.curPlayer, -1)[0]))
|
opts.append((c, c.getStrongFor(self.head.curPlayer)))
|
||||||
opts.sort(key=lambda x: x[1])
|
opts.sort(key=lambda x: x[1])
|
||||||
print('[i] Evaluated Options:')
|
print('[i] Evaluated Options:')
|
||||||
for o in opts:
|
for o in opts:
|
||||||
|
Loading…
Reference in New Issue
Block a user