Задача про N королев

Задача про N королев формулюється наступним чином. Потрібно розставити на шахматній досці Nкоролев таким чином , щоб ніякі дві королеви не змогли побити одна одну згідно правил гри в шахи. Тому, ніякі дві королеви не можуть бути розміщені в одному ряду: по вертикалі , горизонталі , діагоналі.

Для вирішення задачі, пронумеруємо вертикальні та горизонтальні рядки шахматної доски від 1 до N. Для нумерації діагоналі , розділимо їх на два типи таким чином , щоб діагональ специфицифікувалась типом і номером, які обчислюються із її вертикальних і горизонтальних рядів:

Diagonal = N + Column - Row (type 1)

Diagonal = Row + Column - 1 (type 2)

Якщо ви дивитесь на шахматну доску на ряд 1 по горизонталі та колонку 1 по вертикалі з лівої сторони , тоді Tun1розділяє діагоналлю клітку як символ похилої риски вліво (\), а Tun2- вправо (/). Малюнок9.5. демонструє нумерацію діагоналей Tunу2 на досці 4х4.

| 1 | 2 | 3 | 4 |

Задача про N королев - student2.ru

1 | 1 | 2 | 3 | 4 |

2 | 2 | 3 | 4 | 5 |

3 | 3 | 4 | 5 | 6 |

4 | 4 | 5 | 6 | 7 |

Мал. 9.5. Нумерація діагоналей Типу2 на шахматній досці.

Для вирішення задачі про N королев на Пролозі, ми повинні вміти встановлювати який рядок, колонка і діагональ ще не зайняті , а також вміти відмічати де вже розміщені королеви.

Позицію королеви можна описати за допомогою зазначення номера рядка та колонки:

queen = q(integer, integer) .

Такий опис задає позицію одної королеви. Для фіксації більшої кількості позицій, можемо використать список:

queens = queen* .

Нам, також, будуть потрібні декілька списків чисел, які будуть визначати ще не зайняті королевами ряди , колонки та діагоналі. Ці списки опишемо наступним чином:

freelist = integer* .

Шахматну дошку зможемо обробляти як єдиний об'єкт, якщо зробимо наступний опис:

board = board(queens, freelist,freelist,freelist,freelist)

де чотири аргументи типу freelistзадають відповідно ряди, колонки та діагоналі Типу1і Типу2.

Наприклад, шахматну доску 4х4 без королев можна задать:

board([],[1,2,3,4],[1,2,3,4],[1,2,3,4,5,6,7],[1,2,3,4,5,6,7]),

а шахматну доску з однією королевою в самому лівому верхньому кутку опише предикат:

board([q(1,1)],[2,3,4],[2,3,4],[1,2,3,4,5,6,7],[2,3,4,5,6,7])

Накінець, ми можемо вирішити поставлену задачу, описуючи відношення між пустою доскою і доскою з N королевами. Визначимо предикат placeN(integer, board, board) з двома фразами. Королеви розташовуються одна за одною, поки кожний рядок і кожна колонка не будуть зайняті. Тому в першій фразі два списки freerows і freecols - пусті:

placeN(_, board(D,[],[],X,Y), board(D,[],[],X,Y)):- !.

placeN(_, Board1, Rеsult):-

Наши рекомендации