diff --git a/src/go/engine.py b/src/go/engine.py --- a/src/go/engine.py +++ b/src/go/engine.py @@ -1,9 +1,14 @@ -from util import EMPTY,BLACK,WHITE +from .core import PASS from . import core -def transitionSequence(state1, state2, diff, limit=0): - return [] +## Compute move sequence from state1 to state2. +# +# @param colorIn {BLACK,WHITE}: color to start the sequence +# @param colorOut {BLACK,WHITE}: color to close the sequence +def getTransitionSequence(state1,state2,colorIn,colorOut,diff): + eng.load(state1,diff) + eng.iterativelyDeepen(state2,colorIn,colorOut) class SpecGo(core.Go): @@ -17,7 +22,7 @@ class SpecGo(core.Go): Also any non-missing stones of partially deleted (or replaced) groups had to be replayed, so add them too. Needs to handle snapback, throw-in. There's no end to what could be theoretically relevant, but such sequences are long and we will pretend they won't happen.""" - res=(set(),set()) + res=({PASS},{PASS}) for d in diff: (r,c,action,color)=d colorKey=(1-color)>>1 # {-1,1}->{1,0} @@ -55,48 +60,46 @@ class Engine: self._g.load(state1) self._moveList=self._g.listRelevantMoves(diff) - def iterativelyDeepen(self,state2,toMove=None): - for i in range(1,10): - for color in [toMove] if toMove else [BLACK,WHITE]: - self._g.toMove=color - seq=self.dfs(state2,i) - if seq: - seq.reverse() - return seq + def iterativelyDeepen(self,state2,colorIn,colorOut): + startDepth=1 if colorIn==colorOut else 2 + self._g.toMove=colorIn + + for i in range(startDepth,10,2): + seq=self.dfs(state2,i) + if seq: + seq.reverse() + return seq def dfs(self,state2,limit): g=self._g moveSet=self._moveList[(1-g.toMove)>>1] - for (r,c) in moveSet.copy(): - if g.board[r][c]!=EMPTY: continue - neighbours=( - g.board[r-1][c] if r>0 else None, - g.board[r+1][c] if r+10 else None, - g.board[r][c+1] if c+1>1].remove(m) if g.hash()==state2.hash(): - g.undoMove(r,c,captured) - moveSet.add((r,c)) - return [(g.toMove,r,c)] + self._undoMove(m,captured) + return [(g.toMove,*m)] if limit>1: seq=self.dfs(state2,limit-1) if seq: - g.undoMove(r,c,captured) - moveSet.add((r,c)) - seq.append((g.toMove,r,c)) + self._undoMove(m,captured) + seq.append((g.toMove,*m)) return seq - g.undoMove(r,c,captured) - moveSet.add((r,c)) + self._undoMove(m,captured) return False + def _undoMove(self,move,captured): + g=self._g + g.undoMove(*move,captured) + k=(1-g.toMove)>>1 + self._moveList[k].add(move) + if move==PASS: + self._moveList[1-k].add(move) + eng=Engine()