Common Lisp Package: BLOCKS-WORLD

This package contains the source code of chapter 21, @em{"The Blocks World with Classes and Methods"} from @a[http://www.amazon.com/Lisp-3rd-Patrick-Winston/dp/0201083191]{ Lisp (3rd edition)} by Winston and Horn. @begin[A picture of the world]{section} The block objects represent a world that "looks" like this: @begin{pre} /----\ ^ /---------\ ^ | b4 | / \ | | / \ \____/ /_w7_\ | | / \ /----\ /----\ | | / \ /--------\ /^\ | b1 | | b2 | | b3 | / \ | b6 | (l8 ) \____/ \____/ \_________/ /_w5__\ \________/ \./ +-----------------------------------------------------------+ | | +-----------------------------------------------------------+ @end{pre} @end{section} @begin[Example]{section} In the initial configuration, where all blocks have been placed directly on the table (not shown), @fun{put-on} will move the objects like this: @begin{pre} BLOCKS-WORLD> (put-on b1 b2) Move hand to pick up B1 at location (1 2). Grasp B1. Removing support relations between B1 and TABLE. Move B1 to top of B2 at location (2 2). Adding support relations between B1 and B2. Ungrasp B1. T @end{pre} @end{section} @begin[The different kinds of blocks]{section} Movable blocks than can be moved onto load supporting blocks. Using multiple inheritance, there are also blocks that can do both. @aboutclass{basic-block} @aboutclass{load-bearing-block} @aboutclass{movable-block} @end{section} @begin[Block properties]{section} Slot readers: @aboutfun{block-name} @aboutfun{block-position} @aboutfun{block-width} @aboutfun{block-height} @aboutfun{block-supported-by} @aboutfun{block-support-for} @end{section} @begin[Concrete block classes]{section} These are the blocks found in our world: @aboutclass{table} @aboutclass{brick} @aboutclass{wedge} @aboutclass{ball} @end{section} @begin[The hand]{section} The hand is movable. It can hold at most one block. @aboutclass{hand} @aboutfun{hand-name} @aboutfun{hand-position} @aboutfun{hand-grasping} @end{section}

README:

FUNCTION

Private

FIND-SPACE (OBJECT SUPPORT)

@arg[object]{a @class{movable-block}} @arg[support]{a @class{basic-block}} @return{undocumented or nil} @short{Find space on support for object.} Returns nil if no space could be found. @see{get-space} @see{make-space}

Undocumented

INTERSECTIONS-P (OBJECT OFFSET BASE OBSTACLES)

TOP-LOCATION (OBJECT)

GENERIC-FUNCTION

Public

ADD-SUPPORT (OBJECT SUPPORT)

@arg[object]{a @class{movable-block}} @arg[support]{a @class{basic-block}} @return{a boolean} @short{Note that @code{object} has been put onto @code{support}.} This function maintains the slots @fun{block-supported-by} and @fun{block-support-for}.

CLEAR-TOP (SUPPORT)

@arg[support]{a @class{load-bearing-block}} @return{nil} @short{Make space on top of this object.} Removes all blocks @code{support} is supporting. @see{get-rid-of} @see{block-support-for}

GET-RID-OF (OBJECT)

@arg[object]{a @class{movable-block}} @return{unspecified} @short{Moves @code{object} onto the @class{table}.} @see{put-on}

GET-SPACE (OBJECT SUPPORT)

@arg[object]{a @class{movable-block}} @arg[support]{a @class{basic-block}} @return{undocumented, but non-nil} @short{Find or make space on support for object.} @see{find-space} @see{make-space}

GRASP (OBJECT)

@arg[object]{a @class{movable-block}} @return{t} @short{Grasps the block using the hand.} Makes sure to ungrasp the block currently grasped by the @class{hand}, if any. @see{ungrasp}

MAKE-SPACE (OBJECT SUPPORT)

@arg[object]{a @class{movable-block}} @arg[support]{a @class{basic-block}} @return{undocumented, but non-nil} @short{Make space on support for object.} Takes all necessary actions to make space available. @see{get-space} @see{find-space}

MOVE (OBJECT SUPPORT)

@arg[object]{a @class{movable-block}} @arg[support]{a @class{load-bearing-block}} @return{a boolean} @short{Move block @code{object} onto block @code{support}.} This is a helper function for @fun{put-on}.

PUT-ON (OBJECT SUPPORT)

@arg[object]{a @class{movable-block}} @arg[support]{a @class{basic-block}} @return{a boolean} @short{Move block @code{object} onto block @code{support}.} Prints the steps taken and returns T or prints an error message and returns nil. @see{get-space} @see{grasp} @see{move} @see{ungrasp}

REMOVE-SUPPORT (OBJECT)

@arg[object]{a @class{movable-block}} @return{a boolean} @short{Note that @code{object} has been taken from @code{support}.} This function maintains the slots @fun{block-supported-by} and @fun{block-support-for}.

UNGRASP (OBJECT)

@arg[object]{a @class{movable-block}} @return{a boolean} @short{Ungrasps the block if hand is holding it.} Returns t if successful, or nil if the @class{hand} didn't hold this block. @see{grasp}

SLOT-ACCESSOR

Public

BLOCK-HEIGHT (INSTANCE)

The @arg[instance]{a @class{basic-block}} @return{an integer} @short{Returns the block's height.} The size of a block is specified as width and height, and determines which parts of the world this block occupies. No other objects can be placed to an overlapping position. @see{block-position} @see{block-width}

SETFBLOCK-HEIGHT (NEW-VALUE OBJECT)

Set the @arg[instance]{a @class{basic-block}} @return{an integer} @short{Returns the block's height.} The size of a block is specified as width and height, and determines which parts of the world this block occupies. No other objects can be placed to an overlapping position. @see{block-position} @see{block-width}

BLOCK-NAME (INSTANCE)

The @arg[instance]{a @class{basic-block}} @return{a symbol} @short{Returns the block's name, a symbol.} In the examples from the book, a global variable of this name is used to refer to @code{instance}.

SETFBLOCK-NAME (NEW-VALUE OBJECT)

Set the @arg[instance]{a @class{basic-block}} @return{a symbol} @short{Returns the block's name, a symbol.} In the examples from the book, a global variable of this name is used to refer to @code{instance}.

BLOCK-POSITION (INSTANCE)

The @arg[instance]{a @class{basic-block}} @return{a list of two integers} @short{Returns the block's position.} The position of a block is specified as a list of its x and y coordinates, where the first axis runs along the table, and the second axis points upwards towards the hand. Together with the block's width and height, the position determines which parts of the world this block occupies. No other objects can be placed to an overlapping position. @see{block-height} @see{block-width} @see{hand-position}

SETFBLOCK-POSITION (NEW-VALUE OBJECT)

Set the @arg[instance]{a @class{basic-block}} @return{a list of two integers} @short{Returns the block's position.} The position of a block is specified as a list of its x and y coordinates, where the first axis runs along the table, and the second axis points upwards towards the hand. Together with the block's width and height, the position determines which parts of the world this block occupies. No other objects can be placed to an overlapping position. @see{block-height} @see{block-width} @see{hand-position}

BLOCK-SUPPORT-FOR (INSTANCE)

The @arg[instance]{a @class{load-bearing-block}} @return{a list of blocks} @short{Returns the blocks that have been placed onto this instance.} @see{block-supported-by}

SETFBLOCK-SUPPORT-FOR (NEW-VALUE OBJECT)

Set the @arg[instance]{a @class{load-bearing-block}} @return{a list of blocks} @short{Returns the blocks that have been placed onto this instance.} @see{block-supported-by}

BLOCK-SUPPORTED-BY (INSTANCE)

The @arg[instance]{a @class{basic-block}} @return{nil, or a block} @short{Returns the block this instance has been placed onto.} All blocks except for the table sit on top of another block, which supports them. @see{block-support-for}

SETFBLOCK-SUPPORTED-BY (NEW-VALUE OBJECT)

Set the @arg[instance]{a @class{basic-block}} @return{nil, or a block} @short{Returns the block this instance has been placed onto.} All blocks except for the table sit on top of another block, which supports them. @see{block-support-for}

BLOCK-WIDTH (INSTANCE)

The @arg[instance]{a @class{basic-block}} @return{an integer} @short{Returns the block's width.} The size of a block is specified as width and height, and determines which parts of the world this block occupies. No other objects can be placed to an overlapping position. @see{block-position} @see{block-height}

SETFBLOCK-WIDTH (NEW-VALUE OBJECT)

Set the @arg[instance]{a @class{basic-block}} @return{an integer} @short{Returns the block's width.} The size of a block is specified as width and height, and determines which parts of the world this block occupies. No other objects can be placed to an overlapping position. @see{block-position} @see{block-height}

HAND-GRASPING (INSTANCE)

The @arg[instance]{a @class{hand}} @return{a @class{movable-block}, or nil} @short{Returns the block the hand is currently holding.}

SETFHAND-GRASPING (NEW-VALUE OBJECT)

Set the @arg[instance]{a @class{hand}} @return{a @class{movable-block}, or nil} @short{Returns the block the hand is currently holding.}

HAND-NAME (INSTANCE)

The @arg[instance]{a @class{hand}} @return{a symbol} @short{Returns the hand's name, a symbol.} @begin{implementation-node} The hand is always called @code{blocks-world::*hand*}. @end{implementation-node}

SETFHAND-NAME (NEW-VALUE OBJECT)

Set the @arg[instance]{a @class{hand}} @return{a symbol} @short{Returns the hand's name, a symbol.} @begin{implementation-node} The hand is always called @code{blocks-world::*hand*}. @end{implementation-node}

HAND-POSITION (INSTANCE)

The @arg[instance]{a @class{hand}} @return{a list of two integers} @short{Returns the hand's position.} The position of a hand is specified as a list of its x and y coordinates, where the first axis runs along the table, and the second axis points upwards towards the hand. @see{block-position}

SETFHAND-POSITION (NEW-VALUE OBJECT)

Set the @arg[instance]{a @class{hand}} @return{a list of two integers} @short{Returns the hand's position.} The position of a hand is specified as a list of its x and y coordinates, where the first axis runs along the table, and the second axis points upwards towards the hand. @see{block-position}

VARIABLE

Public

TABLE

@unexport{}

Private

Undocumented

*BLOCKS*

*HAND*

B1

B2

B3

B4

B6

L8

W5

W7

CLASS

Public

BALL

@short{The block is a sphere.} Because this block doesn't have a flat top, it cannot support other blocks.

BASIC-BLOCK

@short{The superclass of all objects in the Blocks World (not including the hand).} Subclasses of @code{basic-block} characterize different kinds of objects, and have different properties. They all have a name, given as @slot{block-name} and in the examples from the book, a global variable of that name is used to refer to them. Since this chapter is an explanation of CLOS, no specific constructor function is defined, and users may call @code{make-instance} directly. @see-slot{block-width} @see-slot{block-height} @see-slot{block-position} @see-slot{block-supported-by}

BRICK

@short{A useful movable building block with a flat top.} Because this block has a flat top, it supports other blocks.

HAND

@short{The hand that moves the world.} This hand can be used to move every @class{movable-block}. @see-slot{hand-name} @see-slot{hand-position} @see-slot{hand-grasping}

LOAD-BEARING-BLOCK

@short{The superclass of objects in the Blocks World that other blocks can be placed onto.} This class is mixed into most blocks, except for the @class{wedge} and the @class{ball}. @see-slot{block-support-for}

MOVABLE-BLOCK

@short{The superclass of objects in the Blocks World that can be moved by the hand.} This class is mixed into all blocks except for the @class{table}.

TABLE

@short{The table supporting the rest of the world.} The entire rest of the world sits on this table. The table itself cannot be moved. For each world, this class is meant to be a singleton.

WEDGE

@short{An interesting movable building block.} Because this block doesn't have a flat top, it cannot support other blocks.