|
|
Tile puzzle program explanation |
|
|
download Delphi project
Puzzle dimensions
const dimensions = array[1..7] of byte = (4,5,7,8,10,11,13);
var dimcode : byte=5; //1..7
dim : byte = 10; //boardsize dim*dim
Status
Each square may have the status:
type Tpos3 = (poEmpty,poH1,poH2,poH3,poV1,poV2,poV3,poCenter);
var board : array[1..13,1..13] of TPos3; //maximum size
Tile position
Type Ttile3 = record
dir : byte; // 1:right 2:up 4:left 8:down
posX,posY : byte; //board position of left/top square of tile
end;
The Ttile3 type is used during player moves.
The computer search needs a list of moves for backtracking.
type Tmove = record
dir : char; //'H' (horizontal or 'V'(vertical) tile
mx : byte; //board coordinates
my : byte; //..
end;
var greenX : byte = 5;//X position of green tile
greenY : byte = 5;//Y …
Function GOSearch does the search.
type TsearchResult = (srNo,srYes,srAbort);
function GOsearch : TsearchResult;
var x,y : byte; //board position
moveNr : byte; //number of moves done
movelist : array[1..56] of TMove;
begin
……………
End;
searchresult values
srNO : no solution
srYes : solution
srAbort : search ended by stop button pressed.
Computer search flowchart
The search starts by clearing the moves list.
Then the next empty square (cell) is looked for.
The search is left to right, top to bottom. No empty cell left means puzzle solved.
On next empty cell, a test is made for a horizontal 1x3 tile empty space.
If no free cells for horizontal tile a test is made for a vertical tile.
If no space, the last tile is removed.
If this tile was a horizontal one, a vertical tile is tested at this position.
If the last tile was a 'V' type, the previous tile is deleted.
All tiles removed means : there is no solution.
Because of crossing loops, GOTO statements and labels are used.
(flowchart presents labels in colored ellipses)
Interesting fact:
It looks like backtracking is superfluous.
I never encountered a solution that required backtracking.
During the search a variable timeout counts down from 1.000.000 to zero for each tile placed.
When reaching zero the counter is reset to 1000.000,
the board status is displayed and statement "application.processmessages" is executed
to keep in touch with Windows.
Drawing
Used bitmaps:
mapA : holds empty board, used to erase (parts) of mapB.
mapB : holds board + 1x1 green tile + yellow tiles.
greenmap : holds 1x1 green tile.
H3Tile : holds 1x3 horizontal yellow tile.
V3Tile : holds 1x3 vertical yellow tile.
Maps 3..5 are painted once at create time.
Below the maps are shown for a dimension 5x5 board:
A mouse-down on an empty board places the green tile.
A mouse-down on the green tile sets the centerflag.
Subsequent mouse-moves now shift the green tile.
A mouse-up clears the centerflag.
A mouse-down on a board with green tile places dots at cells where a yellow tile may set placed.
Following mouse-moves test for the direction.
If 2 cells are covered the yellow tile is placed on mapB and the regflag sets
to block new tile placement as the mouse pointer moves.
Regflag is cleared by a mouse-up event.
To erase a tile on mapB, a mapB.canvas.copyrect(r,mapA.canvas,r) is used
where r is the required rectangle to copy.
Step mode
The computer search can by done step-by-step.
With the stepmode checkbox checked and after a tile is placed,
the board is copied to paintbox1 and procedure searchpause is called:
procedure searchpause;
begin
pauseFlag := true;
while pauseFlag do application.ProcessMessages;
end;
The pauseflag is cleared by pressing the "space" bar.
This ends the tiles puzzle description.
Please refer to the source code for details.
|
|