首页 > 解决方案 > 如何以新的方式解决八盖特曼问题?

问题描述

我需要编写一个程序来解决著名的八皇后国际象棋问题。可以在https://en.wikipedia.org/wiki/Eight_queens_puzzle找到问题的描述

这个问题有很多解决方案,所以为了让用户有选择的余地,程序一开始会加载其中一个指挥官的位置。然后他会安排剩下的七个人,让他们不会互相攻击。

某些输入可能没有解决方案,因此程序必须为此做好准备。该程序还必须处理不正确的输入。

入口 程序从标准输入中读取代数记法中的指挥官之一的位置。

退出 程序将八名指挥官的位置列表或关于缺乏解决方案的消息输出到标准输出。

示例 输入其中一个皇后的位置:a2 a2 b4 c6 d8 e3 f1 g7 h5

我在这里堆叠:(对角线效果不好,没有完成由“0”发生,我不知道如何将数字交换为字母以继续以某种方式工作)

n = 8
board = [[0] * n for row in range(n)]


def playField(self, area):
  area = input('Give position of hetman: ').upper()
  x = area[0]
  y = area[1]
  print(area[0].isdigit())
  if x.isdigit() or y.isdigit():
    if int(x)>n or int(x)<1 or int(y)>n or int(y)<1:
      print("Wrong position, give new one: ")
      playField(board, area)
    else:
      print(area[0],area[1])
      for row in range(n):
        for column in range(n):
          board[row][column] = 1  #complete board "1"
          board[int(x)-1][int(y)-1] = 69 #taken place complete "69" for now, later it will be "0" 
          if board[row][int(y)-1]==69:  #check taken row
            print("tag",board[row],board[int(y)-1])
            board[row][int(y)-1]=0 #complete taken row "0"
            print("taken row")
          if board[int(x)-1][column]==69: #check taken column
            board[int(x)-1][column]=0  #complete taken column "0"
            print("taken column")
          else:
            print('free')

      print("row,column: ", row,column)
      print("x,y: ", x,y)

      for row in range(n):
        for column in range(n):
          przX = abs(row - int(x))
          przY = abs(column - int(y))
          if (przX == przY):  #check taken diagonal

            print("diagonal:", row+1, column+1)


      print(board)

      for row in range(n):
        for column in range(n):
          if(board[row][column]==1): #if in place is "1" it means it is result
            print("results: ",row,column)


  else:
    print("wrong")
    playField(board, area)




playField(board, n)

我尝试实现此代码,但仍然无法正常工作:

n = 8
board = [[0] * n for row in range(n)]

def play_field(board, n, x, y):
    print(x, y)

    answers = solve(n,x,y)
    first_answer = next(answers)

    print(list(enumerate(first_answer, start=1)))

def get_position(n):
    """Prompt a user for a string resembling F2 and return coordinate pair.

    Fails for values above 9 / I."""  # docstring; explains what the function
                                      # does and its limitations. Optional.
    while True:
        position = input('Give position of hetman: ').upper()
        if len(position) != 2:
            print("Position must be 2 characters long.")
            continue  # restart the while True: loop
        x_str, y_str = position
        try:  # attempt to run the following code
            x = "ABCDEFGHI".index(x_str)  # outputs the location in the string
                                          # where the value of x_str can be found
                                          # (starts counting at 0)
        except ValueError:  # if x_str wasn't in "ABCDEFGHI"
            print("The first character must be a letter.")
            continue
        try:
            y = int(y_str) - 1  # Python starts counting at 0, so we need to
                                # make sure 1 becomes 0, 2 becomes 1 etc.
        except ValueError:  # if y_str couldn't be converted to an int
            print("The second character must be a number.")
            continue
        if not (0 <= x < n and 0 <= y < n):
            print("Values out of range.")
            continue
        return x, y  # return x and y, exiting the loop

def under_attack(col, queens):
        return col in queens or \
               any(abs(col - x) == len(queens)-i for i,x in enumerate(queens))

def solve(n,x,y):
        solutions = [[x,y]]
        for row in range(n):
            solutions = (solution+[i+1]
                           for solution in solutions 

                           for i in range(n)
                           if not under_attack(i+1, solution))
        return solutions



x, y = get_position(n)
play_field(board, n, x, y)

标签: python-3.x

解决方案


你的函数真的应该分成几个更小的函数。让我们首先将缩进级别更改为四个空格并重命名playFieldplay_field符合PEP-8,并删除一些空行。我也会修正play_field's 的论点;它们应该是boardand n,而不是selfand area。(按照惯例,self应该只用于一个类的方法;你这里没有一个类。忽略你现在得到的任何例子。)

n = 8
board = [[0] * n for row in range(n)]

