2017-06-28 55 views
2

我有一個國際象棋棋盤排列,看起來像這樣:在一個維數組找到一個對角線邊界

00 01 02 03 04 05 06 07 
08 09 10 11 12 13 14 15 
16 17 18 19 20 21 22 23 
24 25 26 27 28 29 30 31 
32 33 34 35 36 37 38 39 
40 41 42 43 44 45 46 47 
48 49 50 51 52 53 54 55 
56 57 58 59 60 61 62 63 

現在我試圖找到的position功能,在黑板上的數字,給出我是上/右對角線上倒數第二個數字,例如爲60,我試圖找到38,30,我試圖找到22.我可以硬編碼該死的東西,但它真的更好找到一個功能,這樣做。到目前爲止,它困擾着我。

我沒有遇到下/右和對角線以及上/左對角線的問題,但是這個問題困擾着我。任何幫助表示讚賞。

下面如下,我對工作的代碼:

# EightQueens.py 
# Joshua Marshall Moore 
# [email protected] 
# June 24th, 2017 

# The eight queens problem consists of setting up eight queens on a chess board 
# so that no two queens threaten each other. 

# This is an attempt to find all possible solutions to the problem. 

# The board is represented as a set of 64 numbers each representing a position 
# on the board. Array indexing begins with zero. 

# 00 01 02 03 04 05 06 07 
# 08 09 10 11 12 13 14 15 
# 16 17 18 19 20 21 22 23 
# 24 25 26 27 28 29 30 31 
# 32 33 34 35 36 37 38 39 
# 40 41 42 43 44 45 46 47 
# 48 49 50 51 52 53 54 55 
# 56 57 58 59 60 61 62 63 

# Test: 
# The following combination should yield a True from the check function. 

# 6, 9, 21, 26, 32, 43, 55, 60 

from itertools import combinations 
import pdb 

# works 
def down_right_boundary(pos): 
    boundary = (8-pos%8)*8 
    applies = (pos%8)+1 > int(pos/8) 
    if applies: 
     return boundary 
    else: 
     return 64 

# works 
def up_left_boundary(pos): 
    boundary = ((int(pos/8)-(pos%8))*8)-1 
    applies = (pos%8) <= int(pos/8) 
    if applies: 
     return boundary 
    else: 
     return -1 

def up_right_boundary(pos): 
    boundary = [7, 15, 23, 31, 39, 47, 55, 62][pos%8]-1 
    # 7: nil 
    # 14: 7-1 
    # 15: 15-1 
    # 21: 7-1 
    # 22: 15-1 
    # 23: 23-1 
    # 28: 7-1 
    # 29: 15-1 
    # 30: 23-1 
    # 31: 31-1 
    # 35: 7-1 
    # 36: 15-1 
    # 37: 23-1 
    # 38: 31-1 
    # 39: 39-1 
    # 42: 7-1 
    # 43: 15-1 
    # 44: 23-1 
    # 45: 31-1 
    # 46: 39-1 

    applies = pos%8>=pos%7 
    if applies: 
     return boundary 
    else: 
     return -1 

def down_left_boundary(pos): 
    boundary = 64 
    applies = True 
    if applies: 
     return boundary 
    else: 
     return 64 

def check(positions): 

    fields = set(range(64)) 
    threatened = set() 

    # two queens per quadrant 
    quadrants = [ 
     set([p for p in range(0, 28) if (p%8)<4]), 
     set([p for p in range(4, 32) if (p%8)>3]), 
     set([p for p in range(32, 59) if (p%8)<4]), 
     set([p for p in range(36, 64) if (p%8)>3]) 
    ] 

    #for q in quadrants: 
    # if len(positions.intersection(q)) != 2: 
    #  return False 

    # check the queen's ranges 
    for pos in positions: 

     pdb.set_trace() 

     # threatened |= set(range(pos, -1, -8)[1:]) # up 
     # threatened |= set(range(pos, 64, 8)[1:]) # down 
     # threatened |= set(range(pos, int(pos/8)*8-1, -1)[1:]) # left 
     # threatened |= set(range(pos, (int(pos/8)+1)*8, 1)[1:]) # right 

     # down right diagonal: 
     # There are two conditions here, one, the position is above the 
     # diagonal, two, the position is below the diagonal. 
     # Above the diagonal can be expressed as pos%8>int(pos/8). 
     # In the event of a position above the diagonal, I need to limit the 
     # range to 64-(pos%8) to prevent warping the board into a field that 
     # connects diagonals like Risk. 
     # Otherwise, 64 suffices as the ending condition. 
     threatened |= set(range(pos, down_right_boundary(pos), 9)[1:]) # down right 

     print(pos, threatened) 
     pdb.set_trace() 
     # 

     # up left diagonal: 
     # Similarly, if the position is above the diagonal, -1 will suffice as 
     # the range's ending condition. Things are more complicated if the 
     # position is below the diagonal, as I must prevent warping, again. 
     threatened |= set(range(pos, up_left_boundary(pos), -9)[1:]) # up left 

     print(pos, threatened) 
     pdb.set_trace() 
     # 

     # up right diagonal: 
     # Above the diagonal takes on a different meaning here, seeing how I'm 
     # dealing with the other diagonal. It is defined by pos58>pos%7. Now I 
     # restrict the range to a (pos%8)*8, creating a boundary along the right 
     # side of the board. 
     threatened |= set(range(pos, up_right_boundary(pos), -7)[1:]) # up right 

     print(pos, threatened) 
     pdb.set_trace() 
     # 

     # down left diagonal: 
     # I reuse a similar definition to that of the diagonal as above. The 
     # bound for left hand side of the board looks as follows: 
     # ((pos%8)*7)+(pos%8) 
     threatened |= set(range(pos, down_left_boundary(pos), 7)[1:]) # down left 

     print(pos, threatened) 
     pdb.set_trace() 
     # 

    if len(positions.intersection(threatened)) > 0: 
     return False 

    return True 


