Changeset - 32221aadca28
[Not reviewed]
default
0 3 1
Laman - 7 years ago 2017-12-15 20:10:12

optimized board hashing: computing only hash diff
4 files changed with 35 insertions and 13 deletions:
0 comments (0 inline, 0 general)
src/benchmark.py
Show inline comments
 
new file 100644
 
import cProfile
 

	
 
from tests.testEngine import TestTransitions
 

	
 

	
 
t=TestTransitions()
 

	
 
cProfile.run(r"""
 
t.testReal()
 
""")
src/go/core.py
Show inline comments
 
import logging as log
 

	
 
from util import EMPTY,BLACK,WHITE, colorNames,hashBoard
 
from util import EMPTY,BLACK,WHITE, colorNames,hashBoard,diffHash
 
from .helperboard import HelperBoard
 
from .gamerecord import GameRecord
 

	
 
@@ -12,7 +12,8 @@ class Go:
 
		self.board=[[EMPTY]*boardSize for x in range(boardSize)]
 
		self.toMove=BLACK
 
		self._helper=HelperBoard(self.board)
 
		self._hashes=[]
 
		self._freshHash=hashBoard(self.board) # always reflecting current state of the board
 
		self._hashes=[self._freshHash]
 
		self._record=GameRecord()
 

	
 
	## Executes a move.
 
@@ -21,25 +22,27 @@ class Go:
 
	#
 
	#  @param color BLACK or WHITE
 
	#  @return True on success, False on failure (illegal move)
 
	def doMove(self,color,row,col):
 
	def doMove(self,color,r,c):
 
		if color!=self.toMove: log.warning("move by %s out of order",colorNames[color])
 
		if self.board[row][col]!=EMPTY: return False
 
		if self.board[r][c]!=EMPTY: return False
 

	
 
		self.board[row][col]=color
 
		self.board[r][c]=color
 
		self._freshHash^=diffHash(r,c,EMPTY,color)
 

	
 
		# capture neighbors
 
		for r,c in ((-1,0),(1,0),(0,-1),(0,1)):
 
		for dr,dc in ((-1,0),(1,0),(0,-1),(0,1)):
 
			self._helper.clear()
 
			if not self._helper.floodFill(-color,row+r,col+c,EMPTY): self._remove()
 
			if not self._helper.floodFill(-color,r+dr,c+dc,EMPTY): self._remove()
 

	
 
		# check for suicide and prevent it
 
		self._helper.clear()
 
		if not self._helper.floodFill(color,row,col,EMPTY):
 
			self.board[row][col]=EMPTY
 
		if not self._helper.floodFill(color,r,c,EMPTY):
 
			self.board[r][c]=EMPTY
 
			self._freshHash=self._hashes[-1]
 
			return False
 
		self._record.move(color,row,col)
 
		self._record.move(color,r,c)
 
		self.toMove=-1*color
 
		self._hashes.append(self.hash())
 
		self._hashes.append(self._freshHash)
 
		return True
 

	
 
	def undoMove(self,r,c,captures):
 
@@ -54,6 +57,7 @@ class Go:
 
		self.board[r][c]=EMPTY
 
		self.toMove*=-1
 
		self._hashes.pop()
 
		self._freshHash=self._hashes[-1]
 

	
 
	def transitionMove(self,board):
 
		res=transitionMove(self.board,board)
 
@@ -65,9 +69,11 @@ class Go:
 
		for (r,row) in enumerate(board):
 
			for (c,x) in enumerate(row):
 
				self.board[r][c]=x
 
		self._freshHash=hashBoard(self.board)
 
		self._hashes=[self._freshHash]
 

	
 
	def hash(self):
 
		return hashBoard(self.board)
 
		return self._hashes[-1]
 

	
 
	## Removes stones at coordinates marked with True in self.helper.
 
	def _remove(self):
 
@@ -75,6 +81,7 @@ class Go:
 

	
 
	def _fill(self,filling):
 
		for (r,c) in self._helper.getContinuousArea():
 
			self._freshHash^=diffHash(r,c,self.board[r][c],filling)
 
			self.board[r][c]=filling
 

	
 

	
src/statebag.py
Show inline comments
 
@@ -39,9 +39,11 @@ class BoardState:
 
		self.moves=[]
 
		self.weight=0
 
		self.diff2Prev=None
 
		self._hash=None
 

	
 
	def hash(self):
 
		return hashBoard(self._board)
 
		if self._hash is None: self._hash=hashBoard(self._board)
 
		return self._hash
 

	
 
	def export(self):
 
		return exportBoard(self._board)
src/util.py
Show inline comments
 
@@ -52,6 +52,9 @@ def hashBoard(board):
 
			res^=zobristNums[r][c][item+1]
 
	return res
 

	
 
def diffHash(r,c,oldItem,newItem):
 
	h=zobristNums[r][c]
 
	return h[oldItem+1] ^ h[newItem+1]
 

	
 
def exportBoard(board):
 
	substitutions={EMPTY:".", BLACK:"X", WHITE:"O"}
0 comments (0 inline, 0 general)