Soduku Generator
The First Limbo Program I wrote :-)
-it may be noticeable that it took a bit longer and got a lot more complicated than I expected lol, Nick
# An engine to build sudoku boards.# - Nick Grayson, 2005
implement sud;
sud : module
{
init : fn(ctxt : ref Draw->Context, nil : list of string);
};
# start of global variable definitions
BOARDSIZE : int = 9; # Width and Height of the board
NUMBER_SIZE : int = 9; # What the random number should be modulised to
stuck : int; # This is not a nice variable to have
verticalstart : int; # Position on the board ( vertical )
horizontalstart : int; # Position on the borad ( horizontal )
numbersin : int; # Amount of numbers added into each 3by3 box
sudokus : int; # Number of Sudoku Boards to print out
hasitreset : int; # This would probably be better served by a return value
i : int;
f : int;
y : int;
x : int;
d : int;
a : int;
BOARD := array [9] of { * => array[9] of int}; #Stores Sudoku Board
NAT := array [9] of { * => array[9] of int}; #number accross test
NDT := array [9] of { * => array[9] of int}; #number down test
NBT := array [9] of int; #number 3 by 3 box test
ININE := array [9] of int; #Checks random interger has been all the numbers 0 through to 8
include "sys.m";
include "draw.m";
include "rand.m";
include "keyring.m";
include "security.m";
rand : Rand;
sys : Sys;
print: import sys;
#
#
# Main body of the program.
#
init(ctxt : ref Draw->Context, nil : list of string)
{
sys = load Sys Sys->PATH;
random := load Random Random->PATH;
rand = load Rand Rand->PATH;
rand->init(random->randomint(Random->ReallyRandom));
#controls how many sudokus are printed and starts go to make them
while(sudokus<1){
go();
printsoduku();
sudokus=sudokus+1;
}
}
# Function declaration
#calls sudoku generator for each of the nine 3 by 3 boxes in the Sudoku
go() {
gofor: for(verticalstart=0;verticalstart<7; verticalstart=verticalstart+3) {
for(horizontalstart=0;horizontalstart<7; horizontalstart=horizontalstart+3) {
clearbox();
generator(horizontalstart, verticalstart);
if(hasitreset > 0) {
break gofor;
}
}
}
if(hasitreset > 0) {
reset();
go();
}
}
# calls makebox and checks if it works
generator(horizontalstart, verticalstart : int) {
stuck = 0 ;
numbersin=0;
while (numbersin != 9 ) {
makebox();
stuck= stuck + 1;
if (stuck > 50) {
hasitreset= 1;
return;
}
}
}
#Makes 3 by 3 box
makebox(){
for(a = horizontalstart;a <(horizontalstart+3) ;a++) {
for(d = verticalstart; d <(verticalstart+3);d++) {
f = 0 ;
clearININE();
while(f < 1) {
i = rand->rand(NUMBER_SIZE);
if(ININE[i] == 0) {
ININE[i] = (ININE[i] +1);
if((NAT[a][i] == 0) && (NDT[d][i] == 0) && (NBT[i] == 0)) {
BOARD[a][d] = i;
NAT[a][i] = (NAT[a][i]+1);
NDT[d][i] = (NDT[d][i]+1);
NBT[i] = (NBT[i] +1);
f= ++f;
numbersin=numbersin+1;
}
}
else {
if((ININE[0]+ININE[1]+ININE[2]+ININE[3]+ININE[4]+ININE[5]+ININE[6]+ININE[7]+ININE[8])==9) {
clearININE();
return;
}
}
}
}
}
}
# Resets back to 0 everything that is required to make a 3 by 3 box
# Used between generating the 3 by 3 boxes and if there has been no possible 3 by 3 box found
reset() {
verticalstart=0;
horizontalstart=0;
hasitreset=0;
for(y=0;y<BOARDSIZE;y++) {
for(x=0;x<BOARDSIZE;x++) {
NAT[y][x]=0;
NDT[y][x]=0;
}
}
clearbox();
}
# Clears the array checking that each number in the 3 by 3 box is used only once
# Used between generating the 3 by 3 boxes and if there has been no possible 3 by 3 box found
clearbox() {
x=0;
for(x=0;x<BOARDSIZE;x++) # Resetting clearbox to 0
{
NBT[x]= 0;
}
}
# Clears the array checking ensuring that the numbers 0 through 8 are tried at each postion in the Sudoku board if necesarry
# Used after each number is added to the board and if there is no possible number that can be added
clearININE() {
x=0;
for(x=0;x<BOARDSIZE;x++) # Resetting ININE to 0
{
ININE[x]= 0;
}
}
# Prints Sudoku
printsoduku() {
for(y=0;y<BOARDSIZE;y++){
for(x=0;x<BOARDSIZE;x++) {
print("%d ",BOARD[y][x]);
}
print("\n");
}
print("\n");
}