数据结构与算法--回溯算法:马踏棋盘算法(骑士周游)Python实现马踏棋盘算法 一步步带你用Python实现马踏棋盘算法

基本概述

  • 概念:
    在这里插入图片描述
    在这里插入图片描述
  • 算法解析:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

Python实现

未优化前
# 马踏棋盘算法

class HorseChessBoard(object):
    def __init__(self, size):
        self.X = size  # 棋盘的列数
        self.Y = size  # 棋盘的行数
        # 创建一个二维数组,用于记录每一步所走的位置
        self.chess_board = [[0 for col in range(size)] for row in range(size)]
        # 创建一个数组,标记棋盘的各个位置是否被访问过,boolean,默认都是False
        self.visited = [[False for col in range(size)] for row in range(size)]
        # 是否完成游戏标志
        self.finished = False

    def travel_chess_board(self, row: int, col: int, step: int):
        """
        :param chess_board: 传入棋盘
        :param row: 马儿当前的位置行 第几行,从0开始(x)
        :param col: 马儿当前的位置列 第几列,从0开始(y)
        :param step: 是第几步,初始位置是第1步
        :return:
        """
        self.chess_board[row][col] = step
        # 标记该位置已经访问
        self.visited[row][col] = True
        # 获取当前位置可以走的下一个位置的集合
        next_step = self.get_next(row, col)
        # 遍历 next_step
        for p in next_step:  # 取出下一个可以走的位置
            if not self.visited[p[0]][p[1]]:  # 判断该点是否已经访问过
                self.travel_chess_board(p[0], p[1], step + 1)
        # 判断马儿是否完成了任务,使用 step 和 应该走的步数比较
        # 如果没有达到数量,则表示没有完成任务,将整个棋盘置为0
        # 说明:棋盘到目前位置仍然没有走完,处于回溯状态
        if (step < self.X * self.Y) & (not self.finished):  # 如果已经无路可走但仍未结束,或者处于回溯过程中
            self.chess_board[row][col] = 0
            self.visited[row][col] = False
        else:  # 已经完成游戏
            self.finished = True

    def get_next(self, x, y):
        """
        返回当前位置的下一步所有可走位置集合
        :return: res
        """
        res = []
        # 表示走6 的位置
        if (x - 1 >= 0) & (y - 2 >= 0):
            res.append([x - 1, y - 2])
        # 表示走5 的位置
        if (x - 2 >= 0) & (y - 1 >= 0):
            res.append([x - 2, y - 1])
        # 表示走7 的位置
        if (x + 1 < self.X) & (y - 2 >= 0):
            res.append([x + 1, y - 2])
        # 表示走0 的位置
        if (x + 2 < self.X) & (y - 1 >= 0):
            res.append([x + 2, y - 1])
        # 表示走4 的位置
        if (x - 2 >= 0) & (y + 1 < self.Y):
            res.append([x - 2, y + 1])
        # 表示走3 的位置
        if (x - 1 >= 0) & (y + 2 < self.Y):
            res.append([x - 1, y + 2])
        # 表示走1 的位置
        if (x + 2 < self.X) & (y + 1 < self.Y):
            res.append([x + 2, y + 1])
        # 表示走2 的位置
        if (x + 1 < self.X) & (y + 2 < self.Y):
            res.append([x + 1, y + 2])

        return res


if __name__ == '__main__':
    game = HorseChessBoard(6)
    game.travel_chess_board(3, 2, 1)
    # 输出棋盘的最后情况
    for rows in game.chess_board:
        for steps in rows:
            print(steps, end=" ")
        print()
'''输出结果
8 3 6 29 32 21 
5 28 9 22 15 30 
2 7 4 31 20 33 
27 10 1 16 23 14 
36 17 12 25 34 19 
11 26 35 18 13 24 
'''
  • 用游戏来验证一下结果:

    在这里插入图片描述
    在这里插入图片描述
    发现完成正确哦~接下来就是进行优化!
贪心算分优化
# 马踏棋盘算法

