python八皇后问题92种解决方案动态演示

python八皇后问题92种解决方案动态演示

python八皇后问题92种解决方案动态演示
python八皇后问题92种解决方案动态演示

python八皇后问题92种解决方案动态演示

"""
   八皇后问题动态演示_图章版。本程序演示了八皇后问题的92种解决方案。

"""
from sprites import *

width,height = 400,400
screen = Screen()
screen.title('python八皇后问题92种解决方案动态演示by李兴球')

ft = ('黑体',18,'bold')
ft2 = ('新宋体',12,'normal')
tom = Sprite(visible=False)          # 负责画格子与显示标题信息的
tom.color('magenta')
tom.addy(250)
tom.write("八皇后问题动态演示",align='center',font=ft)
tom.addy(-30)
tom.color('blue')
tom.write("本程序由Python精灵模块开发",align='center',font=ft2)
tom.home()
cors = tom.draw_grid2(8,8,50,50)     # 画8x8,长宽为50的格子图
tom.shape('res/black.png')
# 下面是画黑白相间的格子
c = 0
for rows in cors:
    index = c % 2
    for xy in rows:
        tom.goto(xy)
        if index % 2 == 0 :tom.stamp()
        index += 1
    c = c + 1
jack = Sprite('res/queen.png')

rose = Sprite(visible=False)         # 负责显示一种输出结果的
rose.sety(-250)
rose.font = ('楷体',24,'bold')
rose.color('red')

def have_conflict(x,y):
    """ 检测同列,斜线上有没有值为1的"""
    for r in range(x):   # 同列,不超过第x行,因为下面的没必要检测         
        if grids[r][y] == 1 :return True
    # 左上斜检测
    r = x
    c = y
    while True:
        r = r-1
        c = c-1
        if r < 0 or c < 0 :break
        if grids[r][c] == 1 : return True

    # 右上斜检测
    r = x
    c = y
    while True:
        r = r-1
        c = c+1
        if r < 0  or c > 7  :break
        if grids[r][c] == 1 : return True
    
def output():
    s = ''
    for r in grids:       # 每一行
        for c in r:       # 每行中的每个数           
            if c == 1 :
               s = s + str(r.index(c))
               print(r.index(c),end='')
    print()
    rose.clear()
    info = f'第{counter+1}种解决方案:{s}'
    rose.write(info,align='center',font=rose.font)    
        
        
grids = [[0 for i in range(8)],
         [0 for i in range(8)],
         [0 for i in range(8)],
         [0 for i in range(8)],
         [0 for i in range(8)],
         [0 for i in range(8)],
         [0 for i in range(8)],
         [0 for i in range(8)]]
x = 0                             # x表示行
y = 0                             # y表示列
counter = 0
# 键是(x,y),值是图章编号的字典
stampdict = {}                      # 保存对应坐标图章编号的字典
cleardelay = 0.005                  # 清除等待时间
setdelay = 0.005                    # 放置皇后,等待时间
resultdelay = 5                     # 找到一种结果后的等待时间
while True: 
    while y < 8:                  # 每一列都不行,则回溯到上一行
        
        if have_conflict(x,y):    # 有冲突则下一列
            y = y + 1
        else:
            grids[x][y] = 1       # 否则这里放1,表示放皇后            
            jack.goto(cors[x][y])
            stampdict[(x,y)] = jack.stamp() # 保存图章编号
            jack.wait(setdelay)
            if x == 7 :           # 说明有了一个解了
                print('结果',end='')
                output()           # 输出这种结果
                
                jack.wait(resultdelay)
                counter += 1       # 计下数
                grids[x][y] = 0    # 清掉以便尝试下一列
                jack.goto(cors[x][y])
                jack.clearstamp(stampdict[(x,y)]) # 清除这个图章编号
                jack.wait(cleardelay)
                
                y = y + 1          # 尝试下一列,向右移尝试
            else:
                x = x + 1          # 下一行
                y = 0              #  从0列开始
            
    # 如果所有的y位置都不行,回到上一行
    x = x - 1
    if x == -1 :break
    # 寻找上一行的y
    for i in range(8):
        if grids[x][i] == 1:
            grids[x][i] = 0     # 清除这种
            jack.goto(cors[x][i])
            jack.clearstamp(stampdict[(x,i)])
            jack.wait(cleardelay)
            y = i + 1           # 如果刚好又是8会继续回到上一行
            break
    
        

李兴球

李兴球的博客是Python创意编程原创博客

评论已关闭。