completed ToH board ADT implementation
This commit is contained in:
parent
8386194964
commit
59a36fe5f3
2 changed files with 135 additions and 4 deletions
129
toh_board.c
129
toh_board.c
|
|
@ -14,7 +14,136 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "toh_disk.h"
|
#include "toh_disk.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef NULL
|
||||||
|
#undef NULL
|
||||||
|
#define NULL ((void *)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Abstraction of a rod type */
|
/** Abstraction of a rod type */
|
||||||
/* Hint: Define a type 'Rod' as a pointer to Disk
|
/* Hint: Define a type 'Rod' as a pointer to Disk
|
||||||
for usage in exchange with Disk array */
|
for usage in exchange with Disk array */
|
||||||
|
|
||||||
|
struct TohBoardData {
|
||||||
|
Rod rods[3][MAX_DISKS];
|
||||||
|
};
|
||||||
|
|
||||||
|
static TohBoard static_board = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the instance of the 'Tower of Hanoi' board.
|
||||||
|
* Exactly one instance is supported.
|
||||||
|
*
|
||||||
|
* @return TohBoard The board instance.
|
||||||
|
*/
|
||||||
|
TohBoard tb_get_board() {
|
||||||
|
if (tb_is_valid(static_board)) {
|
||||||
|
return static_board;
|
||||||
|
}
|
||||||
|
|
||||||
|
static_board = (TohBoard)calloc(sizeof(struct TohBoardData), 1);
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
for (int j = 0; j < MAX_DISKS; j++) {
|
||||||
|
static_board->rods[i][j] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return static_board;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all disks from any rod of the given board.
|
||||||
|
*
|
||||||
|
* @param board The board instance in focus.
|
||||||
|
*/
|
||||||
|
void tb_clear_board(TohBoard board) {
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
for (int j = 0; j < MAX_DISKS; j++) {
|
||||||
|
board->rods[i][j] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether or not the given board is valid.
|
||||||
|
* A board is NOT valid, if it is 0.
|
||||||
|
*
|
||||||
|
* @param board The board to evaluate.
|
||||||
|
* @return If the given board is valid, false otherwise.
|
||||||
|
*/
|
||||||
|
bool tb_is_valid(TohBoard board) {
|
||||||
|
return board != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the top-most disk of the given rod and removes it from this rod.
|
||||||
|
*
|
||||||
|
* @param board The board instance in focus.
|
||||||
|
* @param rodName The rod from which the disk shall be taken and removed.
|
||||||
|
* @return The removed disk or 0, if no disk was on the rod.
|
||||||
|
*/
|
||||||
|
Disk tb_pop_disk(TohBoard board, RodName rodName) {
|
||||||
|
if (!tb_is_valid(board)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Disk disk = NULL;
|
||||||
|
for (int i = MAX_DISKS - 1; i >= 0; i--) {
|
||||||
|
if (board->rods[rodName][i] != NULL) {
|
||||||
|
disk = board->rods[rodName][i];
|
||||||
|
board->rods[rodName][i] = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return disk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the given disk to the given rod, if this
|
||||||
|
* is allowed according to the rules.
|
||||||
|
*
|
||||||
|
* @param board The board instance in focus.
|
||||||
|
* @param rodName The rod on which the disk shall be placed.
|
||||||
|
* @param disk The disk to place on the rod.
|
||||||
|
* @return True if the disk could be legally placed on the rod
|
||||||
|
* (move is allowed and disk is valid), false otherwise.
|
||||||
|
*/
|
||||||
|
bool tb_push_disk(TohBoard board, RodName rodName, Disk disk) {
|
||||||
|
if (!tb_is_valid(board) || !td_is_valid(disk)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_DISKS; i++) {
|
||||||
|
if (board->rods[rodName][i] == NULL) {
|
||||||
|
// Check if it is at the bottom or if the it is smaller than the one below
|
||||||
|
if (i > 0 && !td_is_smaller(board->rods[rodName][i - 1], disk)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
board->rods[rodName][i] = disk;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the disk from the named rod at the given position.
|
||||||
|
*
|
||||||
|
* @param board The board instance in focus.
|
||||||
|
* @param rodName The rod on which the disk shall be placed.
|
||||||
|
* @param idx The index of the desired disk on the named rod.
|
||||||
|
* Index 0 addresses the bottom-most disk.
|
||||||
|
* @return The addressed disk or 0, if not disk is located on the
|
||||||
|
* index position of the named rod.
|
||||||
|
*/
|
||||||
|
Disk tb_get_disk(TohBoard board, RodName rodName, unsigned short idx) {
|
||||||
|
if (!tb_is_valid(board) || idx >= MAX_DISKS) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// no need to check, as everything is going to be initalized with 0
|
||||||
|
return board->rods[rodName][idx];
|
||||||
|
}
|
||||||
10
toh_board.h
10
toh_board.h
|
|
@ -26,7 +26,9 @@ typedef enum {
|
||||||
LEFT,
|
LEFT,
|
||||||
MIDDLE,
|
MIDDLE,
|
||||||
RIGHT
|
RIGHT
|
||||||
} Rod;
|
} RodName;
|
||||||
|
|
||||||
|
typedef Disk Rod;
|
||||||
|
|
||||||
/** Declares type for the 'Tower of Hanoi' board */
|
/** Declares type for the 'Tower of Hanoi' board */
|
||||||
typedef struct TohBoardData* TohBoard;
|
typedef struct TohBoardData* TohBoard;
|
||||||
|
|
@ -62,7 +64,7 @@ bool tb_is_valid(TohBoard board);
|
||||||
* @param rodName The rod from which the disk shall be taken and removed.
|
* @param rodName The rod from which the disk shall be taken and removed.
|
||||||
* @return The removed disk or 0, if no disk was on the rod.
|
* @return The removed disk or 0, if no disk was on the rod.
|
||||||
*/
|
*/
|
||||||
TohBoard tb_pop_disk(TohBoard board, Rod rodName);
|
Disk tb_pop_disk(TohBoard board, RodName rodName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies the given disk to the given rod, if this
|
* Applies the given disk to the given rod, if this
|
||||||
|
|
@ -74,7 +76,7 @@ TohBoard tb_pop_disk(TohBoard board, Rod rodName);
|
||||||
* @return True if the disk could be legally placed on the rod
|
* @return True if the disk could be legally placed on the rod
|
||||||
* (move is allowed and disk is valid), false otherwise.
|
* (move is allowed and disk is valid), false otherwise.
|
||||||
*/
|
*/
|
||||||
bool tb_push_disk(TohBoard board, Rod rodName, TohDisk disk);
|
bool tb_push_disk(TohBoard board, RodName rodName, Disk disk);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the disk from the named rod at the given position.
|
* Provides the disk from the named rod at the given position.
|
||||||
|
|
@ -86,6 +88,6 @@ bool tb_push_disk(TohBoard board, Rod rodName, TohDisk disk);
|
||||||
* @return The addressed disk or 0, if not disk is located on the
|
* @return The addressed disk or 0, if not disk is located on the
|
||||||
* index position of the named rod.
|
* index position of the named rod.
|
||||||
*/
|
*/
|
||||||
TohDisk tb_get_disk(TohBoard board, Rod rodName, unsigned short idx);
|
Disk tb_get_disk(TohBoard board, RodName rodName, unsigned short idx);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Loading…
Add table
Add a link
Reference in a new issue