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.