Py学习  »  Python

Python中的8皇后解决方案

Matt • 4 年前 • 801 次点击  

很久以前,我在网上找到了下面的C代码,并尝试用Python实现这个解决方案。当我编译C代码时,我得到了预期的结果;当我运行Python脚本时,我没有收到任何输出。下面是C代码以及我将其转换为Python的过程。我应该注意到,我做这个小项目是为了学习Python语法。从我无力的调试尝试中可以看出,问题在于我实现了diagonalsOK()函数。任何建议都将不胜感激!

#include <stdio.h>

/* SOLUTION TO EIGHT QUEENS PROBLEM
Author: Eilon Lipton
Date: 1/26/2000
http://www.yoe.org/progchan/start.shtml

All code is copyright (C) Eilon Lipton, 2000
You may use it for educational purposes but please give me credit
if you show the solution to others.
*/

/* Since this program outputs many lines, you should probably redirect its
output to a file like so:
eightq > solution.txt
and then open the file solution.txt in any text editor to see the
results */

/* This function resets the board to an empty board */
void clearboard(int board[8][8])
{
   int i, j;

for (i = 0; i < 8; i++)
  for (j = 0; j < 8; j++)
     board[i][j] = 0;
}


/* This function prints out the board to the screen using a simple diagram 
*/
void printsolution(int board[8][8])
{
   int i, j;

   for (i = 0; i < 8; i++)
   {
      for (j = 0; j < 8; j++)
      {
         if (board[i][j] == 0)
         {
            printf("*");
         }
         else
         {
            printf("Q");
         }
      }

      printf("\n");
   }

   printf("\n");
}


/* Counts how many queens are in a certain row */
int rowOK(int row, int board[8][8])
{
   int i, counter;

   counter = 0;

   for (i = 0; i < 8; i++)
   {
      counter = counter + board[row][i];
   }

       return counter;
    }


/* Counts how many queens are in the two diagonals crossing a certain place 
*/
int diagonalsOK(int row, int column, int board[8][8]){
int i, counter;

counter = 0;

/* This function is a bit tricky:
  We try every diagonal extending no more than 8 spaces in each of the four 
directions
  (down/left, down/right, up/left, and up/right */
for (i = 1; i < 8; i++) {
  if ((row - i) >= 0) {
     if ((column - i) >= 0) {
        counter = counter + board[row - i][column - i];
     }

     if ((column + i) < 8) 
     {
        /* down/right */
        counter = counter + board[row - i][column + i];
     }
  }

  if ((row + i) < 8)   /* check that row is not out of bounds */
  {
     if ((column - i) >= 0)  /* check that column is not out of bounds */
     {
        /* up/left */
        counter = counter + board[row + i][column - i];
     }

     if ((column + i) < 8)  /* check that column is not out of bounds */
     {
        /* up/right*/
        counter = counter + board[row + i][column + i];
     }
  }
}

return counter;
  }


/* This is the most important function, it is described on the web page */
void addqueen(int column, int board[8][8])
{
   int row;

   for (row = 0; row < 8; row++)
   {
      board[row][column] = 1;

      if ((rowOK(row, board) == 1) &&
      (diagonalsOK(row, column, board) == 0))
      {
         if (column == 7)
         {
            printsolution(board);
         }
         else
         {
            addqueen(column + 1, board);
         }
      }

      board[row][column] = 0;
   }
}


/* Main function */
int main()
{
   int board[8][8];

   printf("Meow?\n");
   clearboard(board);
   addqueen(0, board);

   return 0;
}

Python转换尝试:

board = [[0, 0, 0, 0, 0, 0, 0, 0],
        [0, 1, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0],
        [1, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0]]

def clearBoard(board):
    for i in range(8):
        for j in range(8):
            board[i][j] = 0

def printBoard(board):
    for i in range(8):
       for j in range(8):
           if board[i][j] == 1:
               print("Q", end="")
           else:
               print("X", end="")
       print("")
    print("")

def rowOK(row, board):
    counter = 0

    for i in range(8):
        counter += board[row][i]
    return counter

def diagsOK(row, col, board):

    counter = 0

    for i in range(8):
        if (row - i) >= 0:
            if (col - i) >= 0:
                counter = counter + board[row - i][col - i]
            if (col + i) < 7:
                counter = counter + board[row - i][col + i]
        if (row + i) < 8:
            if (col - i) >= 0:
                counter = counter + board[row + i][col - i]
            if (col + i) < 8:
                counter = counter + board[row + i][col + i]
    return counter

def addQueen(col, board):
    for row in range(8):
        board[row][col] = 1
        if rowOK(row, board) == 1 & diagsOK(row, col, board) == 0:
        #print("Adding first queen...")
            if col == 7:
                printBoard(board)
            else:
                addQueen(col + 1, board)
        board[row][col] = 0


