Squeak Class Documentation category index | class index  
 
ChineseCheckers
  category: Morphic-Games
  superclass: BorderedMorph
  subclasses:

An implementation of Chinese Checkers by Dan Ingalls. April 9, 2000.

board: A 19x19 rhombic array, addressed by row@col points, in which is imbedded the familiar six-pointed layout of cells. A cell outside the board is nil (-).
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - 5 - - - - -
- - - - - - - - - - - - 5 5 - - - - -
- - - - - - - - - - - 5 5 5 - - - - -
- - - - - - - - - - 5 5 5 5 - - - - -
- - - - - 6 6 6 6 0 0 0 0 0 4 4 4 4 -
- - - - - 6 6 6 0 0 0 0 0 0 4 4 4 - -
- - - - - 6 6 0 0 0 0 0 0 0 4 4 - - -
- - - - - 6 0 0 0 0 0 0 0 0 4 - - - -
- - - - - 0 0 0 0 0 0 0 0 0 - - - - -
- - - - 1 0 0 0 0 0 0 0 0 3 - - - - -
- - - 1 1 0 0 0 0 0 0 0 3 3 - - - - -
- - 1 1 1 0 0 0 0 0 0 3 3 3 - - - - -
- 1 1 1 1 0 0 0 0 0 3 3 3 3 - - - - -
- - - - - 2 2 2 2 - - - - - - - - - -
- - - - - 2 2 2 - - - - - - - - - - -
- - - - - 2 2 - - - - - - - - - - - -
- - - - - 2 - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
Cells within the board contain 0 if empty, or a team number (1..6) if occupied by a piece of that team. An extra border of nils around the whole reduces bounds checking to a nil test.

sixDeltas: An array giving the x@y deltas for the 6 valid steps in CCW order from a given cell. For team 1 they are: in fr, fl, l, bl, br, r. To get, eg fl for a given team, use (sixDeltas atWrap: team+1).

teams: An array of six teams, each of which is an array of the x@y locations of the 10 pieces.

homes: The x@y coordinates of the six home points, namely 14@2, 18@6, 14@14, 6@18, 2@14, 6@6. The goal, or farthest point in destination triangle, is thus (homes atWrap: teamNo+3).

autoPlay: An array of booleans, parallel to teams, where true means that Squeak will make the moves for the corresponding team.

whoseMove: A team number specifying whose turn it is next. Set to 0 when game is over.

plannedMove: If not nil, it means the board is in a state where it is animating the next move to be made so that it can be seen.

movePhase: Holds the state of display of the planned move so that, eg, it can appear one jump at a time. Advances from 1 to (plannedMove size * 2).

A move is an array of locs which are the path of the move.

Once the morph is open, the menu command 'reset...' allows you to reset the board and change the number of players. The circle at turnIndicatorLoc indicates the color of the team whose turn it is. If it is a human, play waits for drag and drop of a piece of that color.

The current strategy is very simple: generate all moves, score them and pick the best. Beyond this, it will look ahead a number of moves, but this becomes very expensive without pruning. Pruning would help the speed of play, especially in the end game where we look a little deeper. A more effective strategy would consider opponents' possible moves as well, but this is left as an exercise for the serious programmer.

instance methods
  board geometry
  at:
at:put:
boardCenter
boardLocAt:
cellPointAt:
distFrom:to:
extent:
pieceSize
turnIndicatorLoc

  display
  drawOn:
printOn:

  drag and drop
  acceptDroppingMorph:event:
okToPickUpPieceAt:
pieceAt:
wantsDroppedMorph:event:

  game sequence
  nextTurn
showNextMoveSegment
step
stepTime

  initialization
  board:teams:
copyBoard
initialize
teams:autoPlay:

  menu
  addCustomMenuItems:hand:
addMenuItemsTo:hand:
animateMoves
dontAnimateMoves
handlesMouseDown:
mouseDown:
newGame
reset

  moves
  allMovesFrom:
