Anda di halaman 1dari 18

Hong Kong Certificate of Education Examination 2007

Computer and Information Technology

Coursework
Report
Module A (Algorithm and Programming): Sudoku
Game

Candidate Name: Chan Hing Faat


Class: 5D
Seat Number: 2
Date: 05 December, 2006
Forewords
Introduction

Sudoku also known as Number Place or Nanpure, is a logic-based placement puzzle. The
aim of the puzzle is to enter a numerical digit from 1 through 9 in each cell of a 9*9 grid
made up of 3*3 sub grids (called "regions"), starting with various digits given in some
cells (the "givens"); each row, column, and region must contain only one instance of each
numeral. Completing the puzzle requires patience and logical ability.

Objectives
The main objective of this coursework is to write a program for playing a Sudoku game.
The program should be able to receive input from the user and print the layout of the
game grid as output. Apart from that, it should also be capable of setting up puzzles and
checking the user’s solution.

About this report


The report covers four essential aspects: solution designs, tests, enhancements and
evaluations. In solution designs, the basic model of a Sudoku game is evaluated and
defined. Also, there is an investigation for suitable programming languages. The part of
tests includes the results and conclusions. In enhancements, I will consider elements
which are based on the basic model and can add more colors to the game. Finally, in the
evaluations, I will make an overall conclusion. On top of that, I will share what I have
learnt from this coursework.

Solution designs
By the problem solving technique, divide-and-conquer, I find that this big task can be
divided into simpler tasks which are easier to deal with. However, since some are
dependent on other, I have to solve them one-by-one logically.

Basic structures
Programming is just like architecture, the stronger the base, the stronger the building.
Thus the basic structures should be well-organized to make further works easier.
Fortunately, there are only two elements for carrying out a Sudoku game. They are cell
and Sudoku grid.

Cell

A cell is a box containing its possible numbers. It is said to be unknown if it contains


more than one possible number. Among two cells, they can be compared to determine
whether both of them contain the same number or not.

Sudoku grid
Theoretical speaking, a Sudoku grid can be represented by a 2-dimensional n*n-sized
array, with each entry is a cell. In this coursework, 9*9-sized Sudoku grid is usually
referred.

Basic functions
With the two elements, I still need some operations with respects of them and the user.
Input
A Sudoku grid contains n*n cells and each cell has its own position. Therefore, the user
must enter the column number, the row number, and a value to be assigned.

Output
The output is an n*n square, known cells are shown as their numbers inside according to
their positions. The unknown cells leave blank.

Puzzle solver
Definition
A puzzle solver is not a must but it definitely helps a lot. For instance, it can check the
answer submitted by the user. In addition, it broadens my horizons in the field of
computer programming.

Analysis
In order to be familiar with the steps computers make to solve a Sudoku puzzle, I carry
experiments on paper. In the experiments, a 4x4 grid like the below one is required.

1,2,3, 1,2,3, 1,2,3, 1,2,3,4


4 4 4
1,2,3, 1,2,3, 1,2,3, 1,2,3,4
4 4 4
1,2,3, 1,2,3, 1,2,3, 1,2,3,4
4 4 4
1,2,3, 1,2,3, 1,2,3, 1,2,3,4
4 4 4

Experiment A: Basic algorithm

Initially each cell has 4 possible values, i.e. 1,2,3,4. When a puzzle is given, some cells
will have only one possible value. For example, the grid would look like the following:

1 1,2,3, 1,2,3, 3
4 4
1,2,3, 1,2,3, 2 1,2,3,4
4 4
1,2,3, 1 1,2,3, 1,2,3,4
4 4
4 1,2,3, 1,2,3, 2
4 4

According to Sudoku’s rules, each row, column, and region must not contain more than
one instance of a number. We now go through from the 1st box to the last one. If a box
has only one possible value, we can check other boxes on the same row, column and
region. For the boxes which could also have that value, reduce that value from them. If a
box has no possible values after reduction, then it is impossible to solve this puzzle.

Checked box on each step is underlined:

1 2,3,4 2,3,4 3
2,3,4 2,3,4 2 1,2,3,4

2,3,4 1 1,2,3, 1,2,3,4


4
4 1,2,3, 1,2,3, 2
4 4

1 2,4 2,4 3
2,3,4 2,3,4 2 1,2,4

2,3,4 1 1,2,3, 1,2,4


4
4 1,2,3, 1,2,3, 2
4 4

1 2,4 4 3
3,4 3,4 2 1, 4

2,3,4 1 1,3,4 1,2,4


4 1,2,3, 1,3,4 2
4

1 2,4 4 3
3,4 3,4 2 1, 4

2,3,4 1 3,4 2,4


4 2,3,4 1,3,4 2