clearBoard(board)
addQueen(0, board)
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/49475
 
801 次点击  
文章 [ 3 ]  |  最新文章 4 年前
Matt
Reply   •   1 楼
Matt    5 年前

谢谢大家的意见。我发现问题出在我的diagsOK()函数的实现上。我仍然不确定这个函数哪里出错了,但是我在如何正确地编写这个函数上做了一些思考,并提出了下面的解决方案。这个问题肯定有一个更简单、更优雅的解决方案,但我想用我知道的方法来解决它。我已经测试了下面的解决方案,它是有效的。我很高兴:-)

# Matt Lozier's 8 Queens Solution in Python.
#
# Thanks to Eilon Lipton (elipton@microsoft.com) for his logic 
# in implementing the addQueen() function, which I adapted to Python
# from his C implementation.

# This 2D array (or in Python lists of lists) is one solution

board = [[0, 0, 0, 0, 0, 1, 0, 0],
         [0, 0, 0, 1, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 1, 0],
         [1, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 1],
         [0, 1, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 1, 0, 0, 0],
         [0, 0, 1, 0, 0, 0, 0, 0]]

def clearBoard(board):
    for i in range(8):
        for j in range(8):
            board[i][j] = 0

def printBoard(board):
    for i in range(8):
        for j in range(8):
            if board[i][j] == 1:
                print("Q", end="")
            else:
                print("X", end="")
        print("")
    print("")

def checkColsOK(board):
    for i in range(8):
        sum = 0
        for j in range(8):
            sum += board[j][i]
        if sum > 1:
            return 0




def checkRowsOK(board):
    for i in range(8):
        sum = 0
        for j in range (8):
            sum += board[i][j]
        if sum > 1:
            return 0


def checkDiagsOK(board):

# left to right, bottom up
    counter = 8
    sum = 0

    for i in range(8):
        x = i
        y = 0
        for j in range(counter):
            #print(board[y][x], end="")
            sum += board[y][x]
            x += 1
            y +=1
        counter -= 1

        #print("")
        #print("There are ", end="")
        #print(sum, end="")
        #print(" queens in this diagonal.")
        if sum > 1:
            return 0
        sum = 0


# right to left, top down
    counter = 8
    sum = 0

    for i in range(8):
        x = i
        y = 0
        for j in range(counter):
            #print(board[x][y], end="")
            sum += board[x][y]
            x += 1
            y +=1
        counter -= 1

        #print("")
        #print("There are ", end="")
        #print(sum, end="")
        #print(" queens in this diagonal.")

        if sum > 1:
            return 0
        sum = 0


# right to left, bottom up
    counter = 8
    sum = 0

    for i in reversed(range(8)):
        x = i
        y = 0
        for j in range(counter):
            #print(board[x][y], end="")
            sum += board[x][y]
            x -= 1
            y += 1
        counter -= 1

        #print("")
        #print("There are ", end="")
        #print(sum, end="")
        #print(" queens in this diagonal.")

        if sum > 1:
            return 0
        sum = 0

# left to right, top down
    counter = 8
    sum = 0

    for i in range(8):
        x = 7
        y = i
        for j in range(counter):
            #print(board[x][y], end="")
            sum += board[x][y]
            x -= 1
            y += 1
        counter -= 1

        #print("")
        #print("There are ", end="")
        #print(sum, end="")
        #print(" queens in this diagonal.")

        if sum > 1:
            return 0
        sum = 0

def addQueen(board, col):

    row = 0

    for row in range(8):
        board[row][col] = 1
        if (checkRowsOK(board) != 0 and checkDiagsOK(board) != 0):
            if col == 7:
                printBoard(board)
            else:
                addQueen(board, col + 1)
        board[row][col] = 0


clearBoard(board)
addQueen(board, 0)

#if checkDiagsOK(board) != 0:
#    print("Diagonals are OK!")

#if checkRowsOK(board) != 0:
#    print("Rows are OK!")

#if checkRowsOK(board) != 0:
#    print ("Cols are OK!")

#printBoard(board)

#clearBoard(board)

#printBoard(board)
Tané Tachyon
Reply   •   2 楼
Tané Tachyon    5 年前

您还需要检查列是否正常,但是如果您像这样更改addQueen:

def addQueen(col, board):
    for row in range(8):
        if rowOK(row, board) == 0 and diagsOK(row, col, board) == 0:
            board[row][col] = 1
            if col == 7:
                printBoard(board)
            else:
                addQueen(col + 1, board)
Xion
Reply   •   3 楼
Xion    5 年前

首先,在addQueen之后添加print(board)语句,并将其与注释clearBoard时进行比较,您可以看到您放入的board数组似乎清除了所有内容,并将获得0的输出。

这会让你知道发生了什么。