2020幻影围棋 第三天围棋规则模块(一)

围棋规则其实很简单,首先每个棋子会有气,相连的一片棋子共用气,那么基于这个规则我们可以构造这样一个Group类:

class Group(namedtuple(
    'Group',
    ['id', 'stones', 'liberties', 'color']
)):
    """

    ++++++
    ++..++
    ++..++
    +*++++
    上面那些点就构成了一个群
    群: 一个群就是一大片连着的相同颜色的棋子
    :stones 群内棋子的集合
    :liberties 群周围相邻且没有棋子的点的集合
    :color 群内棋子的颜色
    """

    def __eq__(self, other):
        return self.stones == other.stones and self.liberties == other.liberties and self.color == other.color

这个群是一个命名元组类,Group是这个命名元组的名称,后面接了他的四个属性。
基于这个数据结构我们可以构造一个气追踪器类,用于记录和更新棋盘上棋子的气。

class LibertyTracker(object):
    @staticmethod
    def newTrackerFromBaseBoard(board=gf.Board.getStaticBaseBoard())
    def __init__(self, groupIndexMap=None, groups=None, librtyCacheMap=None, maxGroupId=1)
    def __deepcopy__(self, memodict={})
    def addStone(self, color, point, phantom=True)
    def _handleCaptures(self, capturedStones)
    def _createGroup(self, color, point, liberties)
    def _delGroup(self, groupId)
    def _captureGroup(self, groupId, phantom)
    def _mergeGroup(self, group1Id, group2Id)
    def _updateLiberties(self, groupId, add=None, remove=None)

首先来看这个静态方法,这个静态方法用于根据当前棋面生产出LibertyTrakcer:

 @staticmethod
    def newTrackerFromBaseBoard(board=gf.Board.getStaticBaseBoard()):
        """
        :param board 默认为基础棋盘。
        从基础棋盘上创建自由度追踪器
        :return: LibertyTracker
        """
        baseBoard = np.copy(board)
        curGroupId = 0
        libTracker = LibertyTracker()
        for color in (WHITE, BLACK):
            while color in baseBoard:
                curGroupId += 1
                foundColor = np.where(baseBoard == color)
                # point的值为第一个点
                point = foundColor[0][0], foundColor[1][0]
                chain, reached = findReached(point=point, baseBoard=baseBoard)
                # 相邻且为EMPTY的点的集合
                liberties = set(r for r in reached if baseBoard[r] == EMPTY)
                newGroup = Group(curGroupId, chain, liberties, color)
                libTracker.groups[curGroupId] = newGroup
                for c in chain:
                    libTracker.groupIndexMap[c] = curGroupId
                #在另一张图上标注这里已经有棋子了
                placeStones(baseBoard, FILL, chain)
        libTracker.maxGroupId = curGroupId

        libertyCounts = np.zeros([SIZE, SIZE], dtype=np.uint8)
        for group in libTracker.groups.values():
            # 一个群的自由度
            libNum = len(group.liberties)
            for s in group.stones:
                libertyCounts[s] = libNum
        libTracker.libertyCacheMap = libertyCounts

        return libTracker

该方法会遍历棋盘上的棋子,用findReached方法:

def findReached(point, baseBoard=gf.Board.baseBoard):
    """
    深搜
     返回当前点相同颜色(WHITE,BLACK,EMPTY)所连成的链以及相邻不同颜色的集合(WHITE,BLACK,EMPTY)
    :param baseBoard:基础棋盘(二维数组)
    :param point:当前点(元组对象)
    :return: sameColorChain: 相同颜色连成的一片点的集合 diffColorReached: 相邻不同颜色的点的集合
    """
    if isinstance(point, gf.Point):
        point = point.toTuple()
    color = baseBoard[point]
    sameColorChain = set([point])
    diffColorReached = set()
    frontier = [point]
    while frontier:
        cur = frontier.pop()
        sameColorChain.add(cur)
        for p in NEIGHBORS[cur]:
            if baseBoard[p] == color and not p in sameColorChain:
                frontier.append(p)
            elif baseBoard[p] != color:
                diffColorReached.add(p)
    return sameColorChain, diffColorReached

findReached方法用深搜的方法得到一个群的集合,以及群周围一圈位置的集合。
LibertyTrakcer的构造函数:

 def __init__(self, groupIndexMap=None, groups=None, librtyCacheMap=None, maxGroupId=1):
        """
        一个"自由度追踪器"类,
        :param groupIndexMap: 一个棋盘(群的索引, 二维数组),上面用不同的数字(ID)标明不同的群 例如
                                1 1 1 1
                                1 2 2 1
                                1 2 1 1
        :param groups: 一个字典, 根据群的ID返回群
        :param librtyCacheMap: 记录每个群的自由度(周围相邻且为EMPTY的点的数量, 二维数组)
        :param maxGroupId: 记录ID最大的群的ID
        """
        self.groupIndexMap = groupIndexMap if groupIndexMap is not None else -np.ones([SIZE, SIZE], dtype=np.int16)
        self.groups = groups or {}
        self.libertyCacheMap = librtyCacheMap if librtyCacheMap is not None else np.zeros([SIZE, SIZE], dtype=np.uint8)
        self.maxGroupId = maxGroupId
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值