1 2,4 4 3
3 3,4 2 1, 4

2,3 1 3,4 2,4


4 2,3 1,3 2
1 2,4 4 3
3 3,4 2 1, 4

2,3 1 3,4 4
4 3 1,3 2

Then we make a new turn, starting from the 1st box again. Do the same things until the
number of boxes with only one possible value become 16. Finally, the solved grid will be
obtained:

1 2 4 3
3 4 2 1

2 1 3 4
4 3 1 2

In conclusion, computers can solve a easy Sudoku puzzle by using simple loops. And the
dimension of a Sudoku grid must be 3, i.e. a 9*9 Sudoku grid should be an array like
arr[9][9][9], in order to do such task.

Experiment B: Solve by guessing

After we use the basic algorithm i.e. scanning to solve a Sudoku puzzle, sometimes we
meet a problem as described below:

1 2 4 3
3 4 2 1

2 1,3 1,3 4
4 1,3 1,3 2

The computer can do nothing as there are two possible solutions. However, if the
computer makes a guess, it will finally get a solution. To make things easier, it will
search for the cell with smallest number of possible values. Then it makes a copy of the
grid and assigns one of the possible values into the corresponding cell. Solve the copy by
scanning and do guess if necessary. If the copy does not have a solution, make another
guess for the original grid. In this manner, a recursion is formed.
To conclude, when the number of cells with only one possible value is not increased after
scanning, guessing must be used. The programming technique, recursive function i.e.
function calls itself, can be adapted.

Implementation

Puzzle generator
Definition
A proper Sudoku puzzle has a unique solution. In this task, I have to write a proper
Sudoku puzzle generator, which can generate at random due to the game play.

Analysis
At first, I consider how to generate a Sudoku puzzle that must have solution. This should
require the use of the solver that has been done. Second, I consider how to check the
number of solutions of a Sudoku puzzle.

Implementation & Debugging


My first idea is that first generate an empty grid and then fill in some 26 cells. Only
assign a number randomly chosen from the possible numbers in a cell. When some 26
cells are assigned, use the solver to check if the puzzle has solution. If no, do the process
again. However, this is too slow as puzzles with no solution are usually generated and the
solver consumes time. So I give up this idea.
Afterwards, I try to reverse my thought. What if generate an answer first? Yes, it works. I
can use the solver to generate a solved Sudoku puzzle. Then just set some 55 cells as
unknowns. So the puzzle must have at least one solution.

Now I have to define a function for checking the number of solutions of a Sudoku puzzle.
Soon I find meaningless and almost impossible, as the number may be extremely large.
What I want is a Boolean value indicates if a puzzle has only one solution. So when the
counter becomes 2, then the function will return false i.e. the puzzle has more than one
solution. Notice, the counter must be greater than or equal to 1 since the puzzle must have
at least one solution.

With the function stated above, I can check the uniqueness of a Sudoku puzzle. So I
modify the generator: after it generates a random puzzle, it will generate another one if
that one does not have a unique solution. However, the same problem happens again i.e.
puzzles with no unique solution are usually generated and the solver consumes time.

Finally, I found that I can check the uniqueness whenever a cell is set as unknown.
Although the frequency of the uniqueness checking function increases many, the overall
speed is increased greatly and the generation takes 500 milliseconds at average on my
antique computer. The main reason is related to probability.

First, let Ei be the probability of the event that the puzzle still can be proper after the ith
chosen cell is set as unknown. By my original method, some 26 cells are set as unknowns
before the puzzle is checked for uniqueness. Hence the probability of the event that the
puzzle can be proper when the 26th chosen cell is set as unknown is E1*E2*E3*...*E26,
which is almost impossible to happen.

Then let's consider this practical method. If the puzzle does not pass the checking after
the ith randomly chosen cell is set as unknown, then the generator will choose another ith
randomly chosen cell and set it as unknown. In this way, when the ith cell is chosen
randomly, the puzzle still can be proper and there are i-1 unknown cells. Also, the
probability of that the puzzle still can be proper is Ei but not E1*E2*E3*...*Ei.
Therefore, it is more likely to generate a proper Sudoku puzzle.

This theory can be illustrated by throwing five dice to get all dice faced 1. When you
throw the five dice together, the probability of that all five dice face 1 is 1/6 raised to the
power of 5. Almost impossible. However, if it is allowed that you can keep dice faced 1,
you can done the task in just a few throws.

First throw (keep the 3 dice faced 1)


Second throw (keep the new die faced 1)

Third throw (The task is finished)


There are also other benefits brought by this kind of generation. Apparently, when the
user finishes his puzzle, the program does not need to check his answer by solving the
puzzle to check. Instead, since the puzzle has only one solution, the program first saves
the answer, which is generated by the puzzle generator before, into an array, so it can
check the cells one-by-one. This requires much less time than generating the answer.

