皇后谜题Python

皇后谜题(Queen Puzzle)一般指的是将八个皇后放在象棋盘上,使得互相不能吃掉对方(即任意两个皇后不在同一横线、竖线、斜线上)。

标准国际象棋盘是8X8的黑白格子,我们可以把问题扩展到任意长度的正方形盘上,由此编写一个类。

class QueenPuzzle:
    def __init__(self, board_size):
        self.board_size = board_size
        self.nb_of_solutions = 0
        self.nb_of_tested_permutations = 0
        self._solutions = []
        self._solve_puzzle()

    def solution(self, k):
        k -= 1
        cells = {0: '\N{White Large Square}', 1: '\N{Black Large Square}'}
        queens = {0: '\N{Large Red Circle}', 1: '\N{Large Blue Circle}'}
        for i in range(self.board_size):
            for j in range(self.board_size):
                black_or_white = (i + j) % 2
                if j == self._solutions[k][i]:
                    print(queens[black_or_white], end='')
                else:
                    print(cells[black_or_white], end='')
            print()

    def _solve_puzzle(self):
        self._L = list(range(self.board_size))
        for is_solution in self._heap_permute(self.board_size):
            self.nb_of_tested_permutations += 1
            if is_solution:
                self.nb_of_solutions += 1
                self._solutions.append(list(self._L))

    def _heap_permute(self, length):
        if length == 1:
            yield not self._attacks_queen_below()
        else:
            length -= 1
            for i in range(length):
                yield from self._heap_permute_below(length)
                if length % 2:
                    self._L[i], self._L[length] = self._L[length], self._L[i]
                else:
                    self._L[0], self._L[length] = self._L[length], self._L[0]
            yield from self._heap_permute_below(length)

    def _heap_permute_below(self, length):
        for is_solution in self._heap_permute(length):
            if self._attacks_queen_below(length):
                yield False
                if length > 1:
                    self._skip_permutations(length)
                break
            yield is_solution

    def _skip_permutations(self, skip_size):
        if skip_size % 2 or skip_size == 2:
            self._L[0], self._L[skip_size - 1] =\
                   self._L[skip_size - 1], self._L[0]
        elif skip_size == 4:
            self._L[: 3], self._L[3] = self._L[1 : 4], self._L[0]
        else:
            self._L[: 2], self._L[2 : skip_size - 2],\
             self._L[skip_size - 2], self._L[skip_size - 1] =\
                    self._L[skip_size - 3 : skip_size - 1],\
                     self._L[1 : skip_size - 3],\
                      self._L[skip_size - 1], self._L[0]

    def _attacks_queen_below(self, n=0):
        return any(abs(self._L[i] - self._L[n]) == i - n
                       for i in range(n + 1, self.board_size)
                  )

例如运行:

Solution_8=QueenPuzzle(8)

Solution_8._solutions

则会返回所有满足要求的解答

列表中的第n个数字表示的是第n+1行的皇后应站在哪一列

Solution_8.solution(k)则会返回第k个解答的图样

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值