Week 11 Tutorial
Code Review
A lab pair will present their solution to one of the lab exercises from Week 9.
The review should take about 10 minutes. The reviewees should give a brief description of their code, and the class should ask questions, comment on the quality of the code, and suggest improvements.
Linked Lists
In the lectures, we have been looking at linked lists: a way of storing a series of numbers (or other types), similarly to an array, but without a fixed size.
In your tutorial, discuss linked lists, and walk through some examples.
Use the list struct from lectures, i.e.
typedef struct _node *Node;
typedef struct _list *List;
typedef struct _list {
Node head;
} list;
typedef struct _node {
int value;
Node next;
} node;
You may want to consider:
- creating a node
- creating a list
- adding nodes to a list
- removing nodes from a list
- traversing the list
- i.e. going through every list element to perform some operation – perhaps printing the list, or summing the values.
Final Card Down: Game ADT
There are three stages in the Final Card-Down assignment:
- testGame.c Testing the Game ADT,
- Game.c Implementing the Game ADT,
- player.c Using the Game ADT.
In this tutorial we will be looking at implementing the Game ADT.
You should be familiar with Game.h
now – if not, go and read it ASAP.
In the past, when we’ve created a struct and a pointer to a struct, we’ve done them in the same place, e.g.
typedef struct _node *Node;
typedef struct _node {
int value;
Node next;
}
In Game.h
, you’ll notice that the typedef declaring that a Game
is a
pointer to a struct _game
, but the game struct itself isn’t actually
defined.
This is intentional – as it’s up to you to decide how you’ll implement
your game struct – i.e. what fields it will need to contain. To do
this, you will need to think about the game, and look at the various
interface functions in Game.h
– what will you need to store, to keep
track of the game state throughout the game?
Let’s think about a very very basic version of the game – one which has no functionality except for keeping track of turn numbers.
So, we should be able to call the newGame
function, to create a new
game; the currentTurn
function, to get the current turn, and the
playMove
function (ignoring the actual move that’s passed in).
Some example tests for this overly-simplified Game ADT implementation:
// Create a new game.
Game g = newGame(/* ... */);
// The turn number should start at 0.
assert (currentTurn(g) == 0);
// Make a move....
// We don't actually care what the contents of this are,
// so we'll make everything 0 for now.
playerMove move = { 0 };
move->action = END_TURN;
// Make the move
playMove(g, move);
// Because we made an END_TURN move, the turn has ended,
// and so we should now be up to turn 1 (player 1's turn)
assert (currentTurn(g) == 1);
// ... and so on.
What would you need in the game struct for this?
typedef struct _game {
int turnNumber; // perhaps something like this?
// ... anything else?
} game;
What would you need to do in newGame
to set this up?
Game newGame (/* ... */) {
// allocate memory for a game struct
// set the turn number to start at 0
}
What about in currentTurn
?
int currentTurn (Game game) {
return game->turnNumber;
}
What about in playMove?
void playMove(Game game, playerMove move) {
// if the player played an END_TURN move...
// their turn has ended, so increase the turn number.
}
What would you need to add to also keep track of the current player?