Как оптимизировать код диагонального движения для шахматного движка? - PullRequest
0 голосов
/ 24 июня 2018

Я сейчас нахожусь в процессе создания своего собственного шахматного движка и мог бы действительно использовать некоторые предложения о том, как сделать этот сегмент кода для вычисления диагональных ходов более эффективным. (Это очевидно только для диагоналей, идущих вверх-вправо)

На данный момент я использую «Try-Except» для итерации по 1, а затем мой оператор return отфильтровывает любые внешние значения. Однако это кажется очень громоздким способом ведения дел.

Будем весьма благодарны за любые комментарии или советы о том, как изменить этот код.

import argparse, json

chessBoard = [[1, 1, 1, 1, 1, 1, 1, 1] for i in range(8)]

chess_map_from_alpha_to_index = {
    "a" : 0,
    "b" : 1,
    "c" : 2,
    "d" : 3,
    "e" : 4,
    "f" : 5,
    "g" : 6,
    "h" : 7
}

chess_map_from_index_to_alpha = {
    0: "a",
    1: "b",
    2: "c",
    3: "d",
    4: "e",
    5: "f",
    6: "g",
    7: "h"
}


def getBishopMoves(pos, chessBoard):
    column, row = list(pos.strip().lower())
    row = int(row) - 1
    column = chess_map_from_alpha_to_index[column]
    i,j = row, column
    solutionMoves = []

#Up-Right Diagonal
    try:
        temp = chessBoard[i + 1][j + 1]
        solutionMoves.append([i + 1, j + 1])
    except:
        pass
    try:
        temp = chessBoard[i + 2][j + 2]
        solutionMoves.append([i + 2, j + 2])
    except:
        pass
    try:
        temp = chessBoard[i + 3][j + 3]
        solutionMoves.append([i + 3, j + 3])
    except:
        pass
    try:
        temp = chessBoard[i + 4][j + 4]
        solutionMoves.append([i + 4, j + 4])
    except:
        pass
    try:
        temp = chessBoard[i + 5][j + 5]
        solutionMoves.append([i + 5, j + 5])
    except:
        pass
    try:
        temp = chessBoard[i + 6][j + 6]
        solutionMoves.append([i + 6, j + 6])
    except:
        pass
    try:
        temp = chessBoard[i + 7][j + 7]
        solutionMoves.append([i + 7, j + 7])
    except:
        pass    
    try:
        temp = chessBoard[i + 7][j + 7]
        solutionMoves.append([i + 7, j + 7])
    except:
        pass   

    temp = [i for i in solutionMoves if i[0] >=0 and i[1] >=0]
    solutionMoves = ["".join([chess_map_from_index_to_alpha[i[1]], str(i[0] + 1)]) for i in temp]
    solutionMoves.sort()
    return solutionMoves

1 Ответ

0 голосов
/ 24 июня 2018

Для епископа необходимо учитывать четыре различных направления: вверх-вправо, вниз-вправо, вниз-влево, вверх-влево. Для всех четырех вариантов вы можете найти максимальные прогнозируемые координаты для каждого, а затем выполнить итерацию ко всем. Если во время итерации встречается другая часть, цикл останавливается. Возможная реализация этого алгоритма ниже:

board = [['-', '-', '-', '-', '-', '-', '-', '-'], 
         ['-', '-', '-', '-', '-', '-', '-', '-'], 
         ['-', '-', '-', '-', '-', '-', '-', '-'], 
         ['-', '-', '-', '-', '-', '-', '-', '-'], 
         ['-', '-', '-', 'b', '-', '-', '-', '-'], 
         ['-', '-', '-', '-', '-', '-', '-', '-'], 
         ['-', '-', '-', '-', '-', '-', '-', '-'], 
         ['-', '-', '-', '-', '-', '-', '-', '-']]
options = [lambda x, y:(x+1, y+1), lambda x, y:(x+1, y-1), lambda x, y:(x-1, y-1), lambda x, y:(x-1, y+1)]
projected = [lambda x, y:(x+min([x,y]), y+min([x,y])), lambda x, y:(x+min([x,y]), y-min([x,y])), lambda x, y:(x-min([x,y]), y-min([x,y])), lambda x, y:(x-min([x,y]), y+min([x,y]))]
def iterate_towards(current, to, func):
   while current != to:
      current = list(func(*current))
      if board[current[0]][current[-1]] != '-':
        break
      yield current
   yield to

def get_bishop_moves(current:list):
   for a, b in zip(options, projected):
      yield list(iterate_towards([3, 4], list(b(*current)), a))

print(list(get_bishop_moves([3, 4])))

Выход:

[[[4, 5], [5, 6], [6, 7]], [[4, 3], [5, 2], [6, 1]], [[2, 3], [1, 2], [0, 1]], [[2, 5], [1, 6], [0, 7]]]
...