/* Chapter 6 Review 6
Student Name, Date */
#include <iostream>
#include "pegclass.h"
//----------------------------------------------------------------
void MoveRing(PegClass &FromPeg, PegClass &ToPeg)
/* Moves a ring from the FromPeg to the ToPeg.
Pre: FromPeg is not empty.
Post: A Ring has been moved */
{
int Size = FromPeg.RemoveRing();
ToPeg.AddRing(Size);
}
//----------------------------------------------------------------
void FillPeg(PegClass &P, int N)
{
for (int RingAdd = N; RingAdd >= 1; RingAdd--)
P.AddRing(RingAdd);
}
void GetUserMove(char &Source, char &Destination)
{
std::cout << "Source Peg (L/M/R): ";
std::cin >> Source;
std::cout << "Destination Peg (L/M/R): ";
std::cin >> Destination;
}
//----------------------------------------------------------------
void MakeUserMove(char Source, char Destination, PegClass &Peg1, PegClass &Peg2, PegClass &Peg3)
/* Moves peg from Source to Destination
Post: Top peg from Source moved to top of Destination pegs */
{
int size;
if (Source == 'L' && Destination == 'M')
MoveRing(Peg1, Peg2);
else if (Source == 'L' && Destination == 'R')
MoveRing(Peg1, Peg3);
else if (Source == 'M' && Destination == 'L')
MoveRing(Peg2, Peg1);
else if (Source == 'M' && Destination == 'R')
MoveRing(Peg2, Peg3);
else if (Source == 'R' && Destination == 'L')
MoveRing(Peg3, Peg1);
else if (Source == 'R' && Destination == 'M')
MoveRing(Peg3, Peg2);
}
//----------------------------------------------------------------
int main()
{
PegClass Left(4), Middle(4), Right(4);
char Source, Destination;
FillPeg(Left, 3);
Left.ShowAll();
GetUserMove(Source, Destination);
MakeUserMove(Source, Destination, Left, Middle, Right);
Left.ShowAll();
std::cin.get();
std::cin.get();
return(0);
}
/* Lawrenceville Press PegClass type DECLARATION */
/* October 1997 */
#ifndef _PEGCLASS_
#define _PEGCLASS_
#include <iostream>
#include "vector.h"
//#include <lvp\bool.h>
class PegClass {
public:
PegClass(); // Not configured; must call SetPeg() later
PegClass(int Height);
~PegClass();
void SetPeg(int Height);
void AddRing(int Size);
int RemoveRing();
int TopRing() const; // Returns size of top Ring
int RingsOnPeg() const; // Returns number of Rings on peg
void ShowAll() const; // Shows _all_ declared and configured pegs
const PegClass & operator = ( const PegClass & P ); // Assignment
private:
struct PegData { // Data needed for a single Peg
vector<int> PegStack; // An array representing the rings
bool Configured; //False, if init'ed by default,
// parameterless constructor
int NumRings; // Number of rings currently on peg
int Hgt; // Height of peg
};
static vector<PegData> PegList; // List of all Pegs constructed
static int MaxRingSize; // Used in spacing the pegs
int MySpot; // Location of _this_ peg in PegList
// Copy constructor "hidden" by private definition.
PegClass(const PegClass &PegClass); // Copy constructor
void DrawBlanks(int N) const; // Utility function for spacing the Pegs
};
#endif
/* Lawrenceville Press PegClass type IMPLEMENTATION */
/* October 1997 */
/* Revised: March 1999 TopRing calls abort() if there */
/* are no rings on the peg */
#include "pegclass.h"
#include <iostream>
// Must initialize static members here
vector<PegClass::PegData> PegClass::PegList;
int PegClass::MaxRingSize = 7;
const PegClass & PegClass::operator = ( const PegClass & P ) // Assignment
{
PegList[MySpot].PegStack = PegList[P.MySpot].PegStack;
PegList[MySpot].Hgt = PegList[P.MySpot].Hgt;
PegList[MySpot].NumRings = PegList[P.MySpot].NumRings;
PegList[MySpot].Configured = PegList[P.MySpot].Configured;
return *this;
}
//-------------------------------------------
PegClass::~PegClass()
/* Deletes the peg (by flagging) */
{
PegList.resize(PegList.length()-1);
}
//-------------------------------------------
PegClass::PegClass(int Height)
/* Creates a PegClass object with given height.
Pre: Height > 0
Post: Peg is created with given height*/
{
int spot = PegList.length();
PegList.resize(PegList.length()+1);
PegList[spot].PegStack.resize(Height);
PegList[spot].Hgt = Height;
PegList[spot].NumRings = 0;
PegList[spot].Configured = true;
MySpot = spot;
}
//-------------------------------------------
PegClass::PegClass()
/* Creates an unconfigured PegClass object
Post: Peg is created */
{
int spot = PegList.length();
PegList.resize(PegList.length()+1);
PegList[spot].Configured = false;
MySpot = spot;
}
//-------------------------------------------
void PegClass::SetPeg(int Height)
/* Sets the height of a previously unconfigured peg
Pre: Height > 0
Post: Peg is configured with given height */
{
PegList[MySpot].PegStack.resize(Height);
PegList[MySpot].Hgt = Height;
PegList[MySpot].NumRings = 0;
PegList[MySpot].Configured = true;
}
//-------------------------------------------
int PegClass::RingsOnPeg() const
/* Returns number of rings on peg
Post: Number of rings on peg returned */
{
if (!PegList[MySpot].Configured) {
std::cout << "Peg not configured!" << std::endl;
abort();
}
return(PegList[MySpot].NumRings);
}
//-------------------------------------------
void PegClass::AddRing(int Size)
/* Adds a ring of given size to top of peg.
Pre: 1 <= Size <= MaxRingSize
Post: Ring has been added to top of peg */
{
if (!PegList[MySpot].Configured) {
std::cout << "Peg not configured!" << std::endl;
abort();
}
if (PegList[MySpot].NumRings < PegList[MySpot].Hgt &&
Size <= MaxRingSize &&
Size > 0) {
PegList[MySpot].PegStack[PegList[MySpot].NumRings] = Size;
PegList[MySpot].NumRings++;
}
else abort();
}
//-------------------------------------------
int PegClass::RemoveRing()
/* Removes top ring from the peg and returns its size.
Pre: Peg is not empty
Post: Top ring removed, and size returned. */
{
if (!PegList[MySpot].Configured) {
std::cout << "Peg not configured!" << std::endl;
abort();
}
if (PegList[MySpot].NumRings > 0) {
PegList[MySpot].NumRings--;
}
else
abort();
return(PegList[MySpot].PegStack[PegList[MySpot].NumRings]);
}
//-------------------------------------------
int PegClass::TopRing() const
/* Returns size of top ring.
Pre: Peg is not empty
Post: Size of top ring on peg returned. */
{
if (!PegList[MySpot].Configured) {
std::cout << "Peg not configured!" << std::endl;
abort();
}
if (PegList[MySpot].NumRings > 0)
return(PegList[MySpot].PegStack[PegList[MySpot].NumRings-1]);
else
abort();
}
//-------------------------------------------
void PegClass::DrawBlanks(int N) const
/* Draws N blanks
Pre: N >= 0
Post: N blanks have been drawn */
{
for (int i=1; i <= N; i++)
std::cout << " ";
}
//-------------------------------------------
void PegClass::ShowAll() const
/* Shows all declared and configured pegs
Post: All configured pegs have been displayed */
{
int i;
int PegCount = 0;
int MaxHgt = 0;
for (i=0; i < PegList.length() ; i++) {
if (PegList[i].Configured) {
PegCount++;
if (PegList[i].Hgt > MaxHgt)
MaxHgt = PegList[i].Hgt;
}
}
for (int Row = MaxHgt-1; Row >= 0; Row--) {
// do a Row
for (i=0; i < PegList.length() ; i++)
// Do Peg i in this Row
if (!PegList[i].Configured)
; // Do nothing
else
if (PegList[i].Hgt > Row) {
if (PegList[i].NumRings > Row) { // If a Ring on this row
// Draw a Ring (possibly empty)
int Col;
for (Col=(-MaxRingSize); Col <= (-1); Col++)
if ( PegList[i].PegStack[Row] >= (-Col) )
std::cout << "X";
else
std::cout << " ";
std::cout << "|";
for (Col=1; Col <= MaxRingSize; Col++)
if (PegList[i].PegStack[Row] >= Col)
std::cout << "X";
else
std::cout << " ";
}
else {
DrawBlanks(MaxRingSize);
std::cout << "|";
DrawBlanks(MaxRingSize);
}
}
else {
DrawBlanks(MaxRingSize);
std::cout << " ";
DrawBlanks(MaxRingSize);
}
std::cout << std::endl;
}
for (int Col = 1; Col <= (2*MaxRingSize+1)*PegCount; Col++)
std::cout << "-";
std::cout << std::endl;
}
#ifndef _VECTOR_H
#define _VECTOR_H
/* Lawrenceville Press vector type DECLARATION */
/* June 1997, updated March 1999 comments updated */
/* */
/* The vector class is based on the class apvector defined */
/* for use in the AP Computer Science courses. */
/* */
/* Inclusion of the C++ classes defined for use in the */
/* Advanced Placement Computer Science courses does not */
/* constitute endorsement of the other material in */
/* "A Guide to Programming in C++" (Lawrenceville Press, */
/* June 1997) by the College Board, Educational Testing */
/* Service, or the AP Computer Science Development Committee.*/
/* */
/* vector class consistent with a subset of the standard C++ */
/* vector class as defined in the draft ANSI standard */
// *******************************************************************
// Revised: January 13,1998, added explicit to int constructor
// Revised: 8/14/98 abort changed to exit
//
// APCS vector class template
//
// implements "safe" (range-checked) arrays
// examples are given at the end of this file
// *******************************************************************
// If your compiler supports the keyword explicit, comment out the
// #define explicit line below, leaving the #define means explicit
// is ignored, but doesn't generate an error
//
// This will disallow a typically erroneous implicit type-conversion:
// vector<int> v( 10 );
// v = 0; // Oops!! Allowed because of implicit type-con2lversion.
//#define explicit
template <class itemType>
class vector
{
public:
// constructors/destructor
vector() : // default constructor (size==0)
mySize(0),
myList(0)
{
}
explicit vector(int size) : // initial size of vector is size
mySize(size),
myList(new itemType[size])
{
}
vector(int size, const itemType & fillValue) : // all entries == fillValue
mySize(size),
myList(new itemType[size])
{
for (int k = 0; k < size; k++)
myList[k] = fillValue;
}
vector(const vector & vec) : // copy constructor
mySize(vec.length()),
myList(new itemType[mySize])
{
for (int k = 0; k < mySize; k++)
myList[k] = vec.myList[k];
}
~vector() // destructor
{
delete [] myList;
}
// assignment
const vector & operator=(const vector & vec)
{
if (this != &vec) // don't assign to self!
{
delete [] myList; // get rid of old storage
mySize = vec.length();
myList = new itemType [mySize]; // allocate new storage
// copy vec
for (int k = 0; k < mySize; k++)
{
myList[k] = vec.myList[k];
}
}
return *this; // permit a = b = c = d
}
// accessors
int length() const // capacity of vector
{
return mySize;
}
// indexing
itemType & operator[](int index) // indexing with range checking
{
if (index < 0 || mySize <= index)
{
std::cerr << "Illegal vector index: " << index << " max index = " << (mySize-1) << std::endl;
exit(1);
}
return myList[index];
}
const itemType & operator[](int index) const // indexing with range checking
{
if (index < 0 || mySize <= index)
{
std::cerr << "Illegal vector index: " << index << " max index = " << (mySize-1) << std::endl;
exit(1);
}
return myList[index];
}
// modifiers
void resize(int newSize) // change size dynamically; can result in losing values
{
int numToCopy = newSize < mySize ? newSize : mySize;
// allocate new storage and copy element into new storage
itemType * newList = new itemType[newSize];
for (int k = 0; k < numToCopy; k++)
newList[k] = myList[k];
delete [] myList; // de-allocate old storage
mySize = newSize; // assign new storage/size
myList = newList;
}
private:
int mySize; // # elements in array
itemType * myList; // array used for storage
};
// *******************************************************************
// Specifications for vector functions
//
// The template parameter itemType must satisfy the following two conditions:
// (1) itemType has a 0-argument constructor
// (2) operator = is defined for itemType
// Any violation of these conditions may result in compilation failure.
//
// Any violation of a function's precondition will result in an error message
// followed by a call to exit.
//
// constructors/destructor
//
// vector( )
// postcondition: vector has a capacity of 0 items, and therefore it will
// need to be resized
//
// vector( int size )
// precondition: size >= 0
// postcondition: vector has a capacity of size items
//
// vector( int size, const itemType & fillValue )
// precondition: size >= 0
// postcondition: vector has a capacity of size items, all of which are set
// by assignment to fillValue after default construction
//
// vector( const vector & vec )
// postcondition: vector is a copy of vec
//
// ~vector( )
// postcondition: vector is destroyed
//
// assignment
//
// const vector & operator = ( const vector & rhs )
// postcondition: normal assignment via copying has been performed;
// if vector and rhs were different sizes, vector
// has been resized to match the size of rhs
//
// accessor
//
// int length( ) const
// postcondition: returns vector's size (number of memory cells
// allocated for vector)
//
// indexing
//
// itemType & operator [ ] ( int k ) -- index into nonconst vector
// const itemType & operator [ ] ( int k ) const -- index into const vector
// description: range-checked indexing, returning kth item
// precondition: 0 <= k < length()
// postcondition: returns the kth item
//
// modifier
//
// void resize( int newSize )
// description: resizes the vector to newSize elements
// precondition: the current capacity of vector is length; newSize >= 0
//
// postcondition: the current capacity of vector is newSize; for each k
// such that 0 <= k <= min(length, newSize), vector[k]
// is a copy of the original; other elements of vector are
// initialized using the 0-argument itemType constructor
// Note: if newSize < length, elements may be lost
//
// examples of use
// vector<int> v1; // 0-element vector
// vector<int> v2(4); // 4-element vector
// vector<int> v3(4, 22); // 4-element vector, all elements == 22.
#endif