$ include "seed7_05.s7i";
include "window.s7i";
include "keybd.s7i";
include "float.s7i";
include "draw.s7i";
include "stdfont9.s7i";
include "pixmap_file.s7i";
include "dialog.s7i";
include "pic16.s7i";
const integer: WINDOW_WIDTH is 896;
const integer: WINDOW_HEIGHT is 704;
const integer: STRETCH_FACTOR is 68;
const integer: PIXMAP_SIZE is 32;
const integer: SMALL_PIXMAP_SIZE is 16;
const integer: FIELD_XPOS is 8;
const integer: FIELD_YPOS is 64;
const integer: FIELD_BORDER is 3;
const integer: X_SHIFT is FIELD_XPOS + FIELD_BORDER - STRETCH_FACTOR * 2;
const integer: Y_SHIFT is FIELD_YPOS + FIELD_BORDER - STRETCH_FACTOR * 2;
const integer: CELL_SHIFT is 5;
const integer: CELL_SIZE is STRETCH_FACTOR - 2 * CELL_SHIFT + 1;
const integer: PIXMAP_SHIFT is CELL_SHIFT + (CELL_SIZE - PIXMAP_SIZE) div 2;
const integer: SMALL_PIXMAP_SHIFT is CELL_SHIFT + (CELL_SIZE - 3 * SMALL_PIXMAP_SIZE) div 2;
const integer: TOP_BUTTON_Y is 16;
const integer: TOP_BUTTON_MIN_X is 14;
const integer: RIGHT_BUTTON_X is X_SHIFT + STRETCH_FACTOR * 11 + 16;
const integer: RIGHT_BUTTON_MIN_Y is Y_SHIFT + STRETCH_FACTOR * 2 + CELL_SHIFT;
const integer: EXIT_BUTTON_X is 850;
const color: BACKGROUND is black;
const color: FOREGROUND is white;
var text: info is STD_NULL;
var array PRIMITIVE_WINDOW: blue_digits is 0 times PRIMITIVE_WINDOW.value;
var array PRIMITIVE_WINDOW: red_digits is 0 times PRIMITIVE_WINDOW.value;
var array PRIMITIVE_WINDOW: small_digits is 0 times PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: single_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: double_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: triple_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: exit_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: checkmark_pixmap is PRIMITIVE_WINDOW.value;
var array array integer: field is 9 times 9 times 0;
var array array bitset: candidates is 9 times 9 times EMPTY_SET;
var array array boolean: user_input is 9 times 9 times FALSE;
var boolean: blue_changes is FALSE;
var boolean: show_candidates is FALSE;
var boolean: show_solution is FALSE;
var boolean: lookForSingles is FALSE;
var boolean: lookForHiddenSingles is FALSE;
var boolean: lookForLockedCandidates is FALSE;
var boolean: lookForNakedPairs is FALSE;
var boolean: lookForNakedTriples is FALSE;
var boolean: lookForNakedQuads is FALSE;
var boolean: lookForHiddenPairs is FALSE;
var boolean: lookForHiddenTriples is FALSE;
var boolean: lookForHiddenQuads is FALSE;
var boolean: lookForXWing is FALSE;
var boolean: lookForSwordfish is FALSE;
var boolean: quit is FALSE;
const array string: blue_zero is [](
" ",
" ",
" xBBBBBBBBBc ",
" xBBc xBBc ",
" xBc xBc ",
" xBc xBc ",
" xBc xBc ",
" xBc xBc ",
" xBc xBBBc ",
" xBc xBBBBc ",
" xBc xBBBBc ",
" xBc xBBBBc ",
" xBc xBBBBc ",
" xBBc xBBBBc ",
" xBBBBBBBBBc ",
" ");
const array string: blue_one is [](
" ",
" ",
" xBBBBc ",
" xBc ",
" xBc ",
" xBc ",
" xBc ",
" xBc ",
" xBBBc ",
" xBBBBc ",
" xBBBBc ",
" xBBBBc ",
" xBBBBc ",
" xBBBBc ",
" xBBBBBBBBBBc ",
" ");
const array string: blue_two is [](
" ",
" ",
" xBBBBBBBBBc ",
" xBBc xBBc ",
" xBc xBc ",
" xBc ",
" xBc ",
" xBc ",
" xBBBBBBBBBc ",
" xBBBBc ",
" xBBBBc ",
" xBBBBc ",
" xBBBBc ",
" xBBBBc ",
" xBBBBBBBBBBBc ",
" ");
const array string: blue_three is [](
" ",
" ",
" xBBBBBBBBBc ",
" xBBc xBBc ",
" xBc xBc ",
" xBc ",
" xBc ",
" xBc ",
" xBBBBBBBBBc ",
" xBBBBc ",
" xBBBBc ",
" xBBBBc ",
" xBc xBBBBc ",
" xBBc xBBBBc ",
" xBBBBBBBBBc ",
" ");
const array string: blue_four is [](
" ",
" ",
" xBc ",
" xBc ",
" xBc ",
" xBc ",
" xBc xBc ",
" xBc xBc ",
" xBBBBBBBBBBBc ",
" xBBBBc ",
" xBBBBc ",
" xBBBBc ",
" xBBBBc ",
" xBBBBc ",
" xBBBBc ",
" ");
const array string: blue_five is [](
" ",
" ",
" xBBBBBBBBBBBc ",
" xBc ",
" xBc ",
" xBc ",
" xBc ",
" xBc ",
" xBBBBBBBBBBc ",
" xBBBBc ",
" xBBBBc ",
" xBBBBc ",
" xBc xBBBBc ",
" xBBc xBBBBc ",
" xBBBBBBBBBc ",
" ");
const array string: blue_six is [](
" ",
" ",
" xBBBBBBBBBc ",
" xBBc xBBc ",
" xBc xBc ",
" xBc ",
" xBc ",
" xBc ",
" xBBBBBBBBBBc ",
" xBc xBBBBc ",
" xBc xBBBBc ",
" xBc xBBBBc ",
" xBc xBBBBc ",
" xBBc xBBBBc ",
" xBBBBBBBBBc ",
" ");
const array string: blue_seven is [](
" ",
" ",
" xBBBBBBBBBBBc ",
" xBc ",
" xBc ",
" xBc ",
" xBc ",
" xBBc ",
" xBBBBBBc ",
" xBBBBc ",
" xBBBBc ",
" xBBBBc ",
" xBBBBc ",
" xBBBBc ",
" xBBBBc ",
" ");
const array string: blue_eight is [](
" ",
" ",
" xBBBBBBBBBc ",
" xBBc xBBc ",
" xBc xBc ",
" xBc xBc ",
" xBc xBc ",
" xBc xBc ",
" xBBBBBBBBBc ",
" xBc xBBBBc ",
" xBc xBBBBc ",
" xBc xBBBBc ",
" xBc xBBBBc ",
" xBBc xBBBBc ",
" xBBBBBBBBBc ",
" ");
const array string: blue_nine is [](
" ",
" ",
" xBBBBBBBBBc ",
" xBBc xBBc ",
" xBc xBc ",
" xBc xBc ",
" xBc xBc ",
" xBc xBc ",
" xBBBBBBBBBBc ",
" xBBBBc ",
" xBBBBc ",
" xBBBBc ",
" xBc xBBBBc ",
" xBBc xBBBBc ",
" xBBBBBBBBBc ",
" ");
const array string: red_zero is [](
" ",
" ",
" xRRRRRRRRRO ",
" xRRO xRRO ",
" xRO xRO ",
" xRO xRO ",
" xRO xRO ",
" xRO xRO ",
" xRO xRRRO ",
" xRO xRRRRO ",
" xRO xRRRRO ",
" xRO xRRRRO ",
" xRO xRRRRO ",
" xRRO xRRRRO ",
" xRRRRRRRRRO ",
" ");
const array string: red_one is [](
" ",
" ",
" xRRRRO ",
" xRO ",
" xRO ",
" xRO ",
" xRO ",
" xRO ",
" xRRRO ",
" xRRRRO ",
" xRRRRO ",
" xRRRRO ",
" xRRRRO ",
" xRRRRO ",
" xRRRRRRRRRRO ",
" ");
const array string: red_two is [](
" ",
" ",
" xRRRRRRRRRO ",
" xRRO xRRO ",
" xRO xRO ",
" xRO ",
" xRO ",
" xRO ",
" xRRRRRRRRRO ",
" xRRRRO ",
" xRRRRO ",
" xRRRRO ",
" xRRRRO ",
" xRRRRO ",
" xRRRRRRRRRRRO ",
" ");
const array string: red_three is [](
" ",
" ",
" xRRRRRRRRRO ",
" xRRO xRRO ",
" xRO xRO ",
" xRO ",
" xRO ",
" xRO ",
" xRRRRRRRRRO ",
" xRRRRO ",
" xRRRRO ",
" xRRRRO ",
" xRO xRRRRO ",
" xRRO xRRRRO ",
" xRRRRRRRRRO ",
" ");
const array string: red_four is [](
" ",
" ",
" xRO ",
" xRO ",
" xRO ",
" xRO ",
" xRO xRO ",
" xRO xRO ",
" xRRRRRRRRRRRO ",
" xRRRRO ",
" xRRRRO ",
" xRRRRO ",
" xRRRRO ",
" xRRRRO ",
" xRRRRO ",
" ");
const array string: red_five is [](
" ",
" ",
" xRRRRRRRRRRRO ",
" xRO ",
" xRO ",
" xRO ",
" xRO ",
" xRO ",
" xRRRRRRRRRRO ",
" xRRRRO ",
" xRRRRO ",
" xRRRRO ",
" xRO xRRRRO ",
" xRRO xRRRRO ",
" xRRRRRRRRRO ",
" ");
const array string: red_six is [](
" ",
" ",
" xRRRRRRRRRO ",
" xRRO xRRO ",
" xRO xRO ",
" xRO ",
" xRO ",
" xRO ",
" xRRRRRRRRRRO ",
" xRO xRRRRO ",
" xRO xRRRRO ",
" xRO xRRRRO ",
" xRO xRRRRO ",
" xRRO xRRRRO ",
" xRRRRRRRRRO ",
" ");
const array string: red_seven is [](
" ",
" ",
" xRRRRRRRRRRRO ",
" xRO ",
" xRO ",
" xRO ",
" xRO ",
" xRRO ",
" xRRRRRRO ",
" xRRRRO ",
" xRRRRO ",
" xRRRRO ",
" xRRRRO ",
" xRRRRO ",
" xRRRRO ",
" ");
const array string: red_eight is [](
" ",
" ",
" xRRRRRRRRRO ",
" xRRO xRRO ",
" xRO xRO ",
" xRO xRO ",
" xRO xRO ",
" xRO xRO ",
" xRRRRRRRRRO ",
" xRO xRRRRO ",
" xRO xRRRRO ",
" xRO xRRRRO ",
" xRO xRRRRO ",
" xRRO xRRRRO ",
" xRRRRRRRRRO ",
" ");
const array string: red_nine is [](
" ",
" ",
" xRRRRRRRRRO ",
" xRRO xRRO ",
" xRO xRO ",
" xRO xRO ",
" xRO xRO ",
" xRO xRO ",
" xRRRRRRRRRRO ",
" xRRRRO ",
" xRRRRO ",
" xRRRRO ",
" xRO xRRRRO ",
" xRRO xRRRRO ",
" xRRRRRRRRRO ",
" ");
const array string: blue_single is [](
" ",
" ",
" ",
" ",
" xBBBc ",
" xBBBBBc ",
" xBBBBBBBc ",
" xBBBBBBBc ",
" xBBBBBBBc ",
" xBBBBBc ",
" xBBBc ",
" ",
" ",
" ",
" ");
const array string: blue_double is [](
" ",
" xBBBc ",
" xBBBBBc ",
" xBBBBBc ",
" xBBBBBc ",
" xBBBc ",
" ",
" ",
" ",
" ",
" ",
" xBBBc ",
" xBBBBBc",
" xBBBBBc",
" xBBBBBc",
" xBBBc ");
const array string: blue_triple is [](
" ",
" xBc ",
" xBBBc ",
" xBBBc ",
" xBc ",
" ",
" xBc ",
" xBBBc ",
" xBBBc ",
" xBc ",
" ",
" xBc ",
" xBBBc",
" xBBBc",
" xBc ");
const array string: candidates_pic is [](
" ",
" BB BBB BBB",
" B B B",
" B B BB",
" BBB BBB BBB",
" ",
" B BBB BB",
" B B B B ",
" BBB BBB BBB",
" B BB BBB",
" ",
" BBB BBB BBB",
" B BBB BBB",
" B BBB B",
" B BBB BB ");
const proc: initCandidates is func
local
var integer: row is 0;
var integer: column is 0;
begin
for row range 1 to 9 do
for column range 1 to 9 do
if user_input[row][column] then
candidates[row][column] := {field[row][column]};
else
field[row][column] := 0;
candidates[row][column] := {1 .. 9};
rect(X_SHIFT + STRETCH_FACTOR * succ(column) + CELL_SHIFT,
Y_SHIFT + STRETCH_FACTOR * succ(row) + CELL_SHIFT,
CELL_SIZE, CELL_SIZE, BACKGROUND);
end if;
end for;
end for;
end func;
const proc: initGrid is func
local
var integer: row is 0;
var integer: column is 0;
begin
for row range 1 to 10 do
if row rem 3 = 1 then
rect(X_SHIFT + STRETCH_FACTOR * 2 - 1, Y_SHIFT + STRETCH_FACTOR * succ(row) - 1,
STRETCH_FACTOR * 9 + 3, 3, FOREGROUND);
else
line(X_SHIFT + STRETCH_FACTOR * 2, Y_SHIFT + STRETCH_FACTOR * succ(row),
STRETCH_FACTOR * 9, 0, FOREGROUND);
end if;
end for;
for column range 1 to 10 do
if column rem 3 = 1 then
rect(X_SHIFT + STRETCH_FACTOR * succ(column) - 1, Y_SHIFT + STRETCH_FACTOR * 2 - 1,
3, STRETCH_FACTOR * 9 + 3, FOREGROUND);
else
line(X_SHIFT + STRETCH_FACTOR * succ(column), Y_SHIFT + STRETCH_FACTOR * 2,
0, STRETCH_FACTOR * 9, FOREGROUND);
end if;
end for;
end func;
const proc: clearField (in integer: row, in integer: column) is func
begin
rect(X_SHIFT + STRETCH_FACTOR * succ(column) + CELL_SHIFT + 1,
Y_SHIFT + STRETCH_FACTOR * succ(row) + CELL_SHIFT + 1,
CELL_SIZE - 2, CELL_SIZE - 2, BACKGROUND);
end func;
const proc: markField (in integer: row, in integer: column) is func
begin
rect(X_SHIFT + STRETCH_FACTOR * succ(column) + CELL_SHIFT + 1,
Y_SHIFT + STRETCH_FACTOR * succ(row) + CELL_SHIFT + 1,
CELL_SIZE - 2, CELL_SIZE - 2, light_gray);
end func;
const proc: clearDigit (in integer: row, in integer: column) is func
begin
field[row][column] := 0;
user_input[row][column] := FALSE;
initCandidates;
rect(X_SHIFT + STRETCH_FACTOR * succ(column) + PIXMAP_SHIFT,
Y_SHIFT + STRETCH_FACTOR * succ(row) + PIXMAP_SHIFT,
PIXMAP_SIZE, PIXMAP_SIZE, BACKGROUND);
end func;
const proc: setRedDigit (in integer: row, in integer: column,
in integer: digit) is func
begin
field[row][column] := digit;
user_input[row][column] := TRUE;
candidates[row][column] := {digit};
clearField(row, column);
put(X_SHIFT + STRETCH_FACTOR * succ(column) + PIXMAP_SHIFT,
Y_SHIFT + STRETCH_FACTOR * succ(row) + PIXMAP_SHIFT,
red_digits[digit]);
end func;
const proc: setBlueDigit (in integer: row, in integer: column,
in integer: digit) is func
begin
field[row][column] := digit;
candidates[row][column] := {digit};
blue_changes := TRUE;
clearField(row, column);
put(X_SHIFT + STRETCH_FACTOR * succ(column) + PIXMAP_SHIFT,
Y_SHIFT + STRETCH_FACTOR * succ(row) + PIXMAP_SHIFT,
blue_digits[digit]);
end func;
const proc: writeSmallDigit (in integer: row, in integer: column,
in integer: digit) is func
begin
put(X_SHIFT + STRETCH_FACTOR * succ(column) + SMALL_PIXMAP_SHIFT +
(pred(digit) mod 3) * 16,
Y_SHIFT + STRETCH_FACTOR * succ(row) + SMALL_PIXMAP_SHIFT +
(pred(digit) div 3) * 16,
small_digits[digit]);
end func;
const proc: excludeInRow (in integer: row, in integer: digit) is func
local
var integer: column is 0;
begin
for column range 1 to 9 do
if field[row][column] = 0 then
excl(candidates[row][column], digit);
end if;
end for;
end func;
const proc: excludeInColumn (in integer: column, in integer: digit) is func
local
var integer: row is 0;
begin
for row range 1 to 9 do
if field[row][column] = 0 then
excl(candidates[row][column], digit);
end if;
end for;
end func;
const proc: excludeInBox (in integer: row, in integer: column, in integer: digit) is func
local
var integer: row1 is 0;
var integer: col1 is 0;
begin
for row1 range succ(pred(row) div 3 * 3) to succ(pred(row) div 3) * 3 do
for col1 range succ(pred(column) div 3 * 3) to succ(pred(column) div 3) * 3 do
if field[row1][col1] = 0 then
excl(candidates[row1][col1], digit);
end if;
end for;
end for;
end func;
const proc: excludeDigit (in integer: row, in integer: column) is func
begin
excludeInRow(row, field[row][column]);
excludeInColumn(column, field[row][column]);
excludeInBox(row, column, field[row][column]);
end func;
const proc: excludeFields is func
local
var integer: row is 0;
var integer: column is 0;
begin
for row range 1 to 9 do
for column range 1 to 9 do
if field[row][column] <> 0 then
excludeDigit(row, column);
end if;
end for;
end for;
end func;
const proc: showAllCandidates is func
local
var integer: row is 1;
var integer: column is 1;
var integer: digit is 0;
begin
for row range 1 to 9 do
for column range 1 to 9 do
if field[row][column] = 0 then
clearField(row, column);
box(X_SHIFT + STRETCH_FACTOR * succ(column) + CELL_SHIFT,
Y_SHIFT + STRETCH_FACTOR * succ(row) + CELL_SHIFT,
CELL_SIZE, CELL_SIZE, light_green);
for digit range 1 to 9 do
if digit in candidates[row][column] then
writeSmallDigit(row, column, digit);
end if;
end for;
elsif not user_input[row][column] then
setBlueDigit(row, column, field[row][column]);
end if;
end for;
end for;
flushGraphic;
end func;
const proc: checkSingles (inout boolean: changeDone) is func
local
var integer: row is 0;
var integer: column is 0;
var integer: digit is 0;
begin
for row range 1 to 9 do
for column range 1 to 9 do
if field[row][column] = 0 then
if card(candidates[row][column]) = 1 then
digit := min(candidates[row][column]);
field[row][column] := digit;
candidates[row][column] := {digit};
excludeDigit(row, column);
changeDone := TRUE;
end if;
end if;
end for;
end for;
end func;
const proc: checkHiddenSinglesInRow (in integer: row,
inout boolean: changeDone) is func
local
var integer: digit is 0;
var integer: column is 0;
var integer: foundColumn is 0;
var integer: foundCount is 0;
begin
for digit range 1 to 9 do
foundCount := 0;
for column range 1 to 9 do
if digit in candidates[row][column] then
foundColumn := column;
incr(foundCount);
end if;
end for;
if foundCount = 1 and field[row][foundColumn] = 0 then
field[row][foundColumn] := digit;
candidates[row][foundColumn] := {digit};
excludeDigit(row, foundColumn);
changeDone := TRUE;
end if;
end for;
end func;
const proc: checkHiddenSinglesInColumn (in integer: column,
inout boolean: changeDone) is func
local
var integer: digit is 0;
var integer: row is 0;
var integer: foundRow is 0;
var integer: foundCount is 0;
begin
for digit range 1 to 9 do
foundCount := 0;
for row range 1 to 9 do
if digit in candidates[row][column] then
foundRow := row;
incr(foundCount);
end if;
end for;
if foundCount = 1 and field[foundRow][column] = 0 then
field[foundRow][column] := digit;
candidates[foundRow][column] := {digit};
excludeDigit(foundRow, column);
changeDone := TRUE;
end if;
end for;
end func;
const proc: checkHiddenSinglesInBox (in integer: startRow, in integer: startColumn,
inout boolean: changeDone) is func
local
var integer: digit is 0;
var integer: row is 0;
var integer: column is 0;
var integer: foundRow is 0;
var integer: foundColumn is 0;
var integer: foundCount is 0;
begin
for digit range 1 to 9 do
foundCount := 0;
for row range startRow to startRow + 2 do
for column range startColumn to startColumn + 2 do
if digit in candidates[row][column] then
foundRow := row;
foundColumn := column;
incr(foundCount);
end if;
end for;
end for;
if foundCount = 1 and field[foundRow][foundColumn] = 0 then
field[foundRow][foundColumn] := digit;
candidates[foundRow][foundColumn] := {digit};
excludeDigit(foundRow, foundColumn);
changeDone := TRUE;
end if;
end for;
end func;
const proc: checkHiddenSingles (inout boolean: changeDone) is func
local
var integer: row is 0;
var integer: column is 0;
begin
for row range 1 to 9 do
checkHiddenSinglesInRow(row, changeDone);
end for;
for column range 1 to 9 do
checkHiddenSinglesInColumn(column, changeDone);
end for;
for row range 1 to 7 step 3 do
for column range 1 to 7 step 3 do
checkHiddenSinglesInBox(row, column, changeDone);
end for;
end for;
end func;
const proc: checkLockedCandidatesInRow (in integer: row,
inout boolean: changeDone) is func
local
var integer: digit is 0;
var integer: column is 0;
var integer: foundColumn is 0;
var integer: row1 is 0;
begin
for digit range 1 to 9 do
foundColumn := 0;
for column range 1 to 9 do
if digit in candidates[row][column] then
if foundColumn = 0 then
foundColumn := succ((pred(column) div 3) * 3);
elsif column < foundColumn or column > foundColumn + 2 then
foundColumn := 10;
end if;
end if;
end for;
if foundColumn in {1 .. 9} then
for row1 range succ(pred(row) div 3 * 3) to succ(pred(row) div 3) * 3 do
if row1 <> row then
for column range foundColumn to foundColumn + 2 do
if digit in candidates[row1][column] then
excl(candidates[row1][column], digit);
changeDone := TRUE;
end if;
end for;
end if;
end for;
end if;
end for;
end func;
const proc: checkLockedCandidatesInColumn (in integer: column,
inout boolean: changeDone) is func
local
var integer: digit is 0;
var integer: row is 0;
var integer: foundRow is 0;
var integer: col is 0;
begin
for digit range 1 to 9 do
foundRow := 0;
for row range 1 to 9 do
if digit in candidates[row][column] then
if foundRow = 0 then
foundRow := succ((pred(row) div 3) * 3);
elsif row < foundRow or row > foundRow + 2 then
foundRow := 10;
end if;
end if;
end for;
if foundRow in {1 .. 9} then
for col range succ(pred(column) div 3 * 3) to succ(pred(column) div 3) * 3 do
if col <> column then
for row range foundRow to foundRow + 2 do
if digit in candidates[row][col] then
excl(candidates[row][col], digit);
changeDone := TRUE;
end if;
end for;
end if;
end for;
end if;
end for;
end func;
const proc: checkLockedCandidatesInBox (in integer: startRow, in integer: startColumn,
inout boolean: changeDone) is func
local
var integer: digit is 0;
var integer: row is 0;
var integer: column is 0;
var integer: foundRow is 0;
var integer: foundColumn is 0;
begin
for digit range 1 to 9 do
foundRow := 0;
foundColumn := 0;
for row range startRow to startRow + 2 do
for column range startColumn to startColumn + 2 do
if digit in candidates[row][column] then
if foundRow = 0 then
foundRow := row;
elsif foundRow <> row then
foundRow := 10;
end if;
if foundColumn = 0 then
foundColumn := column;
elsif foundColumn <> column then
foundColumn := 10;
end if;
end if;
end for;
end for;
if foundRow in {1 .. 9} then
for column range 1 to 9 do
if column < startColumn or column > startColumn + 2 then
if digit in candidates[foundRow][column] then
excl(candidates[foundRow][column], digit);
changeDone := TRUE;
end if;
end if;
end for;
end if;
if foundColumn in {1 .. 9} then
for row range 1 to 9 do
if row < startRow or row > startRow + 2 then
if digit in candidates[row][foundColumn] then
excl(candidates[row][foundColumn], digit);
changeDone := TRUE;
end if;
end if;
end for;
end if;
end for;
end func;
const proc: checkLockedCandidates (inout boolean: changeDone) is func
local
var integer: row is 0;
var integer: column is 0;
begin
for row range 1 to 9 do
checkLockedCandidatesInRow(row, changeDone);
end for;
for column range 1 to 9 do
checkLockedCandidatesInColumn(column, changeDone);
end for;
for row range 1 to 7 step 3 do
for column range 1 to 7 step 3 do
checkLockedCandidatesInBox(row, column, changeDone);
end for;
end for;
end func;
const proc: checkNakedPairsInRow (in integer: row,
inout boolean: changeDone) is func
local
var integer: col1 is 0;
var integer: col2 is 0;
var integer: column is 0;
var set of integer: pairSet is EMPTY_SET;
begin
for col1 range 1 to 8 do
if card(candidates[row][col1]) = 2 then
pairSet := candidates[row][col1];
for col2 range succ(col1) to 9 do
if candidates[row][col2] = pairSet then
for column range 1 to 9 do
if column <> col1 and column <> col2 and
card(candidates[row][column] & pairSet) <> 0 then
candidates[row][column] := candidates[row][column] - pairSet;
changeDone := TRUE;
end if;
end for;
end if;
end for;
end if;
end for;
end func;
const proc: checkNakedPairsInColumn (in integer: column,
inout boolean: changeDone) is func
local
var integer: row1 is 0;
var integer: row2 is 0;
var integer: row is 0;
var set of integer: pairSet is EMPTY_SET;
begin
for row1 range 1 to 8 do
if card(candidates[row1][column]) = 2 then
pairSet := candidates[row1][column];
for row2 range succ(row1) to 9 do
if candidates[row2][column] = pairSet then
for row range 1 to 9 do
if row <> row1 and row <> row2 and
card(candidates[row][column] & pairSet) <> 0 then
candidates[row][column] := candidates[row][column] - pairSet;
changeDone := TRUE;
end if;
end for;
end if;
end for;
end if;
end for;
end func;
const proc: checkNakedPairsInBox (in integer: startRow, in integer: startColumn,
inout boolean: changeDone) is func
local
var integer: row1 is 0;
var integer: row2 is 0;
var integer: col1 is 0;
var integer: col2 is 0;
var integer: row is 0;
var integer: column is 0;
var set of integer: pairSet is EMPTY_SET;
begin
for row1 range startRow to startRow + 2 do
for col1 range startColumn to startColumn + 2 do
if card(candidates[row1][col1]) = 2 then
pairSet := candidates[row1][col1];
for row2 range startRow to startRow + 2 do
for col2 range startColumn to startColumn + 2 do
if (row2 <> row1 or col2 <> col1) and
candidates[row2][col2] = pairSet then
for row range startRow to startRow + 2 do
for column range startColumn to startColumn + 2 do
if (row <> row1 or column <> col1) and
(row <> row2 or column <> col2) and
card(candidates[row][column] & pairSet) <> 0 then
candidates[row][column] := candidates[row][column] - pairSet;
changeDone := TRUE;
end if;
end for;
end for;
end if;
end for;
end for;
end if;
end for;
end for;
end func;
const proc: checkNakedPairs (inout boolean: changeDone) is func
local
var integer: row is 0;
var integer: column is 0;
begin
for row range 1 to 9 do
checkNakedPairsInRow(row, changeDone);
end for;
for column range 1 to 9 do
checkNakedPairsInColumn(column, changeDone);
end for;
for row range 1 to 7 step 3 do
for column range 1 to 7 step 3 do
checkNakedPairsInBox(row, column, changeDone);
end for;
end for;
end func;
const proc: checkNakedTriplesInRow (in integer: row,
inout boolean: changeDone) is func
local
var integer: col1 is 0;
var integer: col2 is 0;
var integer: col3 is 0;
var integer: column is 0;
var set of integer: tripleSet is EMPTY_SET;
begin
for col1 range 1 to 7 do
if card(candidates[row][col1]) in {2, 3} then
for col2 range succ(col1) to 8 do
if card(candidates[row][col2]) >= 2 and
card(candidates[row][col1] | candidates[row][col2]) <= 3 then
for col3 range succ(col2) to 9 do
if card(candidates[row][col3]) >= 2 then
tripleSet := candidates[row][col1] | candidates[row][col2] |
candidates[row][col3];
if card(tripleSet) = 3 then
for column range 1 to 9 do
if column <> col1 and column <> col2 and column <> col3 and
card(candidates[row][column] & tripleSet) <> 0 then
candidates[row][column] := candidates[row][column] - tripleSet;
changeDone := TRUE;
end if;
end for;
end if;
end if;
end for;
end if;
end for;
end if;
end for;
end func;
const proc: checkNakedTriplesInColumn (in integer: column,
inout boolean: changeDone) is func
local
var integer: row1 is 0;
var integer: row2 is 0;
var integer: row3 is 0;
var integer: row is 0;
var set of integer: tripleSet is EMPTY_SET;
begin
for row1 range 1 to 7 do
if card(candidates[row1][column]) in {2, 3} then
for row2 range succ(row1) to 8 do
if card(candidates[row2][column]) >= 2 and
card(candidates[row1][column] | candidates[row2][column]) <= 3 then
for row3 range succ(row2) to 9 do
if card(candidates[row3][column]) >= 2 then
tripleSet := candidates[row1][column] | candidates[row2][column] |
candidates[row3][column];
if card(tripleSet) = 3 then
for row range 1 to 9 do
if row <> row1 and row <> row2 and row <> row3 and
card(candidates[row][column] & tripleSet) <> 0 then
candidates[row][column] := candidates[row][column] - tripleSet;
changeDone := TRUE;
end if;
end for;
end if;
end if;
end for;
end if;
end for;
end if;
end for;
end func;
const proc: checkNakedTriplesInBox (in integer: startRow, in integer: startColumn,
inout boolean: changeDone) is func
local
var integer: row1 is 0;
var integer: row2 is 0;
var integer: row3 is 0;
var integer: col1 is 0;
var integer: col2 is 0;
var integer: col3 is 0;
var integer: row is 0;
var integer: column is 0;
var set of integer: tripleSet is EMPTY_SET;
begin
for row1 range startRow to startRow + 2 do
for col1 range startColumn to startColumn + 2 do
if card(candidates[row1][col1]) in {2, 3} then
for row2 range startRow to startRow + 2 do
for col2 range startColumn to startColumn + 2 do
if (row2 <> row1 or col2 <> col1) and
card(candidates[row2][col2]) >= 2 and
card(candidates[row1][col1] | candidates[row2][col2]) <= 3 then
for row3 range startRow to startRow + 2 do
for col3 range startColumn to startColumn + 2 do
if (row3 <> row1 or col3 <> col1) and
(row3 <> row2 or col3 <> col2) and
card(candidates[row3][col3]) >= 2 then
tripleSet := candidates[row1][col1] | candidates[row2][col2] |
candidates[row3][col3];
if card(tripleSet) = 3 then
for row range startRow to startRow + 2 do
for column range startColumn to startColumn + 2 do
if (row <> row1 or column <> col1) and
(row <> row2 or column <> col2) and
(row <> row3 or column <> col3) and
card(candidates[row][column] & tripleSet) <> 0 then
candidates[row][column] := candidates[row][column] - tripleSet;
changeDone := TRUE;
end if;
end for;
end for;
end if;
end if;
end for;
end for;
end if;
end for;
end for;
end if;
end for;
end for;
end func;
const proc: checkNakedTriples (inout boolean: changeDone) is func
local
var integer: row is 0;
var integer: column is 0;
begin
for row range 1 to 9 do
checkNakedTriplesInRow(row, changeDone);
end for;
for column range 1 to 9 do
checkNakedTriplesInColumn(column, changeDone);
end for;
for row range 1 to 7 step 3 do
for column range 1 to 7 step 3 do
checkNakedTriplesInBox(row, column, changeDone);
end for;
end for;
end func;
const proc: checkNakedQuadsInRow (in integer: row,
inout boolean: changeDone) is func
local
var integer: col1 is 0;
var integer: col2 is 0;
var integer: col3 is 0;
var integer: col4 is 0;
var integer: column is 0;
var set of integer: quadSet is EMPTY_SET;
begin
for col1 range 1 to 6 do
if card(candidates[row][col1]) in {2, 3, 4} then
for col2 range succ(col1) to 7 do
if card(candidates[row][col2]) >= 2 and
card(candidates[row][col1] | candidates[row][col2]) <= 4 then
for col3 range succ(col2) to 8 do
if card(candidates[row][col3]) >= 2 and
card(candidates[row][col1] | candidates[row][col2] |
candidates[row][col3]) <= 4 then
for col4 range succ(col3) to 9 do
if card(candidates[row][col4]) >= 2 then
quadSet := candidates[row][col1] | candidates[row][col2] |
candidates[row][col3] | candidates[row][col4];
if card(quadSet) = 4 then
for column range 1 to 9 do
if column <> col1 and column <> col2 and column <> col3 and column <> col4 and
card(candidates[row][column] & quadSet) <> 0 then
candidates[row][column] := candidates[row][column] - quadSet;
changeDone := TRUE;
end if;
end for;
end if;
end if;
end for;
end if;
end for;
end if;
end for;
end if;
end for;
end func;
const proc: checkNakedQuadsInColumn (in integer: column,
inout boolean: changeDone) is func
local
var integer: row1 is 0;
var integer: row2 is 0;
var integer: row3 is 0;
var integer: row4 is 0;
var integer: row is 0;
var set of integer: quadSet is EMPTY_SET;
begin
for row1 range 1 to 6 do
if card(candidates[row1][column]) in {2, 3, 4} then
for row2 range succ(row1) to 7 do
if card(candidates[row2][column]) >= 2 and
card(candidates[row1][column] | candidates[row2][column]) <= 4 then
for row3 range succ(row2) to 8 do
if card(candidates[row3][column]) >= 2 and
card(candidates[row1][column] | candidates[row2][column] |
candidates[row3][column]) <= 4 then
for row4 range succ(row3) to 9 do
if card(candidates[row4][column]) >= 2 then
quadSet := candidates[row1][column] | candidates[row2][column] |
candidates[row3][column] | candidates[row4][column];
if card(quadSet) = 4 then
for row range 1 to 9 do
if row <> row1 and row <> row2 and row <> row3 and row <> row4 and
card(candidates[row][column] & quadSet) <> 0 then
candidates[row][column] := candidates[row][column] - quadSet;
changeDone := TRUE;
end if;
end for;
end if;
end if;
end for;
end if;
end for;
end if;
end for;
end if;
end for;
end func;
const proc: checkNakedQuadsInBox (in integer: startRow, in integer: startColumn,
inout boolean: changeDone) is func
local
var integer: row1 is 0;
var integer: row2 is 0;
var integer: row3 is 0;
var integer: row4 is 0;
var integer: col1 is 0;
var integer: col2 is 0;
var integer: col3 is 0;
var integer: col4 is 0;
var integer: row is 0;
var integer: column is 0;
var set of integer: quadSet is EMPTY_SET;
begin
for row1 range startRow to startRow + 2 do
for col1 range startColumn to startColumn + 2 do
if card(candidates[row1][col1]) in {2, 3, 4} then
for row2 range startRow to startRow + 2 do
for col2 range startColumn to startColumn + 2 do
if (row2 <> row1 or col2 <> col1) and
card(candidates[row2][col2]) >= 2 and
card(candidates[row1][col1] | candidates[row2][col2]) <= 4 then
for row3 range startRow to startRow + 2 do
for col3 range startColumn to startColumn + 2 do
if (row3 <> row1 or col3 <> col1) and
(row3 <> row2 or col3 <> col2) and
card(candidates[row3][col3]) >= 2 and
card(candidates[row1][col1] | candidates[row2][col2] |
candidates[row3][col3]) <= 4 then
for row4 range startRow to startRow + 2 do
for col4 range startColumn to startColumn + 2 do
if (row4 <> row1 or col4 <> col1) and
(row4 <> row2 or col4 <> col2) and
(row4 <> row3 or col4 <> col3) and
card(candidates[row4][col4]) >= 2 then
quadSet := candidates[row1][col1] | candidates[row2][col2] |
candidates[row3][col3] | candidates[row4][col4];
if card(quadSet) = 4 then
for row range startRow to startRow + 2 do
for column range startColumn to startColumn + 2 do
if (row <> row1 or column <> col1) and
(row <> row2 or column <> col2) and
(row <> row3 or column <> col3) and
(row <> row4 or column <> col4) and
card(candidates[row][column] & quadSet) <> 0 then
candidates[row][column] := candidates[row][column] - quadSet;
changeDone := TRUE;
end if;
end for;
end for;
end if;
end if;
end for;
end for;
end if;
end for;
end for;
end if;
end for;
end for;
end if;
end for;
end for;
end func;
const proc: checkNakedQuads (inout boolean: changeDone) is func
local
var integer: row is 0;
var integer: column is 0;
begin
for row range 1 to 9 do
checkNakedQuadsInRow(row, changeDone);
end for;
for column range 1 to 9 do
checkNakedQuadsInColumn(column, changeDone);
end for;
for row range 1 to 7 step 3 do
for column range 1 to 7 step 3 do
checkNakedQuadsInBox(row, column, changeDone);
end for;
end for;
end func;
const proc: checkHiddenPairsInRow (in integer: row,
inout boolean: changeDone) is func
local
var integer: column is 0;
var integer: digit1 is 0;
var integer: digit2 is 0;
var array set of integer: columnsWithDigit is 9 times EMPTY_SET;
var set of integer: pairColumns is EMPTY_SET;
var set of integer: pairSet is EMPTY_SET;
begin
for column range 1 to 9 do
for digit1 range candidates[row][column] do
incl(columnsWithDigit[digit1], column);
end for;
end for;
for digit1 range 1 to 8 do
if card(columnsWithDigit[digit1]) = 2 then
pairColumns := columnsWithDigit[digit1];
for digit2 range succ(digit1) to 9 do
if columnsWithDigit[digit2] = pairColumns then
pairSet := {digit1, digit2};
for column range pairColumns do
if card(candidates[row][column] - pairSet) <> 0 then
candidates[row][column] := pairSet;
changeDone := TRUE;
end if;
end for;
end if;
end for;
end if;
end for;
end func;
const proc: checkHiddenPairsInColumn (in integer: column,
inout boolean: changeDone) is func
local
var integer: row is 0;
var integer: digit1 is 0;
var integer: digit2 is 0;
var array set of integer: rowsWithDigit is 9 times EMPTY_SET;
var set of integer: pairRows is EMPTY_SET;
var set of integer: pairSet is EMPTY_SET;
begin
for row range 1 to 9 do
for digit1 range candidates[row][column] do
incl(rowsWithDigit[digit1], row);
end for;
end for;
for digit1 range 1 to 8 do
if card(rowsWithDigit[digit1]) = 2 then
pairRows := rowsWithDigit[digit1];
for digit2 range succ(digit1) to 9 do
if rowsWithDigit[digit2] = pairRows then
pairSet := {digit1, digit2};
for row range pairRows do
if card(candidates[row][column] - pairSet) <> 0 then
candidates[row][column] := pairSet;
changeDone := TRUE;
end if;
end for;
end if;
end for;
end if;
end for;
end func;
const proc: checkHiddenPairsInBox (in integer: startRow, in integer: startColumn,
inout boolean: changeDone) is func
local
var integer: row is 0;
var integer: column is 0;
var integer: digit1 is 0;
var integer: digit2 is 0;
var array set of integer: cellsWithDigit is 9 times EMPTY_SET;
var set of integer: pairCells is EMPTY_SET;
var set of integer: pairSet is EMPTY_SET;
begin
for row range startRow to startRow + 2 do
for column range startColumn to startColumn + 2 do
for digit1 range candidates[row][column] do
incl(cellsWithDigit[digit1], succ(pred(row) * 3 + pred(column)));
end for;
end for;
end for;
for digit1 range 1 to 8 do
if card(cellsWithDigit[digit1]) = 2 then
pairCells := cellsWithDigit[digit1];
for digit2 range succ(digit1) to 9 do
if cellsWithDigit[digit2] = pairCells then
pairSet := {digit1, digit2};
for row range startRow to startRow + 2 do
for column range startColumn to startColumn + 2 do
if succ(pred(row) * 3 + pred(column)) in pairCells then
if card(candidates[row][column] - pairSet) <> 0 then
candidates[row][column] := pairSet;
changeDone := TRUE;
end if;
end if;
end for;
end for;
end if;
end for;
end if;
end for;
end func;
const proc: checkHiddenPairs (inout boolean: changeDone) is func
local
var integer: row is 0;
var integer: column is 0;
begin
for row range 1 to 9 do
checkHiddenPairsInRow(row, changeDone);
end for;
for column range 1 to 9 do
checkHiddenPairsInColumn(column, changeDone);
end for;
for row range 1 to 7 step 3 do
for column range 1 to 7 step 3 do
checkHiddenPairsInBox(row, column, changeDone);
end for;
end for;
end func;
const proc: checkHiddenTriplesInRow (in integer: row,
inout boolean: changeDone) is func
local
var integer: column is 0;
var integer: digit1 is 0;
var integer: digit2 is 0;
var integer: digit3 is 0;
var array set of integer: columnsWithDigit is 9 times EMPTY_SET;
var set of integer: tripleColumns is EMPTY_SET;
var set of integer: tripleSet is EMPTY_SET;
begin
for column range 1 to 9 do
for digit1 range candidates[row][column] do
incl(columnsWithDigit[digit1], column);
end for;
end for;
for digit1 range 1 to 7 do
if card(columnsWithDigit[digit1]) in {2, 3} then
for digit2 range succ(digit1) to 8 do
if card(columnsWithDigit[digit2]) >= 2 and
card(columnsWithDigit[digit1] | columnsWithDigit[digit2]) <= 3 then
for digit3 range succ(digit2) to 9 do
if card(columnsWithDigit[digit3]) >= 2 then
tripleColumns := columnsWithDigit[digit1] | columnsWithDigit[digit2] |
columnsWithDigit[digit3];
if card(tripleColumns) = 3 then
tripleSet := {digit1, digit2, digit3};
for column range tripleColumns do
if card(candidates[row][column] - tripleSet) <> 0 then
candidates[row][column] := candidates[row][column] -
(candidates[row][column] - tripleSet);
changeDone := TRUE;
end if;
end for;
end if;
end if;
end for;
end if;
end for;
end if;
end for;
end func;
const proc: checkHiddenTriplesInColumn (in integer: column,
inout boolean: changeDone) is func
local
var integer: row is 0;
var integer: digit1 is 0;
var integer: digit2 is 0;
var integer: digit3 is 0;
var array set of integer: rowsWithDigit is 9 times EMPTY_SET;
var set of integer: tripleRows is EMPTY_SET;
var set of integer: tripleSet is EMPTY_SET;
begin
for row range 1 to 9 do
for digit1 range candidates[row][column] do
incl(rowsWithDigit[digit1], row);
end for;
end for;
for digit1 range 1 to 7 do
if card(rowsWithDigit[digit1]) in {2, 3} then
for digit2 range succ(digit1) to 8 do
if card(rowsWithDigit[digit2]) >= 2 and
card(rowsWithDigit[digit1] | rowsWithDigit[digit2]) <= 3 then
for digit3 range succ(digit2) to 9 do
if card(rowsWithDigit[digit3]) >= 2 then
tripleRows := rowsWithDigit[digit1] | rowsWithDigit[digit2] |
rowsWithDigit[digit3];
if card(tripleRows) = 3 then
tripleSet := {digit1, digit2, digit3};
for row range tripleRows do
if card(candidates[row][column] - tripleSet) <> 0 then
candidates[row][column] := candidates[row][column] -
(candidates[row][column] - tripleSet);
changeDone := TRUE;
end if;
end for;
end if;
end if;
end for;
end if;
end for;
end if;
end for;
end func;
const proc: checkHiddenTriplesInBox (in integer: startRow, in integer: startColumn,
inout boolean: changeDone) is func
local
var integer: row is 0;
var integer: column is 0;
var integer: digit1 is 0;
var integer: digit2 is 0;
var integer: digit3 is 0;
var array set of integer: cellsWithDigit is 9 times EMPTY_SET;
var set of integer: tripleCells is EMPTY_SET;
var set of integer: tripleSet is EMPTY_SET;
begin
for row range startRow to startRow + 2 do
for column range startColumn to startColumn + 2 do
for digit1 range candidates[row][column] do
incl(cellsWithDigit[digit1], succ(pred(row) * 3 + pred(column)));
end for;
end for;
end for;
for digit1 range 1 to 7 do
if card(cellsWithDigit[digit1]) in {2, 3} then
for digit2 range succ(digit1) to 8 do
if card(cellsWithDigit[digit2]) >= 2 and
card(cellsWithDigit[digit1] | cellsWithDigit[digit2]) <= 3 then
for digit3 range succ(digit2) to 9 do
if card(cellsWithDigit[digit3]) >= 2 then
tripleCells := cellsWithDigit[digit1] | cellsWithDigit[digit2] |
cellsWithDigit[digit3];
if card(tripleCells) = 3 then
tripleSet := {digit1, digit2, digit3};
for row range startRow to startRow + 2 do
for column range startColumn to startColumn + 2 do
if succ(pred(row) * 3 + pred(column)) in tripleCells then
if card(candidates[row][column] - tripleSet) <> 0 then
candidates[row][column] := candidates[row][column] -
(candidates[row][column] - tripleSet);
changeDone := TRUE;
end if;
end if;
end for;
end for;
end if;
end if;
end for;
end if;
end for;
end if;
end for;
end func;
const proc: checkHiddenTriples (inout boolean: changeDone) is func
local
var integer: row is 0;
var integer: column is 0;
begin
for row range 1 to 9 do
checkHiddenTriplesInRow(row, changeDone);
end for;
for column range 1 to 9 do
checkHiddenTriplesInColumn(column, changeDone);
end for;
for row range 1 to 7 step 3 do
for column range 1 to 7 step 3 do
checkHiddenTriplesInBox(row, column, changeDone);
end for;
end for;
end func;
const proc: checkHiddenQuadsInRow (in integer: row,
inout boolean: changeDone) is func
local
var integer: column is 0;
var integer: digit1 is 0;
var integer: digit2 is 0;
var integer: digit3 is 0;
var integer: digit4 is 0;
var array set of integer: columnsWithDigit is 9 times EMPTY_SET;
var set of integer: quadColumns is EMPTY_SET;
var set of integer: quadSet is EMPTY_SET;
begin
for column range 1 to 9 do
for digit1 range candidates[row][column] do
incl(columnsWithDigit[digit1], column);
end for;
end for;
for digit1 range 1 to 6 do
if card(columnsWithDigit[digit1]) in {2, 3, 4} then
for digit2 range succ(digit1) to 7 do
if card(columnsWithDigit[digit2]) >= 2 and
card(columnsWithDigit[digit1] | columnsWithDigit[digit2]) <= 4 then
for digit3 range succ(digit2) to 8 do
if card(columnsWithDigit[digit3]) >= 2 and
card(columnsWithDigit[digit1] | columnsWithDigit[digit2] |
columnsWithDigit[digit3]) <= 4 then
for digit4 range succ(digit3) to 9 do
if card(columnsWithDigit[digit4]) >= 2 then
quadColumns := columnsWithDigit[digit1] | columnsWithDigit[digit2] |
columnsWithDigit[digit3] | columnsWithDigit[digit4];
if card(quadColumns) = 4 then
quadSet := {digit1, digit2, digit3, digit4};
for column range quadColumns do
if card(candidates[row][column] - quadSet) <> 0 then
candidates[row][column] := candidates[row][column] -
(candidates[row][column] - quadSet);
changeDone := TRUE;
end if;
end for;
end if;
end if;
end for;
end if;
end for;
end if;
end for;
end if;
end for;
end func;
const proc: checkHiddenQuadsInColumn (in integer: column,
inout boolean: changeDone) is func
local
var integer: row is 0;
var integer: digit1 is 0;
var integer: digit2 is 0;
var integer: digit3 is 0;
var integer: digit4 is 0;
var array set of integer: rowsWithDigit is 9 times EMPTY_SET;
var set of integer: quadRows is EMPTY_SET;
var set of integer: quadSet is EMPTY_SET;
begin
for row range 1 to 9 do
for digit1 range candidates[row][column] do
incl(rowsWithDigit[digit1], row);
end for;
end for;
for digit1 range 1 to 6 do
if card(rowsWithDigit[digit1]) in {2, 3, 4} then
for digit2 range succ(digit1) to 7 do
if card(rowsWithDigit[digit2]) >= 2 and
card(rowsWithDigit[digit1] | rowsWithDigit[digit2]) <= 4 then
for digit3 range succ(digit2) to 8 do
if card(rowsWithDigit[digit3]) >= 2 and
card(rowsWithDigit[digit1] | rowsWithDigit[digit2] |
rowsWithDigit[digit3]) <= 4 then
for digit4 range succ(digit3) to 9 do
if card(rowsWithDigit[digit4]) >= 2 then
quadRows := rowsWithDigit[digit1] | rowsWithDigit[digit2] |
rowsWithDigit[digit3] | rowsWithDigit[digit4];
if card(quadRows) = 4 then
quadSet := {digit1, digit2, digit3, digit4};
for row range quadRows do
if card(candidates[row][column] - quadSet) <> 0 then
candidates[row][column] := candidates[row][column] -
(candidates[row][column] - quadSet);
changeDone := TRUE;
end if;
end for;
end if;
end if;
end for;
end if;
end for;
end if;
end for;
end if;
end for;
end func;
const proc: checkHiddenQuadsInBox (in integer: startRow, in integer: startColumn,
inout boolean: changeDone) is func
local
var integer: row is 0;
var integer: column is 0;
var integer: digit1 is 0;
var integer: digit2 is 0;
var integer: digit3 is 0;
var integer: digit4 is 0;
var array set of integer: cellsWithDigit is 9 times EMPTY_SET;
var set of integer: quadCells is EMPTY_SET;
var set of integer: quadSet is EMPTY_SET;
begin
for row range startRow to startRow + 2 do
for column range startColumn to startColumn + 2 do
for digit1 range candidates[row][column] do
incl(cellsWithDigit[digit1], succ(pred(row) * 3 + pred(column)));
end for;
end for;
end for;
for digit1 range 1 to 6 do
if card(cellsWithDigit[digit1]) in {2, 3, 4} then
for digit2 range succ(digit1) to 7 do
if card(cellsWithDigit[digit2]) >= 2 and
card(cellsWithDigit[digit1] | cellsWithDigit[digit2]) <= 4 then
for digit3 range succ(digit2) to 8 do
if card(cellsWithDigit[digit3]) >= 2 and
card(cellsWithDigit[digit1] | cellsWithDigit[digit2] |
cellsWithDigit[digit3]) <= 4 then
for digit4 range succ(digit3) to 9 do
if card(cellsWithDigit[digit4]) >= 2 then
quadCells := cellsWithDigit[digit1] | cellsWithDigit[digit2] |
cellsWithDigit[digit3] | cellsWithDigit[digit4];
if card(quadCells) = 4 then
quadSet := {digit1, digit2, digit3, digit4};
for row range startRow to startRow + 2 do
for column range startColumn to startColumn + 2 do
if succ(pred(row) * 3 + pred(column)) in quadCells then
if card(candidates[row][column] - quadSet) <> 0 then
candidates[row][column] := candidates[row][column] -
(candidates[row][column] - quadSet);
changeDone := TRUE;
end if;
end if;
end for;
end for;
end if;
end if;
end for;
end if;
end for;
end if;
end for;
end if;
end for;
end func;
const proc: checkHiddenQuads (inout boolean: changeDone) is func
local
var integer: row is 0;
var integer: column is 0;
begin
for row range 1 to 9 do
checkHiddenQuadsInRow(row, changeDone);
end for;
for column range 1 to 9 do
checkHiddenQuadsInColumn(column, changeDone);
end for;
for row range 1 to 7 step 3 do
for column range 1 to 7 step 3 do
checkHiddenQuadsInBox(row, column, changeDone);
end for;
end for;
end func;
const proc: checkXWingForDigit (in integer: digit,
inout boolean: changeDone) is func
local
var integer: row is 0;
var integer: row1 is 0;
var integer: row2 is 0;
var integer: column is 0;
var integer: column1 is 0;
var integer: column2 is 0;
var array set of integer: rowsInColumn is 9 times EMPTY_SET;
var array set of integer: columnsInRow is 9 times EMPTY_SET;
var set of integer: xWingColumns is EMPTY_SET;
var set of integer: xWingRows is EMPTY_SET;
begin
for row1 range 1 to 9 do
for column1 range 1 to 9 do
if digit in candidates[row1][column1] then
incl(rowsInColumn[column1], row1);
incl(columnsInRow[row1], column1);
end if;
end for;
end for;
for row1 range 1 to 8 do
if card(columnsInRow[row1]) = 2 then
xWingColumns := columnsInRow[row1];
for row2 range succ(row1) to 9 do
if columnsInRow[row2] = xWingColumns then
for row range 1 to 9 do
if row <> row1 and row <> row2 then
if card(columnsInRow[row] & xWingColumns) <> 0 then
for column range 1 to 9 do
if column in xWingColumns then
excl(candidates[row][column], digit);
end if;
end for;
changeDone := TRUE;
end if;
end if;
end for;
end if;
end for;
end if;
end for;
for column1 range 1 to 8 do
if card(rowsInColumn[column1]) = 2 then
xWingRows := rowsInColumn[column1];
for column2 range succ(column1) to 9 do
if rowsInColumn[column2] = xWingRows then
for column range 1 to 9 do
if column <> column1 and column <> column2 then
if card(rowsInColumn[column] & xWingRows) <> 0 then
for row range 1 to 9 do
if row in xWingRows then
excl(candidates[row][column], digit);
end if;
end for;
changeDone := TRUE;
end if;
end if;
end for;
end if;
end for;
end if;
end for;
end func;
const proc: checkXWing (inout boolean: changeDone) is func
local
var integer: digit is 0;
begin
for digit range 1 to 9 do
checkXWingForDigit(digit, changeDone);
end for;
end func;
const proc: checkSwordfishForDigit (in integer: digit,
inout boolean: changeDone) is func
local
var integer: row is 0;
var integer: row1 is 0;
var integer: row2 is 0;
var integer: row3 is 0;
var integer: column is 0;
var integer: column1 is 0;
var integer: column2 is 0;
var integer: column3 is 0;
var array set of integer: rowsInColumn is 9 times EMPTY_SET;
var array set of integer: columnsInRow is 9 times EMPTY_SET;
var set of integer: swordfishColumns is EMPTY_SET;
var set of integer: swordfishRows is EMPTY_SET;
begin
for row1 range 1 to 9 do
for column1 range 1 to 9 do
if digit in candidates[row1][column1] then
incl(rowsInColumn[column1], row1);
incl(columnsInRow[row1], column1);
end if;
end for;
end for;
for row1 range 1 to 7 do
if card(columnsInRow[row1]) in {2, 3} then
for row2 range succ(row1) to 8 do
if card(columnsInRow[row2]) >= 2 and
card(columnsInRow[row1] | columnsInRow[row2]) <= 3 then
for row3 range succ(row2) to 9 do
if card(columnsInRow[row3]) >= 2 then
swordfishColumns := columnsInRow[row1] | columnsInRow[row2] |
columnsInRow[row3];
if card(swordfishColumns) = 3 then
for row range 1 to 9 do
if row <> row1 and row <> row2 and row <> row3 then
if card(columnsInRow[row] & swordfishColumns) <> 0 then
for column range 1 to 9 do
if column in swordfishColumns then
excl(candidates[row][column], digit);
end if;
end for;
changeDone := TRUE;
end if;
end if;
end for;
end if;
end if;
end for;
end if;
end for;
end if;
end for;
for column1 range 1 to 7 do
if card(rowsInColumn[column1]) in {2, 3} then
for column2 range succ(column1) to 8 do
if card(rowsInColumn[column2]) >= 2 and
card(rowsInColumn[column1] | rowsInColumn[column2]) <= 3 then
for column3 range succ(column2) to 9 do
if card(rowsInColumn[column3]) >= 2 then
swordfishRows := rowsInColumn[column1] | rowsInColumn[column2] |
rowsInColumn[column3];
if card(swordfishRows) = 3 then
for column range 1 to 9 do
if column <> column1 and column <> column2 and column <> column3 then
if card(rowsInColumn[column] & swordfishRows) <> 0 then
for row range 1 to 9 do
if row in swordfishRows then
excl(candidates[row][column], digit);
end if;
end for;
changeDone := TRUE;
end if;
end if;
end for;
end if;
end if;
end for;
end if;
end for;
end if;
end for;
end func;
const proc: checkSwordfish (inout boolean: changeDone) is func
local
var integer: digit is 0;
begin
for digit range 1 to 9 do
checkSwordfishForDigit(digit, changeDone);
end for;
end func;
const proc: solve is func
local
var boolean: changeDone is FALSE;
begin
repeat
changeDone := FALSE;
excludeFields;
if lookForSingles then
checkSingles(changeDone);
end if;
if lookForHiddenSingles then
checkHiddenSingles(changeDone);
end if;
if lookForLockedCandidates then
checkLockedCandidates(changeDone);
end if;
if lookForNakedPairs then
checkNakedPairs(changeDone);
end if;
if lookForNakedTriples then
checkNakedTriples(changeDone);
end if;
if lookForNakedQuads then
checkNakedQuads(changeDone);
end if;
if lookForHiddenPairs then
checkHiddenPairs(changeDone);
end if;
if lookForHiddenTriples then
checkHiddenTriples(changeDone);
end if;
if lookForHiddenQuads then
checkHiddenQuads(changeDone);
end if;
if lookForXWing then
checkXWing(changeDone);
end if;
if lookForSwordfish then
checkSwordfish(changeDone);
end if;
until not changeDone;
end func;
const proc: blueChanges is func
begin
repeat
blue_changes := FALSE;
excludeFields;
flushGraphic;
until not blue_changes;
end func;
const func char: readCommand (in integer: row, in integer: column) is func
result
var char: command is ' ';
begin
command := getc(KEYBOARD);
box(X_SHIFT + STRETCH_FACTOR * succ(column) + CELL_SHIFT,
Y_SHIFT + STRETCH_FACTOR * succ(row) + CELL_SHIFT,
CELL_SIZE, CELL_SIZE, BACKGROUND);
end func;
const proc: showSolved is func
local
var integer: row is 1;
var integer: column is 1;
begin
for row range 1 to 9 do
for column range 1 to 9 do
if not user_input[row][column] and field[row][column] <> 0 then
clearField(row, column);
setBlueDigit(row, column, field[row][column]);
end if;
end for;
end for;
end func;
const proc: showNumberOfCandidates (in integer: number) is func
local
var integer: row is 1;
var integer: column is 1;
begin
for row range 1 to 9 do
for column range 1 to 9 do
if field[row][column] = 0 then
clearField(row, column);
if card(candidates[row][column]) = number then
markField(row, column);
end if;
end if;
end for;
end for;
end func;
const proc: showCandidatesDigit (in integer: number) is func
local
var integer: row is 1;
var integer: column is 1;
begin
for row range 1 to 9 do
for column range 1 to 9 do
if field[row][column] = 0 then
clearField(row, column);
if number in candidates[row][column] then
markField(row, column);
end if;
end if;
end for;
end for;
end func;
const proc: showCandidates is func
local
var integer: row is 1;
var integer: column is 1;
var integer: digit is 0;
begin
for row range 1 to 9 do
for column range 1 to 9 do
if field[row][column] = 0 then
for digit range 1 to 9 do
if digit in candidates[row][column] then
writeSmallDigit(row, column, digit);
end if;
end for;
end if;
end for;
end for;
end func;
const proc: showStrategyCheckboxes is func
local
var integer: number is 0;
var boolean: button_is_on is FALSE;
begin
rect(RIGHT_BUTTON_X - 6, RIGHT_BUTTON_MIN_Y - 3 + 39 * 2, 256, 39 * 11, black);
for number range 3 to 13 do
box(RIGHT_BUTTON_X + 4, RIGHT_BUTTON_MIN_Y + 4 + 39 * pred(number), 24, 24, FOREGROUND);
setPosXY(info, 45, RIGHT_BUTTON_MIN_Y + 18 + 39 * pred(number));
case number of
when {3}:
write(info, "singles");
button_is_on := lookForSingles;
when {4}:
write(info, "hidden singles");
button_is_on := lookForHiddenSingles;
when {5}:
write(info, "locked candidates");
button_is_on := lookForLockedCandidates;
when {6}:
write(info, "naked pairs");
button_is_on := lookForNakedPairs;
when {7}:
write(info, "naked triples");
button_is_on := lookForNakedTriples;
when {8}:
write(info, "naked quads");
button_is_on := lookForNakedQuads;
when {9}:
write(info, "hidden pairs");
button_is_on := lookForHiddenPairs;
when {10}:
write(info, "hidden triples");
button_is_on := lookForHiddenTriples;
when {11}:
write(info, "hidden quads");
button_is_on := lookForHiddenQuads;
when {12}:
write(info, "x-wing");
button_is_on := lookForXWing;
when {13}:
write(info, "swordfish");
button_is_on := lookForSwordfish;
end case;
if button_is_on then
put(RIGHT_BUTTON_X + 8, RIGHT_BUTTON_MIN_Y + 8 + 39 * pred(number),
checkmark_pixmap);
else
rect(RIGHT_BUTTON_X + 8, RIGHT_BUTTON_MIN_Y + 8 + 39 * pred(number),
16, 16, BACKGROUND);
end if;
end for;
end func;
const proc: hideStrategyCheckboxes is func
begin
rect(RIGHT_BUTTON_X - 6, RIGHT_BUTTON_MIN_Y - 3 + 39 * 2, 256, 39 * 11, black);
end func;
const proc: showButtons is func
local
var integer: number is 0;
begin
for number range 0 to 12 do
box(TOP_BUTTON_MIN_X + 48 * number, TOP_BUTTON_Y, 32, 32, FOREGROUND);
case number of
when {1 .. 9}:
put(TOP_BUTTON_MIN_X + 8 + 48 * number, TOP_BUTTON_Y + 8,
small_digits[number]);
when {10}:
put(TOP_BUTTON_MIN_X + 8 + 48 * number, TOP_BUTTON_Y + 8,
single_pixmap);
when {11}:
put(TOP_BUTTON_MIN_X + 8 + 48 * number, TOP_BUTTON_Y + 8,
double_pixmap);
when {12}:
put(TOP_BUTTON_MIN_X + 8 + 48 * number, TOP_BUTTON_Y + 8,
triple_pixmap);
end case;
end for;
put(EXIT_BUTTON_X, TOP_BUTTON_Y, exit_pixmap);
for number range 1 to 2 do
box(RIGHT_BUTTON_X + 4, RIGHT_BUTTON_MIN_Y + 4 + 39 * pred(number), 24, 24, FOREGROUND);
setPosXY(info, 45, RIGHT_BUTTON_MIN_Y + 18 + 39 * pred(number));
case number of
when {1}:
write(info, "show candidates");
when {2}:
write(info, "show solution");
end case;
end for;
end func;
const proc: loadField (in string: stri) is func
local
var integer: number is 0;
var integer: row is 0;
var integer: column is 0;
begin
if length(stri) = 81 then
for number range 1 to 81 do
row := succ(pred(number) div 9);
column := succ(pred(number) rem 9);
if stri[number] in {'1' .. '9'} then
setRedDigit(row, column, ord(stri[number]) - ord('0'));
end if;
end for;
end if;
end func;
const proc: processCommand is func
local
var integer: x is 0;
var integer: y is 0;
var integer: row is 1;
var integer: column is 1;
var integer: candidate_digit is 0;
var integer: button_num is 0;
var boolean: button_is_on is FALSE;
var integer: digit is 0;
var char: command is ' ';
begin
showButtons;
repeat
box(X_SHIFT + STRETCH_FACTOR * succ(column) + CELL_SHIFT,
Y_SHIFT + STRETCH_FACTOR * succ(row) + CELL_SHIFT,
CELL_SIZE, CELL_SIZE, light_red);
flushGraphic;
if show_solution then
solve;
showSolved;
end if;
if candidate_digit >= 10 then
showNumberOfCandidates(candidate_digit - 9);
else
showCandidatesDigit(candidate_digit);
end if;
if show_candidates then
showCandidates;
end if;
repeat
command := readCommand(row, column);
case command of
when {KEY_DOWN}:
if row < 9 then
incr(row);
else
row := 1;
end if;
when {KEY_UP}:
if row > 1 then
decr(row);
else
row := 9;
end if;
when {KEY_RIGHT}:
if column < 9 then
incr(column);
else
column := 1;
end if;
when {KEY_LEFT}:
if column > 1 then
decr(column);
else
column := 9;
end if;
when {KEY_HOME}:
row := 1;
when {KEY_END}:
row := 9;
when {KEY_PGUP}:
column := 1;
when {KEY_PGDN}:
column := 9;
when {'q', 'Q', KEY_CLOSE}:
quit := TRUE;
when {KEY_ESC}:
bossMode(quit);
when {'1' .. '9'}:
if field[row][column] <> 0 then
clearDigit(row, column);
blueChanges;
end if;
if ord(command) - ord('0') in candidates[row][column] then
setRedDigit(row, column, ord(command) - ord('0'));
blueChanges;
end if;
when {' '}:
clearDigit(row, column);
when {KEY_MOUSE1}:
x := clickedXPos(KEYBOARD);
y := clickedYPos(KEYBOARD);
if x >= X_SHIFT + STRETCH_FACTOR * 2 + 1 and
x <= X_SHIFT + STRETCH_FACTOR * 11 and
y >= Y_SHIFT + STRETCH_FACTOR * 2 + 1 and
y <= Y_SHIFT + STRETCH_FACTOR * 11 then
row := pred(y - Y_SHIFT) div STRETCH_FACTOR - 1;
column := pred(x - X_SHIFT) div STRETCH_FACTOR - 1;
elsif y >= TOP_BUTTON_Y and y <= TOP_BUTTON_Y + 32 and
x >= TOP_BUTTON_MIN_X and x <= TOP_BUTTON_MIN_X + 32 + 48 * 12 and
(x - TOP_BUTTON_MIN_X) rem 48 <= 32 then
box(TOP_BUTTON_MIN_X + 4 + 48 * candidate_digit, TOP_BUTTON_Y + 4, 24, 24, BACKGROUND);
candidate_digit := (x - TOP_BUTTON_MIN_X) div 48;
box(TOP_BUTTON_MIN_X + 4 + 48 * candidate_digit, TOP_BUTTON_Y + 4, 24, 24, FOREGROUND);
elsif y >= TOP_BUTTON_Y and y <= TOP_BUTTON_Y + 32 and
x >= EXIT_BUTTON_X and x <= EXIT_BUTTON_X + 32 then
quit := TRUE;
elsif x >= RIGHT_BUTTON_X and x <= RIGHT_BUTTON_X + 32 and
y >= RIGHT_BUTTON_MIN_Y and y <= RIGHT_BUTTON_MIN_Y + 32 + 39 * 12 and
(y - RIGHT_BUTTON_MIN_Y) rem 39 <= 32 then
button_num := (y - RIGHT_BUTTON_MIN_Y) div 39;
case button_num of
when {0}:
show_candidates := not show_candidates;
button_is_on := show_candidates;
when {1}:
show_solution := not show_solution;
button_is_on := show_solution;
if not show_solution then
hideStrategyCheckboxes;
initCandidates;
blueChanges;
else
showStrategyCheckboxes;
end if;
end case;
if show_solution then
case button_num of
when {2}:
lookForSingles := not lookForSingles;
if not lookForSingles then
initCandidates;
blueChanges;
end if;
button_is_on := lookForSingles;
when {3}:
lookForHiddenSingles := not lookForHiddenSingles;
if not lookForHiddenSingles then
initCandidates;
blueChanges;
end if;
button_is_on := lookForHiddenSingles;
when {4}:
lookForLockedCandidates := not lookForLockedCandidates;
if not lookForLockedCandidates then
initCandidates;
blueChanges;
end if;
button_is_on := lookForLockedCandidates;
when {5}:
lookForNakedPairs := not lookForNakedPairs;
if not lookForNakedPairs then
initCandidates;
blueChanges;
end if;
button_is_on := lookForNakedPairs;
when {6}:
lookForNakedTriples := not lookForNakedTriples;
if not lookForNakedTriples then
initCandidates;
blueChanges;
end if;
button_is_on := lookForNakedTriples;
when {7}:
lookForNakedQuads := not lookForNakedQuads;
if not lookForNakedQuads then
initCandidates;
blueChanges;
end if;
button_is_on := lookForNakedQuads;
when {8}:
lookForHiddenPairs := not lookForHiddenPairs;
if not lookForHiddenPairs then
initCandidates;
blueChanges;
end if;
button_is_on := lookForHiddenPairs;
when {9}:
lookForHiddenTriples := not lookForHiddenTriples;
if not lookForHiddenTriples then
initCandidates;
blueChanges;
end if;
button_is_on := lookForHiddenTriples;
when {10}:
lookForHiddenQuads := not lookForHiddenQuads;
if not lookForHiddenQuads then
initCandidates;
blueChanges;
end if;
button_is_on := lookForHiddenQuads;
when {11}:
lookForXWing := not lookForXWing;
if not lookForXWing then
initCandidates;
blueChanges;
end if;
button_is_on := lookForXWing;
when {12}:
lookForSwordfish := not lookForSwordfish;
if not lookForSwordfish then
initCandidates;
blueChanges;
end if;
button_is_on := lookForSwordfish;
end case;
end if;
if show_solution or button_num <= 1 then
if button_is_on then
put(RIGHT_BUTTON_X + 8, RIGHT_BUTTON_MIN_Y + 8 + 39 * button_num,
checkmark_pixmap);
else
rect(RIGHT_BUTTON_X + 8, RIGHT_BUTTON_MIN_Y + 8 + 39 * button_num,
16, 16, BACKGROUND);
end if;
end if;
end if;
when {KEY_MOUSE3}:
x := clickedXPos(KEYBOARD);
y := clickedYPos(KEYBOARD);
if x >= X_SHIFT + STRETCH_FACTOR * 2 + 1 and
x <= X_SHIFT + STRETCH_FACTOR * 11 and
y >= Y_SHIFT + STRETCH_FACTOR * 2 + 1 and
y <= Y_SHIFT + STRETCH_FACTOR * 11 then
row := pred(y - Y_SHIFT) div STRETCH_FACTOR - 1;
column := pred(x - X_SHIFT) div STRETCH_FACTOR - 1;
x -:= pred(column) * STRETCH_FACTOR + FIELD_XPOS + 12;
y -:= pred(row) * STRETCH_FACTOR + FIELD_YPOS + 12;
if x >= 0 and x < 48 and y >= 0 and y < 48 then
digit := 1 + x div 16 + 3 * (y div 16);
if digit in candidates[row][column] then
excl(candidates[row][column], digit);
else
incl(candidates[row][column], digit);
end if;
end if;
end if;
end case;
until not inputReady(KEYBOARD);
until quit;
end func;
const proc: writeCentered (inout text: screen, in integer: yPos, in string: stri) is func
begin
setPosXY(screen, (WINDOW_WIDTH - 632 - width(stdFont9, stri)) div 2, yPos);
writeln(screen, stri);
end func;
const proc: main is func
begin
screen(WINDOW_WIDTH, WINDOW_HEIGHT);
selectInput(curr_win, KEY_CLOSE, TRUE);
clear(BACKGROUND);
info := openPixmapFontFile(curr_win, 630, 0);
setFont(info, stdFont9);
color(info, white, black);
KEYBOARD := GRAPH_KEYBOARD;
writeCentered(info, 280, "S U D O K U 7");
writeCentered(info, 312, "Copyright (C) 2006 Thomas Mertes");
writeCentered(info, 344, "This program is free software under the");
writeCentered(info, 360, "terms of the GNU General Public License");
writeCentered(info, 392, "Sudoku7 is written in the");
writeCentered(info, 408, "Seed7 programming language.");
writeCentered(info, 440, "Homepage: http://seed7.sourceforge.net");
initGrid;
blue_digits := [0](
createPixmap(blue_zero, 2, BACKGROUND),
createPixmap(blue_one, 2, BACKGROUND),
createPixmap(blue_two, 2, BACKGROUND),
createPixmap(blue_three, 2, BACKGROUND),
createPixmap(blue_four, 2, BACKGROUND),
createPixmap(blue_five, 2, BACKGROUND),
createPixmap(blue_six, 2, BACKGROUND),
createPixmap(blue_seven, 2, BACKGROUND),
createPixmap(blue_eight, 2, BACKGROUND),
createPixmap(blue_nine, 2, BACKGROUND));
red_digits := [0](
createPixmap(red_zero, 2, BACKGROUND),
createPixmap(red_one, 2, BACKGROUND),
createPixmap(red_two, 2, BACKGROUND),
createPixmap(red_three, 2, BACKGROUND),
createPixmap(red_four, 2, BACKGROUND),
createPixmap(red_five, 2, BACKGROUND),
createPixmap(red_six, 2, BACKGROUND),
createPixmap(red_seven, 2, BACKGROUND),
createPixmap(red_eight, 2, BACKGROUND),
createPixmap(red_nine, 2, BACKGROUND));
small_digits := [0](
createPixmap(blue_zero, 1, BACKGROUND),
createPixmap(blue_one, 1, BACKGROUND),
createPixmap(blue_two, 1, BACKGROUND),
createPixmap(blue_three, 1, BACKGROUND),
createPixmap(blue_four, 1, BACKGROUND),
createPixmap(blue_five, 1, BACKGROUND),
createPixmap(blue_six, 1, BACKGROUND),
createPixmap(blue_seven, 1, BACKGROUND),
createPixmap(blue_eight, 1, BACKGROUND),
createPixmap(blue_nine, 1, BACKGROUND));
single_pixmap := createPixmap(blue_single, 1, BACKGROUND);
double_pixmap := createPixmap(blue_double, 1, BACKGROUND);
triple_pixmap := createPixmap(blue_triple, 1, BACKGROUND);
exit_pixmap := createPixmap(exit_pic, 2, BACKGROUND);
checkmark_pixmap := createPixmap(checkmark_pic, 1, BACKGROUND);
initCandidates;
processCommand;
end func;