Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Объектно-ориентированное программирование.PDF
Скачиваний:
208
Добавлен:
01.05.2014
Размер:
3.64 Mб
Скачать

converted to PDF by BoJIoc

columnDifference |

columnDifference := testColumn — column. ((row = testRow) or:

[ row + columnDifference = testRow]) or: [ row — columnDifference = testRow])

ifTrue: [ true ].

neighbor canAttack: testRow column: testColumn

Вместо того чтобы проверять условие на отрицание, язык Smalltalk предоставляет явный оператор ifFalse, используемый в методе advance:

advance

"сначала попробуем следующую строку " (row < 8)

ifTrue: [ row := row + 1. self findSolution].

"не можем двигаться дальше, сдвигаем соседа " (neighbor advance)

ifFalse: [ false ]. " начнем со строки 1 " row := 1.

self findSolution

Цикл while в языке Smalltalk должен использовать блок при проверке условия, как в следующем примере:

findSolution

[ neighbor canAttack: row column: column ] whileTrue: [ self advance ifFalse: [ false ] ].

true

Для получения списка окончательных позиций используется рекурсивный метод. Вспомним, что караульная величина создает пустой список в ответ на сообщение result:

result

neighbor result; addLast: row

Решение будет получено с помощью вызова следующего метода, не являющегося частью класса Queen и относящегося к некоторому другому классу, например, такому как Object:

solvePuzzle | lastQueen | lastQueen := SentinelQueen new.

1 to: 8 do: [:i | lastQueen := (Queen new) setColumn: i neighbor: lastQueen. lastQueen findSolution ].

lastQueen result

Решение задачи о восьми ферзях, построенное без применения караульной величины, описано в моей более ранней книге по языку Smalltalk [Budd 1987].

Упражнения

1.Измените программы так, чтобы они выдавали все возможные решения, а не только одно. Сколько существует решений задачи о восьми ферзях? Сколько из них являются поворотами других? Как можно отбросить повороты?

2.Как вы можете объяснить, что караульный класс в языках Objective–C и Smalltalk не предоставляет свою версию метода findSolution, несмотря на то что сообщение findSolution посылается соседу в методе advance?

3.Предположим, мы обобщим задачу о восьми ферзях как проблему N ферзей. Задача: как расположить N ферзей на шахматной доске N ґ N? Как изменятся программы? Ясно, что существуют N, для которых нет решений (например, N=2