Languages comparison & selection


Since I know some programming medium which is capable of making a Sudoku game, I
first take a look into their abilities and differences.

Name C Flash C#

Type Imperative Script Object-oriented

Platform availability Any platforms Any browsers .NET only

Computational speed Very fast Very slow Fair

Ease of drawing eye- Very difficult, need Very easy. Also Easy with nice
candy user-interface supports from makes interactive developing
graphic libraries user-interface environment e.g.
Visual Studio
Ease of debugging Good Poor Good

Obviously, C is the best for making experimental programs as I need fast output rather
than beautiful output. Moreover, it is relatively easy to debug a C program.
After I finish the basic model in C, I translate all the codes into Flash Action Script.
Owing to the weak computational power of Flash, the Flash program can only generate
Sudoku puzzles which may have more than one solution. And it cannot solve a Sudoku
puzzle. This is not what I want so I decide to find another possible solution.

I think I can make use of the Internet. Firstly, I write a server program for doing
complicated works such as puzzle generation in C#. Then the flash client gets puzzles
from it. But the problem is that writing a networking structure is quite time-consuming.
Also I cannot switch on my computer everyday.

Fortunately I remember that Flash projector can call an external executables e.g. a C
program. With this clue, I soon realize a simple and working solution. A C program can
write to disk and a Flash can read from disk. In other words, they can communicate via a
file. To generate a puzzle, trigger the C program in the Flash program. Then C program
will generate puzzle and answer, and then save them to two respective files. Then the
Flash program reads the two files and presents the data in a beautiful way. The result, at
which I am surprised, is perfect.

Tests
Now I have proper Sudoku puzzles, but I have no idea at which level of difficulty they
should be rated. In order to find out what factors affect the game play of a Sudoku puzzle,
I carry out the following tests.

Stage 1: By human
My classmates love dealing with Sudoku puzzles so they could be a very good testing
platform. After all, the user is human. The thing that I want them to test for me is the
game play.

I give one of my classmates who is an experienced Sudoku puzzle player two Sudoku
puzzles. One has 36 givens and another has 25 givens. She solved that with 36 givens in a
few minutes and said its difficulty should be rated of two stars out of five. For the one
with 25 givens, she spent at least 30 minutes and said its difficulty should be at four stars.
From the result, I could conclude that the difficulty of a Sudoku puzzle increases with
significant decreasing number of its givens.

Stage 2: By computer
I generate a Sudoku puzzles and save it into a file so I can test with the same puzzle any
time. Surprisingly, I find that the steps taken by the solver to solve the same puzzle can
be different from time to time. Since the solver solves randomly, I guess that the
difficulty of a puzzle depends on your luck. Sometimes, you need to guess a number to
continue the game. But if you guess wrong you may need to take more steps to get the
solution. Just like quiting a maze, you need to go back if you make a wrong turn.

Enhancements
After building the robust base, I can start to build it up and make it more attractive. Some
enhancements are unseen to the user whereas they are mainly for speeding up the
program. Others are graphical enhancements which make the program more user-
friendly.

Optimizations
Code optimizations involve logical thinking. The aim is to do fewer jobs but still achieve
desirable results.

Structures
Although a cell can be transformed into a 9-sized char array, a grid's memory
consumption is thus as high as 9*9*9*8 bits and the operations such as comparison
requires many steps to get results.

Consider the characteristics of a 9-bit variable. It is an arrangement of 9 bits, so it can


replace the array storing 9 possible numbers in this way:

000000001 represents only 1 is possible,


000000010 represents only 2 is possible,
000000100 represents only 3 is possible, and so on.

Also, 000000101 represents 1 and 3 are possible numbers,


000000000 represents no possible numbers,
111111111 represents 1 to 9 are all possible, and so on.

In programming languages, there are bitwise operations. They are AND, OR, NOT, etc.
With them, comparison between two cells can be written in just one line: if (a & b).
Variable a and b are compared if they contain the same possible number. If a equals
000000001 and b equals 000000101, then the result is true because both they contain 1 as
a possible number.
In a run, the number of cells created is huge and most time is spent on their operations.
After adapting this change, the program can run much more efficiently.

Algorithms
This basic model of the algorithm works, but not efficiently. Therefore, I make some
changes to the code in order to achieve the same result in a cleverer and faster way.

In some essential parts of the code, I write to make some possible answers at random. If
some may fail, they will be rejected. However, I cannot take it granted that they will not
come back i.e. the rand() function generates them again. For example, the generator only
assigns unknown to cells with given numbers randomly. When there are more unknown
cells, the number of failure attempts made by the generator increases certainly.

