#!/bin/sh echo 'Start of newsolit, part 01 of 01:' echo 'x - Makefile' sed 's/^X//' > Makefile << '/' X####################################################################### X# Makefile for solitare game X# ####################################################################### XCC = gcc XCXX = g++ XCFLAGS= -g XLIBS = -lInterViewsX11 -lg++ -lX11 -lm X# The following two rules add automaticity to c++ suffixes X.SUFFIXES: .cc .C X.cc.o: X $(CXX) $(CFLAGS) -c $< X.C.o: X $(CXX) $(CFLAGS) -c $< X####################################################################### Xfilesc = solitare.cc cardview.cc pile.cc genericlist.cc Xfileso = solitare.o cardview.o pile.o genericlist.o X Xsolitare: $(fileso) X $(CXX) $(CFLAGS) -o solitare $(fileso) $(LIBS) X Xpack: X packmail -o'newsolit' Makefile *.h $(filesc) / echo 'x - card.h' sed 's/^X//' > card.h << '/' X// X// card.h - definition file for card behavior X// cards have a suit, a rank, and a color X// X// written by tim budd, oregon state university, 1990 X// X X# ifndef Cardh X# define Cardh X X// X// ---------------------------- class Card X// Xclass Card X{ X public: X // constructor X Card(int, int); X X int color (); X int rank (); X int suit (); X X private: X int s; // suit value X int r; // rank value X}; X Xinline Card::Card(int sv, int cv) { s = sv; r = cv; } X Xinline int Card::rank () { return r; } X Xinline int Card::suit () { return s; } X Xinline int Card::color() { return suit() % 2; } X X# define nilCard (Card *) 0 X X# endif / echo 'x - cardview.h' sed 's/^X//' > cardview.h << '/' X// X// cardview.h - definition for viewing a card X// X// provides protocol for displaying a card on an output device X// X// written by tim budd, oregon state university, 1990 X// X X# ifndef CardViewh X# define CardViewh X X# include "card.h" X X// X// ---------------------------- class Card X// Xclass CardView X{ X public: X // constructor X CardView(Card *); X CardView(int s, int c); X X // constants X const int CardWidth = 68; X const int CardHeight = 75; X X Card * card(); X void draw (); X void erase (); X int faceUp (); X void flip (); X int includes (int, int); X int x (); X int y (); X void moveTo (int, int); X X private: X Card * theCard; // the card value X int up; // true if face up X int locx; // x location of card X int locy; // y location of card X}; X Xinline Card* CardView::card() { return theCard; } X Xinline int CardView::faceUp() { return up; } X Xinline void CardView::flip() { up = ! up; } X Xinline int CardView::x() { return locx; } X Xinline int CardView::y() { return locy; } X Xinline void CardView::moveTo(int sx, int sy) { locx = sx; locy = sy; } X X# endif / echo 'x - game.h' sed 's/^X//' > game.h << '/' X// interface description of game window for X// solitaire game X// X// written by tim budd, oregon state university, 1990 X// X X# ifndef SeenGameh X# define SeenGameh X X# include X# include X X# include "pile.h" X Xclass GameWindow : public MonoScene X{ Xpublic: X CardPile *discard; // the discard pile X CardPile *deck; // the umplayed card deck X X GameWindow(); X X void newGame(); // start a new game X void clearArea (int, int, int, int); X int suitCanAdd(Card*); X CardPile * suitAddPile(Card*); X int tableCanAdd(Card*); X CardPile * tableAddPile(Card*); X Xprotected: X CardPile * allPiles[13]; // all piles X CardPile * suitPiles[4]; // the pile of suits X CardPile * table[7]; // the playing table X X void virtual Handle (Event&); X void virtual Redraw(Coord,Coord,Coord,Coord); X}; X# endif / echo 'x - genericlist.h' sed 's/^X//' > genericlist.h << '/' X// X// Generic Data Structures X// Lists and Ordered Lists, Stacks and Queues, Sets X// Written by Tim Budd X// Oregon State University X// June 1991 X// X// copyrighted but can be freely redistributed as long as notice X// of authorship is retained. X X# ifndef genericlist X# define genericlist X X// ************************************************************************ X// Linked Lists X// ************************************************************************ X Xclass genericLink; // forward declaration X Xclass genericList { Xpublic: X ~genericList(); X X void first(); X void next(); X void removeCurrent(); X Xprotected: X // making the constructor procted insures subclassing X genericList(); X X // used by subclasses for implementation X void addToEnd(void *); X void addToFront(void *); X genericLink * currentValue(); X X // usually redefined by subclasses X void * current(); X int includes(void *); X virtual int match(void *, void *); X void * remove(void *); X Xprivate: X friend class genericListIterator; X genericLink * data; X genericLink * crnt; // used to iterate over lists X}; X Xinline genericList::genericList() X{ X data = 0; X crnt = 0; X} X Xinline genericLink * genericList::currentValue() X{ X return crnt; X} X Xinline void genericList::first() X{ X crnt = data; X} X X// ************************************************************************ X// List Iterators X// ************************************************************************ X Xclass genericListIterator { Xpublic: X void first(); X void next(); X Xprotected: X genericListIterator(genericList *); X X genericList * theList; X genericLink * ptr; X X void * current(); X}; X Xinline genericListIterator::genericListIterator(genericList * tl) X{ theList = tl; ptr = tl->data; } X Xinline void genericListIterator::first() X{ ptr = theList->data; } X X// ************************************************************************ X// Ordered Lists X// ************************************************************************ X Xclass genericOrderedList : public genericList { X Xprotected: X virtual int compare (void *, void *); X virtual int match(void *, void *); X void add(void *); X}; X X// ************************************************************************ X// Stacks and Queues X// ************************************************************************ X Xclass genericStack : private genericList { X Xprotected: X void push(void * v) X { genericList::addToFront(v); } X void * top(); X X genericList::current; X Xpublic: X void pop(); X X genericList::first; X genericList::next; X}; X Xclass genericQueue : public genericStack { X Xprotected: X void push(void * v) X { genericList::addToEnd(v); } X}; X X// ************************************************************************ X// Sets X// ************************************************************************ X Xclass genericSet : private genericList { Xprotected: X void add(void *); X X genericList::current; X genericList::includes; X genericList::remove; X genericList::match; X Xpublic: X genericList::first; X genericList::next; X}; X X# endif / echo 'x - link.h' sed 's/^X//' > link.h << '/' X// X// link.h - interface for class Link, representing linked lists of cards. X// X// written by tim budd, oregon state university, 1990 X// X# ifndef Linkh X# define Linkh X X// X// ------------------------------------------------ class Link X// Xclass Link X{ Xprotected: X Link * link; X void add(Link &); X Link * next(); X void setLink(Link *); X}; X Xinline void Link::setLink(Link * c) X{ link = c; } X Xinline Link * Link::next() X{ return link; } X Xinline void Link::add(Link & c) X{ c.setLink(next()); setLink(&c); } X X// X// ------------------------------------------------- class LinkedList X// Xclass LinkedList : private Link X{ Xpublic: X int isEmpty(); X void addFirst(Link &); X}; X Xinline int LinkedList::isEmpty() X{ return Link::next() == 0; } X Xinline void LinkedList::addFirst(Link & c) X{ Link::add(c); } X X# endif / echo 'x - pile.h' sed 's/^X//' > pile.h << '/' X// X// pile.h - interface for class Pile, representing a pile of cards X// uses instances of class Card X// X// written by tim budd, oregon state university, 1990 X// changed in June 1991 to use the generic data structures X// from the revised chapter 17. X// X X# ifndef Pileh X# define Pileh X X# include "cardview.h" X# include "genericlist.h" X X// X// ---------------------------- class CardPile X// Xclass CardPile : public genericStack X{ Xpublic: X CardPile(int, int); X X X void virtual addCard (CardView *); X int virtual canTake(Card *); X int contains (int, int); X CardView * current(); X void virtual display(); X void virtual initialize(); X CardView * removeCard (); X void virtual select(int, int); X CardView * top(); X CardView * nextToTop(); X Xprivate: X int x; // x location of pile X int y; // y location of pile X}; X Xinline CardPile::CardPile(int a, int b) : genericStack() { x = a; y = b; } X Xinline CardView * CardPile::top() X{ return (CardView *) genericStack::top(); } X Xinline CardView * CardPile::current() X{ return (CardView *) genericStack::current(); } X X// X// ---------------------------- class DealPile X// Xclass DealPile : public CardPile X{ Xpublic: X DealPile(); X X void shuffleTo (CardPile *); X}; X Xinline DealPile::DealPile() : CardPile(0, 0) { ; } X X// X// ---------------------------- class SuitPile X// X// X// SuitPile - the pile of suit cards X// at the top of the board X Xclass SuitPile : public CardPile X{ Xpublic: X int virtual canTake (Card *); X}; X X// X// ---------------------------- class TablePile X// X// Xclass TablePile : public CardPile X{ X public: X TablePile(int c, int x, int y) : CardPile(x, y) { column = c; } X X void virtual addCard (CardView *); X int virtual canTake (Card *); X void copyBuild (CardView *, CardPile *); X void virtual display (); X void virtual select (int, int); X void virtual initialize (); X Xprivate: X int column; // our column number X}; X X X// X// ---------------------------- class DeckPile X// X// X Xclass DeckPile : public CardPile X{ Xpublic: X void virtual addCard (CardView *); X void virtual initialize (); X void virtual select (int, int); X}; X X// X// ---------------------------- class DiscardPile X// X// X Xclass DiscardPile : public CardPile X{ Xpublic: X void virtual addCard (CardView *); X void virtual select (int, int); X}; X X# endif / echo 'x - solitare.cc' sed 's/^X//' > solitare.cc << '/' X// X// solitaire game using Interviews interface X// X// written by tim budd, oregon state university, 1990 X// X X# include X# include X# include X# include X# include X# include X# include X X# include "game.h" X X# define BoardWidth 600 X# define BoardHeight 450 X XGameWindow *game; X Xextern "C" { Xvoid exit(); X} X X// The Quit button at the bottom of the screen halts game Xclass QuitButton : public PushButton X{ Xpublic: X QuitButton() : PushButton("quit", new ButtonState(false), true) {;} X void virtual Press() { exit(0); } X}; X X// The Start button at the bottom of the screen starts game Xclass StartButton : public PushButton X{ Xpublic: X StartButton() : PushButton("start", new ButtonState(false), true) {;} X void virtual Press() { game->newGame(); } X}; X XCanvas * drawField; // the drawing area for game XPainter * painter; // the object used to draw the cards XDealPile * newDeck; // the original unshuffled deck X X// X// the main program X// create a new game window X// map it onto the screen with two buttons at bottom X// start it up X// X Xint main (int argc, char ** argv) { X X World *world = new World("solitaire", argc, argv); X X game = new GameWindow; X X world->InsertApplication( new VBox(game, X new HBox(new QuitButton, new StartButton))); X X drawField = game->GetCanvas(); X X world->Run(); X} X X// X// initialize the game window X// XGameWindow::GameWindow(){ X int i, j, hight; X X // create a new shape for our drawing area X shape = new Shape; X shape->Rect(BoardWidth, BoardHeight); X shape->Rigid(hfil, hfil, vfil, vfil); X X // create a new sensor so that we can catch mouse down events X input = new Sensor; X input->Catch(DownEvent); X X // create a new painter for drawing X painter = new Painter; X X // now some game specific initialization X // create the original (unshuffled) deck X newDeck = new DealPile(); X for (i = 0; i < 4; i++) X for (j = 1; j <= 13; j++) X newDeck->addCard(new CardView(i, j)); X X // create suit piles X hight = BoardHeight - round(1.5*CardView::CardHeight); X // create the deck and discard piles X allPiles[0] = deck = new DeckPile(500, hight); X allPiles[1] = discard = new DiscardPile(400, hight); X // create suit piles X for (i = 0; i < 4; i++) X allPiles[i+2] = suitPiles[i] = X new SuitPile(30 + (round(1.4*CardView::CardWidth) * i), hight); X X X // create tableau X hight = BoardHeight - round(2.7*CardView::CardHeight); X for (i = 0; i < 7; i++) X allPiles[i+6] = table[i] = X new TablePile(i, 10 + (round(1.2*CardView::CardWidth) * i), X hight); X X} X X// X// start up a new game X// Xvoid GameWindow::newGame() X{ int i; X X // initialize all the piles X for (i = 0; i < 13; i++) X allPiles[i]->initialize(); X X // then redraw the game window X Draw(); X} X X// X// redraw the window X// Xvoid GameWindow::Redraw(Coord a, Coord b, Coord c, Coord d) X{ int i; X X // first clear the entire playing area X clearArea(0,0, BoardWidth, BoardHeight); X X // then display the piles X for (i = 0; i < 13; i++) X allPiles[i]->display(); X} X X// X// handle a mouse down event in the game window X// Xvoid GameWindow::Handle (Event& e) X{ int i; X X // we are only interested in mouse down events X if (e.eventType != DownEvent) return; X X for (i = 0; i < 13; i++) X if (allPiles[i]->contains(e.x, e.y)) { X allPiles[i]->select(e.x, e.y); X return; X } X return; X} X X// X// see if any of the suit piles can add a specific card X// Xint GameWindow::suitCanAdd(Card *aCard) X{ int i; X X for (i = 0; i < 4; i++) X if (suitPiles[i]->canTake(aCard)) return 1; X return 0; X} X X// X// see if any of the table piles can add a specific card X// Xint GameWindow::tableCanAdd(Card *aCard) X{ int i; X X for (i = 0; i < 7; i++) X if (table[i]->canTake(aCard)) return 1; X return 0; X} X X// X// return which of the suit piles can add a card X// XCardPile *GameWindow::suitAddPile(Card *aCard) X{ int i; X X for (i = 0; i < 4; i++) X if (suitPiles[i]->canTake(aCard)) X return suitPiles[i]; X // hopefully this won't happen X return newDeck; X} X X// X// return which of the table piles can add a card X// XCardPile *GameWindow::tableAddPile(Card *aCard) X{ int i; X X for (i = 0; i < 7; i++) X if (table[i]->canTake(aCard)) X return table[i]; X // hopefully this won't happen X return newDeck; X} X X// X// clear out a given area in the game window X// Xvoid GameWindow::clearArea(int a, int b, int c, int d) X{ Color *fg, *bg; X X // first get the foreground and background colors X fg = painter->GetFgColor(); X bg = painter->GetBgColor(); X // then reverse them X painter->SetColors(bg, fg); X // then draw a filled rectangle X painter->FillRect(drawField, a, b, c, d); X // then restore the colors X painter->SetColors(fg, bg); X} / echo 'x - cardview.cc' sed 's/^X//' > cardview.cc << '/' X// X// card.c - implementation of card behavior X// X// written by tim budd, oregon state university, 1990 X// X X# include "cardview.h" X# include X# include X X// the actual drawing is done using interview tools: Xextern Canvas * drawField; Xextern Painter * painter; X X// X// ---------------------------- class CardView X// X Xstatic char *suits[ ] = {"Heart", "Club", "Diamond", "Spade" }; X Xstatic char *ranks[ ] = {"blank", "Ace", "2", "3", "4", "5", "6", X "7", "8", "9", "10", "Jack", "Queen", "King" }; X X//const int CardView::CardWidth = 68; X//const int CardView::CardHeight = 75; X X// constructors XCardView::CardView(Card * c) X{ X theCard = c; X up = 0; X locx = locy = 0; X} X XCardView::CardView(int s, int c) X{ X theCard = new Card(s, c); X up = 0; X locx = locy = 0; X} X X// draw Xvoid CardView::draw() X{ X // erase the card and redraw it X erase(); X painter->Rect(drawField, x(), y(), x()+CardWidth, y()+CardHeight); X if (up) { // draw the card face up X painter->MoveTo(x()+12, y()+round(CardHeight*0.80)); X painter->Text(drawField, suits[theCard->suit()]); X painter->MoveTo(x()+15, y()+round(CardHeight*0.60)); X painter->Text(drawField, ranks[theCard->rank()]); X } X else { int n; // draw the card face down X n = x()+round(CardWidth*0.3); X painter->Line(drawField, n, y()+5, n, y()+CardHeight-10); X n = x()+round(CardWidth*0.7); X painter->Line(drawField, n, y()+5, n, y()+CardHeight-10); X n = y()+round(CardHeight*0.3); X painter->Line(drawField, x()+5, n, x()+CardWidth-10, n); X n = y()+round(CardHeight*0.7); X painter->Line(drawField, x()+5, n, x()+CardWidth-10, n); X } X} X X// erase Xvoid CardView::erase() X{ Color *fg, *bg; X X // first get the foreground and background colors X fg = painter->GetFgColor(); X bg = painter->GetBgColor(); X // then reverse them X painter->SetColors(bg, fg); X // then draw a filled rectangle X painter->FillRect(drawField, x(), y(), x()+CardWidth, y()+CardHeight); X // then restore the colors X painter->SetColors(fg, bg); X} X X// includes Xint CardView::includes(int a, int b) X{ X return (a >= x()) && (a <= x() + CardHeight) && (b >= y()) && X (b <= y() + CardWidth); X} / echo 'x - pile.cc' sed 's/^X//' > pile.cc << '/' X// X// pile.c -- implementation for class CardPile X// X// X// written by tim budd, oregon state university, 1990 X// revised June 1991 X// X X# include "game.h" X Xextern GameWindow * game; Xextern DealPile * newDeck; X X// X// ---------------------------- class CardPile X// X Xvoid CardPile::addCard(CardView *aCard) X{ X if (aCard != 0) { X genericStack::push(aCard); X aCard->moveTo(x, y); X } X} X Xint CardPile::canTake(Card *aCard) X{ X return 0; X} X Xint CardPile::contains(int a, int b) X{ X for (first(); current(); next()) X if (current()->includes(a, b)) X return 1; X return 0; X} X Xvoid CardPile::display() X{ X if (top() == 0) X game->clearArea(x, y, x+CardView::CardWidth, y+CardView::CardHeight); X else X top()->draw(); X} X Xvoid CardPile::initialize() X{ X // make sure pile is empty by repeately popping X first(); X while (current()) { X pop(); X first(); X } X} X XCardView * CardPile::removeCard() X{ CardView * p; X X if (top() == 0) X return 0; X p = top(); X pop(); X return p; X} X Xvoid CardPile::select(int x, int y) X{ /* do nothing */ ; } X XCardView * CardPile::nextToTop() X{ X // return next to top card, if there is one X first(); X if (current()) { X next(); X return current(); X } X return 0; X} X X// X// ---------------------------- class DealPile X// X Xextern "C" { int rand(); } X Xvoid DealPile::shuffleTo(CardPile *aPile) X{ X int max, limit, i; X X // first see how many cards we have X // and make sure they are all face down X for (max = 0, first(); current(); next()) { X max++; X if (current()->faceUp()) current()->flip(); X } X X // then pull them out, randomly, one at a time X for (; max > 0; max--) { X limit = ((rand() >> 3) % max) + 1; X first(); X for (i = 1; i <= limit; ) { X while (current()->faceUp()) next(); X i += 1; X if (i <= limit) next(); X } X // create a copy so it can X // be independently manipuated X aPile->addCard(new CardView(current()->card())); X current()->flip(); X } X} X X// X// ---------------------------- class DeckPile X// X Xvoid DeckPile::initialize() X{ X CardPile::initialize(); X newDeck->shuffleTo(this); X} X Xvoid DeckPile::addCard(CardView *c) X{ X if (c->faceUp()) X c->flip(); X CardPile::addCard(c); X} X Xvoid DeckPile::select(int x, int y) // turn over a new card X{ CardView *c; X X c = removeCard(); X if (c) { X (game->discard)->addCard(c); X display(); X (game->discard)->display(); X } X} X X// X// ---------------------------- class DiscardPile X// X Xvoid DiscardPile::addCard(CardView *c) X{ X if (!(c->faceUp())) X c->flip(); X CardPile::addCard(c); X} X Xvoid DiscardPile::select(int x, int y) // play the current face card X{ CardPile *aPile; X X if (top() == 0) return; X // see if we can move it to a suit pile X if (game->suitCanAdd(top()->card())) { X aPile = game->suitAddPile(top()->card()); X aPile->addCard(removeCard()); X display(); X aPile->display(); X return; X } X // else see if we can move to a table pile X if (game->tableCanAdd(top()->card())) { X aPile = game->tableAddPile(top()->card()); X aPile->addCard(removeCard()); X display(); X aPile->display(); X return; X } X // else do nothing X} X X// X// ---------------------------- class SuitPile X// X Xint SuitPile::canTake(Card *aCard) X{ X if (top() == 0) { // we're empty, can take an ace X if (aCard->rank() == 1) return 1; X return 0; X } X if ((top()->card())->suit() != aCard->suit()) X return 0; X if (((top()->card())->rank() + 1) == aCard->rank()) X return 1; X return 0; X} X X// X// ---------------------------- class TablePile X// X Xvoid TablePile::initialize() X{ int i; X X // put the right number of cards on the table X CardPile::initialize(); X for (i = 0; i <= column; i++) X addCard((game->deck)->removeCard()); X // flip the last one X if (top() != 0) { X top()->flip(); X } X} X Xvoid TablePile::addCard(CardView *aCard) X{ int tx, ty; X X if (top() == 0) X CardPile::addCard(aCard); X else { X tx = top()->x(); X ty = top()->y(); X // figure out where to place the card X if (top()->faceUp() && nextToTop() && nextToTop()->faceUp()) X ; // do nothing, place on top of top card X else X // else move it down a bit X ty -= round(CardView::CardHeight * 0.5); X CardPile::addCard(aCard); X aCard->moveTo(tx, ty); X } X} X Xint TablePile::canTake(Card *aCard) X{ X if (top() == 0) { // can take kings on an empty pile X if (aCard->rank() == 13) return 1; X return 0; X } X // see if colors are different X if ((top()->card())->color() == aCard->color()) return 0; X // see if numbers are legal X if (((top()->card())->rank() - 1) == aCard->rank()) X return 1; X return 0; X} X Xvoid TablePile::copyBuild(CardView *c, CardPile *aPile) X{ CardView *d; X X top()->erase(); X d = removeCard(); X display(); X if (c != d) copyBuild(c, aPile); X aPile->addCard(d); X aPile->display(); X} X Xstatic void stackDisplay(CardPile *pile) X{ X CardView * p = pile->current(); X if (p) { X pile->next(); X stackDisplay(pile); X p->erase(); X p->draw(); X } X} X Xvoid TablePile::display() X{ Card *p; X X // zero or one cards, can't do any better X if (top() == 0) X CardPile::display(); X // otherwise half display all the covered cards X else { X first(); X stackDisplay(this); X } X} X Xvoid TablePile::select(int x, int y) X{ Card *c; X int i; X X // no cards, do nothing X if (top() == 0) return; X X // if top card is not flipped, flip it now X if (! top()->faceUp()) { X top()->erase(); X top()->flip(); X top()->draw(); X return; X } X X // if it was to top card, see if we can move it X if (top()->includes(x, y)) { X // see if we can move it to a suit pile X if (game->suitCanAdd(top()->card())) { X copyBuild(top(), game->suitAddPile(top()->card())); X return; X } X // else see if we can move to a table pile X // but only if it is not part of pile X if ((nextToTop() == 0) || ! ((nextToTop()->faceUp()))) X if (game->tableCanAdd(top()->card())) { X copyBuild(top(), game->tableAddPile(top()->card())); X return; X } X } X X // else see if we can move a pile X for (first(); current(); next()) X if (current()->faceUp() && current()->includes(x, y)) { X if (game->tableCanAdd(current()->card())) { X copyBuild(current(), X game->tableAddPile(current()->card())); X } X return; X } X // else do nothing X} / echo 'x - genericlist.cc' sed 's/^X//' > genericlist.cc << '/' X// X// Generic Data Structures X// Lists and Ordered Lists, Stacks and Queues, Sets X// Written by Tim Budd X// Oregon State University X// June 1991 X// X// X// copyrighted but can be freely redistributed as long as notice X// of authorship is retained. X X# include "genericlist.h" X X// ************************************************************************ X// generic Linked Lists X// ************************************************************************ X Xclass genericLink { Xpublic: X void * element; X genericLink * next; X X genericLink (void *, genericLink * n = 0); X ~genericLink(); X X void addToFront(void *); X void addToEnd(void *); X genericLink * remove(void *); X}; X Xinline genericLink::genericLink(void *v, genericLink * n) X{ X element = v; X next = n; X} X XgenericLink::~genericLink() X{ X // delete the sequence of link fields X if (next) X delete next; X} X Xvoid genericLink::addToFront(void * v) X{ X next = new genericLink(v, next); X} X Xvoid genericLink::addToEnd(void * v) X{ X if (next) X next->addToEnd(v); X else X next = new genericLink(v); X} X XgenericLink * genericLink::remove(void * v) X{ X if (this == v) X return next; X if (next) X next = next->remove(v); X return this; X} X XgenericList::~genericList() X{ X // get rid of the links X if (data) X delete data; X} X Xvoid genericList::addToFront(void *v) X{ X data = new genericLink(v, data); X} X Xvoid genericList::addToEnd(void * v) X{ X if (data) X data->addToEnd(v); X else X data = new genericLink(v); X} X Xvoid * genericList::current() X{ X if (crnt) X return crnt->element; X return 0; X} X Xint genericList::includes(void * v) X{ X for (first(); current(); next()) X if (match(current(), v)) X return 1; X return 0; X} X Xint genericList::match(void * x, void * y) X{ X return x == y; X} X Xvoid genericList::removeCurrent() X{ X if (data == crnt) // its the first element X data = crnt->next; X else X data = data->remove(crnt); X X // now delete the link structure X // parent class is responsible for deleting value portion X X crnt->next = 0; X delete crnt; X crnt = 0; X} X Xvoid * genericList::remove(void * v) X{ X for (first(); current(); next()) X if (match(current(), v)) { X // we return the element we found X // which may not be same as arg X void * fv = current(); X removeCurrent(); X return fv; X } X return 0; X} X Xvoid genericList::next() X{ X crnt = crnt->next; X} X X// ************************************************************************ X// List Iterators X// ************************************************************************ X Xvoid genericListIterator::next() X{ ptr = ptr->next; } X Xvoid * genericListIterator::current() X{ X if (ptr) X return ptr->element; X return 0; X} X X// ************************************************************************ X// generic Ordered Lists X// ************************************************************************ X Xint genericOrderedList::compare(void * a, void * b) X{ X // return equal X return 0; X} X Xint genericOrderedList::match(void * a, void * b) X{ X return 0 == compare(a, b); X} X Xvoid genericOrderedList::add(void * v) X{ X // manipulate the list entirely through links X first(); X X // case 1, no elements or first element X if ((! current()) || (compare(v, current()) < 0)) X addToFront(v); X X // case 2, somewhere in list X else { X genericLink * p = currentValue(); X for (next(); current(); next()) { X if (compare(v, current()) < 0) { X p->addToFront(v); X break; X } X p = currentValue(); X } X X // case 3, add to end of list X if (! current()) X p->addToFront(v); X } X} X X// ************************************************************************ X// generic Stacks and Queues X// ************************************************************************ X X// X// the following all operate by positioning the current pointer X// then manipulating the current element X// X Xvoid * genericStack::top() X{ X first(); X return current(); X} X Xvoid genericStack::pop() X{ X first(); X if (current()) X removeCurrent(); X} X X// ************************************************************************ X// Sets X// ************************************************************************ X Xvoid genericSet::add(void * v) X{ X if (! includes(v)) X genericList::addToFront(v); X} / echo 'Part 01 of newsolit complete.' exit