Scribbled games docs
svn: r9246
This commit is contained in:
parent
890cd46fa1
commit
18f4087673
|
@ -8,7 +8,7 @@ possible to remap single click (instead of double click)?
|
||||||
#lang mzscheme
|
#lang mzscheme
|
||||||
|
|
||||||
(require games/cards mred mzlib/class mzlib/list mzlib/unit string-constants
|
(require games/cards mred mzlib/class mzlib/list mzlib/unit string-constants
|
||||||
"../show-help.ss")
|
"../show-scribbling.ss")
|
||||||
|
|
||||||
(provide game@)
|
(provide game@)
|
||||||
(define game@ (unit (import) (export)
|
(define game@ (unit (import) (export)
|
||||||
|
@ -16,7 +16,8 @@ possible to remap single click (instead of double click)?
|
||||||
(define table (make-table "Aces" 6 5))
|
(define table (make-table "Aces" 6 5))
|
||||||
|
|
||||||
(make-object button% (string-constant help-menu-label) table
|
(make-object button% (string-constant help-menu-label) table
|
||||||
(let ([show-help (show-help (list "games" "aces") "Aces Help")])
|
(let ([show-help (show-scribbling '(lib "games/scribblings/games.scrbl")
|
||||||
|
"aces")])
|
||||||
(lambda x (show-help))))
|
(lambda x (show-help))))
|
||||||
|
|
||||||
(define draw-pile null)
|
(define draw-pile null)
|
||||||
|
|
|
@ -53,7 +53,8 @@
|
||||||
;; Set up the table
|
;; Set up the table
|
||||||
(define t (make-table "Blackjack" 6 3))
|
(define t (make-table "Blackjack" 6 3))
|
||||||
(define status-pane (send t create-status-pane))
|
(define status-pane (send t create-status-pane))
|
||||||
(send t add-help-button status-pane '("games" "blackjack") "Blackjack Help" #f)
|
(send t add-scribble-button status-pane
|
||||||
|
'(lib "games/scribblings/games.scrbl") "blackjack")
|
||||||
(send t show #t)
|
(send t show #t)
|
||||||
(send t set-double-click-action #f)
|
(send t set-double-click-action #f)
|
||||||
(send t set-button-action 'left 'drag/one)
|
(send t set-button-action 'left 'drag/one)
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
** To play Blackjack, run the "PLT Games" application.
|
|
||||||
|
|
||||||
Standard Blackjack rules, plus the following specifics:
|
|
||||||
|
|
||||||
* 1 player (not counting the dealer)
|
|
||||||
|
|
||||||
* 4 decks, reshuffled after 3/4 of the cards are used
|
|
||||||
|
|
||||||
* Dealer stands on soft 17s
|
|
||||||
|
|
||||||
* Splitting is allowed only on the first two cards, and only if they
|
|
||||||
are equal; 10 and the face cards are all considered equal for
|
|
||||||
splitting
|
|
||||||
|
|
||||||
* Doubling is allowed on all unsplit hands, not on split hands
|
|
||||||
|
|
||||||
* No blackjacks after splitting
|
|
||||||
|
|
||||||
* No surrender
|
|
||||||
|
|
||||||
* No insurance
|
|
||||||
|
|
||||||
* No maximum under-21 hand size
|
|
||||||
|
|
||||||
* Dealer's second card is not revealed if the player busts (or both
|
|
||||||
halves of a split hand bust)
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
@title{@bold{Cards}: Virtual Playing Cards Library}
|
@title{@bold{Cards}: Virtual Playing Cards Library}
|
||||||
|
|
||||||
@defmodule[games/cards/main]{The @schememodname[games/cards/main]
|
@defmodule[games/cards]{The @schememodname[games/cards]
|
||||||
module provides a toolbox for creating cards games.}
|
module provides a toolbox for creating cards games.}
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
@; ----------------------------------------------------------------------
|
||||||
|
@ -357,12 +357,22 @@ Removes @scheme[card] from the table.}
|
||||||
[tt? any/c])
|
[tt? any/c])
|
||||||
void?]{
|
void?]{
|
||||||
|
|
||||||
Adds a @onscreen{Help} button to the give pane, where clicking the
|
Adds a @onscreen{Help} button to the given pane, where clicking the
|
||||||
button opens a new window to display @filepath{doc.txt} from the given
|
button opens a new window to display @filepath{doc.txt} from the given
|
||||||
collection. The @scheme[str] argument is used for the help window
|
collection. The @scheme[str] argument is used for the help window
|
||||||
title. If @scheme[tt?] is true, then @filepath{doc.txt} is displayed
|
title. If @scheme[tt?] is true, then @filepath{doc.txt} is displayed
|
||||||
verbatim, otherwise it is formatted as for @scheme[show-help] from
|
verbatim, otherwise it is formatted as for @scheme[show-help] from
|
||||||
@scheme[(lib "show-help.ss" "games")].}
|
@schememodname[games/show-help].}
|
||||||
|
|
||||||
|
@defmethod[(add-scribble-button [pane (is-a?/c area-container<%>)]
|
||||||
|
[mod-path module-path?]
|
||||||
|
[tag string?])
|
||||||
|
void?]{
|
||||||
|
|
||||||
|
Adds a @onscreen{Help} button to the given pane, where clicking the
|
||||||
|
button opens Scribble-based documentation, as with
|
||||||
|
@scheme[show-scribbling] from @schememodname[games/show-scribbling].}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
@; ----------------------------------------------------------------------
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
"make-cards.ss"
|
"make-cards.ss"
|
||||||
"region.ss"
|
"region.ss"
|
||||||
string-constants
|
string-constants
|
||||||
"../show-help.ss")
|
"../show-help.ss"
|
||||||
|
"../show-scribbling.ss")
|
||||||
|
|
||||||
(provide pasteboard%
|
(provide pasteboard%
|
||||||
table%)
|
table%)
|
||||||
|
@ -601,6 +602,15 @@
|
||||||
(label (string-constant help-menu-label))
|
(label (string-constant help-menu-label))
|
||||||
(callback
|
(callback
|
||||||
(let ([show-help (show-help where title tt?)])
|
(let ([show-help (show-help where title tt?)])
|
||||||
|
(lambda x
|
||||||
|
(show-help))))))]
|
||||||
|
[add-scribble-button
|
||||||
|
(lambda (pane mod tag)
|
||||||
|
(new mred:button%
|
||||||
|
(parent pane)
|
||||||
|
(label (string-constant help-menu-label))
|
||||||
|
(callback
|
||||||
|
(let ([show-help (show-scribbling mod tag)])
|
||||||
(lambda x
|
(lambda x
|
||||||
(show-help))))))])
|
(show-help))))))])
|
||||||
(begin
|
(begin
|
||||||
|
|
|
@ -1,311 +0,0 @@
|
||||||
|
|
||||||
The _Virtual Playing Cards Library_
|
|
||||||
-----------------------------------
|
|
||||||
|
|
||||||
Load the virtual card library with
|
|
||||||
(require games/cards)
|
|
||||||
|
|
||||||
The _cards_ module defines the following procedures:
|
|
||||||
|
|
||||||
> (make-table [title-string] [w] [h]) returns a table named by
|
|
||||||
`title-string' that is `w' cards wide and `h' cards high. A
|
|
||||||
table is an frame% object, with extra methods described
|
|
||||||
below. The table is not initially shown; (send table show #t)
|
|
||||||
shows it. The arguments are optional, with the default values
|
|
||||||
being "Cards", 7, and 3.
|
|
||||||
|
|
||||||
> (make-deck) returns a list of 52 cards, one for each suit-value
|
|
||||||
combination. The cards are all face-down, sorted lowest-suit
|
|
||||||
then lowest-value. A card is an object, with methods described
|
|
||||||
below. A card can only be on one table at a time.
|
|
||||||
|
|
||||||
> (make-card front-bm back-bm-or-#f suit-id value) returns a single
|
|
||||||
card given a bitmap for the front, an optional bitmap for the
|
|
||||||
back, and arbitrary values for the card's suit and value (which
|
|
||||||
are returned by the card's `get-value' and `get-suit-id'
|
|
||||||
methods). All provided bitmaps should be 71 by 96 pixels.
|
|
||||||
|
|
||||||
> (shuffle-list list n) shuffles the given `list' `n' times, returning
|
|
||||||
the new list. Shuffling simulates an actual shuffle: the list is
|
|
||||||
split into halves which are merged back together by repeatedly
|
|
||||||
pulling the top card off one of the halves, randomly selecting
|
|
||||||
one half or the other. According to some mathematical theorem, 7
|
|
||||||
is a large enough `n' to get a perfect shuffle.
|
|
||||||
|
|
||||||
plus a structure:
|
|
||||||
|
|
||||||
> struct:region :: (struct region (x y w h label callback))
|
|
||||||
`x', `y', `w', `h' are coordinates on the table,
|
|
||||||
`label' is a string or bitmap to label the region or #f for no
|
|
||||||
label. When the region is added to a table, a text label is
|
|
||||||
drawn in 12-pixel text, and the label is centered horizontally
|
|
||||||
and 5 pixels down from the region's top outline. If label is
|
|
||||||
#f, no label or box is drawn for the region.
|
|
||||||
`callback' is a procedure that takes a list of cards that were
|
|
||||||
dragged to the region; if callback is #f, the region is not
|
|
||||||
active (i.e., dragging cards to the region doesn't highlight the
|
|
||||||
region box). The region remains hilited until the callback returns.
|
|
||||||
The only mutator on the structure that is available is set-region-callback!.
|
|
||||||
The structure created by make-region actually has extra hidden fields.
|
|
||||||
|
|
||||||
> (make-button-region x y w h label callback) - returns a region like
|
|
||||||
one made by make-region, but the is drawn slightly differently and
|
|
||||||
it reacts differently to cards and the mouse. The label is drawn
|
|
||||||
in the middle of the box instead of at the top, and the callback is
|
|
||||||
called with no arguments when the user clicks the region (instead
|
|
||||||
of dragging cards to the region).
|
|
||||||
|
|
||||||
> (make-background-region x y w h paint-callback) - returns a region that
|
|
||||||
does not respond to mouse clicks, but which has a general paint
|
|
||||||
callback. The `paint-callback' function is called with five
|
|
||||||
arguments: a drawing context, x and y offsets, and the width and
|
|
||||||
height (which are always `w' and `h'). The x and y offsets can be
|
|
||||||
different than the supplied `x' and `y' when part of the table is
|
|
||||||
drawn offscreen. Regions are painted in the order that they are
|
|
||||||
added to a table, and all regions are painted before any card.
|
|
||||||
The `paint-callback' procedure should not assume a particular
|
|
||||||
state for the drawing context (i.e.,current brush or pen), and it
|
|
||||||
should restore any modified drawing context state before
|
|
||||||
returning.
|
|
||||||
|
|
||||||
Plus some extra callback procedures on regions:
|
|
||||||
|
|
||||||
> (region-interactive-callback r)
|
|
||||||
> (set-region-interactive-callback! r hilite-callback)
|
|
||||||
Get and set a callback procedure that is invoked when a region is
|
|
||||||
[un]hilited as the user drags a set of cards to the region. The
|
|
||||||
callback is provided two arguments: a boolean indicating whether the
|
|
||||||
region is hilited, and the list of cards being dragged. Like
|
|
||||||
region-callback, the default is #f, which indicates that the region
|
|
||||||
has no interactive callback (but does not affect whether the region
|
|
||||||
is hilited as cards are dragged). The final unhilite (when cards are
|
|
||||||
potentially delivered) does not trigger this callback.
|
|
||||||
|
|
||||||
|
|
||||||
Table methods: [in addition to standard frame% methods]
|
|
||||||
--------------
|
|
||||||
|
|
||||||
> add-card :: (send t add-card card x y) - adds `card' to the table
|
|
||||||
with its top-left corner at (`x',`y') in table pixels.
|
|
||||||
|
|
||||||
> add-cards :: (send t add-cards cards x y [offset-proc]) - adds list
|
|
||||||
of cards at (`x',`y'); the optional `offset-proc' procedure is
|
|
||||||
called with an index i (counting from 0) and should return two
|
|
||||||
values: `dx' and `dy'; the ith card is the placed at `x'+`dx'
|
|
||||||
and `y'+`dy'. The cards are added in order on top of cards
|
|
||||||
already one the table such that the first card in `cards' is
|
|
||||||
topmost.
|
|
||||||
|
|
||||||
> add-cards-to-region :: (send t add-cards-to-region cards r) - adds
|
|
||||||
`cards' to fill the region `r', fanning them out bottom-right
|
|
||||||
to top-left. The region `r' does not have to be added to the
|
|
||||||
table.
|
|
||||||
|
|
||||||
|
|
||||||
> remove-card :: (send t remove-card card) - removes `card' from the
|
|
||||||
table
|
|
||||||
|
|
||||||
> remove-cards :: (send t remove-cards cards) - removes `cards' from
|
|
||||||
the table
|
|
||||||
|
|
||||||
|
|
||||||
> move-card :: (send t move-card card x y)
|
|
||||||
> move-cards :: (send t move-cards cards x y [offset-proc])
|
|
||||||
> move-cards-to-region :: (send t move-cards-to-region cards r)
|
|
||||||
These are like the `add-card' methods, except that they move
|
|
||||||
cards already on the table. The movement of the cards is
|
|
||||||
animated. All of the cards are moved at once. If the cards are
|
|
||||||
in snap-back-after-move mode and a drag is active, snapping
|
|
||||||
back will use the new location.
|
|
||||||
|
|
||||||
|
|
||||||
> flip-card :: (send t flip-card card) - flips `card' over with
|
|
||||||
animation.
|
|
||||||
|
|
||||||
> flip-cards :: (send t flip-cards cards) - flips all `cards' over (at
|
|
||||||
once) with animation.
|
|
||||||
|
|
||||||
> card-face-up :: (send t card-face-up card)
|
|
||||||
> cards-face-up :: (send t cards-face-up cards)
|
|
||||||
> card-face-down :: (send t card-face-down card)
|
|
||||||
> cards-face-down :: (send t cards-face-down cards)
|
|
||||||
These are like `flip-card', but only cards that are not
|
|
||||||
already face up/down are flipped.
|
|
||||||
|
|
||||||
> card-to-front :: (send t card-to-front card) - moves `card' in front
|
|
||||||
of all other cards.
|
|
||||||
|
|
||||||
> card-to-back :: (send t card-to-back card) - moves `card' behind all
|
|
||||||
other cards.
|
|
||||||
|
|
||||||
> stack-cards :: (send t stack-cards cards) - the first card in
|
|
||||||
`cards' is not moved; the second card is moved to follow
|
|
||||||
immediately behind the first one, then (send t stack-cards
|
|
||||||
(cdr cards)) is called. If `cards' is empty or contains only
|
|
||||||
one card, no action is taken.
|
|
||||||
|
|
||||||
> card-location :: (send t card-location card) - returns the position
|
|
||||||
of the given card; an exception is raised if the card is not
|
|
||||||
on the table.
|
|
||||||
|
|
||||||
> all-cards :: (send t all-cards) - returns a list of all cards on the
|
|
||||||
table in stacking order from front to back
|
|
||||||
|
|
||||||
> table-width :: (send t table-width) - returns the width of the table
|
|
||||||
in pixels.
|
|
||||||
|
|
||||||
> table-height :: (send t table-height) - returns the height of the
|
|
||||||
table in pixels.
|
|
||||||
|
|
||||||
|
|
||||||
> begin-card-sequence :: (send t begin-card-sequence) - starts a
|
|
||||||
sequence of card or region changes that won't be animated or
|
|
||||||
updated until the end of the sequence.
|
|
||||||
|
|
||||||
> end-card-sequence :: (send t end-card-sequence) - ends a sequence;
|
|
||||||
begin-/end- pairs can be nested.
|
|
||||||
|
|
||||||
|
|
||||||
> add-region :: (send t add-region r) - adds the region `r' to the
|
|
||||||
table; regions are drawn in the order that they are added to
|
|
||||||
the table, and when a region added later is hilighted, it can
|
|
||||||
obscure regions added earlier.
|
|
||||||
|
|
||||||
> remove-region :: (send t remove-region r) - removes the region `r'
|
|
||||||
from the table.
|
|
||||||
|
|
||||||
> hilite-region :: (send t hilite-region r) - manual hilite (usually
|
|
||||||
for animation)
|
|
||||||
|
|
||||||
> unhilite-region :: (send t unhilite-region r) - manual unhilite
|
|
||||||
(usually for animation)
|
|
||||||
|
|
||||||
|
|
||||||
> set-button-action :: (send t set-button-action which action) - sets
|
|
||||||
the way that a mouse click is handled. The which argument must
|
|
||||||
be 'left, 'middle, or 'right. The action argument must be one
|
|
||||||
of:
|
|
||||||
'drag/one - drag only the clicked-on card
|
|
||||||
'drag-raise/one - like drag/one, but raise the card to the
|
|
||||||
top on a click
|
|
||||||
'drag/above - drag the card along with any card on top of the
|
|
||||||
card (i.e., more towards the front and overlapping with
|
|
||||||
the card). The on-top-of relation is closed transitively.
|
|
||||||
'drag-raise/above
|
|
||||||
'drag/below - drag the card along with any card underneath the
|
|
||||||
card (i.e., more towards the back and overlapping with
|
|
||||||
the card). The underneath relation is closed transitively.
|
|
||||||
'drag-raise/below
|
|
||||||
The initial settings are:
|
|
||||||
'left - 'drag-raise/above
|
|
||||||
'middle - 'drag/one
|
|
||||||
'right - 'drag/below
|
|
||||||
|
|
||||||
> set-double-click-action :: (send t set-double-click-action proc) -
|
|
||||||
sets the procedure to be called when a card is
|
|
||||||
double-clicked. The procedure is called with the
|
|
||||||
double-clicked card. The default procedure flips the cards
|
|
||||||
along with its on-top-of cards, raises the cards, and reverses
|
|
||||||
the front-to-back order of the cards
|
|
||||||
|
|
||||||
> set-single-click-action :: (send t set-single-click-action proc) -
|
|
||||||
sets the procedure to be called when a card is single-clicked,
|
|
||||||
after the button action is initiated. (If the card is
|
|
||||||
double-clicked, this action is invoked for the first click,
|
|
||||||
then the double-click action is invoked.) The default action
|
|
||||||
does nothing.
|
|
||||||
|
|
||||||
> pause :: (send t pause n-secs) - pauses, allowing the table display
|
|
||||||
to be updated (unless a sequence is active), but does not let
|
|
||||||
the user click on the cards.
|
|
||||||
|
|
||||||
> animated :: (send t animated) - returns #t is animation is on.
|
|
||||||
> animated :: (send t animated on?) - enables/disables animation.
|
|
||||||
|
|
||||||
> create-status-pane :: (send t create-status-pane) - creates a
|
|
||||||
pane with a status message (initially empty) and returns
|
|
||||||
the pane so that you can add additional controls
|
|
||||||
> set-status :: (send t set-status str) - sets the text message
|
|
||||||
in the status pane
|
|
||||||
> add-help-button :: (send t add-help-button pane coll-path str tt?) -
|
|
||||||
adds a "Help" button to the give pane, where clicking the
|
|
||||||
button opens a new window to display "doc.txt" from the given
|
|
||||||
collection (where `coll-path' is a list of strings to select
|
|
||||||
the collection). The `str' is used for the help window title.
|
|
||||||
If `tt?' is true, then "doc.txt" is displayed verbatim,
|
|
||||||
otherwise it is formatted as for `show-help' from
|
|
||||||
`(lib "show-help.ss" "games").
|
|
||||||
|
|
||||||
|
|
||||||
Card methods:
|
|
||||||
-------------
|
|
||||||
|
|
||||||
> card-width :: (send c card-width) - returns the width of the card in
|
|
||||||
pixels.
|
|
||||||
|
|
||||||
> card-height :: (send c card-height) - returns the height of the card
|
|
||||||
in pixels. All cards have the same width and height.
|
|
||||||
|
|
||||||
> flip :: (send c flip) - flips the card without animation. This is
|
|
||||||
useful for flipping a card before it is added to a table.
|
|
||||||
|
|
||||||
> face-up :: (send c face-up)
|
|
||||||
> face-down :: (send c face-down)
|
|
||||||
Makes the card face up/down without animation.
|
|
||||||
|
|
||||||
> face-down? :: (send c face-down?) - #t if the card is currently
|
|
||||||
face down.
|
|
||||||
|
|
||||||
> get-suit-id :: (send c get-suit-id) - normally 1, 2, 3, or 4 (see
|
|
||||||
`get-suit' for corresponding suit names), but the result can be
|
|
||||||
anything for a card created by `make-card'
|
|
||||||
|
|
||||||
> get-suit :: (send c get-suit) - 'clubs, 'diamonds, 'hearts, 'spades,
|
|
||||||
or 'unknown, depending on whether `get-suit-id' returns 1, 2,
|
|
||||||
3, 4, or something else
|
|
||||||
|
|
||||||
> get-value :: (send c get-value) - normally 1 (Ace), 2, ... 10, 11
|
|
||||||
(Jack), 12 (Queen), or 13 (King), but the result can be
|
|
||||||
anything for a card created by `make-card'
|
|
||||||
|
|
||||||
> user-can-flip :: (send c user-can-flip)
|
|
||||||
> user-can-flip :: (send c user-can-flip can?)
|
|
||||||
Determines whether the user can flip the card interactively,
|
|
||||||
usually by double-clicking it. Initially #t.
|
|
||||||
|
|
||||||
> user-can-move :: (send c user-can-move)
|
|
||||||
> user-can-move :: (send c user-can-move can?)
|
|
||||||
Determines whether the user can move the card interactively,
|
|
||||||
usually by dragging it. Disabling moves has the side-effect of
|
|
||||||
disabling raises and double-clicks. Initially #t.
|
|
||||||
|
|
||||||
> snap-back-after-move :: (send c snap-back-after-move)
|
|
||||||
> snap-back-after-move :: (send c snap-back-after-move on?)
|
|
||||||
Assuming user can move the card interactively, determines
|
|
||||||
whether the card stays where the user dragged it or snaps back
|
|
||||||
to its original place. Initially #f. A region's *interactive*
|
|
||||||
callback can disable snap-back for a card so that the card can
|
|
||||||
be delivered to the region. (A region's normal callback cannot
|
|
||||||
release the card, because it's too late.)
|
|
||||||
|
|
||||||
> stay-in-region :: (send c stay-in-region r)
|
|
||||||
> stay-in-region :: (send c stay-in-region)
|
|
||||||
If `r' is a region, the user cannot move the card out of r.
|
|
||||||
Initially #f.
|
|
||||||
|
|
||||||
> home-region :: (send c home-region r)
|
|
||||||
> home-region :: (send c home-region)
|
|
||||||
If `r' is a region, the user can move the card freely within
|
|
||||||
the region, but it snaps back if moved completely out of the
|
|
||||||
region. If moved partly out of the region, the card is moved
|
|
||||||
enough to get completely back in. Initially #f. A region's
|
|
||||||
*interactive* callback can disable snap-back for a card so that
|
|
||||||
the card can be delivered to the region. (A region's normal
|
|
||||||
callback cannot release the card, because it's too late.)
|
|
||||||
|
|
||||||
> dim :: (send c dim dim?)
|
|
||||||
> dim :: (send c dim)
|
|
||||||
"Highlights" the card by drawing it dimmer than normal.
|
|
||||||
|
|
||||||
> copy :: (send c copy) - makes a new card with the same suit and
|
|
||||||
value.
|
|
|
@ -81,8 +81,8 @@
|
||||||
[parent status-pane]
|
[parent status-pane]
|
||||||
[label "Options..."]
|
[label "Options..."]
|
||||||
[callback (lambda (b e) (configure-dialog))])
|
[callback (lambda (b e) (configure-dialog))])
|
||||||
(send t add-help-button status-pane
|
(send t add-scribble-button status-pane
|
||||||
(list "games" "crazy8s") "Crazy 8s Help" #f)
|
'(lib "games/scribblings/games.scrbl") "crazy8s")
|
||||||
|
|
||||||
;; The "Options.." button opens a configuration dialog that
|
;; The "Options.." button opens a configuration dialog that
|
||||||
;; starts a new game:
|
;; starts a new game:
|
||||||
|
|
|
@ -1,144 +0,0 @@
|
||||||
_Games_
|
|
||||||
=======
|
|
||||||
|
|
||||||
The "PLT Games" (Unix: plt/bin/plt-games) executable is created by
|
|
||||||
"Setup PLT" (Unix: plt/bin/setup-plt).
|
|
||||||
|
|
||||||
The Games program lets you select one of the games distributed by PLT,
|
|
||||||
or other games installed as sub-collections of the "games" collection
|
|
||||||
(see below).
|
|
||||||
|
|
||||||
* Aces - A solitaire card game. Click the "Help" button in Aces for
|
|
||||||
more details.
|
|
||||||
|
|
||||||
- by Robby
|
|
||||||
|
|
||||||
* Same - The object is to score points by removing dots from the
|
|
||||||
board. Click the "Help" button in Same for more details.
|
|
||||||
|
|
||||||
- by Robby
|
|
||||||
|
|
||||||
* Go Fish (against two computer players) - The children's card game
|
|
||||||
where you try to get rid of all you cards by forming pairs.
|
|
||||||
|
|
||||||
- by Matthew
|
|
||||||
|
|
||||||
* Crazy 8s - The card game where you try to get rid of all you cards
|
|
||||||
by matching the top card in the discard pile. Click "Help" in the
|
|
||||||
game for details.
|
|
||||||
|
|
||||||
- by Matthew
|
|
||||||
|
|
||||||
* Blackjack - Standard rules. Click "Help" in the game for specifics.
|
|
||||||
|
|
||||||
- by Matthew
|
|
||||||
|
|
||||||
* Rummy (against one computer player) - A simple variant of the
|
|
||||||
popular card game. Click "Help" in the game for details.
|
|
||||||
|
|
||||||
- by Matthew
|
|
||||||
|
|
||||||
* _Minesweeper_ - A simple version of the classic tile-removing game.
|
|
||||||
|
|
||||||
- by Matthew
|
|
||||||
|
|
||||||
* _Memory_ (matching game) - In case you have small children, too.
|
|
||||||
|
|
||||||
- by Matthew
|
|
||||||
|
|
||||||
* Paint by Numbers - A logic game. Click the "Help" button in Paint
|
|
||||||
by Numbers for more details.
|
|
||||||
|
|
||||||
- by Robby
|
|
||||||
|
|
||||||
* _Lights Out_ - A color-toggling game. Click the "Help" button in
|
|
||||||
Lights Out for more details.
|
|
||||||
|
|
||||||
- by Robby
|
|
||||||
|
|
||||||
* Pousse - A game similar to tic-tac-toe, but tokens are pushed
|
|
||||||
onto the board and can move other pieces. Click the "Help" button
|
|
||||||
in Pousse for more details. You can install your own player
|
|
||||||
programs. (This game was part of the 1998 ICFP programming
|
|
||||||
contest.)
|
|
||||||
|
|
||||||
- by Matthew
|
|
||||||
|
|
||||||
* GCalc - Not really a game, but a demonstration of "concrete
|
|
||||||
abstractions". See
|
|
||||||
http://www.grame.fr/Research/GCalcul/Graphic_Calculus.html
|
|
||||||
ftp://ftp.grame.fr/pub/Documents/ICMC94LambdaCalc.pdf
|
|
||||||
for the theoretic details, and right-click anywhere in the game
|
|
||||||
for instructions.
|
|
||||||
|
|
||||||
- by Eli
|
|
||||||
|
|
||||||
* Checkers - A simple checkers game (with no AI player) intended
|
|
||||||
as a demonstration use of the gl-board-games library.
|
|
||||||
|
|
||||||
- by Scott
|
|
||||||
|
|
||||||
* Jewel - Swap the jewels to make 3-in-a-row.
|
|
||||||
|
|
||||||
- by Dave Ashley
|
|
||||||
and Peter Ivanyi
|
|
||||||
|
|
||||||
Implementing new Games
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
The game-starting console inspects the sub-collections of the "games"
|
|
||||||
collection. If a sub-collection has an info.ss definition (see the mzc
|
|
||||||
manual), the following fields of the collection's "info.ss" file are
|
|
||||||
used:
|
|
||||||
|
|
||||||
* `game' [required] : used as a module name in the sub-collection to
|
|
||||||
load for the game; the module must provide a `game@' unit (see
|
|
||||||
MzLib's "unit.ss" form) with no particular exports; the unit is
|
|
||||||
invoked with no imports to start the game.
|
|
||||||
|
|
||||||
* `name' [defaults to the collection name] : used to label the
|
|
||||||
game-starting button in the game console.
|
|
||||||
|
|
||||||
* `game-icon' [defaults to collection name with ".png"] : used as a
|
|
||||||
path to a bitmap file that is used for the game button's label;
|
|
||||||
this image should be 32 x 32 and have a mask.
|
|
||||||
|
|
||||||
* `game-set' [defaults to "Other Games"] : a label used to group
|
|
||||||
games that declare themselves to be in the same set.
|
|
||||||
|
|
||||||
To implement card games, see the documentation for the "cards"
|
|
||||||
sub-collection of the "games" collection. Card games typically belong
|
|
||||||
in the "Cards" game set.
|
|
||||||
|
|
||||||
|
|
||||||
Showing Help
|
|
||||||
------------
|
|
||||||
|
|
||||||
The _show-help.ss_ library provides a `show-help' function for
|
|
||||||
displaying a help window.
|
|
||||||
|
|
||||||
> (show-help collection frame-title-str verbatim?)
|
|
||||||
|
|
||||||
Returns a thunk for showing a help window. Multiple invocations
|
|
||||||
of the thunk bring the same window to the foreground (until the
|
|
||||||
user closes the window).
|
|
||||||
|
|
||||||
The help window displays "doc.txt" from the given collection, where
|
|
||||||
`coll-path' is a list of strings to select the collection.
|
|
||||||
|
|
||||||
The `frame-title-str' string is used for the help window title.
|
|
||||||
|
|
||||||
If `verbatim?' is true, then "doc.txt" is displayed verbatim,
|
|
||||||
otherwise it is formatted as follows:
|
|
||||||
|
|
||||||
- Any line of the form "** ... **" is omitted.
|
|
||||||
|
|
||||||
- Any line that starts with "*" after whitespace is indented
|
|
||||||
as a bullet point.
|
|
||||||
|
|
||||||
- Any line that contains only "-"s and is as long as the previous
|
|
||||||
line causes the previous line to be formatted as a title.
|
|
||||||
|
|
||||||
- Other lines are paragraph-flowed to fit the window.
|
|
||||||
|
|
||||||
The `verbatim?' argument is optional, and it defaults to #f.
|
|
|
@ -1,8 +0,0 @@
|
||||||
_doors.ss_
|
|
||||||
|
|
||||||
The "doors.ss" library builds on "gl-board.ss" to support simple
|
|
||||||
maze-like games, where the maze is formed by a grid of squares and
|
|
||||||
doors of various types appears between adjacent squares.
|
|
||||||
|
|
||||||
But it's not ready, yet. Check back later.
|
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
GCalc is a system for visually demonstrating the Lambda Calculus.
|
|
||||||
(Not really a game...)
|
|
||||||
|
|
||||||
See the following for the principles:
|
|
||||||
http://www.grame.fr/Research/GCalcul/Graphic_Calculus.html
|
|
||||||
ftp://ftp.grame.fr/pub/Documents/ICMC94LambdaCalc.pdf
|
|
||||||
|
|
||||||
|
|
||||||
The window layout
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
The window is divided into three working areas, each made of cells.
|
|
||||||
Cells hold cube objects, which can be dragged between cells (with a
|
|
||||||
few exceptions that are listed below). The working areas are:
|
|
||||||
|
|
||||||
1. The right side is the storage area. This is used for saving
|
|
||||||
objects -- drag any cube to/from here. Note that cubes can be
|
|
||||||
named for convenience.
|
|
||||||
|
|
||||||
2. The left side is a panel of basic color cubes. These cells always
|
|
||||||
contain a set of basic cubes that are used as the primitive
|
|
||||||
building blocks all other values are made of. They cannot be
|
|
||||||
overwritten. (Note that this includes a transparent cell.)
|
|
||||||
|
|
||||||
3. The center part is the working panel. This is the main panel where
|
|
||||||
new cubes are constructed. The center cell is similar to a storage
|
|
||||||
cell, and the surrounding eight cells all perform some operation on
|
|
||||||
this cell.
|
|
||||||
|
|
||||||
|
|
||||||
User Interaction
|
|
||||||
----------------
|
|
||||||
|
|
||||||
Right-click any cell except for the basic colors on the left panel, or
|
|
||||||
hit escape or F10 for a menu of operations. The menu also includes
|
|
||||||
the keyboard shortcuts for these operations.
|
|
||||||
|
|
||||||
|
|
||||||
Cube operations
|
|
||||||
---------------
|
|
||||||
|
|
||||||
There are six simple operations that are considered part of the simple
|
|
||||||
graphic cube world. The operations correspond to six of the operation
|
|
||||||
cells: a left-right composition is built using the left and the right
|
|
||||||
cells, a top-bottom using the top and the bottom, and a front-back
|
|
||||||
using the top-left and bottom-right. Dragging a cube to one of these
|
|
||||||
cells will use the corresponding operator to combine it with the main
|
|
||||||
cell's cube. Using a right mouse click on one of these cells can be
|
|
||||||
used to cancel dragging an object to that cell, this is not really an
|
|
||||||
undo feature: a right-click on the right cell always splits the main
|
|
||||||
cube to two halves and throws the right side.
|
|
||||||
|
|
||||||
The colored cubes and the six basic operators make this simple domain,
|
|
||||||
which is extended to form a Lambda-Calculus-like language by adding
|
|
||||||
abstractions and applications. Right-clicking on a basic cube on the
|
|
||||||
left panel creates an abstraction which is actually a lambda
|
|
||||||
expression except that colors are used instead of syntactic variables.
|
|
||||||
For example, if the main cell contains `R|G' (red-green on the left
|
|
||||||
and right), then right-clicking the green cube on the left panel
|
|
||||||
leaves us with `lambda G . R|G', which is visualized as `R|G' with a
|
|
||||||
green circle. The last two operator cells are used for application of
|
|
||||||
these abstractions: drag a function to the top-right to have it
|
|
||||||
applied on the main cube, or to the bottom-left to have the main cube
|
|
||||||
applied to it. As in the Lambda Calculus, all abstractions have
|
|
||||||
exactly one variable, use currying for multiple variables.
|
|
||||||
|
|
||||||
So far the result is a domain of colored cubes that can be used in the
|
|
||||||
same way as the simple Lambda Calculus. There is one last extension
|
|
||||||
that goes one step further: function cubes can themselves be combined
|
|
||||||
with other functions using the simple operations. This results in a
|
|
||||||
form of "spatial functions" that behave differently in different parts
|
|
||||||
of the cube according to the construction. For example, a left-right
|
|
||||||
construction of two functions `f|g' operates on a given cube by
|
|
||||||
applying `f' on its left part and `g' on its right part. You can use
|
|
||||||
the preferences dialog to change a few aspects of the computation.
|
|
||||||
|
|
||||||
Use the "Open Example" menu entry to open a sample file that contains
|
|
||||||
lots of useful objects (Church numerals, booleans, lists,
|
|
||||||
Y-combinator, etc).
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
#lang mzscheme
|
#lang mzscheme
|
||||||
|
|
||||||
(require mzlib/class mred mzlib/etc "../show-help.ss" mzlib/unit)
|
(require mzlib/class mred mzlib/etc "../show-scribbling.ss" mzlib/unit)
|
||||||
(provide game@)
|
(provide game@)
|
||||||
|
|
||||||
(define customs '())
|
(define customs '())
|
||||||
|
@ -527,7 +527,9 @@
|
||||||
(instantiate horizontal-pane% (gcalc-frame)))
|
(instantiate horizontal-pane% (gcalc-frame)))
|
||||||
|
|
||||||
(define help
|
(define help
|
||||||
(show-help (list "games" "gcalc") "GCalc Help" #t))
|
(show-scribbling
|
||||||
|
'(lib "games/scribblings/games.scrbl")
|
||||||
|
"gcalc"))
|
||||||
|
|
||||||
(define file-name #f)
|
(define file-name #f)
|
||||||
(define modified? #f)
|
(define modified? #f)
|
||||||
|
|
|
@ -26,7 +26,8 @@
|
||||||
;; Set up the table
|
;; Set up the table
|
||||||
(define t (make-table "Rummy" 8 4.5))
|
(define t (make-table "Rummy" 8 4.5))
|
||||||
(define status-pane (send t create-status-pane))
|
(define status-pane (send t create-status-pane))
|
||||||
(send t add-help-button status-pane '("games" "ginrummy") "Rummy Help" #f)
|
(send t add-scribble-button status-pane
|
||||||
|
'(lib "games/scribblings/games.scrbl") "ginrummy")
|
||||||
(send t show #t)
|
(send t show #t)
|
||||||
(send t set-double-click-action #f)
|
(send t set-double-click-action #f)
|
||||||
(send t set-button-action 'left 'drag-raise/one)
|
(send t set-button-action 'left 'drag-raise/one)
|
||||||
|
|
|
@ -1,95 +0,0 @@
|
||||||
_gl-board.ss_
|
|
||||||
|
|
||||||
The gl-board.ss library uses OpenGL, via the sgl library, to provide generic
|
|
||||||
functionality for 3-dimensional views of board games. It provides support for
|
|
||||||
viewing and positioning the board as well as for moving pieces on the board.
|
|
||||||
It does not handle rendering of the board and pieces themselves. The arrow
|
|
||||||
keys rotate the board, the = and - keys move the board closer and further, and
|
|
||||||
the _ and + keys control the field of vision. Games are played by left
|
|
||||||
clicking the mouse on a piece and dragging it to a space.
|
|
||||||
|
|
||||||
The checkers and goblet games both use the gl-board.ss library.
|
|
||||||
|
|
||||||
The gl-board.ss module provides _gl-board%_, a subclass of canvas%, with the
|
|
||||||
following public methods:
|
|
||||||
|
|
||||||
> (add-space draw info): (->) X ->
|
|
||||||
Adds a space to the board. The draw argument function should draw the space
|
|
||||||
using GL drawing commands. The info argument is associated with the space.
|
|
||||||
Spaces should be drawn on the z = 0 plane.
|
|
||||||
|
|
||||||
> (add-piece x y z draw info): real real real (bool ->) X ->
|
|
||||||
Adds a piece to the board. The draw argument function should draw the piece
|
|
||||||
using GL drawing commands; the argument is #t if the piece is being drawn
|
|
||||||
only for its shadow, #f otherwise. The info argument is associated with the
|
|
||||||
piece. The x, y, and z arguments are the position at which the piece resides.
|
|
||||||
|
|
||||||
> (add-heads-up w h draw info): real real (->) X ->
|
|
||||||
Adds an item to a "heads-up" display at the bottom of the board area. The
|
|
||||||
heads-up area is not affected by rotation or scaling of the board, though
|
|
||||||
it does scale as the window is enlarged. The w and h arguments inidicate
|
|
||||||
the width and height of the object that is shown by `draw'; the heads-up
|
|
||||||
area is intended to show objects up to size 1 x 1. The `draw' function
|
|
||||||
should draw at the origin.
|
|
||||||
|
|
||||||
> (get-spaces): -> (listof X)
|
|
||||||
Returns a list of the infos associated with the current spaces.
|
|
||||||
|
|
||||||
> (get-pieces): -> (listof X)
|
|
||||||
Returns a list of the infos associated with the current pieces.
|
|
||||||
|
|
||||||
> (get-heads-ups) -> (listof X)
|
|
||||||
Returns a list of the infos associated with the current heads-up items.
|
|
||||||
|
|
||||||
> (set-space-draw info draw): X (->) ->
|
|
||||||
Sets to draw the drawing method of all spaces whose info is equal? to the
|
|
||||||
given info.
|
|
||||||
|
|
||||||
> (set-piece-draw info draw): X (boolean ->) ->
|
|
||||||
Sets to draw the drawing method of all pieces whose info is equal? to the
|
|
||||||
given info. The drawing method takes a boolean. If the value it true,
|
|
||||||
then the piece should be drawn for creating its shadow. Otherwise is should
|
|
||||||
be drawn normally.
|
|
||||||
|
|
||||||
> (set-heads-up-draw info draw): X (->) ->
|
|
||||||
Sets to draw the drawing method of all heads-up objects whose info
|
|
||||||
is equal? to the given info.
|
|
||||||
|
|
||||||
> (enable-piece info on?): X boolean ->
|
|
||||||
Enables or disables a piece whose info is equal? to the given info.
|
|
||||||
Disabled pieces are not selectable.
|
|
||||||
|
|
||||||
> (enabled? info): X -> boolean
|
|
||||||
If a piece whose info is equal? to the given info is enabled or not.
|
|
||||||
|
|
||||||
> (remove-piece info): X ->
|
|
||||||
Removes all pieces whose info is equal? to the given info.
|
|
||||||
|
|
||||||
> (remove-heads-up info): X ->
|
|
||||||
Removes all heads-up objects whose info is equal? to the given info.
|
|
||||||
|
|
||||||
|
|
||||||
A gl-board object is constructed as follows:
|
|
||||||
(new gl-board% (min-x real) (max-x real)
|
|
||||||
(min-y real) (max-y real)
|
|
||||||
(lift real)
|
|
||||||
(move (X gl-double-vector ->))
|
|
||||||
;; Optional:
|
|
||||||
(theta real) (phi real))
|
|
||||||
|
|
||||||
The min-x, max-x, min-y, and max-y parameters all specify the dimensions of
|
|
||||||
the board. They are used to setup viewing parameters. The board is viewed
|
|
||||||
centered around the center of the coordinates, and the view attempts to fill
|
|
||||||
the window to them. The optional theta and phi arguments determine the initial
|
|
||||||
rotation of the board, with respective defaults 45 and 0; theta corresponds to
|
|
||||||
the up and down keys, and phi corresponds to the left and right keys. (Holding
|
|
||||||
down Command/Meta/Alt while pressing an arrow key pans the display, instead
|
|
||||||
of rotating.)
|
|
||||||
|
|
||||||
The lift parameter specifies how high off the board mouse-dragged pieces are.
|
|
||||||
|
|
||||||
The gl-board% class invokes the move callback when a piece is selected
|
|
||||||
(left-click) and then unselected. It is given the info associated with the
|
|
||||||
selected piece, and the coordinates the user has dragged it to. If the piece
|
|
||||||
should be moved permanently, the move function must update the board state
|
|
||||||
with remove-piece and add-piece.
|
|
|
@ -1,111 +0,0 @@
|
||||||
** To play Goblet, run the "PLT Games" application.
|
|
||||||
|
|
||||||
"Gobblet!" is a board game from Blue Orange Games:
|
|
||||||
http://www.blueorangegames.com/
|
|
||||||
|
|
||||||
Our 3x3 version actually corresponds to "Gobblet! Jr.", while the 4x4
|
|
||||||
version matches "Gobblet!".
|
|
||||||
|
|
||||||
The Blue Orange web site provides rules for Gobblet! Jr. and
|
|
||||||
Gobblet!. The rules below are in our own words; see also the Blue
|
|
||||||
Orange version.
|
|
||||||
|
|
||||||
Game Rules
|
|
||||||
----------
|
|
||||||
|
|
||||||
The 3x3 game is a generalization of tic-tac-toe:
|
|
||||||
|
|
||||||
* The object of the game is to get three in a row of your color,
|
|
||||||
vertically, horizontally, or diagonally. Size doesn't matter for
|
|
||||||
determining a winner.
|
|
||||||
|
|
||||||
* Each player (red or yellow) starts with 6 pieces: two large, two
|
|
||||||
medium, and two small.
|
|
||||||
|
|
||||||
* On each turn, a player can either place a new piece on the board,
|
|
||||||
or move a piece already on the board --- from anywhere to anywhere,
|
|
||||||
as long as the "from" and "to" are different.
|
|
||||||
|
|
||||||
* A piece can be placed (or moved to) an empty space, or it can be
|
|
||||||
placed/moved on top of a smaller piece already on the board,
|
|
||||||
"gobbling" the smaller piece. The smaller piece does not have to
|
|
||||||
be an opponent's piece, and the smaller piece may itself have
|
|
||||||
gobbled another piece previously.
|
|
||||||
|
|
||||||
* Only visible pieces can be moved, and only visible pieces count
|
|
||||||
toward winning. Gobbled pieces stay on the board, however, and
|
|
||||||
when a piece is moved, any piece that it gobbled stays put and
|
|
||||||
becomes visible.
|
|
||||||
|
|
||||||
* If moving a piece exposes a winning sequence for the opponent, and
|
|
||||||
if the destination for the move does not cover up one of the other
|
|
||||||
pieces in the sequence, then the opponent wins --- even if the move
|
|
||||||
makes a winning sequence for the moving player.
|
|
||||||
|
|
||||||
* Technically, if a player touches a piece, then the piece must be
|
|
||||||
moved on that turn. In other words, you're not allowed to peek
|
|
||||||
under a piece to remind yourself whether it gobbled anything. If
|
|
||||||
the piece can't be moved, the player forfeits. This particular
|
|
||||||
rule is not enforced by our version --- in part because our version
|
|
||||||
supports a rewind button, which is also not in the official game.
|
|
||||||
|
|
||||||
The 4x4 game has a few changes:
|
|
||||||
|
|
||||||
* The object of the game is to get four in a row of your color.
|
|
||||||
|
|
||||||
* Each player (red or yellow) starts with 12 pieces: three large,
|
|
||||||
three medium-large, three medium-small, and three small.
|
|
||||||
|
|
||||||
* Each player's pieces are initially arranged into three stacks off
|
|
||||||
the board, and only visible pieces can be moved onto the board.
|
|
||||||
The initial stacks prevent playing a smaller piece before a
|
|
||||||
corresponding larger piece.
|
|
||||||
|
|
||||||
* When a piece is moved from off-board onto the board, it must be
|
|
||||||
moved to either (1) an empty space, or (2) a space to gobble an
|
|
||||||
opponent's piece that is part of three in a row (for the opponent).
|
|
||||||
In other words, a new piece can gobble only an opponent's piece,
|
|
||||||
and only to prevent an immediate win on the opponent's next turn.
|
|
||||||
These restrictions do not apply when a piece that is already on the
|
|
||||||
board is moved.
|
|
||||||
|
|
||||||
Controls
|
|
||||||
--------
|
|
||||||
|
|
||||||
Click and drag pieces in the obvious way to take a turn. The shadow
|
|
||||||
under a piece shows where it will land when you drop it.
|
|
||||||
|
|
||||||
Use the arrow keys on your keyboard to rotate the board. Use the "-"
|
|
||||||
and "=" keys to zoom in and out. Use "_" and "+" to make the game
|
|
||||||
smaller and larger. (Changing the size adjusts perspective in a
|
|
||||||
slightly different way than zooming.) Depending on how keyboard focus
|
|
||||||
works on your machine, you may have to click the board area to make
|
|
||||||
these controls work.
|
|
||||||
|
|
||||||
The button labeled "<" at the bottom of the window rewinds the game by
|
|
||||||
one turn. The button labeled ">" re-plays one turn in a rewound game.
|
|
||||||
An alternate move can be made at any point in a rewound game,
|
|
||||||
replacing the old game from that point on.
|
|
||||||
|
|
||||||
Auto-Play
|
|
||||||
---------
|
|
||||||
|
|
||||||
Turn on a computer player at any time by checking the "Auto-Play Red"
|
|
||||||
or "Auto-Play Yellow" checkbox. If you rewind the game, you can
|
|
||||||
choose an alternate move for yourself or for the auto-player to find
|
|
||||||
out what would have happened. The auto-player is not always
|
|
||||||
deterministic, so replying the same move might lead to a different
|
|
||||||
result. You can disable an auto-player at any point by unchecking the
|
|
||||||
corresponding "Auto-Play" checkbox.
|
|
||||||
|
|
||||||
Important: In the 3x3 game, you CANNOT win as yellow against the smart
|
|
||||||
auto-player (if the auto-player is allowed to play red from the start
|
|
||||||
of the game). In other words, red has a forced win in the 3x3 game,
|
|
||||||
and the smart auto-player knows the path to victory. You might have a
|
|
||||||
chance to beat the red player in the default mode, though, which is
|
|
||||||
represented by the "Ok" choice (instead of "Smart") in the "Auto-Play
|
|
||||||
Options" dialog.
|
|
||||||
|
|
||||||
Configure the auto-player by clicking the "Auto-Play Options" button.
|
|
||||||
Currently, there's no difference between "Smart" and "Ok" in the 4x4
|
|
||||||
game.
|
|
|
@ -8,7 +8,7 @@
|
||||||
"gui.ss"
|
"gui.ss"
|
||||||
"heuristics.ss"
|
"heuristics.ss"
|
||||||
"explore.ss"
|
"explore.ss"
|
||||||
"../show-help.ss")
|
"../show-scribbling.ss")
|
||||||
|
|
||||||
(provide game@)
|
(provide game@)
|
||||||
|
|
||||||
|
@ -34,8 +34,8 @@
|
||||||
(queue-callback
|
(queue-callback
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(unless help
|
(unless help
|
||||||
(set! help (show-help (list "games" "gobblet")
|
(set! help (show-scribbling '(lib "games/scribblings/games.scrbl")
|
||||||
"Gobblet Help" #f)))
|
"gobblet")))
|
||||||
(help)))))))]
|
(help)))))))]
|
||||||
[MODEL : model^ (model-unit CONFIG)]
|
[MODEL : model^ (model-unit CONFIG)]
|
||||||
[HEURISTICS : heuristics^ (heuristics-unit CONFIG MODEL EXPLORE)]
|
[HEURISTICS : heuristics^ (heuristics-unit CONFIG MODEL EXPLORE)]
|
||||||
|
|
|
@ -36,7 +36,8 @@
|
||||||
;; Set up the table
|
;; Set up the table
|
||||||
(define t (make-table "Go Fish" 8 4.5))
|
(define t (make-table "Go Fish" 8 4.5))
|
||||||
(define status-pane (send t create-status-pane))
|
(define status-pane (send t create-status-pane))
|
||||||
(send t add-help-button status-pane '("games" "gofish") "Go Fish Help" #f)
|
(send t add-scribble-button status-pane
|
||||||
|
'(lib "games/scribblings/games.scrbl") "gofish")
|
||||||
(send t show #t)
|
(send t show #t)
|
||||||
(send t set-double-click-action #f)
|
(send t set-double-click-action #f)
|
||||||
(send t set-button-action 'left 'drag-raise/one)
|
(send t set-button-action 'left 'drag-raise/one)
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#lang setup/infotab
|
#lang setup/infotab
|
||||||
|
|
||||||
|
(define scribblings '(("scribblings/games.scrbl" (multi-page))))
|
||||||
|
|
||||||
(define mred-launcher-libraries (list "main.ss"))
|
(define mred-launcher-libraries (list "main.ss"))
|
||||||
(define mred-launcher-names (list "PLT Games"))
|
(define mred-launcher-names (list "PLT Games"))
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
"shapes.scm"
|
"shapes.scm"
|
||||||
"array.scm"
|
"array.scm"
|
||||||
"text.scm"
|
"text.scm"
|
||||||
"../show-help.ss"
|
"../show-scribbling.ss"
|
||||||
)
|
)
|
||||||
|
|
||||||
(provide game@)
|
(provide game@)
|
||||||
|
@ -50,16 +50,17 @@
|
||||||
(define jewel-difficulty 0)
|
(define jewel-difficulty 0)
|
||||||
|
|
||||||
; table of high scores, loaded from a file
|
; table of high scores, loaded from a file
|
||||||
(define high-scores #( ("NOBODY" "0" "1")
|
(define high-scores (vector
|
||||||
("NOBODY" "0" "1")
|
'("NOBODY" "0" "1")
|
||||||
("NOBODY" "0" "1")
|
'("NOBODY" "0" "1")
|
||||||
("NOBODY" "0" "1")
|
'("NOBODY" "0" "1")
|
||||||
("NOBODY" "0" "1")
|
'("NOBODY" "0" "1")
|
||||||
("NOBODY" "0" "1")
|
'("NOBODY" "0" "1")
|
||||||
("NOBODY" "0" "1")
|
'("NOBODY" "0" "1")
|
||||||
("NOBODY" "0" "1")
|
'("NOBODY" "0" "1")
|
||||||
("NOBODY" "0" "1")
|
'("NOBODY" "0" "1")
|
||||||
("NOBODY" "0" "1")
|
'("NOBODY" "0" "1")
|
||||||
|
'("NOBODY" "0" "1")
|
||||||
))
|
))
|
||||||
|
|
||||||
(define startlife 1000.0)
|
(define startlife 1000.0)
|
||||||
|
@ -1786,8 +1787,7 @@
|
||||||
(jewel-init-game)
|
(jewel-init-game)
|
||||||
|
|
||||||
(define show-jewel-help
|
(define show-jewel-help
|
||||||
(show-help (list "games" "jewel")
|
(show-scribbling '(lib "games/scribblings/games.scrbl") "jewel"))
|
||||||
"Jewel Help" #f))
|
|
||||||
|
|
||||||
(define *MAIN_WINDOW*
|
(define *MAIN_WINDOW*
|
||||||
(new jewel-frame%
|
(new jewel-frame%
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#lang mzscheme
|
#lang mzscheme
|
||||||
(require "board.ss"
|
(require "board.ss"
|
||||||
"../show-help.ss"
|
"../show-scribbling.ss"
|
||||||
mred
|
mred
|
||||||
mzlib/class
|
mzlib/class
|
||||||
mzlib/unit)
|
mzlib/unit)
|
||||||
|
@ -173,7 +173,7 @@
|
||||||
(lambda x
|
(lambda x
|
||||||
(init-board original-board)))
|
(init-board original-board)))
|
||||||
|
|
||||||
(let ([help (show-help (list "games" "lights-out") "Lights Out Help")])
|
(let ([help (show-scribbling '(lib "games/scribblings/games.scrbl") "lights-out")])
|
||||||
(make-object button% "Help" button-panel (lambda x (help))))
|
(make-object button% "Help" button-panel (lambda x (help))))
|
||||||
|
|
||||||
(make-object grow-box-spacer-pane% button-panel)
|
(make-object grow-box-spacer-pane% button-panel)
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
(prefix solve: "solve.ss")
|
(prefix solve: "solve.ss")
|
||||||
"all-problems.ss"
|
"all-problems.ss"
|
||||||
"problem.ss"
|
"problem.ss"
|
||||||
"../show-help.ss"
|
"../show-scribbling.ss"
|
||||||
framework
|
framework
|
||||||
mzlib/class
|
mzlib/class
|
||||||
mzlib/unit
|
mzlib/unit
|
||||||
|
@ -66,9 +66,9 @@
|
||||||
(send g set-value counter)]))))
|
(send g set-value counter)]))))
|
||||||
|
|
||||||
(define show-this-help
|
(define show-this-help
|
||||||
(show-help
|
(show-scribbling
|
||||||
(list "games" "paint-by-numbers")
|
'(lib "games/scribblings/games.scrbl")
|
||||||
"Paint by Numbers Help"))
|
"paint-by-numbers"))
|
||||||
|
|
||||||
(define (configure-font frame)
|
(define (configure-font frame)
|
||||||
(let ([font (get-font-from-user
|
(let ([font (get-font-from-user
|
||||||
|
|
|
@ -14,7 +14,6 @@ corresponds to the unplayed move! that's confusing.
|
||||||
"moves.ss"
|
"moves.ss"
|
||||||
"rules.ss"
|
"rules.ss"
|
||||||
"best-players.ss"
|
"best-players.ss"
|
||||||
"../show-help.ss"
|
|
||||||
framework
|
framework
|
||||||
mzlib/class
|
mzlib/class
|
||||||
mzlib/list
|
mzlib/list
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
** To play Parcheesi, run the "PLT Games" application.
|
|
||||||
|
|
||||||
Parcheesi is a race game for four players. The goal is for each
|
|
||||||
player to move their pieces from the starting position (the circles in
|
|
||||||
the corners) to the home square (in the center of the board), passing
|
|
||||||
a nearly complete loop around the board in the counter-clockwise
|
|
||||||
direction and then heads up towards the main row. For example, the
|
|
||||||
green player enters from the bottom right, travels around the board on
|
|
||||||
the light blue squares, passing each of the corners, until it reaches
|
|
||||||
the middle of the bottom of the board, where it turns off the light
|
|
||||||
blue squares and heads into the central region.
|
|
||||||
|
|
||||||
On each turn, the player rolls two dice and advances the pawn, based
|
|
||||||
on the die rolls. Typically the players may move a pawn for each die.
|
|
||||||
The pawn moves by the number of pips showing on the die and all of the
|
|
||||||
dice must be used to complete a turn.
|
|
||||||
|
|
||||||
There are some exceptions, however:
|
|
||||||
|
|
||||||
- you must roll a 5 (either directly or via summing) to enter from
|
|
||||||
the start area to the main ring.
|
|
||||||
|
|
||||||
- if two pieces of the same color occupy a square, no pieces may
|
|
||||||
pass that square.
|
|
||||||
|
|
||||||
- if an opponent's piece lands on your piece, you piece is returned
|
|
||||||
to the starting area and the opponent receives a bonus of 20
|
|
||||||
(which is treated just as if they had rolled a 20 on the dice).
|
|
||||||
|
|
||||||
- if your piece makes it home (and it must do so by exact count) you
|
|
||||||
get a bonus of 10, to be used as an additional die roll.
|
|
||||||
|
|
||||||
These rules induce a number of unexpected corner cases, but the GUI
|
|
||||||
only lets you make legal moves. Watch the space along the bottom of
|
|
||||||
the board for reasons why a move is illegal or why you have not used
|
|
||||||
all of your die rolls.
|
|
||||||
|
|
||||||
The automated players are:
|
|
||||||
|
|
||||||
- Reckless Renee, who she tries to maximize the chances that someone
|
|
||||||
else bops her.
|
|
||||||
|
|
||||||
- Polite Polly, who tries to minimize the distance her pawns move
|
|
||||||
("no, after _you_. I insist."), and
|
|
||||||
|
|
||||||
- Amazing Grace, who tries to minimize the chance she gets bopped
|
|
||||||
while moving as far as possible.
|
|
|
@ -1,50 +0,0 @@
|
||||||
** To play Pousse, run the "PLT Games" application.
|
|
||||||
|
|
||||||
Pousse (French for "push", pronounced "poo-ss") is a 2 person game,
|
|
||||||
played on an N by N board (usually 4x4). Initially the board is
|
|
||||||
empty, and the players take turns inserting one marker of their color
|
|
||||||
(X or O) on the board. The color X always goes first. The columns
|
|
||||||
and rows are numbered from 1 to N, starting from the top left, as in:
|
|
||||||
|
|
||||||
1 2 3 4
|
|
||||||
+-+-+-+-+
|
|
||||||
1 | | | | |
|
|
||||||
+-+-+-+-+
|
|
||||||
2 | | | | |
|
|
||||||
+-+-+-+-+
|
|
||||||
3 | | | | |
|
|
||||||
+-+-+-+-+
|
|
||||||
4 | | | | |
|
|
||||||
+-+-+-+-+
|
|
||||||
|
|
||||||
A marker can only be inserted on the board by sliding it onto a
|
|
||||||
particular row from the left or from the right, or onto a particular
|
|
||||||
column from the top or from the bottom. So there are 4*N possible
|
|
||||||
"moves" (ways to insert a marker). They are be named "Li", "Ri",
|
|
||||||
"Ti", "Bi" respectively, where "i" is the number of the row or column
|
|
||||||
where the insertion takes place.
|
|
||||||
|
|
||||||
When a marker is inserted, there may be a marker on the square where
|
|
||||||
the insertion takes place. In this case, all markers on the insertion
|
|
||||||
row or column from the insertion square upto the first empty square
|
|
||||||
are moved one square further to make room for the inserted marker.
|
|
||||||
Note that the last marker of the row or column will be pushed off the
|
|
||||||
board (and must be removed from play) if there are no empty squares on
|
|
||||||
the insertion row or column.
|
|
||||||
|
|
||||||
A row or a column is a "straight" of a given color, if it contains N
|
|
||||||
markers of the given color.
|
|
||||||
|
|
||||||
The game ends either when an insertion
|
|
||||||
|
|
||||||
1) repeats a previous configuration of the board; in this case the
|
|
||||||
player who inserted the marker LOSES.
|
|
||||||
|
|
||||||
2) creates a configuration with more straights of one color than
|
|
||||||
straights of the other color; the player whose color is dominant
|
|
||||||
(in number of straights) WINS.
|
|
||||||
|
|
||||||
A game always leads to a win by one of the two players. Draws are
|
|
||||||
impossible.
|
|
||||||
|
|
||||||
[From the 1998 ICFP programming contest.]
|
|
|
@ -2,6 +2,7 @@
|
||||||
(require "utils.ss"
|
(require "utils.ss"
|
||||||
"board.ss"
|
"board.ss"
|
||||||
"board-size.ss"
|
"board-size.ss"
|
||||||
|
"../show-scribbling.ss"
|
||||||
mzlib/class
|
mzlib/class
|
||||||
mzlib/class100
|
mzlib/class100
|
||||||
(all-except mzlib/unit rename) ; rename collides with class100
|
(all-except mzlib/unit rename) ; rename collides with class100
|
||||||
|
@ -655,7 +656,7 @@
|
||||||
(define misc-panel (make-object horizontal-panel% frame))
|
(define misc-panel (make-object horizontal-panel% frame))
|
||||||
(send misc-panel stretchable-height #f)
|
(send misc-panel stretchable-height #f)
|
||||||
|
|
||||||
(make-object button% "Help" misc-panel (lambda (b e) (help #f)))
|
(make-object button% "Help" misc-panel (lambda (b e) (help)))
|
||||||
(make-object button% "Setup..." misc-panel (lambda (b e) (setup)))
|
(make-object button% "Setup..." misc-panel (lambda (b e) (setup)))
|
||||||
(make-object vertical-pane% misc-panel) ; spacer
|
(make-object vertical-pane% misc-panel) ; spacer
|
||||||
|
|
||||||
|
@ -747,38 +748,11 @@
|
||||||
(send setup-dialog show #t))
|
(send setup-dialog show #t))
|
||||||
|
|
||||||
;; Help or source code window:
|
;; Help or source code window:
|
||||||
(define (help code?)
|
(define help
|
||||||
(define f (make-object frame%
|
(show-scribbling
|
||||||
(if code? "Pousse GUI Source Code" "Pousse Help")
|
'(lib "games/scribblings/games.scrbl")
|
||||||
#f 580 300))
|
"pousse"))
|
||||||
(define p (if code?
|
|
||||||
(void)
|
|
||||||
(make-object choice% #f '("Rules" "Using the GUI" "Writing Players")
|
|
||||||
f
|
|
||||||
(lambda (p ev)
|
|
||||||
(send e lock #f)
|
|
||||||
(send e load-file
|
|
||||||
(local-file (case (send p get-selection)
|
|
||||||
[(0) "doc.txt"]
|
|
||||||
[(1) "help.txt"]
|
|
||||||
[(2) "robots.txt"])))
|
|
||||||
(when (zero? (send p get-selection))
|
|
||||||
;; Delete the "run the Games app" line
|
|
||||||
(send e delete 0 (send e line-start-position 2)))
|
|
||||||
(send e lock #t)))))
|
|
||||||
(define c (make-object editor-canvas% f))
|
|
||||||
(define e (make-object text%))
|
|
||||||
(send c set-editor e)
|
|
||||||
(send (send (send e get-style-list)
|
|
||||||
find-named-style
|
|
||||||
"Standard")
|
|
||||||
set-delta
|
|
||||||
(make-object style-delta% 'change-family 'modern))
|
|
||||||
(send e load-file (local-file "doc.txt"))
|
|
||||||
;; Delete the "run the Games app" line
|
|
||||||
(send e delete 0 (send e line-start-position 2))
|
|
||||||
(send e lock #t)
|
|
||||||
(send f show #t))
|
|
||||||
|
|
||||||
; Draw initial board
|
; Draw initial board
|
||||||
(send canvas repaint)
|
(send canvas repaint)
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
** To play Same, run the "PLT Games" application.
|
|
||||||
|
|
||||||
The object of Same is to score points by removing dots from the board.
|
|
||||||
To remove a dot, click on it. As long as there is another dot of the
|
|
||||||
same color next to the clicked dot, it will disappear along with all
|
|
||||||
adjacent dots of the same color. After the dots disappear, dots in
|
|
||||||
the rows above the deleted dots will fall into the vacated spaces. If
|
|
||||||
an entire column is wiped out, all of the dots from the right will
|
|
||||||
slide left to take up the empty column's space.
|
|
||||||
|
|
||||||
Your score increases for each ball removed from the board. The score
|
|
||||||
for each click is a function of the number of balls that disappeared.
|
|
||||||
The "This Click" label shows how many points you would score for
|
|
||||||
clicking the dots underneath the mouse pointer. The score varies
|
|
||||||
quadratically with the number of balls, so eliminating many balls with
|
|
||||||
one click is advantageous.
|
|
||||||
|
|
||||||
Click the New Game button to play again.
|
|
|
@ -4,7 +4,7 @@
|
||||||
mzlib/unit
|
mzlib/unit
|
||||||
mred
|
mred
|
||||||
mzlib/list
|
mzlib/list
|
||||||
"../show-help.ss")
|
"../show-scribbling.ss")
|
||||||
|
|
||||||
(provide game@)
|
(provide game@)
|
||||||
|
|
||||||
|
@ -352,9 +352,9 @@
|
||||||
(define help-button (make-object button% "Help"
|
(define help-button (make-object button% "Help"
|
||||||
hp
|
hp
|
||||||
(let ([show-help
|
(let ([show-help
|
||||||
(show-help
|
(show-scribbling
|
||||||
(list "games" "same")
|
'(lib "games/scribblings/games.scrbl")
|
||||||
"Same Help")])
|
"same")])
|
||||||
(lambda (_1 _2)
|
(lambda (_1 _2)
|
||||||
(show-help)))))
|
(show-help)))))
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
** To play Aces, run the "PLT Games" application.
|
#lang scribble/doc
|
||||||
|
@(require "common.ss")
|
||||||
|
|
||||||
|
@gametitle["Aces" "aces" "Solitaire Card Game"]
|
||||||
|
|
||||||
Aces is a solitaire card game. The object is to remove all of the
|
Aces is a solitaire card game. The object is to remove all of the
|
||||||
cards from the board, except the four Aces.
|
cards from the board, except the four Aces.
|
33
collects/games/scribblings/blackjack.scrbl
Normal file
33
collects/games/scribblings/blackjack.scrbl
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#lang scribble/doc
|
||||||
|
@(require "common.ss")
|
||||||
|
|
||||||
|
@gametitle["Blackjack" "blackjack" "21 Card Game"]
|
||||||
|
|
||||||
|
Standard Blackjack rules with the following specifics:
|
||||||
|
|
||||||
|
@itemize[
|
||||||
|
|
||||||
|
@item{1 player (not counting the dealer).}
|
||||||
|
|
||||||
|
@item{4 decks, reshuffled after 3/4 of the cards are used.}
|
||||||
|
|
||||||
|
@item{Dealer stands on soft 17s.}
|
||||||
|
|
||||||
|
@item{Splitting is allowed only on the first two cards, and only if
|
||||||
|
they are equal. 10 and the face cards are all considered equal
|
||||||
|
for splitting.}
|
||||||
|
|
||||||
|
@item{Doubling is allowed on all unsplit hands, not on split hands.}
|
||||||
|
|
||||||
|
@item{No blackjacks after splitting.}
|
||||||
|
|
||||||
|
@item{No surrender.}
|
||||||
|
|
||||||
|
@item{No insurance.}
|
||||||
|
|
||||||
|
@item{No maximum under-21 hand size.}
|
||||||
|
|
||||||
|
@item{Dealer's second card is not revealed if the player busts (or
|
||||||
|
both halves of a split hand bust).}
|
||||||
|
|
||||||
|
]
|
7
collects/games/scribblings/checkers.scrbl
Normal file
7
collects/games/scribblings/checkers.scrbl
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#lang scribble/doc
|
||||||
|
@(require "common.ss")
|
||||||
|
|
||||||
|
@gametitle["Checkers" "checkers" "Board Game"]
|
||||||
|
|
||||||
|
This simple checkers game (with no AI player) is intended as a
|
||||||
|
demonstration use of the @schememodname[games/gl-board-games] library.
|
27
collects/games/scribblings/common.ss
Normal file
27
collects/games/scribblings/common.ss
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#lang scheme/base
|
||||||
|
|
||||||
|
(require scribble/manual
|
||||||
|
scribble/decode
|
||||||
|
setup/main-collects)
|
||||||
|
(provide (all-from-out scribble/manual)
|
||||||
|
selflink
|
||||||
|
gametitle
|
||||||
|
game)
|
||||||
|
|
||||||
|
(define (selflink str) (link str (tt str)))
|
||||||
|
|
||||||
|
(define game onscreen)
|
||||||
|
|
||||||
|
(define (gametitle name subcol subtitle)
|
||||||
|
(make-splice
|
||||||
|
(list
|
||||||
|
(title #:tag subcol
|
||||||
|
(image (path->main-collects-relative
|
||||||
|
(build-path (collection-path "games" subcol)
|
||||||
|
(format "~a.png" subcol))))
|
||||||
|
" " (onscreen name) " --- " subtitle)
|
||||||
|
(margin-note "To play "
|
||||||
|
(onscreen name)
|
||||||
|
", run the "
|
||||||
|
(exec "PLT Games") " program."
|
||||||
|
" (Under Unix, it's called " (exec "plt-games") ")."))))
|
|
@ -1,14 +1,18 @@
|
||||||
** To play Crazy 8s, run the "PLT Games" application.
|
#lang scribble/doc
|
||||||
|
@(require "common.ss")
|
||||||
|
|
||||||
|
@gametitle["Crazy 8s" "crazy8s" "Card Game"]
|
||||||
|
|
||||||
Try to get rid of all you cards by matching the value or suit of the
|
Try to get rid of all you cards by matching the value or suit of the
|
||||||
top card in the discard pile. In the default mode, click a card to
|
top card in the discard pile. In the default mode, click a card to
|
||||||
discard it; you can adjust the options so that you discard by dragging
|
discard it; you can adjust the options so that you discard by dragging
|
||||||
a card from your hand to the discard pile.
|
a card from your hand to the discard pile.
|
||||||
|
|
||||||
An 8 can be discarded at any time, and in that case, the player who
|
An @onscreen{8} can be discarded at any time, and in that case, the
|
||||||
discarded the 8 gets to pick any suit for it (hence the craziness of
|
player who discarded the @onscreen{8} gets to pick any suit for it
|
||||||
8s). When you discard an 8, a panel of buttons appears to the right
|
(hence the craziness of @onscreen{8}s). When you discard an
|
||||||
of the discard pile, so you can pick the suit.
|
@onscreen{8}, a panel of buttons appears to the right of the discard
|
||||||
|
pile, so you can pick the suit.
|
||||||
|
|
||||||
A player can choose to draw a card instead of discarding, as long as
|
A player can choose to draw a card instead of discarding, as long as
|
||||||
cards are left in the draw pile. A player's turn continues after
|
cards are left in the draw pile. A player's turn continues after
|
||||||
|
@ -18,7 +22,7 @@ middle of the table; you can adjust the options to that you draw by
|
||||||
dragging it from the draw pile to your hand.
|
dragging it from the draw pile to your hand.
|
||||||
|
|
||||||
If no cards are left in the deck, a player may pass instead of
|
If no cards are left in the deck, a player may pass instead of
|
||||||
discarding. To pass, click the "Pass" button.
|
discarding. To pass, click the @onscreen{Pass} button.
|
||||||
|
|
||||||
The status line at the bottom of the window provides instructions as
|
The status line at the bottom of the window provides instructions as
|
||||||
you go.
|
you go.
|
89
collects/games/scribblings/games.scrbl
Normal file
89
collects/games/scribblings/games.scrbl
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
#lang scribble/doc
|
||||||
|
@(require "common.ss")
|
||||||
|
|
||||||
|
@title{@bold{Games}}
|
||||||
|
|
||||||
|
The @exec{PLT Games} executable (or @exec{plt-games} under Unix) lets
|
||||||
|
you select one of the games distributed by PLT or other games
|
||||||
|
installed as sub-collections of the @filepath{games} collection (see
|
||||||
|
@secref["new-games"]).
|
||||||
|
|
||||||
|
@table-of-contents[]
|
||||||
|
|
||||||
|
@; ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@include-section["std-games.scrbl"]
|
||||||
|
|
||||||
|
@; ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@section[#:tag "new-games"]{Implementing new Games}
|
||||||
|
|
||||||
|
The game-starting console inspects the sub-collections of the
|
||||||
|
@filepath{games} collection. If a sub-collection has an
|
||||||
|
@filepath{info.ss} module (see @schememodname[setup/infotab]), the
|
||||||
|
following fields of the collection's "info.ss" file are used:
|
||||||
|
|
||||||
|
@itemize[
|
||||||
|
|
||||||
|
@item{@schemeidfont{game} [required] : used as a module name in the
|
||||||
|
sub-collection to load for the game; the module must provide a
|
||||||
|
@schemeidfont["game@"] unit (see @schememodname[scheme/unit]) with
|
||||||
|
no particular exports; the unit is invoked with no imports to
|
||||||
|
start the game.}
|
||||||
|
|
||||||
|
@item{@schemeidfont{name} [defaults to the collection name] : used to
|
||||||
|
label the game-starting button in the game console.}
|
||||||
|
|
||||||
|
@item{@schemeidfont{game-icon} [defaults to collection name with
|
||||||
|
@filepath{.png}] : used as a path to a bitmap file that is used for
|
||||||
|
the game button's label; this image should be 32 by 32 pixels and
|
||||||
|
have a mask.}
|
||||||
|
|
||||||
|
@item{@schemeidfont{game-set} [defaults to @scheme["Other Games"]] :
|
||||||
|
a label used to group games that declare themselves to be in the
|
||||||
|
same set.}
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
To implement card games, see @schememodname[games/cards]. Card games
|
||||||
|
typically belong in the @scheme["Cards"] game set.
|
||||||
|
|
||||||
|
|
||||||
|
@; ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@section{Showing Help}
|
||||||
|
|
||||||
|
@defmodule[games/show-help]
|
||||||
|
|
||||||
|
@defproc[(show-help [coll-path (listof string?)]
|
||||||
|
[frame-title string?]
|
||||||
|
[verbatim? any/c #f])
|
||||||
|
(-> any)]{
|
||||||
|
|
||||||
|
Returns a thunk for showing a help window based on plain
|
||||||
|
text. Multiple invocations of the thunk bring the same window to the
|
||||||
|
foreground (until the user closes the window).
|
||||||
|
|
||||||
|
The help window displays @filepath{doc.txt} from the collection
|
||||||
|
specified by @scheme[coll-path].
|
||||||
|
|
||||||
|
The @scheme[frame-title] argument is used for the help window title.
|
||||||
|
|
||||||
|
If @scheme[verbatim?] is true, then @filepath{doc.txt} is displayed
|
||||||
|
verbatim, otherwise it is formatted as follows:
|
||||||
|
|
||||||
|
@itemize[
|
||||||
|
|
||||||
|
@item{Any line of the form @litchar{**}....@litchar{**} is omitted.}
|
||||||
|
|
||||||
|
@item{Any line that starts with @litchar{*} after whitespace is indented
|
||||||
|
as a bullet point.}
|
||||||
|
|
||||||
|
@item{Any line that contains only @litchar{-}s and is as long as the previous
|
||||||
|
line causes the previous line to be formatted as a title.}
|
||||||
|
|
||||||
|
@item{Other lines are paragraph-flowed to fit the window.}
|
||||||
|
|
||||||
|
]}
|
||||||
|
|
||||||
|
|
90
collects/games/scribblings/gcalc.scrbl
Normal file
90
collects/games/scribblings/gcalc.scrbl
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
#lang scribble/doc
|
||||||
|
@(require "common.ss")
|
||||||
|
|
||||||
|
@(define Lambda "\u3BB")
|
||||||
|
|
||||||
|
@gametitle["GCalc" "gcalc" "Visual \u3BB-Calculus"]
|
||||||
|
|
||||||
|
@onscreen{GCalc} is a system for visually demonstrating the
|
||||||
|
@|Lambda|-Calculus (not really a game).
|
||||||
|
|
||||||
|
See the following for the principles:
|
||||||
|
|
||||||
|
@centerline{@selflink{http://www.grame.fr/Research/GCalcul/Graphic_Calculus.html}}
|
||||||
|
@centerline{@selflink{ftp://ftp.grame.fr/pub/Documents/ICMC94LambdaCalc.pdf}}
|
||||||
|
|
||||||
|
|
||||||
|
@section{The Window Layout}
|
||||||
|
|
||||||
|
The window is divided into three working areas, each made of cells.
|
||||||
|
Cells hold cube objects, which can be dragged between cells (with a
|
||||||
|
few exceptions that are listed below). The working areas are as
|
||||||
|
follows:
|
||||||
|
|
||||||
|
@itemize[
|
||||||
|
|
||||||
|
@item{The right side is the storage area. This is used for saving
|
||||||
|
objects -- drag any cube to/from here. Note that cubes can be
|
||||||
|
named for convenience.}
|
||||||
|
|
||||||
|
@item{The left side is a panel of basic color cubes. These cells
|
||||||
|
always contain a set of basic cubes that are used as the primitive
|
||||||
|
building blocks all other values are made of. They cannot be
|
||||||
|
overwritten. (Note that this includes a transparent cell.)}
|
||||||
|
|
||||||
|
@item{The center part is the working panel. This is the main panel where
|
||||||
|
new cubes are constructed. The center cell is similar to a storage
|
||||||
|
cell, and the surrounding eight cells all perform some operation on
|
||||||
|
this cell.}
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
@section{User Interaction}
|
||||||
|
|
||||||
|
Right-click any cell except for the basic colors on the left panel, or
|
||||||
|
hit escape or F10 for a menu of operations. The menu also includes
|
||||||
|
the keyboard shortcuts for these operations.
|
||||||
|
|
||||||
|
|
||||||
|
@section{Cube operations}
|
||||||
|
|
||||||
|
There are six simple operations that are considered part of the simple
|
||||||
|
graphic cube world. The operations correspond to six of the operation
|
||||||
|
cells: a left-right composition is built using the left and the right
|
||||||
|
cells, a top-bottom using the top and the bottom, and a front-back
|
||||||
|
using the top-left and bottom-right. Dragging a cube to one of these
|
||||||
|
cells will use the corresponding operator to combine it with the main
|
||||||
|
cell's cube. Using a right mouse click on one of these cells can be
|
||||||
|
used to cancel dragging an object to that cell, this is not really an
|
||||||
|
undo feature: a right-click on the right cell always splits the main
|
||||||
|
cube to two halves and throws the right side.
|
||||||
|
|
||||||
|
The colored cubes and the six basic operators make this simple domain,
|
||||||
|
which is extended to form a @|Lambda|-Calculus-like language by adding
|
||||||
|
abstractions and applications. Right-clicking on a basic cube on the
|
||||||
|
left panel creates an abstraction which is actually a lambda
|
||||||
|
expression except that colors are used instead of syntactic variables.
|
||||||
|
For example, if the main cell contains @onscreen{R|G} (red-green on
|
||||||
|
the left and right), then right-clicking the green cube on the left
|
||||||
|
panel leaves us with @onscreen{@|Lambda| G . R|G}, which is visualized
|
||||||
|
as @onscreen{R|G} with a green circle. The last two operator cells
|
||||||
|
are used for application of these abstractions: drag a function to the
|
||||||
|
top-right to have it applied on the main cube, or to the bottom-left
|
||||||
|
to have the main cube applied to it. As in the @|Lambda|-Calculus,
|
||||||
|
all abstractions have exactly one variable, use currying for multiple
|
||||||
|
variables.
|
||||||
|
|
||||||
|
So far the result is a domain of colored cubes that can be used in the
|
||||||
|
same way as the simple @|Lambda|-Calculus. There is one last
|
||||||
|
extension that goes one step further: function cubes can themselves be
|
||||||
|
combined with other functions using the simple operations. This
|
||||||
|
results in a form of "spatial functions" that behave differently in
|
||||||
|
different parts of the cube according to the construction. For
|
||||||
|
example, a left-right construction of two functions @onscreen{f|g}
|
||||||
|
operates on a given cube by applying @onscreen{f} on its left part and
|
||||||
|
@onscreen{g} on its right part. You can use the preferences dialog to
|
||||||
|
change a few aspects of the computation.
|
||||||
|
|
||||||
|
Use the @onscreen{Open Example} menu entry to open a sample file that
|
||||||
|
contains lots of useful objects: Church numerals, booleans, lists,
|
||||||
|
Y-combinator, etc.
|
|
@ -1,4 +1,7 @@
|
||||||
** To play Rummy, run the "PLT Games" application.
|
#lang scribble/doc
|
||||||
|
@(require "common.ss")
|
||||||
|
|
||||||
|
@gametitle["Rummy" "ginrummy" "Card Game"]
|
||||||
|
|
||||||
This is a simple variant of Rummy.
|
This is a simple variant of Rummy.
|
||||||
|
|
121
collects/games/scribblings/gobblet.scrbl
Normal file
121
collects/games/scribblings/gobblet.scrbl
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
#lang scribble/doc
|
||||||
|
@(require "common.ss")
|
||||||
|
|
||||||
|
@gametitle["Gobblet" "gobblet" "Strategy Game"]
|
||||||
|
|
||||||
|
@bold{Gobblet!} is a board game from Blue Orange Games:
|
||||||
|
|
||||||
|
@centerline{@selflink{http://www.blueorangegames.com/}}
|
||||||
|
|
||||||
|
Our 3x3 version actually corresponds to @bold{Gobblet! Jr.}, while
|
||||||
|
the 4x4 version matches @onscreen{Gobblet!}.
|
||||||
|
|
||||||
|
The Blue Orange web site provides rules for @bold{Gobblet! Jr.} and
|
||||||
|
@bold{Gobblet!}. The rules below are in our own words; see also the
|
||||||
|
Blue Orange version.
|
||||||
|
|
||||||
|
@section{Game Rules}
|
||||||
|
|
||||||
|
The 3x3 game is a generalization of tic-tac-toe:
|
||||||
|
|
||||||
|
@itemize[
|
||||||
|
|
||||||
|
@item{The object of the game is to get three in a row of your color,
|
||||||
|
vertically, horizontally, or diagonally. Size doesn't matter for
|
||||||
|
determining a winner.}
|
||||||
|
|
||||||
|
@item{Each player (red or yellow) starts with 6 pieces: two large,
|
||||||
|
two medium, and two small.}
|
||||||
|
|
||||||
|
@item{On each turn, a player can either place a new piece on the
|
||||||
|
board, or move a piece already on the board---from anywhere to
|
||||||
|
anywhere, as long as the ``from'' and ``to'' are different.}
|
||||||
|
|
||||||
|
@item{A piece can be placed (or moved to) an empty space, or it can
|
||||||
|
be placed/moved on top of a smaller piece already on the board,
|
||||||
|
``gobbling'' the smaller piece. The smaller piece does not have to
|
||||||
|
be an opponent's piece, and the smaller piece may itself have
|
||||||
|
gobbled another piece previously.}
|
||||||
|
|
||||||
|
@item{Only visible pieces can be moved, and only visible pieces count
|
||||||
|
toward winning. Gobbled pieces stay on the board, however, and
|
||||||
|
when a piece is moved, any piece that it gobbled stays put and
|
||||||
|
becomes visible.}
|
||||||
|
|
||||||
|
@item{If moving a piece exposes a winning sequence for the opponent, and
|
||||||
|
if the destination for the move does not cover up one of the other
|
||||||
|
pieces in the sequence, then the opponent wins---even if the move
|
||||||
|
makes a winning sequence for the moving player.}
|
||||||
|
|
||||||
|
@item{Technically, if a player touches a piece, then the piece must
|
||||||
|
be moved on that turn. In other words, you're not allowed to peek
|
||||||
|
under a piece to remind yourself whether it gobbled anything. If
|
||||||
|
the piece can't be moved, the player forfeits. This particular
|
||||||
|
rule is not enforced by our version --- in part because our version
|
||||||
|
supports a rewind button, which is also not in the official game.}
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
The 4x4 game has a few changes:
|
||||||
|
|
||||||
|
@itemize[
|
||||||
|
|
||||||
|
@item{The object of the game is to get four in a row of your color.}
|
||||||
|
|
||||||
|
@item{Each player (red or yellow) starts with 12 pieces: three large,
|
||||||
|
three medium-large, three medium-small, and three small.}
|
||||||
|
|
||||||
|
@item{Each player's pieces are initially arranged into three stacks
|
||||||
|
off the board, and only visible pieces can be moved onto the board.
|
||||||
|
The initial stacks prevent playing a smaller piece before a
|
||||||
|
corresponding larger piece.}
|
||||||
|
|
||||||
|
@item{When a piece is moved from off-board onto the board, it must be
|
||||||
|
moved to either (1) an empty space, or (2) a space to gobble an
|
||||||
|
opponent's piece that is part of three in a row (for the opponent).
|
||||||
|
In other words, a new piece can gobble only an opponent's piece,
|
||||||
|
and only to prevent an immediate win on the opponent's next turn.
|
||||||
|
These restrictions do not apply when a piece that is already on the
|
||||||
|
board is moved.}
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
@section{Controls}
|
||||||
|
|
||||||
|
Click and drag pieces in the obvious way to take a turn. The shadow
|
||||||
|
under a piece shows where it will land when you drop it.
|
||||||
|
|
||||||
|
Use the arrow keys on your keyboard to rotate the board. Use the
|
||||||
|
@onscreen{-} and @onscreen{=} keys to zoom in and out. Use
|
||||||
|
@onscreen{_} and @onscreen{+} to make the game smaller and larger.
|
||||||
|
(Changing the size adjusts perspective in a slightly different way
|
||||||
|
than zooming.) Depending on how keyboard focus works on your machine,
|
||||||
|
you may have to click the board area to make these controls work.
|
||||||
|
|
||||||
|
The button labeled @onscreen{<} at the bottom of the window rewinds
|
||||||
|
the game by one turn. The button labeled @onscreen{>} re-plays one
|
||||||
|
turn in a rewound game. An alternate move can be made at any point in
|
||||||
|
a rewound game, replacing the old game from that point on.
|
||||||
|
|
||||||
|
@section{Auto-Play}
|
||||||
|
|
||||||
|
Turn on a computer player at any time by checking the
|
||||||
|
@onscreen{Auto-Play Red} or @onscreen{Auto-Play Yellow} checkbox. If
|
||||||
|
you rewind the game, you can choose an alternate move for yourself or
|
||||||
|
for the auto-player to find out what would have happened. The
|
||||||
|
auto-player is not always deterministic, so replying the same move
|
||||||
|
might lead to a different result. You can disable an auto-player at
|
||||||
|
any point by unchecking the corresponding
|
||||||
|
@onscreen{Auto-Play"}checkbox.
|
||||||
|
|
||||||
|
Important: In the 3x3 game, you @emph{cannot} win as yellow against
|
||||||
|
the smart auto-player (if the auto-player is allowed to play red from
|
||||||
|
the start of the game). In other words, red has a forced win in the
|
||||||
|
3x3 game, and the smart auto-player knows the path to victory. You
|
||||||
|
might have a chance to beat the red player in the default mode,
|
||||||
|
though, which is represented by the @onscreen{Ok} choice (instead of
|
||||||
|
@onscreen{Smart}) in the @onscreen{Auto-Play Options} dialog.
|
||||||
|
|
||||||
|
Configure the auto-player by clicking the @onscreen{Auto-Play Options}
|
||||||
|
button. Currently, there's no difference between @onscreen{Smart} and
|
||||||
|
@onscreen{Ok} in the 4x4 game.
|
|
@ -1,25 +1,33 @@
|
||||||
** To play Go Fish, run the "PLT Games" application.
|
#lang scribble/doc
|
||||||
|
@(require "common.ss")
|
||||||
|
|
||||||
Go Fish is the children's card game where you try to get rid of all
|
@gametitle["Go Fish" "gofish" "Kid's Card Game"]
|
||||||
you cards by forming pairs. You play against two computer players.
|
|
||||||
|
|
||||||
On Each turn, if you have a match in your hand, drag one of the
|
@game{Go Fish} is the children's card game where you try to get rid of
|
||||||
|
all you cards by forming pairs. You play against two computer
|
||||||
|
players.
|
||||||
|
|
||||||
|
On each turn, if you have a match in your hand, drag one of the
|
||||||
matching cards to your numbered box, and the match will move into the
|
matching cards to your numbered box, and the match will move into the
|
||||||
box.
|
box.
|
||||||
|
|
||||||
After forming matches from your own hand, drag one of your cards to an
|
After forming matches from your own hand, drag one of your cards to an
|
||||||
opponent's area to ask the opponent for a matching card:
|
opponent's area to ask the opponent for a matching card:
|
||||||
|
|
||||||
* If the opponent has a card with the same value as the card that you
|
@itemize[
|
||||||
drag, the opponent will give you the card, and they'll go into your
|
|
||||||
match area. Drag another card to an opponent.
|
|
||||||
|
|
||||||
* If the opponent has no matching card, the top card on draw pile
|
@item{If the opponent has a card with the same value as the card that you
|
||||||
will move, indicating that you must "Go Fish!". Draw a card by
|
drag, the opponent will give you the card, and they'll go into your
|
||||||
|
match area. Drag another card to an opponent.}
|
||||||
|
|
||||||
|
@item{If the opponent has no matching card, the top card on draw pile
|
||||||
|
will move, indicating that you must ``Go Fish!'' Draw a card by
|
||||||
dragging it from the draw pile to your hand. If the drawn card
|
dragging it from the draw pile to your hand. If the drawn card
|
||||||
gives you a match, then the match will automatically move into your
|
gives you a match, then the match will automatically move into your
|
||||||
match area, and it's still your turn (so drag another card to one
|
match area, and it's still your turn (so drag another card to one
|
||||||
of the opponents).
|
of the opponents).}
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
The game is over when one player runs out of cards. The winner is the
|
The game is over when one player runs out of cards. The winner is the
|
||||||
one with the most matches.
|
one with the most matches.
|
|
@ -1,16 +1,23 @@
|
||||||
** To play Jewel, run the "PLT Games" application.
|
#lang scribble/doc
|
||||||
|
@(require "common.ss")
|
||||||
|
|
||||||
The board is an 8x8 array of jewels of 7 types. You need to get 3 or
|
@gametitle["Jewel" "jewel" "3-D Skill Game"]
|
||||||
more in a row horizontally or vertically in order to score points.
|
|
||||||
|
The board is an 8 by 8 array of jewels of 7 types. You need to get 3
|
||||||
|
or more in a row horizontally or vertically in order to score points.
|
||||||
You can swap any two jewels that are next to each other up and down or
|
You can swap any two jewels that are next to each other up and down or
|
||||||
left and right. The mechanic is to either:
|
left and right. The mechanic is to either:
|
||||||
|
|
||||||
* Click the mouse on the first one, then drag in the direction for
|
@itemize[
|
||||||
the swap.
|
|
||||||
|
|
||||||
* Move a bubble using the arrow keys, lock the bubble to a jewel with
|
@item{Click the mouse on the first one, then drag in the direction for
|
||||||
|
the swap.}
|
||||||
|
|
||||||
|
@item{Move a bubble using the arrow keys, lock the bubble to a jewel with
|
||||||
the space bar, and the swap the locked jewel with another by using
|
the space bar, and the swap the locked jewel with another by using
|
||||||
the arrow keys. Space unlocks a locked bubble without swapping.
|
the arrow keys. Space unlocks a locked bubble without swapping.}
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
Jewels can only be swapped if after the swap there are at least 3 or
|
Jewels can only be swapped if after the swap there are at least 3 or
|
||||||
more same shape or color in a row or column. Otherwise the jewels
|
more same shape or color in a row or column. Otherwise the jewels
|
||||||
|
@ -19,15 +26,11 @@ left. When it counts down to 0 the game is over. Getting 3 in a row
|
||||||
adds time to the clock.
|
adds time to the clock.
|
||||||
|
|
||||||
Hit spacebar to start a new game then select the difficulty number by
|
Hit spacebar to start a new game then select the difficulty number by
|
||||||
pressing '0', '1', '2', '3' or '4'. You can always press 'ESC' to
|
pressing @onscreen{0}, @onscreen{1}, @onscreen{2}, @onscreen{3}, or
|
||||||
exit. During playing press 'p' to pause the game.
|
@onscreen{0}. You can always press ESC to exit. During playing press
|
||||||
|
@onscreen{P} to pause the game.
|
||||||
|
|
||||||
The code is released under the LGPL. The code is a conversion of Dave
|
The code is released under the LGPL. The code is a conversion of Dave
|
||||||
Ashley's C program to Scheme with some modifications and enhancements.
|
Ashley's C program to Scheme with some modifications and enhancements.
|
||||||
|
|
||||||
Enjoy.
|
Enjoy.
|
||||||
|
|
||||||
Peter Ivanyi
|
|
||||||
|
|
||||||
(Matthew edited Peter's code and help text a little: added keyboard
|
|
||||||
support, plus other minor changes.)
|
|
|
@ -1,4 +1,7 @@
|
||||||
** To play Lights Out, run the "PLT Games" application.
|
#lang scribble/doc
|
||||||
|
@(require "common.ss")
|
||||||
|
|
||||||
|
@gametitle["Lights Out" "lights-out" "Logic Game"]
|
||||||
|
|
||||||
The object of this game is to turn all of the lights off. Click on a
|
The object of this game is to turn all of the lights off. Click on a
|
||||||
button to turn that light off, but beware it will also toggle the
|
button to turn that light off, but beware it will also toggle the
|
9
collects/games/scribblings/memory.scrbl
Normal file
9
collects/games/scribblings/memory.scrbl
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#lang scribble/doc
|
||||||
|
@(require "common.ss")
|
||||||
|
|
||||||
|
@gametitle["Memory" "memory" "Kid's Game"]
|
||||||
|
|
||||||
|
Flip two cards in a row that have the same picture, and the cards are
|
||||||
|
removed. If the two cards don't match, they are flipped back over, and
|
||||||
|
you try again. Each card has a single match on the board. The game is
|
||||||
|
over and the clock stops when all cards are removed.
|
17
collects/games/scribblings/mines.scrbl
Normal file
17
collects/games/scribblings/mines.scrbl
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#lang scribble/doc
|
||||||
|
@(require "common.ss")
|
||||||
|
|
||||||
|
@gametitle["Minesweeper" "mines" "Logic Game"]
|
||||||
|
|
||||||
|
Remove all the tiles that have no bomb underneath. When you remove
|
||||||
|
such a tile, a number appears that indicates how many of the
|
||||||
|
surrounding squares (up to 8) have a bomb; a blank means zero bombs,
|
||||||
|
and the game automatically uncovers all surrounding tiles in that
|
||||||
|
case.
|
||||||
|
|
||||||
|
Right- or Control-click to flag a tile that you think has a bomb, so
|
||||||
|
that you cannot accidentally uncover it. Right- or Control-click again
|
||||||
|
to remove the flag.
|
||||||
|
|
||||||
|
You don't have to use flags. When all of the non-bomb tiles are
|
||||||
|
removed, the game is over, and the clock stops.
|
|
@ -1,20 +1,23 @@
|
||||||
** To play Paint By Numbers, run the "PLT Games" application.
|
#lang scribble/doc
|
||||||
|
@(require "common.ss")
|
||||||
|
|
||||||
The object of Paint By Numbers is to discover which cells should be
|
@gametitle["Paint By Numbers" "paint-by-numbers" "Logic Game"]
|
||||||
colored blue and which should be colored white. Initially, all
|
|
||||||
squares are grey, indicating that the correct colors are not known.
|
The object of @game{Paint By Numbers} is to discover which cells
|
||||||
The lists of numbers to the left and above the grid are your clues to
|
should be colored blue and which should be colored white. Initially,
|
||||||
the correct color of each square. Each list of numbers specifies the
|
all squares are grey, indicating that the correct colors are not
|
||||||
pattern of blue squares in the row beside it or the column below it.
|
known. The lists of numbers to the left and above the grid are your
|
||||||
Each number indicates the length of a group of blue squares. For
|
clues to the correct color of each square. Each list of numbers
|
||||||
example, if the list of numbers beside the first row is "2 3" then you
|
specifies the pattern of blue squares in the row beside it or the
|
||||||
know that there is a contiguous block of two blue squares followed by
|
column below it. Each number indicates the length of a group of blue
|
||||||
a contiguous block of three blue squares with at least one white
|
squares. For example, if the list of numbers beside the first row is
|
||||||
square between them. The label does not tell you where the blue
|
@onscreen{2 3} then you know that there is a contiguous block of two
|
||||||
squares are, only their shapes. The trick is to gather as much
|
blue squares followed by a contiguous block of three blue squares with
|
||||||
information as you can about each row, and then use that information
|
at least one white square between them. The label does not tell you
|
||||||
to determine more about each column. Eventually you should be able to
|
where the blue squares are, only their shapes. The trick is to gather
|
||||||
fill in the entire puzzle.
|
as much information as you can about each row, and then use that
|
||||||
|
information to determine more about each column. Eventually you
|
||||||
|
should be able to fill in the entire puzzle.
|
||||||
|
|
||||||
Click on a square to toggle it between blue and gray. Hold down a
|
Click on a square to toggle it between blue and gray. Hold down a
|
||||||
modifier key (shift, command, meta, or alt depending on the platform)
|
modifier key (shift, command, meta, or alt depending on the platform)
|
||||||
|
@ -22,22 +25,23 @@ to toggle a square between white and gray. The third button under
|
||||||
unix and the right button under windows also toggles between white and
|
unix and the right button under windows also toggles between white and
|
||||||
gray.
|
gray.
|
||||||
|
|
||||||
For some puzzles, hints are available. Choose the Nongram|Show
|
For some puzzles, hints are available. Choose the @menuitem["Nongram"
|
||||||
Mistakes menu item to receive the hints. This will turn all
|
"Show Mistakes"] menu item to receive the hints. This will turn all
|
||||||
incorrectly colored squares red.
|
incorrectly colored squares red.
|
||||||
|
|
||||||
Thanks to Shoichiro Hattori for his puzzles! Visit him on the web at:
|
Thanks to Shoichiro Hattori for his puzzles! Visit him on the web at:
|
||||||
|
|
||||||
http://hattori.m78.com/puzzle/
|
@centerline{@selflink["http://hattori.m78.com/puzzle/"]}
|
||||||
|
|
||||||
Thanks also to many of the contributors to the Kajitani web site for
|
Thanks also to many of the contributors to the Kajitani web site for
|
||||||
permission to re-distribute their puzzles. Visit them online at:
|
permission to re-distribute their puzzles. Visit them online at:
|
||||||
|
|
||||||
http://www02.so-net.ne.jp/~kajitani/index.html
|
@centerline{@selflink["http://www02.so-net.ne.jp/~kajitani/index.html"]}
|
||||||
|
|
||||||
The specific contributers who have permitted their puzzles to be
|
The specific contributers who have permitted their puzzles to be
|
||||||
redistributed are:
|
redistributed are:
|
||||||
|
|
||||||
|
@verbatim[#:indent 2]{
|
||||||
snordmey /at/ dayton <dot> net
|
snordmey /at/ dayton <dot> net
|
||||||
jtraub /at/ dragoncat <dot> net
|
jtraub /at/ dragoncat <dot> net
|
||||||
e0gb258s /at/ mail <dot> erin <dot> utoronto <dot> ca
|
e0gb258s /at/ mail <dot> erin <dot> utoronto <dot> ca
|
||||||
|
@ -94,4 +98,4 @@ redistributed are:
|
||||||
williamson /at/ proaxis <dot> com
|
williamson /at/ proaxis <dot> com
|
||||||
vacko_6 /at/ hotmail <dot> com
|
vacko_6 /at/ hotmail <dot> com
|
||||||
jojess /at/ earthlink <dot> net
|
jojess /at/ earthlink <dot> net
|
||||||
|
}
|
60
collects/games/scribblings/parcheesi.scrbl
Normal file
60
collects/games/scribblings/parcheesi.scrbl
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
#lang scribble/doc
|
||||||
|
@(require "common.ss")
|
||||||
|
|
||||||
|
@gametitle["Parcheesi" "parcheesi" "Board Game"]
|
||||||
|
|
||||||
|
@onscreen{Parcheesi} is a race game for four players. The goal is for
|
||||||
|
each player to move their pieces from the starting position (the
|
||||||
|
circles in the corners) to the home square (in the center of the
|
||||||
|
board), passing a nearly complete loop around the board in the
|
||||||
|
counter-clockwise direction and then heads up towards the main row.
|
||||||
|
For example, the green player enters from the bottom right, travels
|
||||||
|
around the board on the light blue squares, passing each of the
|
||||||
|
corners, until it reaches the middle of the bottom of the board, where
|
||||||
|
it turns off the light blue squares and heads into the central region.
|
||||||
|
|
||||||
|
On each turn, the player rolls two dice and advances the pawn, based
|
||||||
|
on the die rolls. Typically the players may move a pawn for each die.
|
||||||
|
The pawn moves by the number of pips showing on the die and all of the
|
||||||
|
dice must be used to complete a turn.
|
||||||
|
|
||||||
|
There are some exceptions, however:
|
||||||
|
|
||||||
|
@itemize[
|
||||||
|
|
||||||
|
@item{You must roll a 5 (either directly or via summing) to enter from
|
||||||
|
the start area to the main ring.}
|
||||||
|
|
||||||
|
@item{If two pieces of the same color occupy a square, no pieces may
|
||||||
|
pass that square.}
|
||||||
|
|
||||||
|
@item{If an opponent's piece lands on your piece, you piece is
|
||||||
|
returned to the starting area and the opponent receives a bonus of
|
||||||
|
20 (which is treated just as if they had rolled a 20 on the
|
||||||
|
dice).}
|
||||||
|
|
||||||
|
@item{If your piece makes it home (and it must do so by exact count) you
|
||||||
|
get a bonus of 10, to be used as an additional die roll.}
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
These rules induce a number of unexpected corner cases, but the GUI
|
||||||
|
only lets you make legal moves. Watch the space along the bottom of
|
||||||
|
the board for reasons why a move is illegal or why you have not used
|
||||||
|
all of your die rolls.
|
||||||
|
|
||||||
|
The automated players are:
|
||||||
|
|
||||||
|
@itemize[
|
||||||
|
|
||||||
|
@item{@onscreen{Reckless Renee}, who tries to maximize the chances
|
||||||
|
that someone else bops her.}
|
||||||
|
|
||||||
|
@item{@onscreen{Polite Polly}, who tries to minimize the distance her
|
||||||
|
pawns move. (``No, after @emph{you}. I insist.'')}
|
||||||
|
|
||||||
|
@item{@onscreen{Amazing Grace}, who tries to minimize the chance she
|
||||||
|
gets bopped while moving as far as possible.}
|
||||||
|
|
||||||
|
]
|
||||||
|
|
62
collects/games/scribblings/pousse.scrbl
Normal file
62
collects/games/scribblings/pousse.scrbl
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#lang scribble/doc
|
||||||
|
@(require "common.ss")
|
||||||
|
|
||||||
|
@gametitle["Pousse" "pousse" "Tic-Tac-Toe-like Game"]
|
||||||
|
|
||||||
|
@onscreen{Pousse} (French for "push", pronounced "poo-ss") is a 2
|
||||||
|
person game, played on an @math{N} by @math{N} board (usually 4 by 4).
|
||||||
|
Initially the board is empty, and the players take turns inserting one
|
||||||
|
marker of their color (@onscreen{X} or @onscreen{O}) on the board.
|
||||||
|
The color @onscreen{X} always goes first. The columns and rows are
|
||||||
|
numbered from 1 to @math{N}, starting from the top left, as in:
|
||||||
|
|
||||||
|
@verbatim[#:indent 3]{
|
||||||
|
1 2 3 4
|
||||||
|
+-+-+-+-+
|
||||||
|
1 | | | | |
|
||||||
|
+-+-+-+-+
|
||||||
|
2 | | | | |
|
||||||
|
+-+-+-+-+
|
||||||
|
3 | | | | |
|
||||||
|
+-+-+-+-+
|
||||||
|
4 | | | | |
|
||||||
|
+-+-+-+-+
|
||||||
|
}
|
||||||
|
|
||||||
|
A marker can only be inserted on the board by sliding it onto a
|
||||||
|
particular row from the left or from the right, or onto a particular
|
||||||
|
column from the top or from the bottom. So there are @math{4*N}
|
||||||
|
possible ``moves'' (ways to insert a marker). They are named
|
||||||
|
L@math{i}, R@math{i}, T@math{i}, and B@math{i} respectively, where
|
||||||
|
@math{i} is the number of the row or column where the insertion takes
|
||||||
|
place.
|
||||||
|
|
||||||
|
When a marker is inserted, there may be a marker on the square where
|
||||||
|
the insertion takes place. In this case, all markers on the insertion
|
||||||
|
row or column from the insertion square upto the first empty square
|
||||||
|
are moved one square further to make room for the inserted marker.
|
||||||
|
Note that the last marker of the row or column will be pushed off the
|
||||||
|
board (and must be removed from play) if there are no empty squares on
|
||||||
|
the insertion row or column.
|
||||||
|
|
||||||
|
A row or a column is a @defterm{straight} of a given color if it
|
||||||
|
contains @math{N} markers of the given color.
|
||||||
|
|
||||||
|
The game ends either when an insertion
|
||||||
|
|
||||||
|
@itemize[
|
||||||
|
|
||||||
|
@item{repeats a previous configuration of the board; in this case the
|
||||||
|
player who inserted the marker LOSES.}
|
||||||
|
|
||||||
|
@item{creates a configuration with more straights of one color than
|
||||||
|
straights of the other color; the player whose color is dominant
|
||||||
|
(in number of straights) WINS.}
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
A game always leads to a win by one of the two players. Draws are
|
||||||
|
impossible.
|
||||||
|
|
||||||
|
This game is from the 1998 ICFP programming contest.
|
||||||
|
|
21
collects/games/scribblings/same.scrbl
Normal file
21
collects/games/scribblings/same.scrbl
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#lang scribble/doc
|
||||||
|
@(require "common.ss")
|
||||||
|
|
||||||
|
@gametitle["Same" "same" "Dot-Removing Game"]
|
||||||
|
|
||||||
|
The object of @game{Same} is to score points by removing dots from the
|
||||||
|
board. To remove a dot, click on it. As long as there is another dot
|
||||||
|
of the same color next to the clicked dot, it will disappear along
|
||||||
|
with all adjacent dots of the same color. After the dots disappear,
|
||||||
|
dots in the rows above the deleted dots will fall into the vacated
|
||||||
|
spaces. If an entire column is wiped out, all of the dots from the
|
||||||
|
right will slide left to take up the empty column's space.
|
||||||
|
|
||||||
|
Your score increases for each ball removed from the board. The score
|
||||||
|
for each click is a function of the number of balls that disappeared.
|
||||||
|
The @onscreen{This Click} label shows how many points you would score
|
||||||
|
for clicking the dots underneath the mouse pointer. The score varies
|
||||||
|
quadratically with the number of balls, so eliminating many balls with
|
||||||
|
one click is advantageous.
|
||||||
|
|
||||||
|
Click the @onscreen{New Game} button to play again.
|
7
collects/games/scribblings/slidey.scrbl
Normal file
7
collects/games/scribblings/slidey.scrbl
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#lang scribble/doc
|
||||||
|
@(require "common.ss")
|
||||||
|
|
||||||
|
@gametitle["Slidey" "slidey" "Picture Puzzle"]
|
||||||
|
|
||||||
|
Click a tile to slide it into the adjacent space, and keep shifting
|
||||||
|
tiles that way to repair the picture.
|
62
collects/games/scribblings/spider.scrbl
Normal file
62
collects/games/scribblings/spider.scrbl
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#lang scribble/doc
|
||||||
|
@(require "common.ss")
|
||||||
|
|
||||||
|
@gametitle["Spider" "spider" "Solitaire Card Game"]
|
||||||
|
|
||||||
|
Spider is a solitaire card game played with 104 cards. The cards can
|
||||||
|
include either a single suit, two suits, or four suites. (Choose your
|
||||||
|
variant through the @onscreen{Options} item in the @onscreen{Edit}
|
||||||
|
menu.)
|
||||||
|
|
||||||
|
Terminology:
|
||||||
|
|
||||||
|
@itemize[
|
||||||
|
|
||||||
|
@item{@deftech{Tableau}: one of the ten stacks of cards in the play
|
||||||
|
area. The game starts with six cards in the first four
|
||||||
|
@tech{tableau}s, and five cards in the rest; only the topmost card
|
||||||
|
is face up, and others are revealed when they become the topmost
|
||||||
|
card of the @tech{tableau}.}
|
||||||
|
|
||||||
|
@item{@deftech{Sequence}: a group of cards on the top of a
|
||||||
|
@tech{tableau} that are in the same suit, and that are in
|
||||||
|
@tech{sequence}, with the lowest numbered card topmost (i.e.,
|
||||||
|
closer to the bottom of the screen). King is high and ace is low.}
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
The object of the game is to create a @tech{sequence} with ace through
|
||||||
|
king, at which point the @tech{sequence} is removed from play. Create
|
||||||
|
eight such @tech{sequence}s to win the game.
|
||||||
|
|
||||||
|
On each move, you can take one of the following actions:
|
||||||
|
|
||||||
|
@itemize[
|
||||||
|
|
||||||
|
@item{Move a @tech{sequence} from any @tech{tableau} to one whose
|
||||||
|
topmost card (i.e., closest to the bottom of the screen) has a
|
||||||
|
value that's one more than the @tech{sequence}'s value. Note that
|
||||||
|
if the top card of the target @tech{tableau} has the same suit as
|
||||||
|
the @tech{sequence}, a larger @tech{sequence} is formed, but the
|
||||||
|
target @tech{tableau}'s card is not required to have the same suit.}
|
||||||
|
|
||||||
|
@item{Move a @tech{sequence} to an empty @tech{tableau}.}
|
||||||
|
|
||||||
|
@item{Deal ten cards from the deck (in the upper left corder), one to
|
||||||
|
each @tech{tableau}. This move is allowed only if no
|
||||||
|
@tech{tableau} is empty.}
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
To move a @tech{sequence}, either drag it to the target
|
||||||
|
@tech{tableau}, or click the @tech{sequence} and then click the top
|
||||||
|
card of the target @tech{tableau} (or the place where a single card
|
||||||
|
would be for an empty @tech{tableau}). Click a select card to
|
||||||
|
de-select it. Clicking a card that is not a valid target for the
|
||||||
|
currently selected @tech{sequence} causes the clicked card's
|
||||||
|
@tech{sequence} to be selected (if the card is face up in a
|
||||||
|
@tech{sequence}).
|
||||||
|
|
||||||
|
To deal, click the deck.
|
||||||
|
|
||||||
|
To undo a move, use @onscreen{Undo} from the @onscreen{Edit} menu.
|
25
collects/games/scribblings/std-games.scrbl
Normal file
25
collects/games/scribblings/std-games.scrbl
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#lang scribble/doc
|
||||||
|
@(require "common.ss")
|
||||||
|
|
||||||
|
@title[#:style 'toc #:tag "bundled"]{Bundled Games}
|
||||||
|
|
||||||
|
@local-table-of-contents[]
|
||||||
|
|
||||||
|
@include-section["aces.scrbl"]
|
||||||
|
@include-section["gofish.scrbl"]
|
||||||
|
@include-section["crazy8s.scrbl"]
|
||||||
|
@include-section["blackjack.scrbl"]
|
||||||
|
@include-section["ginrummy.scrbl"]
|
||||||
|
@include-section["spider.scrbl"]
|
||||||
|
@include-section["memory.scrbl"]
|
||||||
|
@include-section["slidey.scrbl"]
|
||||||
|
@include-section["same.scrbl"]
|
||||||
|
@include-section["mines.scrbl"]
|
||||||
|
@include-section["paint-by-numbers.scrbl"]
|
||||||
|
@include-section["lights-out.scrbl"]
|
||||||
|
@include-section["pousse.scrbl"]
|
||||||
|
@include-section["gobblet.scrbl"]
|
||||||
|
@include-section["jewel.scrbl"]
|
||||||
|
@include-section["parcheesi.scrbl"]
|
||||||
|
@include-section["checkers.scrbl"]
|
||||||
|
@include-section["gcalc.scrbl"]
|
23
collects/games/show-scribbling.ss
Normal file
23
collects/games/show-scribbling.ss
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#lang scheme/base
|
||||||
|
|
||||||
|
(require setup/xref
|
||||||
|
scribble/xref
|
||||||
|
scribble/basic
|
||||||
|
scheme/promise
|
||||||
|
net/url
|
||||||
|
net/sendurl)
|
||||||
|
|
||||||
|
(provide show-scribbling)
|
||||||
|
|
||||||
|
(define (show-scribbling mod-path tag)
|
||||||
|
(let ([xref (delay (load-collections-xref))])
|
||||||
|
(lambda ()
|
||||||
|
(let-values ([(path anchor)
|
||||||
|
(xref-tag->path+anchor
|
||||||
|
(force xref)
|
||||||
|
(list 'part (list (module-path-prefix->string mod-path) tag)))])
|
||||||
|
(if path
|
||||||
|
(let ([u (path->url path)])
|
||||||
|
(send-url (url->string u)))
|
||||||
|
(error 'show-scribbling "cannot find docs for: ~e ~e" mod-path tag))))))
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
** To play Spider, run the "PLT Games" application.
|
|
||||||
|
|
||||||
Spider is a solitaire card game played with 104 cards. The cards can
|
|
||||||
include either a single suit, two suits, or four suites. (Choose your
|
|
||||||
variant through the "Options" item in the "Edit" menu.)
|
|
||||||
|
|
||||||
Terminology:
|
|
||||||
|
|
||||||
* Tableau: one of the ten stacks of cards in the play area. The game
|
|
||||||
starts with six cards in the first four tableaus, and five cards in
|
|
||||||
the rest; only the topmost card is face up, and others are revealed
|
|
||||||
when they become the topmost card of the tableau.
|
|
||||||
|
|
||||||
* Sequence: a group of cards on the top of a tableau that are in the
|
|
||||||
same suit, and that are in sequence, with the lowest numbered card
|
|
||||||
topmost (i.e., closer to the bottom of the screen). King is high
|
|
||||||
and ace is low.
|
|
||||||
|
|
||||||
The object of the game is to create a sequence with ace through king,
|
|
||||||
at which point the sequence is removed from play. Create eight such
|
|
||||||
sequences to win the game.
|
|
||||||
|
|
||||||
On each move, you can either:
|
|
||||||
|
|
||||||
* Move a sequence from any tableau to one whose topmost card (i.e.,
|
|
||||||
closest to the bottom of the screen) has a value that's one more
|
|
||||||
than the sequence's value. Note that if the top card of the target
|
|
||||||
tableau has the same suit as the sequence, a larger sequence is
|
|
||||||
formed, but the target tableau's card is not required to have the
|
|
||||||
same suit.
|
|
||||||
|
|
||||||
* Move a sequence to an empty tableau.
|
|
||||||
|
|
||||||
* Deal ten cards from the deck (in the upper left corder), one to
|
|
||||||
each tableau. This move is allowed only if no tableau is empty.
|
|
||||||
|
|
||||||
To move a sequence, either drag it to the target tableau, or click the
|
|
||||||
sequence and then click the top card of the target tableau (or the
|
|
||||||
place where a single card would be for an empty tableau). Click a
|
|
||||||
select card to de-select it. Clicking a card that is not a valid
|
|
||||||
target for the currently selected sequence causes the clicked card's
|
|
||||||
sequence to be selected (if the card is face up in a sequence).
|
|
||||||
|
|
||||||
To deal, click the deck.
|
|
||||||
|
|
||||||
To undo a move, use "Undo" from the "Edit" menu.
|
|
|
@ -1,7 +1,7 @@
|
||||||
#lang mzscheme
|
#lang mzscheme
|
||||||
|
|
||||||
(require games/cards mred mzlib/class mzlib/list mzlib/file mzlib/unit
|
(require games/cards mred mzlib/class mzlib/list mzlib/file mzlib/unit
|
||||||
"../show-help.ss")
|
"../show-scribbling.ss")
|
||||||
|
|
||||||
(define (list-first-n l n)
|
(define (list-first-n l n)
|
||||||
(if (zero? n)
|
(if (zero? n)
|
||||||
|
@ -131,7 +131,8 @@
|
||||||
(send d center)
|
(send d center)
|
||||||
(send d show #t))])
|
(send d show #t))])
|
||||||
|
|
||||||
(define help (show-help '("games" "spider") "Spider Rules" #f))
|
(define help (show-scribbling '(lib "games/scribblings/games.scrbl")
|
||||||
|
"spider"))
|
||||||
(new menu-item%
|
(new menu-item%
|
||||||
[label "&Rules"]
|
[label "&Rules"]
|
||||||
[parent (make-object menu% "&Help" mb)]
|
[parent (make-object menu% "&Help" mb)]
|
||||||
|
|
|
@ -758,7 +758,7 @@
|
||||||
`((a ((name ,(url-anchor-name style)))
|
`((a ((name ,(url-anchor-name style)))
|
||||||
,@(super render-element e part ri)))]
|
,@(super render-element e part ri)))]
|
||||||
[(image-file? style)
|
[(image-file? style)
|
||||||
(let* ([src (image-file-path style)]
|
(let* ([src (main-collects-relative->path (image-file-path style))]
|
||||||
[scale (image-file-scale style)]
|
[scale (image-file-scale style)]
|
||||||
[sz (if (= 1.0 scale)
|
[sz (if (= 1.0 scale)
|
||||||
null
|
null
|
||||||
|
@ -776,7 +776,7 @@
|
||||||
`((width ,(to-num w))
|
`((width ,(to-num w))
|
||||||
(height ,(to-num h))))
|
(height ,(to-num h))))
|
||||||
null))))])
|
null))))])
|
||||||
`((img ((src ,(install-file src)) ,@sz))))]
|
`((img ((src ,(install-file src))) ,@sz)))]
|
||||||
[else (super render-element e part ri)])))
|
[else (super render-element e part ri)])))
|
||||||
|
|
||||||
(define/override (render-table t part ri need-inline?)
|
(define/override (render-table t part ri need-inline?)
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
mzlib/class
|
mzlib/class
|
||||||
scheme/runtime-path
|
scheme/runtime-path
|
||||||
scheme/port
|
scheme/port
|
||||||
|
setup/main-collects
|
||||||
(for-syntax scheme/base))
|
(for-syntax scheme/base))
|
||||||
(provide render-mixin)
|
(provide render-mixin)
|
||||||
|
|
||||||
|
@ -162,7 +163,9 @@
|
||||||
(/ (cadddr style) 255.0))))
|
(/ (cadddr style) 255.0))))
|
||||||
#f)]
|
#f)]
|
||||||
[(image-file? style)
|
[(image-file? style)
|
||||||
(let ([fn (install-file (image-file-path style))])
|
(let ([fn (install-file
|
||||||
|
(main-collects-relative->path
|
||||||
|
(image-file-path style)))])
|
||||||
(printf "\\includegraphics[scale=~a]{~a}" (image-file-scale style) fn))]
|
(printf "\\includegraphics[scale=~a]{~a}" (image-file-scale style) fn))]
|
||||||
[else (super render-element e part ri)])))
|
[else (super render-element e part ri)])))
|
||||||
(when part-label?
|
(when part-label?
|
||||||
|
|
|
@ -174,7 +174,9 @@
|
||||||
|
|
||||||
[target-url ([addr (or/c string? path?)][style any/c])]
|
[target-url ([addr (or/c string? path?)][style any/c])]
|
||||||
[url-anchor ([name string?])]
|
[url-anchor ([name string?])]
|
||||||
[image-file ([path path-string?]
|
[image-file ([path (or/c path-string?
|
||||||
|
(cons/c (one-of/c 'collects)
|
||||||
|
(listof bytes?)))]
|
||||||
[scale real?])])
|
[scale real?])])
|
||||||
|
|
||||||
;; ----------------------------------------
|
;; ----------------------------------------
|
||||||
|
|
|
@ -64,6 +64,9 @@
|
||||||
;; resulting html
|
;; resulting html
|
||||||
(define (xref-render xrefs doc dest-file
|
(define (xref-render xrefs doc dest-file
|
||||||
#:render% [render% (html:render-mixin render%)])
|
#:render% [render% (html:render-mixin render%)])
|
||||||
|
;; In case rendering writes a file (like an image file), which to the
|
||||||
|
;; temp directory:
|
||||||
|
(parameterize ([current-directory (find-system-path 'temp-dir)])
|
||||||
(let* ([dest-file (if (string? dest-file) (string->path dest-file) dest-file)]
|
(let* ([dest-file (if (string? dest-file) (string->path dest-file) dest-file)]
|
||||||
[renderer (new render% [dest-dir (and dest-file (path-only dest-file))]
|
[renderer (new render% [dest-dir (and dest-file (path-only dest-file))]
|
||||||
[css-path 'inline])]
|
[css-path 'inline])]
|
||||||
|
@ -73,7 +76,7 @@
|
||||||
[xs (send renderer render (list doc) (list dest-file) ri)])
|
[xs (send renderer render (list doc) (list dest-file) ri)])
|
||||||
(if dest-file
|
(if dest-file
|
||||||
(void)
|
(void)
|
||||||
(car xs))))
|
(car xs)))))
|
||||||
|
|
||||||
;; Returns (values <tag-or-#f> <form?>)
|
;; Returns (values <tag-or-#f> <form?>)
|
||||||
(define xref-binding-tag
|
(define xref-binding-tag
|
||||||
|
|
Loading…
Reference in New Issue
Block a user