def play_field(board, n):
    area = input('Give position of hetman: ').upper()
    x = area[0]
    y = area[1]
    print(area[0].isdigit())
    if x.isdigit() or y.isdigit():
        if int(x)>n or int(x)<1 or int(y)>n or int(y)<1:
            print("Wrong position, give new one: ")
            playField(board, area)
        else:
            print(area[0],area[1])
            for row in range(n):
                for column in range(n):
                    board[row][column] = 1
                    board[int(x)-1][int(y)-1] = 69
                    if board[row][int(y)-1]==69:
                        print("tag",board[row],board[int(y)-1])
                        board[row][int(y)-1]=0
                        print("taken row")
                    if board[int(x)-1][column]==69:
                        board[int(x)-1][column]=0
                        print("taken column")
                    else:
                        print('free')

            print("row,column: ", row,column)
            print("x,y: ", x,y)

            for row in range(n):
                for column in range(n):
                    przX = abs(row - int(x))
                    przY = abs(column - int(y))
                    if (przX == przY):
                        print("slant :", row+1, column+1)

            print(board)

            for row in range(n):
                for column in range(n):
                    if(board[row][column]==0):
                        print("results: ",row,column)


    else:
        print("wrong")
        playField(board, area)

play_field(board, n)

现在,要做的第一件事是将“接受输入”代码移到另一个函数中:

def get_position():
    area = input('Give position of hetman: ').upper()
    x, y = area  # pretty much the same as x = area[0]; y = area[1]
    print(x.isdigit())

我将在这里停下来,因为这是您的程序目前无法做到的事情。相反,我将重写这个函数:

def get_position(n):
    """Prompt a user for a string resembling F2 and return coordinate pair.

    Fails for values above 9 / I."""  # docstring; explains what the function
                                      # does and its limitations. Optional.
    while True:
        position = input('Give position of hetman: ').upper()
        if len(position) != 2:
            print("Position must be 2 characters long.")
            continue  # restart the while True: loop
        x_str, y_str = position
        try:  # attempt to run the following code
            x = "ABCDEFGHI".index(x_str)  # outputs the location in the string
                                          # where the value of x_str can be found
                                          # (starts counting at 0)
        except ValueError:  # if x_str wasn't in "ABCDEFGHI"
            print("The first character must be a letter.")
            continue
        try:
            y = int(y_str) - 1  # Python starts counting at 0, so we need to
                                # make sure 1 becomes 0, 2 becomes 1 etc.
        except ValueError:  # if y_str couldn't be converted to an int
            print("The second character must be a number.")
            continue
        if not (0 <= x < n and 0 <= y < n):
            print("Values out of range.")
            continue
        return x, y  # return x and y, exiting the loop

现在我们修改play_field为接受xandy作为参数,并且不检查areaor xory本身:

n = 8
board = [[0] * n for row in range(n)]

def play_field(board, n, x, y):
    print(x, y)
    for row in range(n):
        for column in range(n):
            board[row][column] = 1
            board[x][y] = 69
            if board[row][y]==69:
                print("tag",board[row],board[y])
                board[row][y]=0
                print("taken row")
            if board[x][column]==69:
                board[x][column]=0
                print("taken column")
            else:
                print('free')

    print("row,column: ", row,column)
    print("x,y: ", x+1,y+1)

    for row in range(n):
        for column in range(n):
            przX = abs(row - x)
            przY = abs(column - y)
            if (przX == przY):
                print("slant :", row+1, column+1)

    print(board)

    for row in range(n):
        for column in range(n):
            if(board[row][column]==0):
                print("results: ",row,column)

def get_position(n):
    """Prompt a user for a string resembling F2 and return coordinate pair.

    Fails for values above 9 / I."""  # docstring; explains what the function
                                      # does and its limitations. Optional.
    while True:
        position = input('Give position of hetman: ').upper()
        if len(position) != 2:
            print("Position must be 2 characters long.")
            continue  # restart the while True: loop
        x_str, y_str = position
        try:  # attempt to run the following code
            x = "ABCDEFGHI".index(x_str)  # outputs the location in the string
                                          # where the value of x_str can be found
                                          # (starts counting at 0)
        except ValueError:  # if x_str wasn't in "ABCDEFGHI"
            print("The first character must be a letter.")
            continue
        try:
            y = int(y_str) - 1  # Python starts counting at 0, so we need to
                                # make sure 1 becomes 0, 2 becomes 1 etc.
        except ValueError:  # if y_str couldn't be converted to an int
            print("The second character must be a number.")
            continue
        if not (0 <= x < n and 0 <= y < n):
            print("Values out of range.")
            continue
        return x, y  # return x and y, exiting the loop

x, y = get_position(n)
play_field(board, n, x, y)

未完待续...


继续...

用这个替换你的solve函数来解决(双关语幸运事故)问题:

def solve(n,x,y):
    solutions = []
    for row in range(n):
        solutions = (solution+[x if row==y else i+1]
                       for solution in solutions 

                       for i in range(n)
                       if not under_attack(i+1, solution))
    return solutions

这里的神奇之处在于[x if row==y else i+1],它迫使排成一排的皇后y等于x


推荐阅读