Mensa Tiles

[Home]   [Puzzles & Projects]    [Delphi Techniques]   [Math topics]   [Library]   [Utilities]

 

Search

Search WWW

Search DelphiForFun.org

As of October, 2016, Embarcadero is offering a free release of Delphi (Delphi 10.1 Berlin Starter Edition ).     There are a few restrictions, but it is a welcome step toward making more programmers aware of the joys of Delphi.  They do say "Offer may be withdrawn at any time", so don't delay if you want to check it out.  Please use the feedback link to let me know if the link stops working.

 

Support DFF - Shop

 If you shop at Amazon anyway,  consider using this link. We receive a few cents from each purchase.   Thanks.


Support DFF - Donate

 If you benefit from the website,  in terms of knowledge, entertainment value, or something otherwise useful, consider making a donation via PayPal  to help defray the costs.  (No PayPal account necessary to donate via credit card.)  Transaction is secure.

Contact

Feedback:  Send an e-mail with your comments about this program (or anything else).

Search DelphiForFun.org only

 

 

Problem Description

Arrange the 10 tiles shown into a 5 X 5 array of numbers in such a way that the 5-digit horizontal numbers match the 5-digit vertical numbers.  

Background & Techniques

This puzzle is from the book, Mensa Number Puzzles by Harold Gale, Carlton Books, 1993.   There are 200 puzzles in the book including about a dozen of this type, surely enough to justify writing a program to solve them.  

Not much usage description needed so  non-programmers can jump to bottom the page now to download an executable version of the program.

Notes for programmers

This is another exhaustive search program, we'll start with the first tile and place it every possible position on a 5 X 5 grid, then for that position try every legal position for the second tile.   For each valid placement of two tiles, try all positions for the third tile, etc.  until we have placed all, or cannot place any more.    This descending search method suggests using a recursive tile placement routine.   Tryfits is it.  Pass it a tile number, N,  to place and a board with earlier tiles in place and it will systematically check all 25 grid locations to see if the tile N would fit there.  When it finds a location, place tile N and call Tryfits with tile N+1.  When we return from Tryfits, if no solution has been found, remove tile N and continue searching for the next location.   When all the tiles have been placed, we must have a solution so set the SolutionFound flag and stop removing tiles.       

The criteria for placing a tile:

bulletThe the other end of the tile must still be on the grid.
bulletThe spaces to be filled must not already contain a tile.
bulletDiagonal symmetry - if placement will assign value X to grid location [i, j], then diagonally opposite grid location,  [j, i] must either be empty or already contain value X.      

Tryfits calls the Tilefits function to test if a tile fits starting at a given grid position, and procedures AddTile and  RemoveTile as appropriate.  These are all non-graphic routines and the most fun to write.  

The display part is much messier, especially allowing user play.  I used drag and drop logic and spent much time on the DragOverProc and DragDropProc procedures.   It seemed like a good idea at the time, but I never did it working as I had originally planned.   DragoverProc calls occur when the dragged object is dragged over something and must set an Accept variable indicating whether the object can be dropped there.  So when we drag over the playing grid, we need to figure which grid squares would be occupied and whether it will fit there.  A tile should not be eligible to be dropped on another tile, except ... (I hate those excepts) that it must be able to be dropped on itself if, for example the user wants to relocate a horizontal tile one position to the left.    The user doesn't really think that he is dropping a tile on a tile, but the drop/drop logic does.   That's the  essence of the code you will find in  those drag handling procedures.  

The tiles are represented  as TTileObj objects which are derived from TStringGrid controls.   They are kept in a Tiles array.  In addition to the stringgrid stuff, (size, location, and values), each tile also contains the tile number (its index in the Tiles array), and a MoveTo point, (its column/row coordinates on the playing grid).   

Lots of other stuff that you can check out for yourself, enough to put this program in the "Advanced" category with 700+ lines of code.    For the benefit of search engines,  features that may be of interest  include:

Dynamically creating an array of visual controls, including event exits  
Overlay Stop and Solve buttons to allow user to interrupt the solving process.  The Tag field is set and checked to interrupt long processes - animated display of  the solution in this case.
Load and Save using init files (Inifiles unit), including how to save and restore an array of elements.
Use of a Modified boolean flag to warn user that data has changed.  Set by an OnKeyPress event exit and reset by Load or Save operations.  
Doubly dimensioned dynamic arrays.
Animate moving a stringgrid
PageControl OnChanging and OnChange event exits to handle special operations when leaving or entering a Tabsheet.

Running/Exploring the Program 

bulletBrowse source extract 
bulletDownload source 
bulletDownload  executable

Suggestions for Further Explorations

Other sizes of playing grids and tiles could be added.  3X3 or 4X4 grids would be better for younger players. 
 I never did get the drag/drop working completely.  I had intended to disallow drops that violated the diagonal symmetry constraint, but never got it working.  
The Hint button currently places one randomly selected tile in its proper place.  With a little more work, successive clicks could add additional tiles.

Modified: February 18, 2016

 

 

  [Feedback]   [Newsletters (subscribe/view)] [About me]
Copyright 2000-2017, Gary Darby    All rights reserved.