bestMove:forTeam:
checkDoneAfter:
endGameFor:
jumpFor:from:havingVisited:
makeMove:
score:for:
testDone:for:

  parts bin
  initializeToStandAlone

class methods
  parts bin
  descriptionForPartsBin

instance methods
  board geometry top  
 

at:

Primitive. Assumes receiver is indexable. Answer the value of an
indexable element in the receiver. Fail if the argument index is not an
Integer or is out of bounds. Essential. See Object documentation
whatIsAPrimitive.


 

at:put:

Primitive. Assumes receiver is indexable. Store the argument value in
the indexable element of the receiver indicated by index. Fail if the
index is not an Integer or is out of bounds. Or fail if the value is not of
the right type for this kind of collection. Answer the value that was
stored. Essential. See Object documentation whatIsAPrimitive.


 

boardCenter


 

boardLocAt:


 

cellPointAt:


 

distFrom:to:

The six possible moves are: 1@0, 1@-1, 0@1, 0@-1, -1@0, -1@1.


 

extent:


 

pieceSize


 

turnIndicatorLoc


  display top  
 

drawOn:


 

printOn:

For testing only


  drag and drop top  
 

acceptDroppingMorph:event:

This message is sent when a morph is dropped onto a morph that has agreed to accept the dropped morph by responding 'true' to the wantsDroppedMorph:Event: message. This default implementation just adds the given morph to the receiver.


 

okToPickUpPieceAt:


 

pieceAt:


 

wantsDroppedMorph:event:

Return true if the receiver wishes to accept the given morph, which is being dropped by a hand in response to the given event. Note that for a successful drop operation both parties need to agree. The symmetric check is done automatically via aMorph wantsToBeDroppedInto: self.


  game sequence top  
 

nextTurn


 

showNextMoveSegment

Display the current move in progress. Starts with movePhase = 1.
Increments movePhase at each tick. Ends by setting movePhase to 0.


 

step

Do some periodic activity. Use startStepping/stopStepping to start and stop getting sent this message. The time between steps is specified by this morph's answer to the stepTime message. The generic version dispatches control to the player, if any. The nasty circumlocation about owner's transformation is necessitated by the flexing problem that the player remains in the properties dictionary both of the flex and the real morph. In the current architecture, only the top renderer's pointer to the player should actually be honored for the purpose of firing.


 

stepTime

Answer the desired time between steps in milliseconds. This default implementation requests that the 'step' method be called once every second.


  initialization top  
 

board:teams:


 

copyBoard

Return a copy of the board for the purpose of looking ahead one or more moves.


 

initialize

Default creation is for one person against Squeak.


 

teams:autoPlay:

Initialize board, teams, steps, jumps


  menu top  
 

addCustomMenuItems:hand:

Include our modest command set in the ctrl-menu


 

addMenuItemsTo:hand:


 

animateMoves


 

dontAnimateMoves


 

handlesMouseDown:

Prevent stray clicks from picking up the whole game in MVC.


 

mouseDown:

Handle a mouse down event. The default response is to let my eventHandler, if any, handle it.


 

newGame

Reset the board, with same teams.


 

reset

Reset the board, choosing anew how many teams.


  moves top  
 

allMovesFrom:

boardLoc must be occupied


 

bestMove:forTeam:


 

checkDoneAfter:


 

endGameFor:

Return true if we are in the end game (all players within 1 of home triangle).


 

jumpFor:from:havingVisited:

Recursively explore all jumps from loc, leaving in dict
the prior position from which we got there


 

makeMove:


 

score:for:

Return the decrease in distance toward this team's goal


 

testDone:for:

Return true if we are done (all players in home triangle).


  parts bin top  
 

initializeToStandAlone

Default creation is for one person against Squeak.


class methods
  parts bin top  
 

descriptionForPartsBin

If the receiver is a member of a class that would like to be represented in a parts bin, answer the name by which it should be known, and a documentation string to be provided, for example, as balloon help. When the 'nativitySelector' is sent to the 'globalReceiver', it is expected that some kind of Morph will result. The parameters used in the implementation below are for documentation purposes only!