The task is to produce a matrix of 20 hexagon shaped widgets in a honeycomb arrangement. The matrix should be arranged in such a manner that there are five
columns of four hexagons. The hexagons in columns one, three and five are aligned horizontally, whereas the hexagons in columns two and four occupy a lower position within the arrangement. Each hexagon should be the same colour, and should
display a unique randomly selected single capital letter on the front. The application should now wait for the user to select a hexagon, either by using a pointing device, or by pressing a key that carries a corresponding letter on a hexagon. For platforms that support pointing devices and keyboards, the application should support both methods of selection. A record of the chosen letters should be maintained and the code should be suitably commented, at the point where the the selected letter has been determined. The selected hexagon should now change colour on the display. The cycle repeats until the user has chosen all of the letters. Note that each letter can only be selected once and previously selected hexagons retain their colour after selection. The program terminates when all letters have been chosen.

Optionally: output the list of selected letters and show the last selected letter, cater for a different number of columns or a different number of hexagons in each column, cater for two players, (turns alternate and the hexagons change a different colour depending on whether they were selected by player one or player two and records of both players selections are maintained.)



package require Tcl 8.5
package require Tk
 
# How to make a honeycomb
proc honeycomb {w letterpattern} {
    canvas $w -width 500 -height 470
    set basey 10
    foreach row $letterpattern {
	set basex 10
	set majoroffsety 0
	foreach letter $row {
	    set x [expr {$basex + 60}]
	    set y [expr {$basey + 50 + $majoroffsety}]
	    drawhex $w $x $y $letter 30 50
	    set majoroffsety [expr {50 - $majoroffsety}]
	    incr basex 90
	}
	incr basey 100
    }
    return $w
}
 
namespace import tcl::mathop::?   ;# For convenience
# How to draw a single hexagon, centered at a particular point.
proc drawhex {w x y ch dx dy} {
    if {$ch eq ""} return          ;# Allow elision of cells (not used here)
    $w create polygon \
	[- $x $dx] [- $y $dy] [+ $x $dx] [- $y $dy] [+ $x $dx $dx] $y \
	[+ $x $dx] [+ $y $dy] [- $x $dx] [+ $y $dy] [- $x $dx $dx] $y \
	-fill yellow -outline black -tags [list hex$ch hull$ch] -width 3
    $w create text $x $y -text $ch -fill red -tags [list hex$ch txt$ch] \
	-font {Arial 72 bold}
    # Install bindings on items
    $w bind hex$ch <Enter> [list enterhex $w $ch]
    $w bind hex$ch <Leave> [list leavehex $w $ch]
    $w bind hex$ch <Button-1> [list dohex $w $ch]
    # Handle keyboard activity through canvas-level bindings
    bind $w [string toupper $ch] [list dokey $w $ch]
    bind $w [string tolower $ch] [list dokey $w $ch]
}
 
# Callbacks for various bindings
proc enterhex {w ch} {
    global chosen
    if {$ch ni $chosen} {
	$w itemconfigure hull$ch -fill magenta
	$w itemconfigure txt$ch -fill black
    }
}
proc leavehex {w ch} {
    global chosen
    if {$ch ni $chosen} {
	$w itemconfigure hull$ch -fill yellow
	$w itemconfigure txt$ch -fill red
    }
}
proc dohex {w ch} {
    global chosen
    if {$ch ni $chosen} {
	lappend chosen $ch
	puts "chosen $ch"
    }
    if {[llength $chosen] >= 5} {
	destroy $w
    }
}
proc dokey {w ch} {
    enterhex $w $ch
    dohex $w $ch
}
 
# Initial declarations of state variables
set chosen {}
set letterpattern {
    {L A R N D}
    {G U I Y T}
    {P C F E B}
    {V S O M K}
}
 
# Build the GUI
pack [honeycomb .c $letterpattern]
focus .c
# Usually don't use this, but it's ideal for this interaction pattern
tkwait window .c
puts "overall list of characters: $chosen"
exit