chat-noir literate small repairs
svn: r13765
This commit is contained in:
parent
5c7b122118
commit
24e4fd407b
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 9.1 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
@ -1,7 +1,8 @@
|
||||||
#lang scribble/lp
|
#lang scribble/lp
|
||||||
|
|
||||||
@(require (for-label scheme/math) ;; for 'pi' below
|
@(require (for-label scheme/math) ;; for 'pi' below
|
||||||
scheme/math)
|
scheme/math
|
||||||
|
games/scribblings/common)
|
||||||
|
|
||||||
@;{
|
@;{
|
||||||
The command to build this:
|
The command to build this:
|
||||||
|
@ -10,8 +11,7 @@ mzc chat-noir-doc.ss && rm -rf chat-noir-doc && scribble ++xref-in setup/xref lo
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@;{would like to have [#:style 'toc] in the next line ... }
|
@gametitle*["Chat Noir" "chat-noir" "Puzzle Game" #:style '(toc)]
|
||||||
@title{Chat Noir}
|
|
||||||
|
|
||||||
@author[(link "http://www.eecs.northwestern.edu/~robby" "Robby Findler")
|
@author[(link "http://www.eecs.northwestern.edu/~robby" "Robby Findler")
|
||||||
(link "http://www.barzilay.org/" "Eli Barzilay")
|
(link "http://www.barzilay.org/" "Eli Barzilay")
|
||||||
|
@ -23,13 +23,15 @@ that space, and the cat responds by taking a step. If the cat is
|
||||||
completely boxed in and thus unable reach the border, you win. If the
|
completely boxed in and thus unable reach the border, you win. If the
|
||||||
cat does reach the border, you lose.
|
cat does reach the border, you lose.
|
||||||
|
|
||||||
|
@play-margin-note["Chat Noir"]
|
||||||
|
|
||||||
To get some insight into the cat's behavior, hold down the ``h''
|
To get some insight into the cat's behavior, hold down the ``h''
|
||||||
key. It will show you the cells that are on the cat's shortest path to
|
key. It will show you the cells that are on the cat's shortest path to
|
||||||
the edge, assuming that the cell underneath the mouse has been
|
the edge, assuming that the cell underneath the mouse has been
|
||||||
blocked, so you can experiment to see how the shortest paths change
|
blocked, so you can experiment to see how the shortest paths change
|
||||||
by moving your mouse around.
|
by moving your mouse around.
|
||||||
|
|
||||||
The game was inspired by this one the one at
|
The game was inspired by the one at
|
||||||
@link["http://www.gamedesign.jp/flash/chatnoir/chatnoir.html"]{Game
|
@link["http://www.gamedesign.jp/flash/chatnoir/chatnoir.html"]{Game
|
||||||
Design} and has essentially the same rules. It also inspired the final
|
Design} and has essentially the same rules. It also inspired the final
|
||||||
project for the introductory programming course at the University of
|
project for the introductory programming course at the University of
|
||||||
|
@ -39,6 +41,8 @@ The remainder of this document explains the implementation of
|
||||||
the Chat Noir game in a
|
the Chat Noir game in a
|
||||||
@link["http://www.literateprogramming.com/"]{Literate Programming} style.
|
@link["http://www.literateprogramming.com/"]{Literate Programming} style.
|
||||||
|
|
||||||
|
@local-table-of-contents[]
|
||||||
|
|
||||||
@section{Overview}
|
@section{Overview}
|
||||||
|
|
||||||
Chat Noir is implemented using @link["http://www.htdp.org/"]{HtDP}'s universe
|
Chat Noir is implemented using @link["http://www.htdp.org/"]{HtDP}'s universe
|
||||||
|
@ -167,7 +171,7 @@ The @scheme[empty-board] function builds a list of @scheme[cell]s
|
||||||
that correspond to an empty board. For example, here's what an empty
|
that correspond to an empty board. For example, here's what an empty
|
||||||
7x7 board looks like, as a list of cells.
|
7x7 board looks like, as a list of cells.
|
||||||
|
|
||||||
@image["7x7-empty-board.png"]
|
@image["chat-noir/7x7-empty-board.png"]
|
||||||
|
|
||||||
It contains 7 rows and, with the exception of the first and last rows,
|
It contains 7 rows and, with the exception of the first and last rows,
|
||||||
each row contains 7 cells. Notice how the even and odd rows are offset
|
each row contains 7 cells. Notice how the even and odd rows are offset
|
||||||
|
@ -183,7 +187,7 @@ The 3x3 board also has the same property that it consists of three
|
||||||
rows, each with three cells, but where the first and last row are missing
|
rows, each with three cells, but where the first and last row are missing
|
||||||
their left-most cells.
|
their left-most cells.
|
||||||
|
|
||||||
@image["3x3-empty-board.png"]
|
@image["chat-noir/3x3-empty-board.png"]
|
||||||
|
|
||||||
And here is how that board looks as a list of cells.
|
And here is how that board looks as a list of cells.
|
||||||
|
|
||||||
|
@ -697,7 +701,7 @@ For example, in a world of size @scheme[7] with the cat at
|
||||||
@scheme[(make-posn 2 2)], the circles with white centers
|
@scheme[(make-posn 2 2)], the circles with white centers
|
||||||
are on the shortest path to the boundary:
|
are on the shortest path to the boundary:
|
||||||
|
|
||||||
@image["cat-distance-example.png"]
|
@image["chat-noir/cat-distance-example.png"]
|
||||||
|
|
||||||
So we can formulate two test cases using this world, one
|
So we can formulate two test cases using this world, one
|
||||||
in the white circles and one not:
|
in the white circles and one not:
|
||||||
|
|
|
@ -6,26 +6,36 @@
|
||||||
setup/main-collects)
|
setup/main-collects)
|
||||||
(provide (all-from-out scribble/manual)
|
(provide (all-from-out scribble/manual)
|
||||||
selflink
|
selflink
|
||||||
gametitle
|
gametitle gametitle* play-margin-note
|
||||||
game)
|
game)
|
||||||
|
|
||||||
(define (selflink str) (link str (tt str)))
|
(define (selflink str) (link str (tt str)))
|
||||||
|
|
||||||
(define game onscreen)
|
(define game onscreen)
|
||||||
|
|
||||||
(define (gametitle name subcol subtitle)
|
(define (gametitle name subcol subtitle
|
||||||
|
#:style [style #f])
|
||||||
(make-splice
|
(make-splice
|
||||||
(list
|
(list
|
||||||
|
(gametitle* name subcol subtitle #:style style)
|
||||||
|
(play-margin-note name))))
|
||||||
|
|
||||||
|
(define (gametitle* name subcol subtitle
|
||||||
|
#:style [style #f])
|
||||||
(title #:tag subcol
|
(title #:tag subcol
|
||||||
|
#:style style
|
||||||
(make-element
|
(make-element
|
||||||
"noborder"
|
"noborder"
|
||||||
(list
|
(list
|
||||||
(image (path->main-collects-relative
|
(image (path->main-collects-relative
|
||||||
(build-path (collection-path "games" subcol)
|
(build-path (collection-path "games" subcol)
|
||||||
(format "~a.png" subcol))))))
|
(format "~a.png" subcol))))))
|
||||||
" " (onscreen name) " --- " subtitle)
|
" " (onscreen name) " --- " subtitle))
|
||||||
|
|
||||||
|
(define (play-margin-note name)
|
||||||
(margin-note "To play "
|
(margin-note "To play "
|
||||||
(onscreen name)
|
(onscreen name)
|
||||||
", run the "
|
", run the "
|
||||||
(exec "PLT Games") " program."
|
(exec "PLT Games") " program."
|
||||||
" (Under Unix, it's called " (exec "plt-games") ")."))))
|
" (Under Unix, it's called " (exec "plt-games") ")."))
|
||||||
|
|
||||||
|
|
|
@ -39,12 +39,16 @@
|
||||||
(error 'extract-struct-info
|
(error 'extract-struct-info
|
||||||
"struct-info procedure result not properly formed: ~e"
|
"struct-info procedure result not properly formed: ~e"
|
||||||
v))))
|
v))))
|
||||||
si)))
|
(if (set!-transformer? si)
|
||||||
|
(extract-struct-info (set!-transformer-procedure si))
|
||||||
|
si))))
|
||||||
|
|
||||||
(define-values (struct-info?)
|
(define-values (struct-info?)
|
||||||
(lambda (si)
|
(lambda (si)
|
||||||
(or (struct-info-rec? si)
|
(or (struct-info-rec? si)
|
||||||
(struct-declaration-info? si))))
|
(struct-declaration-info? si)
|
||||||
|
(and (set!-transformer? si)
|
||||||
|
(struct-info-rec? (set!-transformer-procedure si))))))
|
||||||
|
|
||||||
(define-values (struct-declaration-info?)
|
(define-values (struct-declaration-info?)
|
||||||
(lambda (x)
|
(lambda (x)
|
||||||
|
|
|
@ -32,12 +32,18 @@
|
||||||
(if (n . > . 1)
|
(if (n . > . 1)
|
||||||
#'(void)
|
#'(void)
|
||||||
(with-syntax ([tag str]
|
(with-syntax ([tag str]
|
||||||
[str str])
|
[str str]
|
||||||
|
[((for-label-mod ...) ...)
|
||||||
|
(map (lambda (expr)
|
||||||
|
(syntax-case expr (require)
|
||||||
|
[(require mod ...)
|
||||||
|
#'(mod ...)]
|
||||||
|
[else null]))
|
||||||
|
(syntax->list #'(expr ...)))])
|
||||||
#`(begin
|
#`(begin
|
||||||
;; ---- This is the new part --------
|
|
||||||
(define-syntax name (make-element-id-transformer
|
(define-syntax name (make-element-id-transformer
|
||||||
(lambda (stx) #'(chunkref name))))
|
(lambda (stx) #'(chunkref name))))
|
||||||
;; ----------------------------------
|
(require (for-label for-label-mod ... ...))
|
||||||
(make-splice
|
(make-splice
|
||||||
(list (make-toc-element
|
(list (make-toc-element
|
||||||
#f
|
#f
|
||||||
|
|
|
@ -68,7 +68,7 @@
|
||||||
chunk-mentions)])
|
chunk-mentions)])
|
||||||
#`(begin body ... (let ([b-id (void)]) b-use) ...)))
|
#`(begin body ... (let ([b-id (void)]) b-use) ...)))
|
||||||
|
|
||||||
(define-syntax (module-begin stx)
|
(define-syntax (literate-begin stx)
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
[(module-begin expr ...)
|
[(module-begin expr ...)
|
||||||
(with-syntax
|
(with-syntax
|
||||||
|
@ -98,6 +98,12 @@
|
||||||
#%provide)))
|
#%provide)))
|
||||||
(cons expanded (loop (cdr exprs)))]
|
(cons expanded (loop (cdr exprs)))]
|
||||||
[else (loop (cdr exprs))]))]))])
|
[else (loop (cdr exprs))]))]))])
|
||||||
#'(#%module-begin
|
#'(begin
|
||||||
body-code ...
|
body-code ...
|
||||||
(tangle)))]))
|
(tangle)))]))
|
||||||
|
|
||||||
|
(define-syntax (module-begin stx)
|
||||||
|
(syntax-case stx ()
|
||||||
|
[(_ id exprs . body)
|
||||||
|
#'(#%module-begin
|
||||||
|
(literate-begin id exprs . body))]))
|
||||||
|
|
|
@ -543,9 +543,7 @@ transformer to generate information about imported structure types, so
|
||||||
that @scheme[match] and subtyping @scheme[define-struct] forms work
|
that @scheme[match] and subtyping @scheme[define-struct] forms work
|
||||||
within the unit.
|
within the unit.
|
||||||
|
|
||||||
The expansion-time information for a structure type is represented
|
The expansion-time information for a structure type can be represented
|
||||||
either as a structure that encapsulates a procedure that takes no
|
|
||||||
arguments and returns a list of six element, or it can be represented
|
|
||||||
directly as a list of six elements (of the same sort that the
|
directly as a list of six elements (of the same sort that the
|
||||||
encapsulated procedure must return):
|
encapsulated procedure must return):
|
||||||
|
|
||||||
|
@ -585,10 +583,18 @@ encapsulated procedure must return):
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Use @scheme[struct-info?] to recognize both forms of information, and
|
Instead of this direct representation, the representation can
|
||||||
use @scheme[extract-struct-info] to obtain a list from either
|
be a structure created by @scheme[make-struct-info] (or an instance of
|
||||||
representation. Use @scheme[make-struct-info] to encapsulate a
|
a subtype of @scheme[struct:struct-info]), which encapsulates a
|
||||||
procedure that represents structure type information.
|
procedure that takes no arguments and returns a list of six
|
||||||
|
elements. Finally, the representation can be an instance of a
|
||||||
|
structure type derived from @scheme[struct:struct-info] that also
|
||||||
|
implements @scheme[prop:procedure], and where the instance is further
|
||||||
|
is wrapped by @scheme[make-set!-transformer].
|
||||||
|
|
||||||
|
Use @scheme[struct-info?] to recognize all allowed forms of the
|
||||||
|
information, and use @scheme[extract-struct-info] to obtain a list
|
||||||
|
from any representation.
|
||||||
|
|
||||||
The implementor of a syntactic form can expect users of the form to
|
The implementor of a syntactic form can expect users of the form to
|
||||||
know what kind of information is available about a structure type. For
|
know what kind of information is available about a structure type. For
|
||||||
|
@ -606,15 +612,17 @@ type.
|
||||||
@defproc[(struct-info? [v any/c]) boolean?]{
|
@defproc[(struct-info? [v any/c]) boolean?]{
|
||||||
|
|
||||||
Returns @scheme[#t] if @scheme[v] is either a six-element list with
|
Returns @scheme[#t] if @scheme[v] is either a six-element list with
|
||||||
the correct shape for representing structure-type information, or a
|
the correct shape for representing structure-type information, a
|
||||||
procedure encapsulated by @scheme[make-struct-info].}
|
procedure encapsulated by @scheme[make-struct-info], or a structure
|
||||||
|
type derived from @scheme[struct:struct-info] and wrapped with
|
||||||
|
@scheme[make-set!-transformer].}
|
||||||
|
|
||||||
@defproc[(checked-struct-info? [v any/c]) boolean?]{
|
@defproc[(checked-struct-info? [v any/c]) boolean?]{
|
||||||
|
|
||||||
Returns @scheme[#t] if @scheme[v] is a procedure encapsulated by
|
Returns @scheme[#t] if @scheme[v] is a procedure encapsulated by
|
||||||
@scheme[make-struct-info] and produced by @scheme[define-struct], but
|
@scheme[make-struct-info] and produced by @scheme[define-struct], but
|
||||||
only when no parent type is specified or the parent type is also
|
only when no parent type is specified or the parent type is also
|
||||||
specified through a transformer binding to such a value).}
|
specified through a transformer binding to such a value.}
|
||||||
|
|
||||||
@defproc[(make-struct-info [thunk (-> (and/c struct-info? list?))])
|
@defproc[(make-struct-info [thunk (-> (and/c struct-info? list?))])
|
||||||
struct-info?]{
|
struct-info?]{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user