Changeset - 7f1984280936
[Not reviewed]
default
0 3 1
Laman - 7 years ago 2017-12-08 19:03:23

Engine draft for exploring move sequences
4 files changed with 89 insertions and 7 deletions:
0 comments (0 inline, 0 general)
src/go/core.py
Show inline comments
 
@@ -101,10 +101,6 @@ def transitionMove(state1,state2):
 
		return False
 

	
 

	
 
def transitionSequence(state1,state2,diff,limit=0):
 
	return []
 

	
 

	
 
def dfs(stack,board,mask):
 
	boardSize=len(board)
 
	(r,c)=stack[0]
src/go/engine.py
Show inline comments
 
new file 100644
 
import core
 

	
 

	
 
def transitionSequence(state1, state2, diff, limit=0):
 
	return []
 

	
 

	
 
class SpecGo(core.Go):
 
	def __init__(self):
 
		super().__init__()
 
		self._diff=[]
 

	
 
	def load(self,state):
 
		for (r,row) in enumerate(state):
 
			for (c,x) in enumerate(row):
 
				self.board[r][c]=x
 

	
 
	def listRelevantMoves(self,diff):
 
		res=([],[])
 
		for d in diff:
 
			(r,c,action,color)=d
 
			colorKey=(1-color)<<1
 
			if action!="-":
 
				res[colorKey].append((r,c))
 
			if action!="+":
 
				self._helper.clear()
 
				self._helper.floodFill(color,r,c)
 
				res[colorKey].extend(self._helper.getLiberties())
 
		return res
 

	
 

	
 
class Engine:
 
	def __init__(self):
 
		self._g=SpecGo()
 
		self._diff=[]
 

	
 
	def load(self,state1,diff):
 
		self._g.load(state1)
 
		self._diff=diff
 

	
 
	def iterativelyDeepen(self,state2):
 
		for i in range(1,10):
 
			seq=self.dfs(state2,i)
 
			if seq: return seq
 

	
 
	def dfs(self,state2,limit):
 
		g=self._g
 
		for m in g.listRelevantMoves():
 
			g.doMove(m)
 
			if g.board==state2: return m
 
			if limit>1:
 
				seq=self.dfs(state2,limit-1)
 
				if seq:
 
					seq.append(m)
 
					return seq
 
			g.undoMove(m)
 
		return False
 

	
 
eng=Engine()
src/go/helperboard.py
Show inline comments
 
@@ -39,6 +39,10 @@ class HelperBoard:
 
		for i in range(self._visitedCount):
 
			yield (self._visited[i*2],self._visited[i*2+1])
 

	
 
	def getLiberties(self):
 
		for i in range(self._libCount):
 
			yield (self._libs[i*2],self._libs[i*2+1])
 

	
 
	def clear(self):
 
		for i in range(self._visitedCount):
 
			(r,c)=(self._visited[i*2],self._visited[i*2+1])
src/statebag.py
Show inline comments
 
@@ -16,19 +16,29 @@ So we try to find the correct crossover 
 
	- remember the better variant
 
- linearize the fork back by discarding s'_j-s preceding the crossover and s_j-s following the crossover
 
"""
 
import random
 

	
 
from util import EMPTY
 
from go.core import transitionSequence
 
from go.engine import transitionSequence
 

	
 
rand=random.Random()
 
rand.seed(361)
 
zobristNums=tuple(
 
	tuple(
 
		tuple(rand.getrandbits(32) for i in range(3)) for c in range(19)
 
	) for r in range(19)
 
)
 

	
 

	
 
## Crude lower bound on edit distance between states.
 
def estimateDistance(diff):
 
	# lot of room for improvements
 
	additions=sum(1 for d in diff if d[2]=="+")
 
	deletions=sum(1 for d in diff if d[2]=="-")
 
	replacements=len(diff)-additions-deletions
 
	if additions>0: return additions+replacements
 
	elif replacements==0 and deletions>0: return 2 # take n, return 1
 
	return replacements # ???
 
	return replacements+1 # ???
 

	
 

	
 
class BoardState:
 
@@ -40,6 +50,13 @@ class BoardState:
 
		self.weight=0
 
		self.diff2Prev=None
 

	
 
	def hash(self):
 
		res=0
 
		for (r,row) in enumerate(self._board):
 
			for (c,item) in enumerate(row):
 
				res^=zobristNums[r][c][item+1]
 
		return res
 

	
 
	def __iter__(self): return iter(self._board)
 

	
 
	def __getitem__(self,key): return self._board[key]
 
@@ -52,9 +69,13 @@ class BoardState:
 
				if item1==item2: continue
 
				elif item2==EMPTY: res.append((r,c,"+",item1))
 
				elif item1==EMPTY: res.append((r,c,"-",item2))
 
				else: res.append((r,c,item2,item1)) # from->to
 
				else: res.append((r,c,"*",item1)) # ->to
 
		return res
 

	
 
	def __eq__(self,x):
 
		# might want to use hash
 
		return self._board==x._board
 

	
 

	
 
class StateBag:
 
	def __init__(self):
 
@@ -62,6 +83,8 @@ class StateBag:
 

	
 
	def pushState(self,board):
 
		sn=BoardState(board)
 
		if self._states and sn==self._states[-1]: return # no change
 

	
 
		for s in reversed(self._states):
 
			diff=sn-s
 
			distEst=estimateDistance(diff)
0 comments (0 inline, 0 general)