На данном сайте используется язык QBasic.
Профессиональный XP позволяет запускать все программы без ограничений.В домашних версиях XP и Vista для запуска программ с графикой Бейсик надо загружать через эмулятор(например dosbox -простым перетаскиванием).В 64-битной 7-е Бейсик можно запустить только через эмулятор.Чтобы сделать скриншот экрана,Бейсик нужно запускать через эмулятор даже в профессиональном XP.
На главной странице размещаются следующие программы:
1 Программа получающая группы симметрии позиций ферзей не атакующих друг друга на обычной шахматной доске(8*8).
2.Нахождение позиций ферзей не атакующих друг друга на доске произвольной размерности n*n и аналогичная программа для магарадж.
3 Нахождение позиций слонов не атакующих друг друга на обычной шахматной доске.
4 Игра "Расставь ферзей".(графика)
5 Визуализация позиций ферзей не атакующих друг друга на обычной доске.(графика)
6 Заполнение доски 7*7 позициями ферзей не атакующих друг друга.
7 Cвязь групп позиций заполнения с магическими квадратами.
Для задачи о позициях 8-и ферзей, не атакующих друг друга на доске 8*8, в сети приводится множество решений на различных языках программирования. Приводятся также 12 базовых позиций, из которых можно получить все позиции путём симметричных преобразований квадрата, однако нет программ, получающих сами группы симметрии. Здесь приводится программа, позволяющая получить эти группы,формируя набор базовых позиций с наименьшими номерами в группе.Фрагмент программы с вложеными циклами генерирует все 92 позиции независимых ферзей,с которыми далее последовательно производятся преобразования симметрии,исключая позиции уже вошедшие в группы симметрии.Список позиций,получаемый генератором (см.Википедия - 8 ферзей) устроен так,что позиции симметричные относительно горизонтальной оси расположены симметрично относительно горизонтальной оси списка.
CLS
DEFINT A-I
OPEN "grupfer8" FOR OUTPUT AS #1
DIM a(92), b(92), c(92), d(92), e(92), f(92), g(92), h(92)
DIM a1(96), b1(96), c1(96), d1(96), e1(96), f1(96), g1(96), h1(96)
FOR a = 1 TO 8
FOR b = 1 TO 8
IF b = a THEN 8
IF ABS(b - a) = 1 THEN 8
FOR c = 1 TO 8
IF c = a OR c = b THEN 7
IF ABS(c - b) = 1 OR ABS(c - a) = 2 THEN 7
FOR d = 1 TO 8
IF d = a OR d = b OR d = c THEN 6
IF ABS(d - c) = 1 OR ABS(d - b) = 2 OR ABS(d - a) = 3 THEN 6
FOR e = 1 TO 8
IF e = a OR e = b OR e = c OR e = d THEN 5
IF ABS(e - d) = 1 OR ABS(e - c) = 2 OR ABS(e - b) = 3 OR ABS(e - a) = 4 THEN 5
FOR f = 1 TO 8
IF f = a OR f = b OR f = c OR f = d OR f = e THEN 4
IF ABS(f - e) = 1 OR ABS(f - d) = 2 OR ABS(f - c) = 3 OR ABS(f - b) = 4 OR ABS(f - a) = 5 THEN 4
FOR g = 1 TO 8
IF g = a OR g = b OR g = c OR g = d OR g = e OR g = f THEN 3
IF ABS(g - f) = 1 OR ABS(g - e) = 2 OR ABS(g - d) = 3 OR ABS(g - c) = 4 OR ABS(g - b) = 5 OR ABS(g - a) = 6 THEN 3
FOR h = 1 TO 8
IF h = a OR h = b OR h = c OR h = d OR h = e OR h = f OR h = g THEN 2
IF ABS(h - g) = 1 OR ABS(h - f) = 2 OR ABS(h - e) = 3 OR ABS(h - d) = 4 OR ABS(h - c) = 5 OR ABS(h - b) = 6 OR ABS(h - a) = 7 THEN 2
p = p + 1
a(p) = a: b(p) = b: c(p) = c: d(p) = d: e(p) = e: f(p) = f: g(p) = g: h(p)= h
2 NEXT h
3 NEXT g
4 NEXT f
5 NEXT e
6 NEXT d
7 NEXT c
8 NEXT b
NEXT a
60 r = r + 1 'номер первой позиции в группе
IF r = 90 THEN END
IF l = 0 THEN 'избежание повторных пробелов между группами
PRINT " "
PRINT #1, " "
END IF
FOR k = 1 TO 8
x(k) = k
NEXT
y(1) = a(r): y(2) = b(r): y(3) = c(r): y(4) = d(r): y(5) = e(r): y(6) = f(r): y(7) = g(r): y(8) = h(r)
FOR n = 1 TO m 'избежание повторного получения групп
IF y(1) = a1(n) AND y(2) = b1(n) AND y(3) = c1(n) AND y(4) = d1(n) AND y(5) = e1(n) AND y(6) = f1(n) AND y(7) = g1(n) AND y(8) = h1(n) THEN l = l + 1: GOTO 60
NEXT
l = 0
rs = rs + 1 'номер группы
PRINT " "; rs
PRINT #1, " "; rs
'производим преобразование координат
'для каждого типа симметрии
'исходное положение
FOR i = 1 TO 8
z(i) = x(i)
u(i) = y(i)
NEXT
GOSUB 1
'отражение от вертикальной оси
PRINT " "
PRINT #1, " "
FOR i = 1 TO 8
z(i) = 9 - x(i)
u(i) = y( i)
NEXT
GOSUB 1
'отражение от горизонтальной оси
PRINT " "
PRINT #1, " "
FOR i = 1 TO 8
z(i) = x(i)
u(i) = 9 - y(i)
NEXT
GOSUB 1
'отражение от диагонали /
PRINT " "
PRINT #1, " "
FOR i = 1 TO 8
z(i) = y(i)
u(i) = x(i)
NEXT
GOSUB 1
'отражение от диагонали \
PRINT " "
PRINT #1, " "
FOR i = 1 TO 8
z(i) = 9 - y(i)
u(i) = 9 - x(i)
NEXT
GOSUB 1
'поворот на 90 гр.
PRINT " "
PRINT #1, " "
FOR i = 1 TO 8
z(i) = y(i)
u(i) = 9 - x(i)
NEXT
GOSUB 1
'поворот на 180 гр.
PRINT " "
PRINT #1, " "
FOR i = 1 TO 8
z(i) = 9 - x(i)
u(i) = 9 - y(i)
NEXT
GOSUB 1
'поворот на 270 гр.
PRINT " "
PRINT #1, " "
FOR i = 1 TO 8
z(i) = 9 - y(i)
u(i) = x(i)
NEXT
GOSUB 1
GOTO 60
END
' ------------------------------------------------------
1 FOR i = 1 TO 8
IF z(i) = 1 THEN o$(i) = "a"
IF z(i) = 2 THEN o$(i) = "b"
IF z(i) = 3 THEN o$(i) = "c"
IF z(i) = 4 THEN o$(i) = "d"
IF z(i) = 5 THEN o$(i) = "e"
IF z(i) = 6 THEN o$(i) = "f"
IF z(i) = 7 THEN o$(i) = "g"
IF z(i) = 8 THEN o$(i) = "h"
NEXT
PRINT " ";
PRINT #1, " ";
'упорядочивание нового расположения по возрастанию
FOR i = 1 TO 8
IF o$(i) = "a" THEN
PRINT o$(i); u(i); " "; :
PRINT #1, o$(i); u(i); " "; : GOTO 21
END IF
NEXT
21 a1 = u(i)
FOR i = 1 TO 8
IF o$(i) = "b" THEN
PRINT o$(i); u(i); " ";
PRINT #1, o$(i); u(i); " "; : GOTO 22
END IF
NEXT
22 b1 = u(i)
FOR i = 1 TO 8
IF o$(i) = "c" THEN
PRINT o$(i); u(i); " ";
PRINT #1, o$(i); u(i); " "; : GOTO 23
END IF
NEXT
23 c1 = u(i)
FOR i = 1 TO 8
IF o$(i) = "d" THEN
PRINT o$(i); u(i); " ";
PRINT #1, o$(i); u(i); " "; : GOTO 24
END IF
NEXT
24 d1 = u(i)
FOR i = 1 TO 8
IF o$(i) = "e" THEN
PRINT o$(i); u(i); " ";
PRINT #1, o$(i); u(i); " "; : GOTO 25
END IF
NEXT
25 e1 = u(i)
FOR i = 1 TO 8
IF o$(i) = "f" THEN
PRINT o$(i); u(i); " ";
PRINT #1, o$(i); u(i); " "; : GOTO 26
END IF
NEXT
26 f1 = u(i)
FOR i = 1 TO 8
IF o$(i) = "g" THEN
PRINT o$(i); u(i); " ";
PRINT #1, o$(i); u(i); " "; : GOTO 27
END IF
NEXT
27 g1 = u(i)
FOR i = 1 TO 8
IF o$(i) = "h" THEN
PRINT o$(i); u(i); " ";
PRINT #1, o$(i); u(i); " "; : GOTO 28
END IF
NEXT
28 h1 = u(i)
m = m + 1 'формирование массива позиций уже вошедших в группы симметрии и расчёт их номеров.
a1(m) = a1: b1(m) = b1: c1(m) = c1: d1(m) = d1: e1(m) = e1: f1(m) = f1: g1(m) = g1: h1(m) = h1
FOR k = 1 TO 92
IF a1(m) = a(k) AND b1(m) = b(k) AND c1(m) = c(k) AND d1(m) = d(k) AND e1(m) = e(k) AND f1(m) = f(k) AND g1(m) = g(k) AND h1(m) = h(k) THEN
PRINT ":"; k
PRINT #1, ":"; k
END IF
NEXT
RETURN
В результате получается следующая таблица:
1
a 1 b 5 c 8 d 6 e 3 f 7 g 2 h 4 : 1
a 4 b 2 c 7 d 3 e 6 f 8 g 5 h 1 : 33
a 8 b 4 c 1 d 3 e 6 f 2 g 7 h 5 : 92
a 1 b 7 c 5 d 8 e 2 f 4 g 6 h 3 : 4
a 6 b 3 c 5 d 7 e 1 f 4 g 2 h 8 : 71
a 8 b 2 c 4 d 1 e 7 f 5 g 3 h 6 : 89
a 5 b 7 c 2 d 6 e 3 f 1 g 4 h 8 : 60
a 3 b 6 c 4 d 2 e 8 f 5 g 7 h 1 : 22
2
a 1 b 6 c 8 d 3 e 7 f 4 g 2 h 5 : 2
a 5 b 2 c 4 d 7 e 3 f 8 g 6 h 1 : 51
a 8 b 3 c 1 d 6 e 2 f 5 g 7 h 4 : 91
a 1 b 7 c 4 d 6 e 8 f 2 g 5 h 3 : 3
a 6 b 4 c 7 d 1 e 3 f 5 g 2 h 8 : 78
a 8 b 2 c 5 d 3 e 1 f 7 g 4 h 6 : 90
a 4 b 7 c 5 d 2 e 6 f 1 g 3 h 8 : 42
a 3 b 5 c 2 d 8 e 6 f 4 g 7 h 1 : 15
3
a 2 b 4 c 6 d 8 e 3 f 1 g 7 h 5 : 5
a 5 b 7 c 1 d 3 e 8 f 6 g 4 h 2 : 57
a 7 b 5 c 3 d 1 e 6 f 8 g 2 h 4 : 88
a 6 b 1 c 5 d 2 e 8 f 3 g 7 h 4 : 65
a 5 b 2 c 6 d 1 e 7 f 4 g 8 h 3 : 52
a 3 b 8 c 4 d 7 e 1 f 6 g 2 h 5 : 28
a 4 b 2 c 8 d 6 e 1 f 3 g 5 h 7 : 36
a 4 b 7 c 3 d 8 e 2 f 5 g 1 h 6 : 41
4
a 2 b 5 c 7 d 1 e 3 f 8 g 6 h 4 : 6
a 4 b 6 c 8 d 3 e 1 f 7 g 5 h 2 : 39
a 7 b 4 c 2 d 8 e 6 f 1 g 3 h 5 : 87
a 4 b 1 c 5 d 8 e 2 f 7 g 3 h 6 : 29
a 3 b 6 c 2 d 7 e 1 f 4 g 8 h 5 : 19
a 5 b 8 c 4 d 1 e 7 f 2 g 6 h 3 : 64
a 5 b 3 c 1 d 6 e 8 f 2 g 4 h 7 : 54
a 6 b 3 c 7 d 2 e 8 f 5 g 1 h 4 : 74
5
a 2 b 5 c 7 d 4 e 1 f 8 g 6 h 3 : 7
a 3 b 6 c 8 d 1 e 4 f 7 g 5 h 2 : 23
a 7 b 4 c 2 d 5 e 8 f 1 g 3 h 6 : 86
a 5 b 1 c 8 d 4 e 2 f 7 g 3 h 6 : 48
a 3 b 6 c 2 d 7 e 5 f 1 g 8 h 4 : 20
a 4 b 8 c 1 d 5 e 7 f 2 g 6 h 3 : 45
a 6 b 3 c 1 d 8 e 5 f 2 g 4 h 7 : 70
a 6 b 3 c 7 d 2 e 4 f 8 g 1 h 5 : 73
6
a 2 b 6 c 1 d 7 e 4 f 8 g 3 h 5 : 8
a 5 b 3 c 8 d 4 e 7 f 1 g 6 h 2 : 56
a 7 b 3 c 8 d 2 e 5 f 1 g 6 h 4 : 85
a 3 b 1 c 7 d 5 e 8 f 2 g 4 h 6 : 13
a 3 b 5 c 7 d 1 e 4 f 2 g 8 h 6 : 16
a 6 b 8 c 2 d 4 e 1 f 7 g 5 h 3 : 80
a 4 b 6 c 1 d 5 e 2 f 8 g 3 h 7 : 37
a 6 b 4 c 2 d 8 e 5 f 7 g 1 h 3 : 77
7
a 2 b 6 c 8 d 3 e 1 f 4 g 7 h 5 : 9
a 5 b 7 c 4 d 1 e 3 f 8 g 6 h 2 : 62
a 7 b 3 c 1 d 6 e 8 f 5 g 2 h 4 : 84
a 5 b 1 c 4 d 6 e 8 f 2 g 7 h 3 : 47
a 6 b 2 c 7 d 1 e 3 f 5 g 8 h 4 : 66
a 4 b 8 c 5 d 3 e 1 f 7 g 2 h 6 : 46
a 4 b 2 c 5 d 8 e 6 f 1 g 3 h 7 : 31
a 3 b 7 c 2 d 8 e 6 f 4 g 1 h 5 : 27
8
a 2 b 7 c 3 d 6 e 8 f 5 g 1 h 4 : 10
a 4 b 1 c 5 d 8 e 6 f 3 g 7 h 2 : 30
a 7 b 2 c 6 d 3 e 1 f 4 g 8 h 5 : 83
a 7 b 1 c 3 d 8 e 6 f 4 g 2 h 5 : 81
a 4 b 7 c 5 d 3 e 1 f 6 g 8 h 2 : 43
a 2 b 8 c 6 d 1 e 3 f 5 g 7 h 4 : 12
a 5 b 8 c 4 d 1 e 3 f 6 g 2 h 7 : 63
a 5 b 2 c 4 d 6 e 8 f 3 g 1 h 7 : 50
9
a 2 b 7 c 5 d 8 e 1 f 4 g 6 h 3 : 11
a 3 b 6 c 4 d 1 e 8 f 5 g 7 h 2 : 21
a 7 b 2 c 4 d 1 e 8 f 5 g 3 h 6 : 82
a 5 b 1 c 8 d 6 e 3 f 7 g 2 h 4 : 49
a 5 b 7 c 2 d 6 e 3 f 1 g 8 h 4 : 61
a 4 b 8 c 1 d 3 e 6 f 2 g 7 h 5 : 44
a 6 b 3 c 5 d 8 e 1 f 4 g 2 h 7 : 72
a 4 b 2 c 7 d 3 e 6 f 8 g 1 h 5 : 32
10
a 3 b 5 c 2 d 8 e 1 f 7 g 4 h 6 : 14
a 6 b 4 c 7 d 1 e 8 f 2 g 5 h 3 : 79
a 6 b 4 c 7 d 1 e 8 f 2 g 5 h 3 : 79
a 5 b 3 c 1 d 7 e 2 f 8 g 6 h 4 : 55
a 5 b 3 c 1 d 7 e 2 f 8 g 6 h 4 : 55
a 4 b 6 c 8 d 2 e 7 f 1 g 3 h 5 : 38
a 3 b 5 c 2 d 8 e 1 f 7 g 4 h 6 : 14
a 4 b 6 c 8 d 2 e 7 f 1 g 3 h 5 : 38
11
a 3 b 5 c 8 d 4 e 1 f 7 g 2 h 6 : 17
a 6 b 2 c 7 d 1 e 4 f 8 g 5 h 3 : 67
a 6 b 4 c 1 d 5 e 8 f 2 g 7 h 3 : 76
a 5 b 7 c 1 d 4 e 2 f 8 g 6 h 3 : 58
a 6 b 3 c 1 d 7 e 5 f 8 g 2 h 4 : 68
a 4 b 2 c 8 d 5 e 7 f 1 g 3 h 6 : 35
a 3 b 7 c 2 d 8 e 5 f 1 g 4 h 6 : 26
a 3 b 6 c 8 d 2 e 4 f 1 g 7 h 5 : 25
12
a 3 b 6 c 2 d 5 e 8 f 1 g 7 h 4 : 18
a 4 b 7 c 1 d 8 e 5 f 2 g 6 h 3 : 40
a 6 b 3 c 7 d 4 e 1 f 8 g 2 h 5 : 75
a 6 b 3 c 1 d 8 e 4 f 2 g 7 h 5 : 69
a 4 b 2 c 7 d 5 e 1 f 8 g 6 h 3 : 34
a 3 b 6 c 8 d 1 e 5 f 7 g 2 h 4 : 24
a 5 b 2 c 8 d 1 e 4 f 7 g 3 h 6 : 53
a 5 b 7 c 2 d 4 e 8 f 1 g 3 h 6 : 59
Сумма номеров позиций связанных симметрией отражения от горизонтальной оси равна 93.
Значит сумма номеров в группе 93*4=372. Группа 10 симметрическая - позиции переходят сами в себя при повороте на 180 градусов.
Понятно, что базовых групп можно составить 8^11*4.
По виду симметрии позиций по отношению к базовой позиции можно определить вид симметрии позиций по отношению друг к другу.
Пусть позиция 1 получается из базовой посредством отражения от горизонталь-
ной оси : x1 = x
y1 = 9 - y
Позиция 2 - посредством отражения от вертикальной оси:
x2 = 9 - x
y2 = y
Выражаем x и y из первой системы уравнений и подставляем во вторую
x2 = 9 - x1
y2 = 9 - y1
Эти уравнения выражают поворот на 180 градусов.
Немного о досках других размерностей.
Данные преобразования координат выполняются и для досок других размерностей,только 9 заменяется на n+1. Понятно,что в условиях данной задачи,позиция не может переходить сама в себя при отражении. Но возможен такой переход не только при повороте на 180 градусов,но и при повороте на 90 и 270 градусов(эти повороты взаимно обратимы). Такие группы симметрии называются дважды симметрическими. Они существуют для досок размерностью 4 и 5 . Для доски 4*4 имеют место 2 позиции не атакующих друг друга ферзей,которые образуют дважды симметрическую группу.
1
a 2 b 4 c 1 d 3
a 3 b 1 c 4 d 2
a 3 b 1 c 4 d 2
a 3 b 1 c 4 d 2
a 3 b 1 c 4 d 2
a 2 b 4 c 1 d 3
a 2 b 4 c 1 d 3
a 2 b 4 c 1 d 3
Для доски 5*5 10 позиций образуют одну обычную и одну дважды симметрическую группы.
1
a 1 b 3 c 5 d 2 e 4
a 4 b 2 c 5 d 3 e 1
a 5 b 3 c 1 d 4 e 2
a 1 b 4 c 2 d 5 e 3
a 3 b 1 c 4 d 2 e 5
a 5 b 2 c 4 d 1 e 3
a 2 b 4 c 1 d 3 e 5
a 3 b 5 c 2 d 4 e 1
2
a 4 b 1 c 3 d 5 e 2
a 2 b 5 c 3 d 1 e 4
a 2 b 5 c 3 d 1 e 4
a 2 b 5 c 3 d 1 e 4
a 2 b 5 c 3 d 1 e 4
a 4 b 1 c 3 d 5 e 2
a 4 b 1 c 3 d 5 e 2
a 4 b 1 c 3 d 5 e 2
Дважды симметрические группы существуют также для больших досок,начиная с доски 12*12,но не для всех.
***************************************************************
Для получения позиций n ферзей не бьющих друг друга на доске n*n, в случае любого n, предлагается программа основанная на том же алгоритме (перебор с возвратом), что и программа с вложенными циклами.Достоинство первой программы в её прозрачности.Поняв её, можно понять и эту.
CLS
DEFINT A-Z
INPUT "Название файла для результатов";FILENAME$
OPEN FILENAME$ FOR OUTPUT AS 1
INPUT " n= "; n
DIM y(n + 1)
1 k = k + 1
IF k = n + 1 THEN 2
8 y(k) = y(k) + 1
IF y(1) = n + 1 THEN END
IF y(k) = n + 1 THEN
y(k) = 0: k = k - 1: GOTO 8
END IF
FOR j = 1 TO k - 1
IF y(j) = y(k) OR ABS(y(k) - y(j)) = k - j THEN 8
NEXT
GOTO 1
2 i# = i# + 1
PRINT i#; ":";
FOR j = 1 TO n
PRINT y(j);
NEXT
PRINT " "
PRINT #1, i#; ":";
FOR j = 1 TO n
PRINT #1, y(j);
NEXT
PRINT #1, " "
k=k-1
GOTO 8
Реально по времени можно дойти до доски 15*15 включительно, при условии создания exe файла в QuickBasice 4.5 или других версиях с компилятором.Терпеливые могут попробывать и доску 16*16,но запись позиций займёт сотни мегабайт.Если не записывать в файл и не выводить на экран,а просто считать,то конечно будет гораздо быстрее.Впрочем всё это посчитано до нас вплоть до доски 26*26 включительно.(Кластер из 300 машин работал в течении полгода.)См.украинскую версию статьи в Википедиию.
Мы же можем быстро найти,что на доске 12*12 будет 14200 позиций-последняя :12,10,8,5,3,1,7,2,11,6,4,9
На доске 13*13 будет 73712 позиций-последняя:
13,11,9,12,5,2,4,1,10,8,6,3,7
Конечно,программы на QBasic-е легко переводятся в код для VB 6.Вот как выглядит код данной программы.(Можно отметить,что в VB 6 нет операторов DEFINT и SLEEP,вместо INPUT используется InputBox.
Если размерность массива задаётся переменной,он уже считается динамическим (в QB - если размерность изменяется в процессе выполнения прграммы).Go To после Then VB ставит сам.Можно также заметиь,что переменной без индекса нельзя присваивать такое же имя что и массиву.Другие отличия могут всплыть при написании при написании конкретных программ.) Результат работы программы смотрим в файле результатов.
Private Sub Command1_Click()
Cls
Dim k,j,n As Integer
n = InputBox("размерность доски")
FileName$ = InputBox("имя файла результатов")
Open FileName$ For Output As 1
ReDim y(n + 1) As Integer
Print " Пожалуйста,подождите."
1 k = k + 1
If k = n + 1 Then GoTo 2
8 y(k) = y(k) + 1
If y(1) = n + 1 Then GoTo 10
If y(k) = n + 1 Then
y(k) = 0: k = k - 1: GoTo 8
End IfМ
For j = 1 To k - 1
If y(j) = y(k) Or Abs(y(k) - y(j)) = k - j Then GoTo 8
Next
GoTo 1
2 I# = I# + 1
Print #1, I#; ":";
For j = 1 To n
Print #1, y(j);
Next
Print #1, " "
GoTo 8
10 Cls
v$ = InputBox("нажмите любую клавишу + Enter и смотрите файл")
END
End Sub
В нетрадиционных шахматах существует фигура называемая “магараджа”,которая совмещает свойства ферзя и коня.Можно дополнить программу,чтобы находить и позиции магарадж,не атакующих друг друга.Их, конечно, будет гораздо меньше,чем позиций ферзей.Они не существуют для досок меньших 10*10.
CLS
DEFINT A-Z
INPUT " имя файла для результатов"; filename$
OPEN filename$ FOR OUTPUT AS 1
INPUT " n= "; n
DIM y(n + 2)
1 k = k + 1
IF k = n + 1 THEN 2
8 y(k) = y(k) + 1
IF y(1) = n + 1 THEN END
IF y(k) = n + 1 THEN
y(k) = 0: k = k - 1: GOTO 8
END IF
FOR j = 1 TO k - 1
IF y(j) = y(k) OR ABS(y(k) - y(j)) = k - j THEN 8
NEXT
GOTO 1
2 r = 0
3 r = r + 1
IF r = n - 2 THEN 4
IF ABS(y(r + 1) - y(r)) = 2 THEN 8
IF ABS(y(r + 2) - y(r)) = 1 THEN 8
GOTO 3
4 IF ABS(y(r + 1) - y(r)) = 2 THEN 8
IF ABS(y(r) - y(r - 1)) = 2 THEN 8
IF ABS(y(r) - y(r - 2)) = 1 THEN 8
IF ABS(y(r + 1) - y(r - 1)) = 1 THEN 8
IF ABS(y(r + 2) - y(r)) = 1 THEN 8
IF ABS(y(r + 2) - y(r + 1)) = 2 THEN 8
i = i + 1
PRINT i; ":";
FOR j = 1 TO n
PRINT y(j);
NEXT
PRINT " "
PRINT #1, i; ":";
FOR j = 1 TO n
PRINT #1, y(j);
NEXT
PRINT #1, " "
GOTO 8
Вот позиции магарадж для доски 10*10. Их всего 4,образующие симметрическую группу.
1 : 3 6 9 1 4 7 10 2 5 8
2 : 4 8 1 5 9 2 6 10 3 7
3 : 7 3 10 6 2 9 5 1 8 4
4 : 8 5 2 10 7 4 1 9 6 3
Близка задаче о независимости ферзей задача о независимости слонов.Очевидно, при взгляде на обычную доску,что на ней можно расположить по 7 слонов каждого цвета,которые не угрожают друг другу.Значит всего 14.Для произвольной доски 2n-2,где n – размерность доски.Понятно,что позиции белопольных и чернопольных слонов рассчитываются отдельно.Ниже представлена программа,которая рассчитывает позиции чёрнопольных слонов на обычной доске.Для белопольных слонов нужно в операторе DATA номера чёрных клеток заменить на номера белых.
Принцип нумерации,я думаю,очевиден- снизу вверх в каждом столбце.
CLS
OPEN "nezslonb" FOR OUTPUT AS #1
DIM y(7) AS INTEGER
DIM n(32), c(32) AS INTEGER
DATA 1,3,5,7,10,12,14,16,17,19,21,23,26,28,30,32,33,35,37,39,42,44,46,48,49,51,53,55,58,60,62,64
FOR n = 1 TO 32
READ c(n)
NEXT
FOR z1% = 1 TO 26
n1% = c(z1%)
y(1) = n1% MOD 8
IF y(1) = 0 THEN y(1) = 8
FOR z2% = z1% + 1 TO 27
n2% = c(z2%)
y(2) = n2% MOD 8
IF y(2) = 0 THEN y(2) = 8
FOR z3% = z2% + 1 TO 28
n3% = c(z3%)
y(3) = n3% MOD 8
IF y(3) = 0 THEN y(3) = 8
FOR z4% = z3% + 1 TO 29
n4% = c(z4%)
y(4) = n4% MOD 8
IF y(4) = 0 THEN y(4) = 8
FOR z5% = z4% + 1 TO 30
n5% = c(z5%)
y(5) = n5% MOD 8
IF y(5) = 0 THEN y(5) = 8
FOR z6% = z5% + 1 TO 31
n6% = c(z6%)
y(6) = n6% MOD 8
IF y(6) = 0 THEN y(6) = 8
FOR z7% = z6% + 1 TO 32
n7% = c(z7%)
y(7) = n7% MOD 8
IF y(7) = 0 THEN y(7) = 8
GOTO 7
6 NEXT z7%
5 NEXT z6%
4 NEXT z5%
3 NEXT z4%
2 NEXT z3%
1 NEXT z2%
NEXT z1%
END
7 x(1) = (n1% - y(1)) / 8 + 1
x(2) = (n2% - y(2)) / 8 + 1
x(3) = (n3% - y(3)) / 8 + 1
x(4) = (n4% - y(4)) / 8 + 1
x(5) = (n5% - y(5)) / 8 + 1
x(6) = (n6% - y(6)) / 8 + 1
x(7) = (n7% - y(7)) / 8 + 1
FOR i = 1 TO 7
FOR j = 1 TO 7
IF ABS(y(i) - y(j)) = ABS(x(i) - x(j)) AND i < j THEN 6
NEXT j
NEXT i
FOR k = 1 TO 7
IF x(k) = 1 THEN x$(k) = "a"
IF x(k) = 2 THEN x$(k) = "b"
IF x(k) = 3 THEN x$(k) = "c"
IF x(k) = 4 THEN x$(k) = "d"
IF x(k) = 5 THEN x$(k) = "e"
IF x(k) = 6 THEN x$(k) = "f"
IF x(k) = 7 THEN x$(k) = "g"
IF x(k) = 8 THEN x$(k) = "h"
NEXT
p = p + 1
PRINT p; ": "; x$(1); y(1); " "; x$(2); y(2); " "; x$(3); y(3); " "; x$(4); y(4); " "; x$(5); y(5); " "; x$(6); y(6); " "; x$(7); y(7)
PRINT #1, p; ": "; x$(1); y(1); " "; x$(2); y(2); " "; x$(3); y(3); " "; x$(4); y(4); " "; x$(5); y(5); " "; x$(6); y(6); " "; x$(7); y(7)
GOTO 6
Вот результат работы программы
1 : a 1 a 3 a 5 a 7 h 2 h 4 h 6
2 : a 1 a 3 a 5 b 8 g 1 h 4 h 6
3 : a 1 a 3 a 7 d 8 e 1 h 2 h 6
4 : a 1 a 3 b 8 d 8 e 1 g 1 h 6
5 : a 1 a 5 a 7 c 1 f 8 h 2 h 4
6 : a 1 a 5 b 8 c 1 f 8 g 1 h 4
7 : a 1 a 7 c 1 d 8 e 1 f 8 h 2
8 : a 1 b 8 c 1 d 8 e 1 f 8 g 1
9 : a 3 a 5 a 7 h 2 h 4 h 6 h 8
10 : a 3 a 5 b 8 g 1 h 4 h 6 h 8
11 : a 3 a 7 d 8 e 1 h 2 h 6 h 8
12 : a 3 b 8 d 8 e 1 g 1 h 6 h 8
13 : a 5 a 7 c 1 f 8 h 2 h 4 h 8
14 : a 5 b 8 c 1 f 8 g 1 h 4 h 8
15 : a 7 c 1 d 8 e 1 f 8 h 2 h 8
16 : b 8 c 1 d 8 e 1 f 8 g 1 h 8
Для белых клеток получаем
1 : a 2 a 4 a 6 a 8 h 3 h 5 h 7
2 : a 2 a 4 a 6 h 1 h 3 h 5 h 7
3 : a 2 a 4 a 8 c 8 f 1 h 5 h 7
4 : a 2 a 4 c 8 f 1 h 1 h 5 h 7
5 : a 2 a 6 a 8 d 1 e 8 h 3 h 7
6 : a 2 a 6 d 1 e 8 h 1 h 3 h 7
7 : a 2 a 8 c 8 d 1 e 8 f 1 h 7
8 : a 2 c 8 d 1 e 8 f 1 h 1 h 7
9 : a 4 a 6 a 8 b 1 g 8 h 3 h 5
10 : a 4 a 6 b 1 g 8 h 1 h 3 h 5
11 : a 4 a 8 b 1 c 8 f 1 g 8 h 5
12 : a 4 b 1 c 8 f 1 g 8 h 1 h 5
13 : a 6 a 8 b 1 d 1 e 8 g 8 h 3
14 : a 6 b 1 d 1 e 8 g 8 h 1 h 3
15 : a 8 b 1 c 8 d 1 e 8 f 1 g 8
16 : b 1 c 8 d 1 e 8 f 1 g 8 h 1
Каждую позицию чёрнопольных слонов можно соеденить с любой позицией белопольных,следовательно,всего получается 16*16=256 позиций.
-----------------------------
Ещё одна программа на эту тему – игра “Расставь ферзей.” Она предлагается на многих сайтах в он-лайн режиме. В отличие от флеш-варинтов, где ферзи ставятся “мышкой”, здесь нужно набирать последовательно номер позиции ферзя в каждом столбце. Если зашли в тупик, набирайте 0. Если ввод ошибочен, раздаётся бип.
DECLARE SUB doska ()
SCREEN 12
DIM a%(1000), b%(1000)
COLOR 8
LINE (20, 25)-(45, 25)
LINE (20, 10)-(20, 25)
LINE (45, 10)-(45, 25)
LINE (20, 10)-(27, 17)
LINE (45, 10)-(38, 17)
LINE (27, 17)-(32, 10)
LINE (38, 17)-(32, 10)
PAINT (30, 15), 2, 8
PAINT (21, 3), 8, 8
GET (20, 0)-(45, 30), a%
CLS
COLOR 8
PAINT (100, 100), 15
LINE (20, 25)-(45, 25)
LINE (20, 10)-(20, 25)
LINE (45, 10)-(45, 25)
LINE (20, 10)-(27, 17)
LINE (45, 10)-(38, 17)
LINE (27, 17)-(32, 10)
LINE (38, 17)-(32, 10)
PAINT (30, 15), 2, 8
GET (20, 0)-(45, 30), b%
FOR i = 1 TO 8
x(i) = i
NEXT
CALL doska
1 x = x + 1
m = m + 1
COLOR 7
2 PRINT "y"; m; "=";
INPUT y
IF y = 0 THEN END
y(m) = y
k = 1.2
FOR i = 1 TO m
FOR j = 1 TO m
IF (y(i)=y(j) OR ABS(x(i) - x(j)) = ABS(y(i) - y(j))) AND i <> j THEN
SOUND 1000, 2
GOTO 2
END IF
NEXT
NEXT
xg% = INT(85 + 40 * k * x)
yg% = INT(450 - 40 * k * y)
IF POINT(xg% - 16, yg% - 19) = 8 THEN
PUT (xg% - 14, yg% - 17), a%, PSET
ELSE
PUT (xg% - 14, yg% - 17), b%, AND
END IF
IF m = 8 THEN 5
GOTO 1
5 PRINT "Ты выиграл!": SLEEP: END
SUB doska
k = 1.2
LINE (0, 0)-(640, 480), 15, BF
COLOR 6
'запись используемых символов
LOCATE (1), (5): PRINT "A"
DIM a%(100)
GET (32, 0)-(38, 15), a%
LOCATE (1), (5): PRINT "B"
DIM b%(100)
GET (32, 0)-(38, 15), b%
LOCATE (1), (5): PRINT "C"
DIM c%(100)
GET (32, 0)-(38, 15), c%
LOCATE (1), (5): PRINT "D"
DIM d%(100)
GET (32, 0)-(38, 15), d%
LOCATE (1), (5): PRINT "E"
DIM e%(100)
GET (32, 0)-(38, 15), e%
LOCATE (1), (5): PRINT "F"
DIM f%(100)
GET (32, 0)-(38, 15), f%
LOCATE (1), (5): PRINT "G"
DIM g%(100)
GET (32, 0)-(38, 15), g%
LOCATE (1), (5): PRINT "H"
DIM h%(100)
GET (32, 0)-(38, 15), h%
LOCATE (1), (5): PRINT "1"
DIM o%(100)
GET (32, 0)-(38, 15), o%
LOCATE (1), (5): PRINT "2"
DIM dv%(100)
GET (32, 0)-(38, 15), dv%
LOCATE (1), (5): PRINT "3"
DIM t%(100)
GET (32, 0)-(38, 15), t%
LOCATE (1), (5): PRINT "4"
DIM ch%(100)
GET (32, 0)-(38, 15), ch%
LOCATE (1), (5): PRINT "5"
DIM p%(100)
GET (32, 0)-(38, 15), p%
LOCATE (1), (5): PRINT "6"
DIM sh%(100)
GET (32, 0)-(38, 15), sh%
LOCATE (1), (5): PRINT "7"
DIM s%(100)
GET (32, 0)-(38, 15), s%
LOCATE (1), (5): PRINT "8"
DIM v%(100)
GET (32, 0)-(38, 15), v%
LOCATE (1), (5): PRINT "-"
DIM mn%(100)
GET (32, 0)-(38, 15), mn%
CLS
'рисование шахматной доски
PAINT (30, 30), 15
LINE (1, 1)-(639, 479), 15, B 'рамка
COLOR 8
FOR n = -4 TO 4
LINE (300 - 160 * k, 230 + k * 40 * n)-(300 + 160 * k, 230 + k * 40 * n)'горизонтали
NEXT
FOR n = -4 TO 4
LINE (300 + 40 * n * k, 230 - 160 * k)-(300 + 40 * n * k, 230 + 160 * k)'вертикали
NEXT
FOR i = 0 TO 3
FOR j = 0 TO 3
x = 300 - 140 * k + 80 * i * k
y = 230 + 140 * k - 80 * j * k
PAINT (x, y), 8
NEXT
NEXT
FOR i = 0 TO 3
FOR j = 0 TO 3
x = 300 - 100 * k + 80 * i * k
y = 230 + 100 * k - 80 * j * k
PAINT (x, y), 8
NEXT
NEXT
PUT (300 - 140 * k, 230 + 160 * k), a%
PUT (300 - 100 * k, 230 + 160 * k), b%
PUT (300 - 60 * k, 230 + 160 * k), c%
PUT (300 - 20 * k, 230 + 160 * k), d%
PUT (300 + 20 * k, 230 + 160 * k), e%
PUT (300 + 60 * k, 230 + 160 * k), f%
PUT (300 + 100 * k, 230 + 160 * k), g%
PUT (300 + 140 * k, 230 + 160 * k), h%
PUT (300 - 170 * k, 230 + 135 * k), o%
PUT (300 - 170 * k, 230 + 95 * k), dv%
PUT (300 - 170 * k, 230 + 55 * k), t%
PUT (300 - 170 * k, 230 + 15 * k), ch%
PUT (300 - 170 * k, 230 - 25 * k), p%
PUT (300 - 170 * k, 230 - 65 * k), sh%
PUT (300 - 170 * k, 230 - 105 * k), s%
PUT (300 - 170 * k, 230 - 145 * k), v%
END SUB
Если допускать возврат ходов,то часть программы,начиная с метки 1, будет такой,как показано ниже.Ввод 0-ля будет вызывать возврат хода.Для выхода из программы нужно ввести отрицательное число.
1 x = x + 1
m = m + 1
COLOR 7
2 PRINT "y"; m; "=";
INPUT y
IF y = 0 THEN 10
IF y < 0 THEN END
y(m) = y
k = 1.2
FOR i = 1 TO m
FOR j = 1 TO
IF (y(i)=y(j) OR ABS(x(i) - x(j)) = ABS(y(i) - y(j))) AND i <> j THEN
SOUND 1000, 2
GOTO 2
END IF
NEXT
NEXT
xg% = INT(85 + 40 * k * x): xg%(m) = xg%
yg% = INT(450 - 40 * k * y): yg%(m) = yg%
IF POINT(xg% - 16, yg% - 19) = 8 THEN
PUT (xg% - 14, yg% - 17), a%, PSET
ELSE
PUT (xg% - 14, yg% - 17), b%, AND
END IF
IF m = 8 THEN 5
GOTO 1
5 PRINT "Ты выиграл!": SLEEP: END
10 IF POINT(xg%(m - 1) - 16, yg%(m - 1) - 19) = 8 THEN
PAINT (xg%(m - 1), yg%(m - 1)), 8
ELSE
PAINT (xg%(m - 1), yg%(m - 1)), 15
END IF
m = m - 1
x = x - 1
GOTO 2
****************************************************************
Если требуется продемонстрировать позицию на доске,используется следующая программа.Она содержит генератор позиций, как 1-я, и подпрограмму ”доска” как предыдущая.Только ферзи рисуются в виде кружков.Вводится номер позиции,т.е. число от 1 до 92.Для выхода ввести 0.
DECLARE SUB doska ()
CLS
DEFINT A-I
DIM a(92), b(92), c(92), d(92), e(92), f(92), g(92), h(92)
FOR a = 1 TO 8
FOR b = 1 TO 8
IF b = a THEN 8
IF ABS(b - a) = 1 THEN 8
FOR c = 1 TO 8
IF c = a OR c = b THEN 7
IF ABS(c - b) = 1 OR ABS(c - a) = 2 THEN 7
FOR d = 1 TO 8
IF d = a OR d = b OR d = c THEN 6
IF ABS(d - c) = 1 OR ABS(d - b) = 2 OR ABS(d - a) = 3 THEN 6
FOR e = 1 TO 8
IF e = a OR e = b OR e = c OR e = d THEN 5
IF ABS(e - d) = 1 OR ABS(e - c) = 2 OR ABS(e - b) = 3 OR ABS(e - a) = 4 THEN 5
FOR f = 1 TO 8
IF f = a OR f = b OR f = c OR f = d OR f = e THEN 4
IF ABS(f - e) = 1 OR ABS(f - d) = 2 OR ABS(f - c) = 3 OR ABS(f - b) = 4 OR ABS(f - a) = 5 THEN 4
FOR g = 1 TO 8
IF g = a OR g = b OR g = c OR g = d OR g = e OR g = f THEN 3
IF ABS(g - f) = 1 OR ABS(g - e) = 2 OR ABS(g - d) = 3 OR ABS(g - c) = 4 OR ABS(g - b) = 5 OR ABS(g - a) = 6 THEN 3
FOR h = 1 TO 8
IF h = a OR h = b OR h = c OR h = d OR h = e OR h = f OR h = g THEN 2
IF ABS(h - g) = 1 OR ABS(h - f) = 2 OR ABS(h - e) = 3 OR ABS(h - d) = 4 OR ABS(h - c) = 5 OR ABS(h - b) = 6 OR ABS(h - a) = 7 THEN 2
i = i + 1
a(i) = a: b(i) = b: c(i) = c: d(i) = d: e(i) = e: f(i) = f: g(i) = g: h(i) = h
PRINT i; " "; "a"; a; " "; "b"; b; " "; "c"; c; " "; "d"; d;
PRINT " "; "e"; e; " "; "f"; f; " "; "g"; g; " "; "h"; h
2 NEXT h
3 NEXT g
4 NEXT f
5 NEXT e
6 NEXT d
7 NEXT c
8 NEXT b
NEXT a
CLS
10 INPUT "i="; p
IF p > 92 THEN PRINT "повторить": GOTO 10
IF p = 0 THEN END
CALL doska
k = 1.2
x = 1
y = a(p)
GOSUB 100
SLEEP 1
x = 2
y = b(p)
GOSUB 100
SLEEP 1
x = 3
y = c(p)
GOSUB 100
SLEEP 1
x = 4
y = d(p)
GOSUB 100
SLEEP 1
x = 5
y = e(p)
GOSUB 100
SLEEP 1
x = 6
y = f(p)
GOSUB 100
SLEEP 1
x = 7
y = g(p)
GOSUB 100
SLEEP 1
x = 8
y = h(p)
GOSUB 100
COLOR 7
PRINT p; " "; "a"; a(p); " "; "b"; b(p); " "; "c"; c(p); " "; "d"; d(p);
PRINT " "; "e"; e(p); " "; "f"; f(p); " "; "g"; g(p); " "; "h"; h(p)
GOTO 10
END
100 xg = 85 + 40 * k * x
yg = 450 - 40 * k * y
CIRCLE (xg, yg), 10, 5
PAINT (xg, yg), 5
RETURN
DEFSNG A-I
SUB doska
k = 1.2
SCREEN 12
LINE (0, 0)-(640, 480), 15, BF
COLOR 6
'запись используемых символов
LOCATE (1), (5): PRINT "A"
DIM a%(100)
GET (32, 0)-(38, 15), a%
LOCATE (1), (5): PRINT "B"
DIM b%(100)
GET (32, 0)-(38, 15), b%
LOCATE (1), (5): PRINT "C"
DIM c%(100)
GET (32, 0)-(38, 15), c%
LOCATE (1), (5): PRINT "D"
DIM d%(100)
GET (32, 0)-(38, 15), d%
LOCATE (1), (5): PRINT "E"
DIM e%(100)
GET (32, 0)-(38, 15), e%
LOCATE (1), (5): PRINT "F"
DIM f%(100)
GET (32, 0)-(38, 15), f%
LOCATE (1), (5): PRINT "G"
DIM g%(100)
GET (32, 0)-(38, 15), g%
LOCATE (1), (5): PRINT "H"
DIM h%(100)
GET (32, 0)-(38, 15), h%
LOCATE (1), (5): PRINT "1"
DIM o%(100)
GET (32, 0)-(38, 15), o%
LOCATE (1), (5): PRINT "2"
DIM dv%(100)
GET (32, 0)-(38, 15), dv%
LOCATE (1), (5): PRINT "3"
DIM t%(100)
GET (32, 0)-(38, 15), t%
LOCATE (1), (5): PRINT "4"
DIM ch%(100)
GET (32, 0)-(38, 15), ch%
LOCATE (1), (5): PRINT "5"
DIM p%(100)
GET (32, 0)-(38, 15), p%
LOCATE (1), (5): PRINT "6"
DIM sh%(100)
GET (32, 0)-(38, 15), sh%
LOCATE (1), (5): PRINT "7"
DIM s%(100)
GET (32, 0)-(38, 15), s%
LOCATE (1), (5): PRINT "8"
DIM v%(100)
GET (32, 0)-(38, 15), v%
LOCATE (1), (5): PRINT "-"
DIM mn%(100)
GET (32, 0)-(38, 15), mn%
CLS
'рисование шахматной доски
PAINT (30, 30), 15
LINE (1, 1)-(639, 479), 15, B 'рамка
COLOR 8
FOR n = -4 TO 4
LINE (300 - 160 * k, 230 + k * 40 * n)-(300 + 160 * k, 230 + k * 40 * n)'горизонтали
NEXT
FOR n = -4 TO 4
LINE (300 + 40 * n * k, 230 - 160 * k)-(300 + 40 * n * k, 230 + 160 * k)'вертикали
NEXT
FOR i = 0 TO 3
FOR j = 0 TO 3
x = 300 - 140 * k + 80 * i * k
y = 230 + 140 * k - 80 * j * k
PAINT (x, y), 8
NEXT
NEXT
FOR i = 0 TO 3
FOR j = 0 TO 3
x = 300 - 100 * k + 80 * i * k
y = 230 + 100 * k - 80 * j * k
PAINT (x, y), 8
NEXT
NEXT
PUT (300 - 140 * k, 230 + 160 * k), … Продолжение »