README.txt

                             Open Flowers

This is the message passing approach to the patience solitaire game
Flower Garden.

This is the variant Flower Venus Garden with Laughing Flowers based
on a relaxed ruleset.  You can move only one card at time but from
anywhere to anywhere.  Sequences in the flower beds have to be
build by suit.  The foundations are built from ace to king but
cards can be moved back into the game. You can double click a card
and if possible it will find its place in the foundations. You can
place up to sixteen cards in the bouquet. There is a good chance of
winning the game.

(The layout of the bouquet, i.e. the reserve of cards at the bottom
of the table is done automatically but only after a card has been
moved successfully. Rethinking and correcting this is left as
exercise for the interested player.)

Description & Rules

One deck of 52 cards.

< from wikipedia
Thirty-six cards are dealt in to six columns, each containing six
cards. The columns are called the "flower beds" and the entire
tableau is sometimes called "the garden." The sixteen leftover
cards become the reserve, or "the bouquet."

The top cards of each flower-bed and all of the cards in the
bouquet are available for play. Cards can only be moved one at a
time and can be built either on the foundations or on the other
flower beds. The foundations are built up by suit, from Ace to King
(a general idea of the game is to release the aces first). The
cards in the garden, on the other hand, can be built down
regardless of suit and any empty flower bed can be filled with any
card. The cards in the bouquet can be used to aid in building, be
put into the foundations, or fill an empty flower bed.

The game is won when all cards end up in the foundations.
> end from wikipedia



NaL (Not a License)

This is free source code - free as in "free like a bird".

This is open source and marketing (which is a little bit like
gardening): if someone gives you a pen at no cost and you have to
refill it to write down you're favourite poem with it and someone
else sings it and the producer of that song makes a whole lot of
money with it then never forget: they could have used any pen to do
the job. Don't break my pencils!



Technical Note: While it is written in a rather traditional way
without mixins, traits or an emphasis on surrogates it might
contain ideas, concepts and terms that go beyond today's message
passing "customs". A new message passing primitive "broadcast" and
the term hub for certain classes are consequences of thinking about
the future of message passing, parallel objects and one new program
code abstraction system "to rule them all" especially when it comes
to open source and the user's ability to adapt and program the
shiny some thousand money units worth machine in front of him. From
LISP machines to BSD to Mach message passing microkernel to
NextStep to ... but that is far away: for me it was from QBASIC to
RISC assembler to NetBeans to Dr. Racket to whatever comes in
handy.



Source Tree Layout

This implementation of Flower Garden started as one file and the one
file approach ended at about 1300 lines of text. Then some parts have
been cut out and are now called sections and the whole was renamed
"Open Flowers". Afterwards with features like the hint system and
additional animations the complexity has risen as have the
prerequisites on the side of the programmer to substantially change
the program.

 /Open Flowers/README.txt
   This little text.

 /Open Flowers/Open Flowers.rkt:
   Classes: stack and subclasses, garden (program action coordinator),
            flower-garden (GUI shell with menu)
   Pseudo classes: flower, flower-garden-table

 /Open Flowers/sections/pretext.rkt (section via include)
   The original pretext with extensions to the Algorithmic Language
   Scheme, Card Logic and debugging/developer utilities.

 /Open Flowers/sections/flower-dialog.rkt (module via require)
   The flower color picker. Class: flower-dialog

 /Open Flowers/sections/layout96l.rkt (section via include)
   The current table and card layout 9 cards wide 6 cards high with
   the foundations on the left side. Class: layout96l

 /Open Flowers/sections/layout77.rkt (DEFUNCT)
   The original layout 7 cards high and 7 cards wide. It's interface
   is not up to date anymore. Class: layout77 (not up to date)

 /Open Flowers/card-faces/

   OXYGEN removed - both Oxygen and White Oxygen need some corrections
   to enhance readability. They're currently unusable. The loader is
   provided nonetheless.

   (This folder contains alternate card faces based on the Oxygen set
   and a loader to create a deck that can be used in Open Flowers. The
   Oxygen Card Faces are in the public domain. See the corresponding
   /svg/ files for further information.)



Sketch: Object Relations / Data Structure
(w/o the implicit relations of the Virtual Playing Cards Library)

 table (sfg, pseudo subclass) <1-         <1-1> flower-dialog
                                 \        /
                                  =      |
     layout hub <1- program action coordinator (sfg) ||<1-1> gui shell
                          = = =
                          | | |
  foundation (sfg)   <n-1>/ | |
  | flower-bed (sfg) <n-1>-/  | 
  | | bouquet (sfg)  <1-1>---/
  \ \ \
   \ \ n> flowers (sfg, pseudo class)
    \ n> flowers (sfg, pseudo class)
     n> flowers (sfg, pseudo class)

<1-1>: a one to one relations where both objects know of each other
object <1- object: the left object is unaware of the hosting by the
                   right object; the right object hosts one left object
object <n-1> object: the right object can host several left objects
                   which are aware of the hosting (i.e. have a back
                   link)
