You are not required to use any of these hints.
type directionType : enum (left, right, down, up) % The tile type. % For elbows, the last two characters in the name indicate the directions % of the exits. For Ts, the last characters indicate the direction of the % stem. type tileType : enum (elbowUR, elbowRD, elbowDL, elbowLU, Tdown, Tleft, Tup, Tright, straightHoriz, straightVert, cross) const numTileTypes := 11 const numPrizes := 5 % Each node contains the type of tile, whether the it contains a prize, % whether it contains the red or blue players' pieces, and pointers to % its left, right, upper and lower neighbours. type squareType : record tile : tileType prize : int hasAPlayer : boolean hasBPlayer : boolean left : ^squareType right : ^squareType up : ^squareType down : ^squareType end record const boardSize := 5These declarations include a type, squareType, for storing each of the 25 tiles in the board. Even though you are required to use circular, doubly-linked lists for the rows and columns, there are other ways to go about defining your square or node type. For instance, you could remove the hasAPlayer and hasBPlayer booleans from the record and instead keep a pointer for each player that points directly to the tile that they are on.
These declarations use "enumerated types" in two places. With an enumerated type, you can compute the next value in the sequence using "succ" (which stands for "successor"). See pages 29-30 of the text for information about enumerated types. Another option is to simply declare constants for each of the tile types and directions. Eg, "const elbowUR : int := 1".
Notice that we have defined 11 different tile types. Really, these represent combinations of tile type and rotation.
% makeRandomTile %---------------------------------------------------------------- % Return a tile selected at random. function makeRandomTile : tileType var which : int randint (which, 0, numTileTypes - 1) var t : tileType := tileType.elbowUR for i : 1 .. which t := succ (t) end for result t end makeRandomTile
Write a procedure that can create a single row of 5 random tiles, and which you will call 5 times. Write another procedure that can take pointers to two consecutive rows and link their up and down pointers to create proper columns.
You can draw a nice board with only plain old characters, as in the example above. The code for this is a bit of a pain however, because you can't do the logical thing:
% The obvious algorithm: for row : 1..5 for column : 1..5 draw a picture representing the tile at (row, column) end for end forThink about why you can't.
Well, you can use this algorithm if you draw a whole tile using a single character. But that's not practical since your picture of the tile has to show the tile type, and who's sitting on it (if any player is) and what prizes are sitting on it (if any).
Click here to get code that will draw a board for you in a text-based mode. If you want to use this code without changing it at all, you are required to save it in its own file and then "include" that file in the spot where you need the code in your program. (And don't bother printing out and handing in the file containing our code.) An include tells the compiler to act as if the code were right there in your file. It's a little different than using an import statement. (See the text, p. 125 if you'd like to know the difference.)
Our drawBoard code presumes the existence of several subprograms. You will have to write these if you want to use our drawBoard:
% tileTypeAt %---------------------------------------------------------------- % Return the type of the tile at location (row, col). function tileTypeAt (row : int, col : int) : tileType % playerAAt %---------------------------------------------------------------- % Return true if player A is at location (row, col), and false otherwise. function playerAAt (row : int, col : int) : boolean % playerBAt %---------------------------------------------------------------- % Return true if player B is at location (row, col), and false otherwise. function playerBAt (row : int, col : int) : boolean % prizeAt %---------------------------------------------------------------- % Return the prize number at location (row, col), or zero if there is % no prize there. function prizeAt (row : int, col : int) : int
All of this should cause you to wonder about the wisdom of this data structure. Was it a good choice?
If you add the optional graphics mode, your players can use the mouse to specify their moves.
You might find it convenient to have a function like this:
% openOn %---------------------------------------------------------------- % Return true iff tile is open on side d, that is, iff you can % arrive at or leave the tile from side d. function openOn (tile : tileType, d : directionType) : boolean