跳至正文
View Categories

1 min read

python开发五子棋6 #

  1. AI类的开发1
  2. AI类的开发2

收获 #

了解五子棋人机交战背后的python原理和机器判断的算法逻辑

AI类的开发1 #

本小节为AI类开发的方法设计,包括获取对手棋子落点,AI棋子落点

class AI:
    def __init__(self, line_points, chessman):
        self._line_points = line_points
        self._my = chessman
        self._opponent = BLACK_CHESSMAN if chessman == WHITE_CHESSMAN else WHITE_CHESSMAN
        self._checkerboard = [[0] * line_points for _ in range(line_points)]

    def get_opponent_drop(self, point):
        self._checkerboard[point.Y][point.X] = self._opponent.Value

    def AI_drop(self):
        point = None
        score = 0
        for i in range(self._line_points):
            for j in range(self._line_points):
                if self._checkerboard[j][i] == 0:
                    _score = self._get_point_score(Point(i, j))
                    if _score > score:
                        score = _score
                        point = Point(i, j)
                    elif _score == score and _score > 0:
                        r = random.randint(0, 100)
                        if r % 2 == 0:
                            point = Point(i, j)
        self._checkerboard[point.Y][point.X] = self._my.Value
        return point

AI类的开发2 #

本小节为AI类开发的方法设计中,判断比赛双方在各自同一方向上的得分的算法开发.算法核心思想:先设定偏移量offset分别为(1, 0), (0, 1), (1, 1), (1,
-1). 便于统计横竖撇捺四个方向上的棋子权重值。再根据每个方向上是否有棋子、棋子的种类和个数、棋子之间的空格数分别设定不同的权重值。根据权重值可以实现
机器与人对战的效果.

#################################在AI类下, AI_drop()函数后,添加以下新的功能函数##############################
def _get_point_score(self, point):
    score = 0
    for os in offset:
        score += self._get_direction_score(point, os[0], os[1])
    return score

def _get_direction_score(self, point, x_offset, y_offset):
    count = 0   # 落子处我方连续子数
    _count = 0  # 落子处对方连续子数
    space = None   # 我方连续子中有无空格
    _space = None  # 对方连续子中有无空格
    both = 0    # 我方连续子两端有无阻挡
    _both = 0   # 对方连续子两端有无阻挡

    # 如果是 1 表示是边上是我方子,2 表示敌方子
    flag = self._get_stone_color(point, x_offset, y_offset, True)
    if flag != 0: # 传入的偏移方向上若存在棋子
        for step in range(1, 6): # 循环判断该方向连着几个棋子
            x = point.X + step * x_offset
            y = point.Y + step * y_offset
            # 若加上偏移量后仍在棋盘内
            if 0 <= x < self._line_points and 0 <= y < self._line_points:
                if flag == 1: # 若该偏移方向两格内有我方棋子
                    if self._checkerboard[y][x] == self._my.Value:#若该位置有我方棋子
                        count += 1 # 我方连续棋子数+1
                        if space is False: # 若已经出现过空格,且探测到我方棋子
                            space = True # 空格出现在我方连续棋子之间
                    elif self._checkerboard[y][x] == self._opponent.Value: # 若该位置是敌方棋子
                        _both += 1 # 敌方棋子受阻挡+1
                        break # 落子后我方安全,跳出循环
                    else: # 若该位置不存在棋子
                        if space is None: # 第一次检测到空格时生效
                            space = False # 表示存在空格但不在白子之间
                        else:
                            break   # 遇到第二个空格退出
                elif flag == 2: # 若该偏移方向上有敌方棋子
                    if self._checkerboard[y][x] == self._my.Value:
                        _both += 1 # 敌方受阻挡+1
                        break # 我方安全,跳出循环
                    elif self._checkerboard[y][x] == self._opponent.Value: # 该位置存在敌方棋子
                        _count += 1 # 敌方连续棋子数+1
                        if _space is False: # 若第二次出现空格
                            _space = True # 对方连续棋子内出现空格事件为
                    else:
                        if _space is None: # 若第一次出现空格
                            _space = False # 敌方连续棋子内还未出现空格
                        else:
                            break # 若在出现敌方棋子前又出现空格,我方安全,跳出循环
            else:
                #偏移后触碰到棋盘边界
                if flag == 1: # 若为己方棋子
                    both += 1 # 己方棋子被堵塞量+1
                elif flag == 2: # 若为敌方棋子
                    _both += 1 # 敌方棋子被堵塞量+1

    if space is False: # 若己方连续棋子内不存在空格
        space = None # 重置
    if _space is False: # 若对方连续棋子内不存在空格
        _space = None # 重置

    # 将设定的偏移量里的X,Y增量取反,重复上述操作
    _flag = self._get_stone_color(point, -x_offset, -y_offset, True)
    if _flag != 0:
        for step in range(1, 6):
            x = point.X - step * x_offset
            y = point.Y - step * y_offset
            if 0 <= x < self._line_points and 0 <= y < self._line_points:
                if _flag == 1:
                    if self._checkerboard[y][x] == self._my.Value:
                        count += 1
                        if space is False:
                            space = True
                    elif self._checkerboard[y][x] == self._opponent.Value:
                        _both += 1
                        break
                    else:
                        if space is None:
                            space = False
                        else:
                            break   # 遇到第二个空格退出
                elif _flag == 2:
                    if self._checkerboard[y][x] == self._my.Value:
                        _both += 1
                        break
                    elif self._checkerboard[y][x] == self._opponent.Value:
                        _count += 1
                        if _space is False:
                            _space = True
                    else:
                        if _space is None:
                            _space = False
                        else:
                            break
            else:
                # 遇到边也就是阻挡
                if _flag == 1:
                    both += 1
                elif _flag == 2:
                    _both += 1

小结 #

本节主要讲述了人机交战背后AI类的算法原理
需要掌握判断比赛双方在各自同一方向上的得分的算法原理