Honeycombs

From Rosetta Code
Revision as of 09:51, 27 May 2011 by rosettacode>Dkf (→‎{{header|Tcl}}: Tinkering)
Honeycombs is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

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. The selected hexagon should now change colour on the display. A message should be now be output saying "The user chose letter E" (or whatever letter the user actually chose). The cycle repeats until the user has chosen five 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 five letters have been chosen.

Tcl

Library: Tk

<lang tcl>package require Tcl 8.5 package require Tk

  1. 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

  1. 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]

}

  1. 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

}

  1. 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}

}

  1. Build the GUI

pack [honeycomb .c $letterpattern] focus .c

  1. Usually don't use this, but it's ideal for this interaction pattern

tkwait window .c puts "overall list of characters: $chosen" exit</lang>