Files
@ 4e67f9e9f027
Branch filter:
Location: OneEye/src/go/core.py - annotation
4e67f9e9f027
2.9 KiB
text/x-python
Engine.listRelevantMoves
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | 3798475f45c1 3798475f45c1 3798475f45c1 07f3fda1cbd7 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 07f3fda1cbd7 3798475f45c1 3798475f45c1 07f3fda1cbd7 07f3fda1cbd7 07f3fda1cbd7 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 4e67f9e9f027 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 07f3fda1cbd7 07f3fda1cbd7 3798475f45c1 3798475f45c1 07f3fda1cbd7 07f3fda1cbd7 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 07f3fda1cbd7 07f3fda1cbd7 07f3fda1cbd7 07f3fda1cbd7 07f3fda1cbd7 07f3fda1cbd7 07f3fda1cbd7 07f3fda1cbd7 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 4e67f9e9f027 3798475f45c1 07f3fda1cbd7 07f3fda1cbd7 07f3fda1cbd7 3798475f45c1 07f3fda1cbd7 a98de30efa51 07f3fda1cbd7 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 3798475f45c1 | import logging as log
from util import EMPTY,BLACK,WHITE,colorNames
from .helperboard import HelperBoard
from .gamerecord import GameRecord
class Go:
## Initializes self.board to a list[r][c]=EMPTY.
def __init__(self,boardSize=19):
self.boardSize=boardSize
self.board=[[EMPTY]*boardSize for x in range(boardSize)]
self.toMove=BLACK
self._helper=HelperBoard(self.board)
self._record=GameRecord()
def listMoves(self,diff=[]):
return []
## Executes a move.
#
# Doesn't check for kos. Suicide not allowed.
#
# @param color BLACK or WHITE
# @return True on success, False on failure (illegal move)
def doMove(self,color,row,col):
if color!=self.toMove: log.warning("move by %s out of order",colorNames[color])
if self.board[row][col]!=EMPTY: return False
self.board[row][col]=color
# capture neighbors
for r,c 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()
# check for suicide
self._helper.clear()
if not self._helper.floodFill(color,row,col,EMPTY):
self.board[row][col]=EMPTY
return False
self._record.move(color,row,col)
self.toMove=-1*color
return True
def undoMove(self,color,r,c,captures):
self.board[r][c]=color
if len(captures)>0:
self._helper.clear()
for (r,c) in captures:
self._helper.floodFill(EMPTY,r,c)
self._fill(-color)
def transitionMove(self,board):
res=transitionMove(self.board,board)
if not res: return res
(r,c,color)=res
return self.doMove(color,r,c)
## Removes stones at coordinates marked with True in self.helper.
def _remove(self):
self._fill(EMPTY)
def _fill(self,filling):
for (r,c) in self._helper.getContinuousArea():
self.board[r][c]=filling
def exportBoard(board):
substitutions={EMPTY:".", BLACK:"X", WHITE:"O"}
return "\n".join("".join(substitutions.get(x,"?") for x in row) for row in board)
def isLegalPosition(board):
boardSize=len(board)
temp=[[None]*boardSize for x in range(boardSize)]
for r in range(boardSize):
for c in range(boardSize):
if board[r][c]==EMPTY: continue
if temp[r][c]: continue
if not dfs([(r,c)],board,temp): return False
return True
def transitionMove(state1,state2):
moves=[]
for (r,(row1,row2)) in enumerate(zip(state1,state2)):
for (c,(item1,item2)) in enumerate(zip(row1,row2)):
if item1==EMPTY and item2!=EMPTY:
moves.append((r,c,item2))
if len(moves)==0:
log.info("no new stone")
return None
elif len(moves)==1:
log.info("new stone: %s",moves[0])
return moves[0]
else:
log.warning("too many new stones: %s",moves)
return False
def dfs(stack,board,mask):
boardSize=len(board)
(r,c)=stack[0]
color=board[r][c]
while len(stack)>0:
(r,c)=stack.pop()
if board[r][c]==EMPTY: return True
elif board[r][c]!=color: continue
elif mask[r][c]: return True
mask[r][c]=True
for (x,y) in ((0,-1),(-1,0),(0,1),(1,0)):
if 0<=r+y<boardSize and 0<=c+x<boardSize:
stack.append((r+y,c+x))
return False
|