if __name__ == '__main__': 

    # print(check(set([55]))) # pass 
    # print(check(set([62]))) # pass 
    # print(check(set([63]))) # pass 
    # print(check(set([48]))) # pass 
    # print(check(set([57]))) # pass 
    # print(check(set([56]))) # pass 
    # print(check(set([8]))) # pass 

    # print(check(set([1]))) # fail 
    # print(check(set([0]))) 
    # print(check(set([6]))) 
    # print(check(set([15]))) 
    # print(check(set([7]))) 

    # print(check(set([6]))) 
    # print(check(set([9]))) 
    print(check(set([21]))) 
    print(check(set([26]))) 
    print(check(set([32]))) 
    print(check(set([43]))) 
    print(check(set([55]))) 
    print(check(set([60]))) 





    print(
     check(set([6, 9, 21, 26, 32, 43, 55, 60])) 
    ) 

    # for potential_solution in combinations(range(64), 8): 
     # is_solution = check(set(potential_solution)) 
     # if is_solution: 
      # print(is_solution, potential_solution) 
+1

你可以請出示一些代碼嗎?目前尚不清楚你嘗試過什麼,以及你所困擾的是什麼。我也不確定我是否理解所需功能的輸入和輸出。 60與38不在同一條對角線上。 – 4castle

+0

60與38不是同一條對角線。我正在尋找對角線上最後一項之前的數字。 –

+0

它將用於範圍函數,因此是對角線之前的函數。 –

回答

1

使用下面的棋盤上的位置:

chessboard = [0,1,2,3,4,5,6,7, 
       8,9,10,11,12,13,14,15, 
       16,17,18,19,20,21,22,23, 
       24,25,26,27,28,29,30,31, 
       32,33,34,35,36,37,38,39, 
       40,41,42,43,44,45,46,47, 
       48,49,50,51,52,53,54,55, 
       56,57,58,59,60,61,62,63] 

我寫了對應於你想要什麼功能(註釋描述代碼):

def return_diagonal(position): # with position being chessboard position 

    while ((position+1)%8) != 0: # while (chess position)+1 is not divisible by eight: 
      position -= 7   # move diagonally upwards (7 chess spaces back) 

    position -= 1     # when reached the right end of the chessboard, move back one position 

    if position < 6:    # if position happens to be in the negative: 
     position = 6    # set position by default to 6 (smallest possible value) 

    return position    # return the position 

函數首先詢問位置是否在最後一列。

如果沒有,請返回7個空格,這是向右斜上。

它再次檢查,直到它到達最後一列。

在那裏,它返回一個空格,以便它從棋盤右端的左側開始一個空格。

但是,如果這個數字是負數(因爲它是左上角的許多數字),這意味着對角線完全延伸到8x8棋盤之外。

所以,在默認情況下,答案應該是6

我做了幾個測試

print(60,return_diagonal(60)) 
print(30,return_diagonal(30)) 
print(14,return_diagonal(14)) 
print(1,return_diagonal(1)) 

用下面的輸出:

原來的位置,第二到上/右對角線上的最後一個數字

60 38 
30 22 
14 6 
1 6 
+0

@JoshuaMoore我認爲我找到了一個可行的解決方案。如果有任何要澄清的事情,請隨時回覆此評論。謝謝! – Larry

+1

感謝您的回答。這很簡單,我可以踢自己。我想我希望能夠解決這個問題的「pythonic」,但你的方式很好,謝謝! –