sfg: stateful game object (may be part of the game state)
|| or =: Parallel Object Interface
     The interface can handle concurrent requests.
    (In this case it manages message passing traffic with a semaphore
    and is generally not really part of the data graph. The layout hub
    is almost completely stateless at its interface, i.e. with respect
    to incoming traffic, but it is not used concurrently.)



Sketch: Class Hierarchy

object
 \ \ \ \
  \ \ \ garden (program action coordinator)
   \ \ flower-garden (gui shell)
    \ stack: foundation, flower-bed, bucket
     layout

dialog: flower-dialog

Virtual Playing Cards Library Extension
 card: pseudo subclass flowers (toplevel)
 table: pseudo subclass table (in garden)



Description of the User Interaction

Most of the event handling is done by the views card<%>, table<%>
and region. (See Event Handling)

According to the rules only one card may be moved at any time.


    
Parallel Objects
(Shared Unit: Display via /table/ object / Animation System)
    
We need the parallel objects approach with the serializing application
interface because of the nested event handling. Without this
synchronization we can start a new deal, i.e. /reset-game/, and while
its animation is running we can start another new deal via the shell's
menu. Sometimes the request seems to be ignored even without
synchronization but usually it's possible. At a first glance this
gives us the expected behavior: the first deal is interrupted and the
second new deal starts. But after the second deal completes the first
deal continues usually with putting the rest of it's cards (which are
kept locally in the environment of /initial-deal/) into the
bucket. After these nested deals we are left with a lot of cards in
the bucket and some empty spots within the flower bed stacks. To avoid
this and other race conditions we choose to ignore user requests from
the shell as long as we are busy. A better tactic would to build in
the possibility to cancel the initial deal and then start the second
new deal on the user's behalf.
    
Another issue arises with the card wiggling which shows the dealer's
hint: it eventually puts the card back at the original position where
the wiggle started. If we make it start a new game during the wiggling
/wiggle-flower-in-garden/ will put back the card to its original
position but only after the inital deal has changed all the positions
of all the other cards. Same for our window cleaner.
    
The current implementation does away with the mess by using a
/semaphore/. There is second line of defence to protect against
programming errors because it's easy to tinker around with the
/semaphore/ in garden class, i.e. the program action coordinator, and
to use it incorrectly. That second security measure is based on a non
atomic boolean. No matter if the /set!/ operation on a boolean is
atomic or not - there will always be - at least in theory - that some
processor cycles long hole where we have checked the mutex but haven't
set it yet. Yet this added layer of protection against misuse of the
/semaphore/ works quite well while developing. To avoid further
complications when using the all purpose semaphore metapher directly
we encapsulate it with two wrappers: /ignore-when-busy/ and
/queue-with-busy/. This is all we need and we sometimes queue events
to not "block" the main thread too much. Other times we queue events
because the Virtual Playing Cards Library queues events and we want to
have a certain order. Queuing two callbacks consecutively seems to
provoke a dead lock like behavior which might be not any more than an
arbitrary restriction on how we can use the /run loop/ but it may even
be another consequence of the nested event handling creating the need
to queue again. Thus we chain the queuing of the callbacks in the
first place. See the implementation of the /game-is-won/ situation.

The user requests originating from the callbacks of the Virtual
Playing Cards Library need to be serialized in time, too.
    
