More new
This commit is contained in:
parent
aabcea14ba
commit
2ced953c77
@ -72,15 +72,18 @@ class TTTState(State):
|
||||
if self.board[ind]=='.':
|
||||
yield Action(self.curPlayer, ind)
|
||||
|
||||
def getScoreFor(self, player):
|
||||
p = ['O','X'][player]
|
||||
sco = 5
|
||||
for w in self.box_won:
|
||||
if w==p:
|
||||
sco += 1
|
||||
elif w!='.':
|
||||
sco -= 0.5
|
||||
return 1/sco
|
||||
#def getScoreFor(self, player):
|
||||
# p = ['O','X'][player]
|
||||
# sco = 5
|
||||
# for w in self.box_won:
|
||||
# if w==p:
|
||||
# sco += 1
|
||||
# elif w!='.':
|
||||
# sco -= 0.5
|
||||
# return 1/sco
|
||||
|
||||
def getPriority(self, score, cascadeMem):
|
||||
return self.generation + score*10 - cascadeMem*5 + 100
|
||||
|
||||
def checkWin(self):
|
||||
self.update_box_won()
|
||||
@ -117,4 +120,4 @@ class TTTState(State):
|
||||
|
||||
if __name__=="__main__":
|
||||
run = Runtime(TTTState())
|
||||
run.game(None, 4)
|
||||
run.game([0,1], 4)
|
||||
|
115
vacuumDecay.py
115
vacuumDecay.py
@ -30,6 +30,9 @@ class Action():
|
||||
return "<P"+str(self.player)+"-"+str(self.data)+">"
|
||||
|
||||
class Universe():
|
||||
def __init__(self):
|
||||
self.scoreProvider = 'naive'
|
||||
|
||||
def newOpen(self, node):
|
||||
pass
|
||||
|
||||
@ -45,18 +48,36 @@ class Universe():
|
||||
def activateEdge(self, head):
|
||||
pass
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Any
|
||||
|
||||
@dataclass(order=True)
|
||||
class PQItem:
|
||||
priority: int
|
||||
data: Any=field(compare=False)
|
||||
|
||||
class QueueingUniverse(Universe):
|
||||
def __init__(self):
|
||||
self.pq = []
|
||||
super().__init__()
|
||||
self.pq = PriorityQueue()
|
||||
|
||||
def newOpen(self, node):
|
||||
heapq.headpush(self.pq, (node.priority, node))
|
||||
item = PQItem(node.getPriority(), node)
|
||||
self.pq.put(item)
|
||||
|
||||
def merge(self, node):
|
||||
self.newOpen(node)
|
||||
return node
|
||||
|
||||
def clearPQ(self):
|
||||
self.pq = []
|
||||
self.pq = PriorityQueue()
|
||||
|
||||
def iter(self):
|
||||
yield heapq.heappop(self.pq)
|
||||
while True:
|
||||
try:
|
||||
yield self.pq.get(False).data
|
||||
except Empty:
|
||||
time.sleep(1)
|
||||
|
||||
def activateEdge(self, head):
|
||||
head._activateEdge()
|
||||
@ -90,7 +111,7 @@ class State(ABC):
|
||||
return choose('What does player '+str(self.curPlayer)+' want to do?', actions)
|
||||
|
||||
# improveMe
|
||||
def getPriority(self, score, cascadeMemory=None):
|
||||
def getPriority(self, score, cascadeMemory):
|
||||
# Used for ordering the priority queue
|
||||
# Priority should not change for the same root
|
||||
# Lower prioritys get worked on first
|
||||
@ -138,6 +159,7 @@ class Node():
|
||||
def __init__(self, state, universe=None, parent=None, lastAction=None):
|
||||
self.state = state
|
||||
if universe==None:
|
||||
print('[!] No Universe defined. Spawning one...')
|
||||
universe = Universe()
|
||||
self.universe = universe
|
||||
self.parent = parent
|
||||
@ -216,12 +238,18 @@ class Node():
|
||||
else:
|
||||
self.strongDecay()
|
||||
|
||||
def decayEvent(self):
|
||||
for c in self.childs:
|
||||
c.strongDecay()
|
||||
|
||||
def strongDecay(self):
|
||||
if self._strongs == [None]*self.playersNum:
|
||||
if not self.scoresAvaible():
|
||||
self._calcScores()
|
||||
self._strongs = self._scores
|
||||
if self.parent:
|
||||
return self.parent._pullStrong()
|
||||
return 1
|
||||
return None
|
||||
|
||||
def getSelfScore(self):
|
||||
@ -247,16 +275,21 @@ class Node():
|
||||
return False
|
||||
return True
|
||||
|
||||
def askUserForAction(self):
|
||||
return self.state.askUserForAction(self.avaibleActions)
|
||||
|
||||
def _calcScores(self):
|
||||
for p in range(self.state.playersNum):
|
||||
self._calcScore(p)
|
||||
|
||||
def _calcScore(self, player):
|
||||
if self.universe.scoreProvider == 'naive':
|
||||
self._scores[player] = self.state.getScoreFor(player)
|
||||
else:
|
||||
raise Exception('Uknown Score-Provider')
|
||||
|
||||
@property
|
||||
def priority(self):
|
||||
return self.state.getPriority(self.score)
|
||||
def getPriority(self):
|
||||
return self.state.getPriority(self.getSelfScore(), self._cascadeMemory)
|
||||
|
||||
@property
|
||||
def playersNum(self):
|
||||
@ -273,11 +306,15 @@ class Node():
|
||||
def curPlayer(self):
|
||||
return self.state.curPlayer
|
||||
|
||||
def getWinner(self):
|
||||
return self.state.checkWin()
|
||||
|
||||
def _activateEdge(self):
|
||||
if not self.strongScoresAvaible():
|
||||
self.universe.newOpen(self)
|
||||
else:
|
||||
for c in self.childs:
|
||||
if c._cascadeMemory > 0.0001:
|
||||
c._activateEdge()
|
||||
|
||||
def __str__(self):
|
||||
@ -312,10 +349,56 @@ def choose(txt, options):
|
||||
return opt
|
||||
print('[!] Invalid Input.')
|
||||
|
||||
class Worker():
|
||||
def __init__(self, universe):
|
||||
self.universe = universe
|
||||
self._alive = True
|
||||
|
||||
def run(self):
|
||||
import threading
|
||||
self.thread = threading.Thread(target=self.runLocal)
|
||||
self.thread.start()
|
||||
|
||||
def runLocal(self):
|
||||
for i, node in enumerate(self.universe.iter()):
|
||||
if not self._alive:
|
||||
return
|
||||
node.decayEvent()
|
||||
|
||||
def kill(self):
|
||||
self._alive = False
|
||||
self.thread.join()
|
||||
|
||||
def revive(self):
|
||||
self._alive = True
|
||||
|
||||
class Trainer():
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def spawnRuntime(self, initState):
|
||||
self._runtime = Runtime(initState)
|
||||
|
||||
def setRuntime(self, runtime):
|
||||
self._runtime = runtime
|
||||
|
||||
def playFrom(self, start=None):
|
||||
if start==None:
|
||||
start = self._runtime.head
|
||||
self._runtime.game([1]*self._runtime.head.playersNum)
|
||||
|
||||
class Runtime():
|
||||
def __init__(self, initState):
|
||||
universe = Universe()
|
||||
self.head = Node(initState,universe = universe)
|
||||
universe = QueueingUniverse()
|
||||
self.head = Node(initState, universe = universe)
|
||||
universe.newOpen(self.head)
|
||||
|
||||
def spawnWorker(self):
|
||||
self.worker = Worker(self.head.universe)
|
||||
self.worker.run()
|
||||
|
||||
def killWorker(self):
|
||||
self.worker.kill()
|
||||
|
||||
def performAction(self, action):
|
||||
for c in self.head.childs:
|
||||
@ -330,10 +413,13 @@ class Runtime():
|
||||
def turn(self, bot=None, calcDepth=7):
|
||||
print(str(self.head))
|
||||
if bot==None:
|
||||
c = choose('Select action?', ['human', 'bot', 'undo'])
|
||||
c = choose('Select action?', ['human', 'bot', 'undo', 'qlen'])
|
||||
if c=='undo':
|
||||
self.head = self.head.parent
|
||||
return
|
||||
elif c=='qlen':
|
||||
print(self.head.universe.pq.qsize())
|
||||
return
|
||||
bot = c=='bot'
|
||||
if bot:
|
||||
self.head.forceStrong(calcDepth)
|
||||
@ -348,11 +434,14 @@ class Runtime():
|
||||
print('[#] I choose to play: ' + str(opts[0][0].lastAction))
|
||||
self.performAction(opts[0][0].lastAction)
|
||||
else:
|
||||
action = self.head.askUserForAction(self.head.avaibleActions)
|
||||
action = self.head.askUserForAction()
|
||||
self.performAction(action)
|
||||
|
||||
def game(self, bots=None, calcDepth=7):
|
||||
self.spawnWorker()
|
||||
if bots==None:
|
||||
bots = [None]*self.head.playersNum
|
||||
while True:
|
||||
while self.head.getWinner()==None:
|
||||
self.turn(bots[self.head.curPlayer], calcDepth)
|
||||
print(self.head.getWinner() + ' won!')
|
||||
self.killWorker()
|
||||
|
Loading…
Reference in New Issue
Block a user