Eventually I invented a programming technique to solve this problem. First of all, declare
an array ans and a variable n indicates its size. Fill the array with possible answers and set
n as its size. Every choosing a possible answers randomly, randomize a variable k
between 0 to n-1 i.e. k = rand()%n. Take the answer by referring to ans[k] and decrease n
by 1. At last, copy ans[n] to ans[k] so the taken answer ans[k] is eliminated. The number
of failure attempts could be made by the generator is minimized.

Graphics
Flash is weak at computing so creation of lots of graphical entities in the same scene can
cause lag. Then I avoid putting too much visual effects in the program to help improve its
smoothness.

Utility functions
The utility functions are not a must for standard Sudoku game but can make the game far
more exciting and interesting.

Timer
A timer can count how long the user takes to finish a Sudoku puzzle. In normal mode, the
user can see how long he spends on the puzzle. In challenging mode, the user will lose
the game once the timer reaches the limited time.

Hints
Sometimes the user would want to give up as they think the puzzle is too difficult. In
order to keep him playing, it should be given option whether he would like a hint or not.
A hint is given in the way that he is told if there are wrong numbers in some cells, or the
possible numbers of a randomly chosen unknown cell. He needs to guess if there is more
than one possible number. In normal mode, the number of hints is unlimited. In
challenging mode, the number of hints is limited to 5.
User-interface
User-interface is a very important topic in programming software, especially for gaming
software.

How to input
Only a single mouse is required for playing the game. To assign a number to a cell, first
choose the wanted number by pressing its cell on the list at right, then press any editable
cells and their number will be the number chosen. The first blank cell on the list is used
to erase the number of a cell.

Later I find that it is too fussy to play the game by click and click only. There should be
shortcuts for the user to choose the number he wants at instant. The Key Listener object
in Flash Action Script can help me to achieve this. When the user presses down a number
key on the keyboard, the listener will change the selected number to assign. By default,
pressing down 0 will change to erasing state.

Eye-candy graphics

Flash is a godsend for making fascinating user-interface easily. The components such as
buttons are shadowed so they appear to be more textured. In addition, there is a feature of
Flash called Tweening, it helps make the components look motional.

Sound effects and music


Different music can create different atmospheres for the user to choose. In advance,
adding sound effects makes the game more realistic.

Game play
One could feel boring with Sudoku games when he gets no challenge. So the program
should give freedom to the user to choose the level of difficulty. Two different modes are
provided.

Normal mode
In normal mode, the user can play Sudoku games without limitation of time and hints.
Besides, the user can see how long he has spent.

Time attack mode


This challenging mode is suitable for Sudoku experts. Without hints, the user must solve
the puzzle in limited time. Initially, he is given 60 seconds. Every time he makes a
correct answer, he will get extra 10 seconds for bonus. But if he makes wrong answer, he
will lose 10 seconds for punishment.

Evaluations
Conclusion
The overall conclusion about this coursework is listed below.

• An n*n Sudoku game involves the operations among n*n cells.


• The user must enter the column number, the row number, and a value to be
assigned for input.
• A Sudoku puzzle can be solved by counting 1 to 9 in regions, rows, and columns
to identify missing numbers and guessing.
• Based on the solver, the generator can generate proper Sudoku puzzle by
removing givens without affecting the uniqueness of the solution.
• A Flash program can communicate with a C program so to achieve both fast
computation and beautiful user-interface.
• The difficulty of a Sudoku puzzle increases with significant decreasing number of
its givens.
• The difficulty of a puzzle depends on luck.
• A 9-sized int array can be replaced by a variable has at least 9 bits (e.g. short, int)
to save memory and reduce the complexity of operations such as comparison.
• Utility functions are added to entertain and excite the user.
• A user-friendly user-interface brings comfort to the user.

Discovers
I am surprised that there are so many variants of Sudoku. Amazingly, a 3D Sudoku
puzzle is possible but it is a combination of Sudoku and Rubik’s cube instead of pure
Sudoku.
I find that the minimum number of givens in a proper 9*9 Sudoku puzzle is 21. I find this
by tracing the counter for unknown cells during generation. Since the generator always
removes around 55 givens only, I suppose there must be a minimum number of givens.
And it could be 21 as one time I see the generator removes 60 givens. So I search in the
Internet and find that some people say it is true.

What have I learnt…?


Definitely, I have learnt a lot from this coursework. First, it gives me a chance to look
deeper and broader into Sudoku. And now I can handle the algorithms used in solving or
generating Sudoku puzzles.

Second, I succeed in making use of the communication between different programming


medium. I am so excited to see the perfect result.
Third, I invent some programming techniques which can be very useful in some
situations.

Last but not least, I get a valuable experience of game programming.

References
http://en.wikipedia.org/wiki/Sudoku

The end

Anda mungkin juga menyukai