NB When /ignore-when-busy/ is called while we are busy it will
display a debug level message with "code red" and ring the
bell. Usually if we decide for this kind of audible feedback it
would be better to implement it in the shell / application class.



    Event Handling
    
    There is no documented message passing protocol for the event
    stream coming from region and table objects. There is no well
    defined order but we can look at the order of events arriving
    and think about it. A drag starts out with a single click
    event. That single click event might or might not match our
    interactor model but we need to make its consequences unhappen
    because the user did not click but drag and we got to know about
    this only later on. There is a place to do that: see
    set-interactive-region-callback! in stack% add-region.
    
    A double click is a time and coordinate dependent event usually
    composed of two single clicks. Depending on the libraries and
    low level routines in use we might expect to see the following
    sequences in the event stream on the same card in a short time
    interval: a period "." denotes a single click event, a colon ":"
    denotes a double click event
    
    ..  two clicks no double click event
    :   one double click event - no single click events
    .:  one single click event and one double click event
    ..: two single click events and one double click event
    :.. one double click event and two single click events
    .:. one single click event then a double click event then
         a single click event again
    
    We can adapt our interaction model or Interactor (see Garnet) to
    avoid misinterpreting events. A single click sets the selection
    and the next click clears the selection. A double click clears the
    selection. With this behaviour in mind there remain two cases of
    event sequences which are not handled in the right way: the first
    one (..) which is degenerate because there is no double click
    event at all. We could try to look at the time codes of the events
    and determine if it was a double click or not but we cannot check
    the pointer coordinates here which is crucial to recognize double
    clicks and drags. Then the last sequence (.:.) is problematic,
    too. And testing suggests that this is our favourite one and only
    sequence of events. On the developer's machine each double click
    event is surrouned by single clicks and we end up with a card that
    has already been moved by the double click event which cleared
    selection and we now receive a single click event for that card:
    it ends up selected (in a foundation). Please bear in mind that a
    click event is a synthesized composed event itself: usually a
    click is defined as the following sequence of low level events:
    mouse button down, mouse button up (within the same spot region in
    screen coordinates). The Virtual Playing Cards Library does not
    use that definition of a click. Another aspect of our event
    handling here to keep in mind is the fact that we do not recieve a
    stream of events as a stream of events but the user defined thunks
    are invoked as event handlers at certain not well defined moments
    not in time but in the execution order of the Virtual Playing
    Cards Library routines intertwined with garbage collection and
    operating system interaction.
    
    Interaction Models have to be learned by the user. Some are
    nowadays common accepted standard (even if not well documented)
    but everything changes: where you're favourite lisp based action
    game developing environment from back then allowed you to choose
    one of a set of actions and then apply it on some object today
    we expect to select the object.e.g. file and then choose one of
    its associated actions, e.g. delete. This is true on most modern
    graphical user interaction shells. But when you do graphic
    design and photo retouch we first choose the action or tool and
    then apply it to some part of the object to design. Vice verse
    these behaviours and people will tell you that it's completely
    broken even if they're already used to both interaction models.
    I don't touch I click - but that's another chapter and out of
    the scope of this little card game.
    
    Some interaction models to not work out anyway: the select card
    then destination approach falls for Moon Flower Garden because
    the bucket is full of cards. Do you want to move the flower to
    the bucket or do you want to select a card in the bucket?


    
    Animations (outdated, see mred/15064 in Racket's bug database)
    
    It seems the animations of the Virtual Playing Cards Library are
    primarily intended to visualize algorithms or better: their time
    ordered consequences. There is a problem where the animation of a
    dragged card doesn't start at the final position of the drag
    when/where the handler is called but it starts at the original
    location of the card which might be percieved as an unpleasant
    flickering. That behaviour of the animation engine depends on a
    set home-region but not only. Not setting the home-region at all
    in the class definition of stack% gives us the correct starting
    positions for the animations after a drag from the Bouquet to a
    Flower Bed. All drags originating from Flower Beds do still
    animate with the described wrong starting position. This might
    have to do with one of the messages in reconfigure-cards but after
    all: the animation engine does not feature any fine grained
    control and is abusing the cards<%> configuration in an
    undocumented way. Nevertheless the wrong starting position seems
    to be a real bug of the animation engine. BTW It doesn't animate
    snap backs either ...  Perhaps they want to fix it. (mred/15064)



Bugs and Maintenance

Bug (mred/15065): in a new game after program start the second card in
a flower bed which was face down could be moved. As reconfigure-cards
in the flower-bed class is rather clear about this issue and because
it happened during the animation of an unrelated move and is part of
the Virtual Playing Cards Library's special behaviours.

DONE -Dev: no more bangs in message passing-

Bug (mred/15065): during an animation an accidental double
click (without the final button up) onto the table background
started a selection with a rectangle whose border was the inverse
color of the current table background. The z-axis order of the
cards and perhaps other things were screwed up afterwards.

Bug (Mac OS X, mred/12252): Racket cancels shutdown, restart, logout.

FIXED garden%: policy an all entry points: ignore when busy -Bug:
There are still some race conditions left with the animation
system. Put one of the aces on the foundations, ask for a new deal
during the animation and after the next deal it ended up in the
bucket. Then it jumped to the next foundation of the previous
animation. Investigating stock games: Rummy does not have any other
user controls. Spider's animations are usually to fast to enter the
race condition but you might want to undo a move (with CMD-Z as a
keyboard shortcut on the Mac) during the animation. Crazy 8s features
an on-table user control: the clear button. It is blocked during
animation. Then there is an option button in the panel but it creates
another table on screen. Blackjack: on-table controls n/a during
animation. Aces: undo via keyboard shortcut during animation leaves
the cards on the stacks but face down. Clicking them provokes another
deal onto the stacks from the deck and other non regular behavior.
Memory and Go Fish do not have any in-game user controls.  It doesn't
seem to be possible to protect from these race conditions completely
as they originate from the nested event event handling of custom user
controls and we don't know about ongoing animations in the
Library. Perhaps some accessible mutex / semaphore on animation would
be helpful.  It doesn't seem to be possible to protect from these race
conditions completely as they originate from the nested event event
handling of custom user controls and we don't know about ongoing
animations in the Library. Perhaps some accessible mutex / semaphore
on animation would be helpful.  The games without controls from the
toolkit incl. menu but with on-table button regions only do not have
that problem.-

Dev: A better syntax / notation for the following sequence in
interfaces with ignore-when-busy policy would be helpful.
 (define (proc/private ...) ...)
 (define/public (proc ...)
   (ignore-when-busy {lambda () (apply proc/private ...)}))
Perhaps its better to seperate these interfaces or to use something
like: {interface #:policy ignore-while-busy
                 method1 method2 ...}

Dev: We cannot listen on booleans??? We need a better way to connect
menu items with states to disable and enable them automagically.

Dev: The different layout variants are out of sync and are copy&paste
work. Use a common-layout superclass instead.