如何以新的方式解决八个黑手党的问题?

时间:2019-01-06 15:54:30

标签: python-3.x

我需要编写一个程序来解决八皇后的著名国际象棋问题。有关问题的描述,请参见https://en.wikipedia.org/wiki/Eight_queens_puzzle

问题有很多解决方案,因此为了给用户选择的选项,程序将从一开始就加载一个hetman的位置。然后,他将安排剩下的7个数字,以使它们不会互相攻击。

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

入口 该程序从标准输入中读取一个hetman的代数符号的位置。

退出 程序将八个hetman的位置列表或有关缺少解决方案的消息输出到标准输出。

示例 输入女王之一的位置: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)

1 个答案:

答案 0 :(得分:0)

您的功能应该真正分成几个较小的功能。首先,将缩进级别更改为四个空格,并将playField重命名为play_field以符合PEP-8,并删除一些空行。我还将修复play_field的论点;它们应该是boardn,而不是selfarea。 (按照惯例,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以接受xy作为参数,而不自己检查areaxy

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