class HorseChessBoard(object):
    def __init__(self, size):
        self.X = size  # 棋盘的列数
        self.Y = size  # 棋盘的行数
        # 创建一个二维数组,用于记录每一步所走的位置
        self.chess_board = [[0 for col in range(size)] for row in range(size)]
        # 创建一个数组,标记棋盘的各个位置是否被访问过,boolean,默认都是False
        self.visited = [[False for col in range(size)] for row in range(size)]
        # 是否完成游戏标志
        self.finished = False

    def travel_chess_board(self, row: int, col: int, step: int):
        """
        :param chess_board: 传入棋盘
        :param row: 马儿当前的位置行 第几行,从0开始(x)
        :param col: 马儿当前的位置列 第几列,从0开始(y)
        :param step: 是第几步,初始位置是第1步
        :return:
        """
        self.chess_board[row][col] = step
        # 标记该位置已经访问
        self.visited[row][col] = True
        # 获取当前位置可以走的下一个位置的集合
        next_step = self.get_next(row, col)
        # 通过贪心算法进行优化,按照下一步的所有可走位置的数量进行非递减排序(升序)
        next_step.sort(key=lambda x: len(self.get_next(x[0], x[1])))
        # 遍历 next_step
        for p in next_step:  # 取出下一个可以走的位置
            if not self.visited[p[0]][p[1]]:  # 判断该点是否已经访问过
                self.travel_chess_board(p[0], p[1], step + 1)
        # 判断马儿是否完成了任务,使用 step 和 应该走的步数比较
        # 如果没有达到数量,则表示没有完成任务,将整个棋盘置为0
        # 说明:棋盘到目前位置仍然没有走完,处于回溯状态
        if (step < self.X * self.Y) & (not self.finished):  # 如果已经无路可走但仍未结束,或者处于回溯过程中
            self.chess_board[row][col] = 0
            self.visited[row][col] = False
        else:  # 已经完成游戏
            self.finished = True

    def get_next(self, x, y):
        """
        返回当前位置的下一步所有可走位置集合
        :return: res
        """
        res = []
        # 表示走6 的位置
        if (x - 1 >= 0) & (y - 2 >= 0):
            res.append([x - 1, y - 2])
        # 表示走5 的位置
        if (x - 2 >= 0) & (y - 1 >= 0):
            res.append([x - 2, y - 1])
        # 表示走7 的位置
        if (x + 1 < self.X) & (y - 2 >= 0):
            res.append([x + 1, y - 2])
        # 表示走0 的位置
        if (x + 2 < self.X) & (y - 1 >= 0):
            res.append([x + 2, y - 1])
        # 表示走4 的位置
        if (x - 2 >= 0) & (y + 1 < self.Y):
            res.append([x - 2, y + 1])
        # 表示走3 的位置
        if (x - 1 >= 0) & (y + 2 < self.Y):
            res.append([x - 1, y + 2])
        # 表示走1 的位置
        if (x + 2 < self.X) & (y + 1 < self.Y):
            res.append([x + 2, y + 1])
        # 表示走2 的位置
        if (x + 1 < self.X) & (y + 2 < self.Y):
            res.append([x + 1, y + 2])

        return res


if __name__ == '__main__':
    game = HorseChessBoard(8)
    game.travel_chess_board(1, 2, 1)
    # 输出棋盘的最后情况
    for rows in game.chess_board:
        for steps in rows:
            print(steps, end=" ")
        print()
  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用Python实现棋盘算法可以使用Minimax算法。这个算法通过递归地搜索所有可能的棋局,并通过评估函数对每个棋局进行评分,以确定最佳落子位置。 你可以使用以下代码作为参考: ```python def minimax(board, depth, maximizing_player): if depth == 0 or game_over(board): return evaluate(board) if maximizing_player: max_eval = float('-inf') for move in get_possible_moves(board): new_board = make_move(board, move, 'X') eval = minimax(new_board, depth - 1, False) max_eval = max(max_eval, eval) return max_eval else: min_eval = float('inf') for move in get_possible_moves(board): new_board = make_move(board, move, 'O') eval = minimax(new_board, depth - 1, True) min_eval = min(min_eval, eval) return min_eval ``` 这个代码使用了递归函数minimax来搜索最佳落子位置。它有三个参数:board表示当前的棋局状态,depth表示搜索的深度,maximizing_player表示当前轮到的玩家是最大化得分的玩家还是最小化得分的玩家。 在函数内部,它首先检查递归的终止条件:如果搜索深度为0或者棋局已经结束,就返回当前棋局的评分。 然后,它根据maximizing_player的值选择最大化得分还是最小化得分。对于最大化得分的玩家,它遍历所有可能的落子位置,递归调用minimax函数,并将新的棋局状态传递给下一层的搜索。它更新max_eval为所有子节点的最大值,并最后返回max_eval。 对于最小化得分的玩家,它的逻辑与最大化得分的玩家相似,只是它更新min_eval为所有子节点的最小值,并最后返回min_eval。 你可以根据自己的需求对这段代码进行修改和扩展,例如添加评估函数、获取可能落子位置的函数等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值