[comp.sources.x] v11i062: seahaven - solitaire card game, Part02/02

weissman%pianoforte.esd.sgi.com@SGI.COM (Terry Weissman) (02/13/91)

Submitted-by: Terry Weissman <weissman%pianoforte.esd.sgi.com@SGI.COM>
Posting-number: Volume 11, Issue 62
Archive-name: seahaven/part02

#!/bin/sh
# to extract, remove the header and type "sh filename"
if `test ! -s ./auto.h`
then
echo "writing ./auto.h"
cat > ./auto.h << '\Rogue\Monster\'
struct SolutionLogRec {
    int rank;
    int suit;
    int dest;			// 0-9 = stack, -99 = space, other = king
    SolutionLogRec *next;
};
typedef struct SolutionLogRec *SolutionLog;

extern int AutoPlay();

extern SolutionLog solutionhead;
\Rogue\Monster\
else
  echo "will not over write ./auto.h"
fi
if `test ! -s ./card.C`
then
echo "writing ./card.C"
cat > ./card.C << '\Rogue\Monster\'
/*
 * Author:  Terry Weissman
 *          weissman@sgi.com
 */

#include "seahaven.h"

extern char *card_bits[52];

struct WindowCardRec {
    Window window;
    Card card;
};

typedef struct WindowCardRec *WindowCard;

static WindowCardRec windowcard[100];
static int numwindowcard = 0;

static GC highlightgc;

static void RegisterWindow(Card card, Window window) {
    int i;
    if (windowcard == 0 || window > windowcard[numwindowcard - 1].window) {
	windowcard[numwindowcard].window = window;
	windowcard[numwindowcard].card = card;
	numwindowcard++;
	return;
    }
    for (i=0 ; i<numwindowcard ; i++) {
	if (windowcard[i].window > window) {
	    for (int j = numwindowcard ; j > i ; j--) {
		windowcard[j] = windowcard[j-1];
	    }
	    windowcard[i].window = window;
	    windowcard[i].card = card;
	    numwindowcard++;
	    return;
	}
    }
    Punt("Bug in RegisterWindow!");
}


Card WindowToCard(Window w) {
    int l, h, i;
    l = 0;
    h = numwindowcard;
    while (l < h) {
	i = (l + h) / 2;
	if (w == windowcard[i].window) return windowcard[i].card;
	if (w > windowcard[i].window) l = i + 1;
	else h = i;
    }
    if (w == windowcard[i].window) return windowcard[i].card;
    return NULL;
}



CardRec::CardRec(int s, int v, unsigned long fore, unsigned long back,
		 char *bitmap) {
    suit = s;
    value = v;
    XSetWindowAttributes attributes;
    long valuemask = CWEventMask | CWBackPixmap;
    attributes.event_mask =
	ButtonPressMask | ButtonReleaseMask | ButtonMotionMask;
    attributes.background_pixmap =
	XCreatePixmapFromBitmapData(dpy, toplevel, bitmap,
				    CARDWIDTH, CARDHEIGHT, fore, back,
				    DefaultDepth(dpy, screen));
    window = XCreateWindow(dpy, toplevel, v * CARDWIDTH, s * CARDHEIGHT,
			   CARDWIDTH, CARDHEIGHT, 0, (int) CopyFromParent,
			   InputOutput, (Visual *) CopyFromParent,
			   valuemask, &attributes);
    XMapWindow(dpy, window);
    RegisterWindow(this, window);
}


Stack CardRec::getStack() {
    return stack;
}

// single stacks are symmetric for saving purposes
Stack CardRec::getFoldedStack() {
    if (stack ==singlestack[0] || stack == singlestack[1]
		    || stack == singlestack[2] || stack == singlestack[3])
      return singlestack[0];
    else
      return stack;
}

int CardRec::getSuit() {
    return suit;
}

int CardRec::getValue() {
    return value;
}

int CardRec::getX() {
    return x;
}

int CardRec::getY() {
    return y;
}

// single stacks are symmetric for saving purposes
int CardRec::getFoldedY() {
    if (stack ==singlestack[0] || stack == singlestack[1]
		    || stack == singlestack[2] || stack == singlestack[3])
      return 0;
    else
      return y;
}

void CardRec::setLoc(int newx, int newy) {
    if (x != newx || y != newy) {
	x = newx;
	y = newy;
	XMoveWindow(dpy, window, x, y);
    }
}


void CardRec::raise() {
    XRaiseWindow(dpy, window);
}


void CardRec::raiseAbove(Card c) {
    XWindowChanges values;
    values.sibling = c->window;
    values.stack_mode = Above;
    XConfigureWindow(dpy, window, CWSibling | CWStackMode, &values);
}


void CardRec::raiseBelow(Card c) {
    XWindowChanges values;
    values.sibling = c->window;
    values.stack_mode = Below;
    XConfigureWindow(dpy, window, CWSibling | CWStackMode, &values);
}

void CardRec::setStack(Stack s) {
    stack = s;
}


void CardRec::highlight() {
    XFillRectangle(dpy, window, highlightgc, 0, 0, CARDWIDTH, CARDHEIGHT);
}

void CardRec::repaint() {
    XClearWindow(dpy, window);
}



Bool CardHandleEvent(XEvent *event) {
    Card card = WindowToCard(event->xany.window);
    if (!card || event->type == KeyPress) return False;
    if (event->type == ButtonPress) {
	if (event->xbutton.button > 1) {
	    int suit = card->getSuit();
	    int value =
		card->getValue() + ((event->xbutton.button == 3) ? 1 : -1);
	    if (value < 0 || value >= NUMVALUES) return True;
	    cards[suit][value]->highlight();
	    XEvent ev;
	    do {
		GetInterestingEvent(&ev);
	    } while (ev.type != ButtonRelease);
	    cards[suit][value]->repaint();
	    return True;
	}
	Card list[20];
	int origx[20], origy[20];
	int num = 0;
	int i;
	for (; card ; card = card->getStack()->getCardAbove(card)) {
	    origx[num] = card->getX();
	    origy[num] = card->getY();
	    list[num++] = card;
	}
	list[num-1]->raise();
	for (i=num-2 ; i>=0 ; i--) {
	    list[i]->raiseBelow(list[i+1]);
	}
	Bool abort = False;
	for (;;) {
	    XEvent ev;
	    GetInterestingEvent(&ev);
	    if (ev.type == ButtonPress) {
		abort = True;
		break;
	    }
	    while (ev.type == MotionNotify && XPending(dpy)) {
		XEvent ev2;
		XPeekEvent(dpy, &ev2);
		if (ev2.type == Expose) {
		    XNextEvent(dpy, &ev2);
		    if (ev2.xexpose.count == 0) score->repaint();
		    continue;
		}
		if (ev2.type != MotionNotify) break;
		GetInterestingEvent(&ev);
	    }
	    if (ev.type == MotionNotify || ev.type == ButtonRelease) {
		for (i=0 ; i<num ; i++) {
		    list[i]->setLoc
			(origx[i] + ev.xbutton.x_root - event->xbutton.x_root,
			 origy[i] + ev.xbutton.y_root - event->xbutton.y_root);
		}
		if (ev.type == ButtonRelease) {
		    Stack stack =
			StackFromPoint(list[0]->getX(), list[0]->getY());
		    if (!stack || stack == list[0]->getStack()) {
			abort = True;
		    }
		    if (!abort && stack->getType() == Single) {
			if (NumAvailableSingles() < num) abort = True;
			if (!abort && !stack->addCard(list[num-1])) {
			    abort = True;
			}
			if (!abort) {
			    for (i=num-2 ; i>=0 ; i--) {
				GetAvailableSingle()->addCard(list[i]);
			    }
			    AutoMoves();
			    UndoBoundary();
			    break;
			}
		    }
		    for (i=1 ; i<num ; i++) {
			if (list[i]->getSuit() != list[i-1]->getSuit() ||
			   list[i]->getValue() != list[i-1]->getValue() - 1) {
			    abort = True;
			    break;
			}
		    }
		    if (NumAvailableSingles() < num - 1) abort = True;
		    if (!abort && num > 1) {
			Card top = stack->getTopCard();
			if ((top == NULL &&
			     list[0]->getValue() != NUMVALUES - 1)
			    || (top != NULL &&
				(top->getSuit() != list[0]->getSuit() ||
				 top->getValue() !=
				     list[0]->getValue() + 1))) {
			    abort = True;
			} else {
			    for (i=num-1 ; i>0 ; i--) {
				GetAvailableSingle()->addCard(list[i],
							      DontMove);
			    }
			}
		    }
		    if (!abort && !stack->addCard(list[0])) abort = True;

		    if (!abort) {
			for (i=1 ; i<num ; i++) {
			    if (!stack->addCard(list[i])) {
				Punt("Bug in CardHandleEvent!");
			    }
			}
			AutoMoves();
			UndoBoundary();
		    }
		    break;
		}
	    }
	}
	if (abort) {
	    for (i=0 ; i<num ; i++) list[i]->setLoc(origx[i], origy[i]);
	}
    }
    return True;
}
    
    


void CardInit() {
    unsigned long red = GetColor("red", BlackPixel(dpy, screen));
    unsigned long white = GetColor("white", WhitePixel(dpy, screen));
    unsigned long black = GetColor("black", BlackPixel(dpy, screen));

    for (int s=0 ; s<NUMSUITS ; s++) {
	for (int v=0 ; v<NUMVALUES ; v++) {
	    cards[s][v] = new CardRec(s, v, (s >= 2) ? black : red, white,
				      card_bits[s * 13 + v]);
	}
    }

    highlightgc = XCreateGC(dpy, toplevel, 0, NULL);
    XSetForeground(dpy, highlightgc,
		   GetColor("blue", BlackPixel(dpy, screen)));
}
\Rogue\Monster\
else
  echo "will not over write ./card.C"
fi
if `test ! -s ./main.C`
then
echo "writing ./main.C"
cat > ./main.C << '\Rogue\Monster\'
/*
 * Author:  Terry Weissman
 *          weissman@sgi.com
 */

#define MAIN


#include "seahaven.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xutil.h>


void Punt(char *str) {
    fprintf(stderr, "%s: %s\n", progname, str);
    exit(1);
}

static void Usage() {
    fprintf(stderr, "Usage: %n [-d display] [-speedup speedfactor]\n",
	    progname);
    exit(1);
}


main(int argc, char **argv) {
    char *displayname = NULL;
    Bool sync = False;
    int i;

    progname = argv[0];

    speedup = 6;

    for (i=1 ; i<argc ; i++) {
	if (i < argc - 1 && (strcmp(argv[i], "-d") == 0 ||
			     strcmp(argv[i], "-display") == 0)) {
	    displayname = argv[++i];
	} else if (strcmp(argv[i], "-sync") == 0) {
	    sync = True;
	} else if (strcmp(argv[i], "-speedup") == 0) {
	    speedup = atoi(argv[++i]);
	    if (speedup <= 0) Usage();
	} else {
	    Usage();
	}
    }

    inautoplay = False;
    score = NULL;

    dpy = XOpenDisplay(displayname);
    if (!dpy) {
	Punt("Can't open display.");
    }
    screen = DefaultScreen(dpy);
    cmap = DefaultColormap(dpy, screen);
    XSynchronize(dpy, sync);

    Visual *visual = DefaultVisual(dpy, screen);

    hascolor = (visual->c_class != StaticGray &&
		visual->c_class != GrayScale && visual->bits_per_rgb > 1);

    backpixel = GetColor("forestgreen", WhitePixel(dpy, screen));

    XSetWindowAttributes attributes;
    long valuemask = CWEventMask | CWBackPixel;
    attributes.event_mask = KeyPressMask;
    attributes.background_pixel = backpixel;

    toplevel = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0,
			     GAMEWIDTH, GAMEHEIGHT, 1, (int) CopyFromParent,
			     InputOutput, (Visual *) CopyFromParent,
			     valuemask, &attributes);
    XSetIconName(dpy, toplevel, "Seahaven");
    XStoreName(dpy, toplevel, "Seahaven Towers");

    font = XLoadQueryFont
	(dpy, "-*-helvetica-medium-r-normal--*-120-*-*-p-*-iso8859-1");
    if (font == NULL) font = XLoadQueryFont(dpy, "fixed");
    if (font == NULL) Punt("Can't find a font!");

    CardInit();
    StackInit();

    score = new ScoreRec();

    int y = GAMEHEIGHT - font->ascent - font->descent - 10;
    int width, width2, width3;
    Window undobutton = CreateButtonWindow("Undo (U)", 10, y,
					   SouthWestGravity, &width);
    Window redobutton = CreateButtonWindow("Redo (R)", 10 + width + 5, y,
					   SouthWestGravity, &width2);
    Window autobutton = CreateButtonWindow("Autoplay",
    					   10 + width + 5 + width2 + 5, y,
					   SouthWestGravity, NULL);
    Window quitbutton = CreateButtonWindow("Quit", 0, 0,
					   SouthEastGravity, &width);
    Window newgamebutton = CreateButtonWindow("New Game", 0, 0,
					      SouthEastGravity, &width2);
    Window restartbutton = CreateButtonWindow("Restart", 0, 0,
					      SouthEastGravity, &width3);
    XMoveWindow(dpy, quitbutton, GAMEWIDTH - width - 10, y);
    XMoveWindow(dpy, newgamebutton, GAMEWIDTH - width - width2 - 20, y);
    XMoveWindow(dpy, restartbutton,
		GAMEWIDTH - width - width2 - width3 - 30, y);

    XMapWindow(dpy, toplevel);

    for (;;) {
	XEvent event;
	GetInterestingEvent(&event);
	if (!CardHandleEvent(&event)) {
	    if (event.type == KeyPress) {
		char buf[100];
		int length;
		length = XLookupString((XKeyEvent *)&event, buf, 100, NULL,
				       NULL);
		for (i=0 ; i<length ; i++) {
		    switch(buf[i]) {
		      case 'u':
		      case 'U':
		      case 'z':
		      case 'Z':
			DoUndo();
			break;
		      case 'r':
		      case 'R':
			DoRedo();
			break;
		      case '\016':
			NewGame();
			break;
		      case '\003':
			XUnmapWindow(dpy, toplevel);
			XFlush(dpy);
			exit(0);
			break;
		    }
		}
	    } else if (event.type == ButtonPress) {
		Window w = event.xbutton.window;
		if (w == undobutton) DoUndo();
		else if (w == redobutton) DoRedo();
		else if (w == restartbutton) DoRestart();
		else if (w == autobutton) DoAutoPlay();
		else if (w == newgamebutton) NewGame();
		else if (w == quitbutton) {
		    XUnmapWindow(dpy, toplevel);
		    XFlush(dpy);
		    exit(0);
		}
	    }
	}
    }
}
\Rogue\Monster\
else
  echo "will not over write ./main.C"
fi
if `test ! -s ./patchlevel.h`
then
echo "writing ./patchlevel.h"
cat > ./patchlevel.h << '\Rogue\Monster\'
#define PATCHLEVEL 0
\Rogue\Monster\
else
  echo "will not over write ./patchlevel.h"
fi
if `test ! -s ./score.C`
then
echo "writing ./score.C"
cat > ./score.C << '\Rogue\Monster\'
/*
 * Author:  Terry Weissman
 *          weissman@sgi.com
 */

#include "seahaven.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>		// For getenv()

ScoreRec::ScoreRec() {
    int x = 10;
    int y = GAMEHEIGHT - 20 - 5 * (font->ascent + font->descent);
    XSetWindowAttributes attributes;
    long valuemask = CWEventMask | CWBackPixel | CWWinGravity;
    attributes.event_mask = ExposureMask;
    attributes.background_pixel = GetColor("forestgreen",
					   WhitePixel(dpy, screen));
    attributes.win_gravity = SouthWestGravity;
    window = XCreateWindow(dpy, toplevel, x, y,
			   GAMEWIDTH, GAMEHEIGHT, 0, (int) CopyFromParent,
			   InputOutput, (Visual *) CopyFromParent,
			   valuemask, &attributes);
    XLowerWindow(dpy, window);
    XMapWindow(dpy, window);


    sprintf(savefile, "%s/.seahavensave", getenv("HOME"));
    FILE *fid = fopen(savefile, "r");
    if (fid) {
	fscanf(fid, "%d %d %d %d %d %d\n", &wins, &losses, &streak,
	       &maxwinstreak, &maxlosestreak, &wonlast);
	for (int i=0 ; i<52 ; i++) {
	    int suit, value;
	    fscanf(fid, "%d %d\n", &suit, &value);
	    deck[i] = cards[suit][value];
	}
	fclose(fid);
	LoadStacks(deck);
    } else {
	wins = 0;
	streak = 0;
	losses = 0;
	maxwinstreak = 0;
	maxlosestreak = 0;
	wonlast = True;
	NewGame();
    }
    gc = XCreateGC(dpy, window, 0, NULL);
    XSetForeground(dpy, gc, GetColor("black", BlackPixel(dpy, screen)));
    XSetFont(dpy, gc, font->fid);
    woncurgame = lostcurgame = False;
    message = "";
}



void ScoreRec::printLine(char *str, int value, char *plural) {
    char buf[200];
    cury += font->ascent + font->descent;
    sprintf(buf, str, value, value == 1 ? "" : plural);
    if (buf[0]) XDrawString(dpy, window, gc, curx, cury, buf, strlen(buf));
}



void ScoreRec::repaint(Bool erasefirst) {
    curx = 0;
    cury = 0;
    if (erasefirst) XClearWindow(dpy, window);
    printLine("%5d win%s", wins);
    printLine("%5d loss%s", losses, "es");
    printLine("%5d game%s played", wins + losses);
    curx = GAMEWIDTH / 2;
    cury = 0;
    if (streak > 0) {
	if (wonlast) printLine("%5d game winning streak", streak);
	else printLine("%5d game losing streak", streak);
    }
    if (maxwinstreak > 0) {
	printLine("%5d game%s in longest winning streak", maxwinstreak);
    }
    if (maxlosestreak > 0) {
	printLine("%5d game%s in longest losing streak", maxlosestreak);
    }
    curx /= 2;
    printLine(message);
}


void ScoreRec::wonGame() {
    if (!woncurgame && !lostcurgame) {
	woncurgame = True;
	wins++;
	if (!wonlast) streak = 0;
	streak++;
	if (maxwinstreak < streak) maxwinstreak = streak;
	wonlast = True;
	message = "";
	repaint(True);
    }
}



void ScoreRec::lostGame() {
    if (!woncurgame && !lostcurgame) {
	lostcurgame = True;
	losses++;
	if (wonlast) streak = 0;
	streak++;
	if (maxlosestreak < streak) maxlosestreak = streak;
	wonlast = False;
	message = "";
	repaint(True);
    }
}


void ScoreRec::newGame() {
    woncurgame = lostcurgame = False;
    setMessage("");
}


Bool ScoreRec::getGameWonOrLost() {
    return woncurgame || lostcurgame;
}


void ScoreRec::saveGameBegin() {
    curx = 0;
}

void ScoreRec::saveGameCard(Card c) {
    deck[curx++] = c;
}

void ScoreRec::saveGameEnd() {
    if (curx != 52) Punt("Bug in ScoreRec::saveGameEnd!");
    FILE *fid = fopen(savefile, "w");
    if (!fid) Punt("Can't open file in ScoreRec::saveGameEnd!");
    fprintf(fid, "%d %d %d %d %d %d\n", wins, losses, streak,
	    maxwinstreak, maxlosestreak, wonlast);
    for (int i=0 ; i<52 ; i++) {
	fprintf(fid, "%d %d\n", deck[i]->getSuit(), deck[i]->getValue());
    }
    fclose(fid);
}


void ScoreRec::setMessage(char *msg) {
    if (strcmp(message, msg)) {
	char *oldmsg = message;
	message = msg;
	repaint(*oldmsg != 0);
    }
}
\Rogue\Monster\
else
  echo "will not over write ./score.C"
fi
if `test ! -s ./seahaven.h`
then
echo "writing ./seahaven.h"
cat > ./seahaven.h << '\Rogue\Monster\'
/*
 * Author:  Terry Weissman
 *          weissman@sgi.com
 */

#define NeedFunctionPrototypes 1


#include <X11/Xlib.h>

#ifndef NULL
#define	NULL 0
#endif NULL

#ifdef MAIN
#define global
#else
#define global extern
#endif


typedef class StackRec *Stack;
typedef class CardRec *Card;

class CardRec {
  public:
    CardRec(int suit, int value, unsigned long fore, unsigned long back,
	    char *bitmap);
//    Window getWindow();
    Stack getStack();
    int getSuit();
    int getValue();
    int getX();
    int getY();
    Stack getFoldedStack();
    int getFoldedY();
    void setLoc(int, int);
    void raise();
    void raiseAbove(Card);
    void raiseBelow(Card);
    void setStack(Stack);	// To be called only by StackRec::addCard
    void highlight();
    void repaint();
  private:
    int suit;
    int value;
    Window window;
    int x, y;
    Stack stack;
};


enum StackType {Single, Play, Done};
enum AnimType {Normal, Animate, DontMove};

class StackRec {
  public:
    StackRec(int x, int y);
    virtual void clear();
    virtual int getX();
    virtual int getY();
    virtual Card getTopCard();
    virtual Card getCardAbove(Card);
    virtual Card popCard();
    virtual Bool addCard(Card, AnimType animate = Normal);
				// Return TRUE iff successful.
    virtual void repositionAll();
    virtual int getStackingHeight();
    virtual StackType getType();
  protected:
    int x, y;
    int numcards;
    Card cards[20];
  private:
    friend class Stack_Iterator;
};

class Stack_Iterator {
  public:
    Stack_Iterator(Stack s) { stack = s; i = s->numcards; }
    Card operator()() {
      if (--i < 0)
        return 0;
      else
        return stack->cards[i];
    }
  private:
    Stack stack;
    int i;	// current index
};


class ScoreRec {
  public:
    ScoreRec();
    void repaint(Bool erasefirst = False);
    void wonGame();
    void lostGame();
    void newGame();
    Bool getGameWonOrLost();
    void saveGameBegin();
    void saveGameCard(Card);
    void saveGameEnd();
    void setMessage(char *);
  private:
    void printLine(char *, int value = 0, char *plural = "s");
    Window window;
    GC gc;
    int wins, losses, streak, maxwinstreak, maxlosestreak;
    int wonlast;		// Should be Bool, but this makes save easier
    int curx, cury;
    char savefile[512];
    Card deck[52];
    Bool woncurgame;
    Bool lostcurgame;
    char *message;
};

typedef struct ScoreRec *Score;

class UndoListRec {
  public:
    UndoListRec();
    void clear();
    void add(Card, Stack);
    void addBoundary();
    void doUndo();
    Bool isEmpty();
  private:
    int num;
    int max;
    Card *cards;
    Stack *stacks;
};

typedef class UndoListRec *UndoList;

static const int NUMSUITS = 4;
static const int NUMVALUES = 13;

static const int CARDWIDTH = 48;
static const int CARDHEIGHT = 66;

static const int GAMEWIDTH = 700;
static const int GAMEHEIGHT = 550;

static const int NUMPLAYSTACK = 10;
static const int NUMSINGLESTACK = 4;
static const int CARDSPERPLAYSTACK = 5;



global char *progname;
global Display *dpy;
global Window toplevel;
global int screen;
global Colormap cmap;
global Bool hascolor;
global Card cards[NUMSUITS][NUMVALUES];
global int speedup;
global Score score;
global XFontStruct *font;
global unsigned long backpixel;
global Bool inautoplay;

// From main.C

void Punt(char *);


// From util.C

extern unsigned long GetColor(char *, unsigned long);
extern void GetInterestingEvent(XEvent *);
extern Window CreateButtonWindow(char *, int, int, int, int *);



// From card.C

void CardInit();
Bool CardHandleEvent(XEvent *);


// From stack.C

void StackInit();
void NewGame();
void AutoMoves();
int NumAvailableSingles();
Stack GetAvailableSingle();
Stack StackFromPoint(int x, int y);
void DoUndo();
void DoRedo();
void DoRestart();
void UndoBoundary();
void LoadStacks(Card deck[52]);
extern Stack playstack[NUMPLAYSTACK];
extern Stack singlestack[NUMSINGLESTACK];
extern Stack donestack[NUMSUITS];
void DoAutoPlay();
\Rogue\Monster\
else
  echo "will not over write ./seahaven.h"
fi
if `test ! -s ./stack.C`
then
echo "writing ./stack.C"
cat > ./stack.C << '\Rogue\Monster\'
/*
 * Author:  Terry Weissman
 *          weissman@sgi.com
 */



#include "seahaven.h"
#include "auto.h"

#include <sys/time.h>		// For time()
#include <math.h>		// For random()
#include <malloc.h>
#include <X11/cursorfont.h>

Stack playstack[NUMPLAYSTACK];
Stack singlestack[NUMSINGLESTACK];
Stack donestack[NUMSUITS];


static Stack allstacks[100];
static int numstacks = 0;

static int initializing = False;
static int undoing = False;

class StackPlayRec : public StackRec {
  public:
    StackPlayRec(int x, int y);
    virtual Bool addCard(Card, AnimType animate = Normal);
    virtual StackType getType();
  private:
};


class StackSingleRec : public StackRec {
  public:
    StackSingleRec(int x, int y);
    virtual Bool addCard(Card, AnimType animate = Normal);
    virtual StackType getType();
  private:
};


class StackDoneRec : public StackRec {
  public:
    StackDoneRec(int x, int y);
    virtual Bool addCard(Card, AnimType animate = Normal);
    virtual int getStackingHeight();
    virtual StackType getType();
  private:
};


UndoListRec::UndoListRec() {
    max = 100;
    cards = (Card *) malloc(max * sizeof(Card));
    stacks = (Stack *) malloc(max * sizeof(Stack));
    clear();
}


void UndoListRec::clear() {
    num = 0;
}

void UndoListRec::add(Card c, Stack s) {
    if (num >= max) {
	max += 100;
	cards = (Card *) realloc((char *) cards, max * sizeof(Card));
	stacks = (Stack *) realloc((char *) stacks, max * sizeof(Stack));
    }
    cards[num] = c;
    stacks[num] = s;
    num++;
}

void UndoListRec::addBoundary() {
    if (num > 0 && cards[num - 1] != NULL) add(NULL, NULL);
}


void UndoListRec::doUndo() {
    initializing = True;	// Hack to fool StackPlayRec::addCard.
    if (num > 0 && cards[num - 1] == NULL) num--;
    while (num > 0 && cards[num - 1] != NULL) {
	num--;
	stacks[num]->addCard(cards[num]);
    }
    initializing = False;
    for (int i=0 ; i<NUMPLAYSTACK ; i++) playstack[i]->repositionAll();
}

Bool UndoListRec::isEmpty() {
    for (int i = 0 ; i<num ; i++) if (cards[i]) return False;
    return True;
}
	
UndoListRec undostack;
UndoListRec redostack;

void AddUndo(Card c, Stack s) {
    UndoList list = undoing ? &redostack : &undostack;
    list->add(c, s);
}


void UndoBoundary() {
    undostack.addBoundary();
    redostack.clear();
}


void DoUndo() {
    undoing = True;
    undostack.doUndo();
    undoing = False;
    redostack.addBoundary();
}

void DoRedo() {
    redostack.doUndo();
    undostack.addBoundary();
}


void DoRestart() {
    while (!undostack.isEmpty()) DoUndo();
}

StackRec::StackRec(int newx, int newy) {
    x = newx;
    y = newy;
    numcards = 0;
    allstacks[numstacks++] = this;
}

void StackRec::clear() {
    numcards = 0;
}

int StackRec::getX() {
    return x;
}

int StackRec::getY() {
    return y;
}

Card StackRec::getTopCard() {
    if (numcards == 0) return NULL;
    return cards[numcards - 1];
}

Card StackRec::getCardAbove(Card c) {
    int i;
    for (i=0 ; i<numcards - 1 ; i++) {
	if (cards[i] == c) return cards[i + 1];
    }
    return NULL;
}


static int Abs(int x) {
    return (x < 0) ? -x : x;
}


static int Max(int a, int b) {
    return (a > b) ? a : b;
}


void StackRec::repositionAll() {
    for (int i=0 ; i<numcards ; i++) {
	cards[i]->setLoc(x, y + i * getStackingHeight());
    }
}

Card StackRec::popCard() {
    if (numcards == 0) return NULL;
    numcards--;
    return cards[numcards];
}

Bool StackRec::addCard(Card c, AnimType animate) {
    if (c->getStack() == this) Punt("Error in StackRec::addCard!");
    if (animate == Animate) {
	c->raise();
	int oldx = c->getX();
	int oldy = c->getY();
	int newx = x;
	int newy = y + numcards * getStackingHeight();
	int numsteps = Max(Abs(oldx - newx), Abs(oldy - newy)) / speedup;
	float curx = (float) oldx;
	float cury = (float) oldy;
	for (int i = 0 ; i<numsteps ; i++) {
	    curx += ((float) (newx - oldx)) / numsteps;
	    cury += ((float) (newy - oldy)) / numsteps;
	    c->setLoc((int) curx, (int) cury);
	    XFlush(dpy);
	}
    }
    if (animate != DontMove) {
	if (numcards > 0) c->raiseAbove(cards[numcards - 1]);
	c->setLoc(x, y + numcards * getStackingHeight());
	if (inautoplay) XFlush(dpy);
    }
    Stack old = c->getStack();
    if (old && old->popCard() != c) {
	Punt("Couldn't find card in old stack in StackRec::addCard!");
    }
    AddUndo(c, c->getStack());
    c->setStack(this);
    cards[numcards++] = c;
    return True;
}


int StackRec::getStackingHeight() {
    return 22;
}

StackType StackRec::getType() {
    Punt("Invalid call to base class: StackRec::getType()");
    return Single;
}

StackPlayRec::StackPlayRec(int x, int y) : (x, y) {
}


Bool StackPlayRec::addCard(Card c, AnimType animate) {
    if (!initializing) {
	if (numcards == 0) {
	    if (c->getValue() != NUMVALUES - 1) return False;
	} else {
	    if (c->getSuit() != cards[numcards - 1]->getSuit() ||
		   c->getValue() != cards[numcards - 1]->getValue() - 1)
		return False;
	}
    }
    return StackRec::addCard(c, animate);
}

StackType StackPlayRec::getType() {
    return Play;
}


StackSingleRec::StackSingleRec(int x, int y) : (x, y) {
    XSetWindowAttributes attributes;
    long valuemask = CWBackPixel | CWBorderPixel;
    attributes.background_pixel = GetColor("darkgreen",
					   WhitePixel(dpy, screen));
    attributes.border_pixel = GetColor("green", BlackPixel(dpy, screen));
    Window w = XCreateWindow(dpy, toplevel, x - 1, y - 1,
			     CARDWIDTH, CARDHEIGHT, 1, (int) CopyFromParent,
			     InputOutput, (Visual *) CopyFromParent,
			     valuemask, &attributes);
    XLowerWindow(dpy, w);
    XMapWindow(dpy, w);
}

StackSingleRec::addCard(Card c, AnimType animate) {
    if (numcards) return False;
    return StackRec::addCard(c, animate);
}

StackType StackSingleRec::getType() {
    return Single;
}


StackDoneRec::StackDoneRec(int x, int y) : (x, y) {
}

StackDoneRec::addCard(Card c, AnimType animate) {
    if (numcards == 0) {
	if (c->getValue() != 0) return False;
    } else {
	if (c->getSuit() != cards[numcards - 1]->getSuit() ||
	      c->getValue() != cards[numcards - 1]->getValue() + 1)
	    return False;
    }
    return StackRec::addCard(c, animate);
}

StackDoneRec::getStackingHeight() {
    return 0;
}

StackType StackDoneRec::getType() {
    return Done;
}


static int Random(int i) {
    return random() % i;
}



void AutoMoves() {
    Bool found;
    int i;
    do {
	found = False;
	for (i=0 ; i<numstacks ; i++) {
	    Card card = allstacks[i]->getTopCard();
	    if (card) {
		Card dcard = donestack[card->getSuit()]->getTopCard();
		if (card->getValue() == (dcard ? dcard->getValue() + 1 : 0)) {
		    donestack[card->getSuit()]->addCard(card,
							inautoplay ? Normal
							: Animate);
		    found = True;
		}
	    }
	}
    } while (found);
    for (i=0 ; i<NUMSUITS ; i++) {
	Card card = donestack[i]->getTopCard();
	if (card == NULL ||
	    donestack[i]->getTopCard()->getValue() < NUMVALUES - 1) return;
    }
    score->wonGame();
}


int NumAvailableSingles() {
    int result = 0;
    for (int i=0 ; i<NUMSINGLESTACK ; i++) {
	if (singlestack[i]->getTopCard() == NULL) result++;
    }
    return result;
}


Stack GetAvailableSingle() {
    for (int i=0 ; i<NUMSINGLESTACK ; i++) {
	if (singlestack[i]->getTopCard() == NULL) return singlestack[i];
    }
    return NULL;
}


Stack StackFromPoint(int x, int y) {
    Stack *checklist;
    int num;
    if (y < playstack[0]->getY() - 20) {
	checklist = singlestack;
	num = NUMSINGLESTACK;
    } else {
	checklist = playstack;
	num = NUMPLAYSTACK;
    }
    for (int i=0 ; i<num ; i++) {
	if (x >= checklist[i]->getX() - CARDWIDTH / 2 &&
	    x < checklist[i]->getX() + CARDWIDTH / 2) return checklist[i];
    }
    return NULL;
}


void NewGame() {
    int i, j, k, w;
    if (score) {
	score->lostGame();	// Has no effect if wonGame() already called.
	score->newGame();
    }
    initializing = True;
    for (i=0 ; i<numstacks ; i++) {
	allstacks[i]->clear();
    }
    Card deck[NUMSUITS * NUMVALUES];
    i = 0;
    for (int s = 0 ; s < NUMSUITS ; s++) {
	for (int v = 0 ; v < NUMVALUES ; v++) {
	    deck[i++] = cards[s][v];
	    cards[s][v]->setStack(NULL);
	}
    }
    if (score) score->saveGameBegin();
    for (k=0 ; k<CARDSPERPLAYSTACK ; k++) {
	for (j=0 ; j<NUMPLAYSTACK ; j++) {
	    w = Random(i);
	    playstack[j]->addCard(deck[w]);
	    if (score) score->saveGameCard(deck[w]);
	    deck[w] = deck[--i];
	}
    }
    for (j=0 ; j<i ; j++) {
	singlestack[j + 1]->addCard(deck[j]);
	if (score) score->saveGameCard(deck[j]);
    }
    if (score) score->saveGameEnd();
    initializing = False;

    AutoMoves();
    undostack.clear();
    redostack.clear();
}



void LoadStacks(Card deck[52]) {
    int i, j, k, w;
    initializing = True;
    for (i=0 ; i<numstacks ; i++) {
	allstacks[i]->clear();
    }
    initializing = True;
    for (int s = 0 ; s < NUMSUITS ; s++) {
	for (int v = 0 ; v < NUMVALUES ; v++) {
	    cards[s][v]->setStack(NULL);
	}
    }
    w = 0;
    for (k=0 ; k<CARDSPERPLAYSTACK ; k++) {
	for (j=0 ; j<NUMPLAYSTACK ; j++) {
	    playstack[j]->addCard(deck[w++]);
	}
    }
    for (j=0 ; j<2 ; j++) {
	singlestack[j + 1]->addCard(deck[w++]);
    }
    initializing = False;

    AutoMoves();
    undostack.clear();
    redostack.clear();
}


class StackNoticeExitRec {
  public:
    StackNoticeExitRec() {}
    ~StackNoticeExitRec();
};


StackNoticeExitRec::~StackNoticeExitRec() {
    if (score->getGameWonOrLost()) NewGame();	// Force save.
}


StackNoticeExitRec noticeexit;

void StackInit() {
    int i;
    srandom(int(time(NULL)));

    for (i=0 ; i<NUMPLAYSTACK ; i++) {
	playstack[i] = new StackPlayRec(i * 70 + 10, 100);
    }
    for (i=0 ; i<NUMSINGLESTACK ; i++) {
	singlestack[i] = new StackSingleRec(i * 70 + 220, 10);
    }
    donestack[0] = new StackDoneRec(10, 10);
    donestack[1] = new StackDoneRec(80, 10);
    donestack[2] = new StackDoneRec(570, 10);
    donestack[3] = new StackDoneRec(640, 10);
}




void DoAutoPlay() {
    static Cursor waitcursor = NULL;
    if (waitcursor == NULL) waitcursor = XCreateFontCursor(dpy, XC_watch);
    XDefineCursor(dpy, toplevel, waitcursor);
    score->lostGame();
    DoRestart();
    XFlush(dpy);
    inautoplay = True;
    int solvable = AutoPlay();
    if (solvable) {
	score->setMessage("Solvable.");
	while (solutionhead) {
	    SolutionLog temp = solutionhead;
	    solutionhead = solutionhead->next;
	    Card card = cards[temp->suit][temp->rank];
	    if (temp->dest == -999) {
		AutoMoves();
		UndoBoundary();
	    } else if (temp->dest == -99) {
		GetAvailableSingle()->addCard(card);
	    } else if (temp->dest <= NUMPLAYSTACK) {
		playstack[temp->dest - 1]->addCard(card);
	    } else {
		if (temp->rank == NUMVALUES - 1) { // King to empty stack.
		    for (int i=0 ; i<NUMPLAYSTACK ; i++) {
			if (playstack[i]->getTopCard() == NULL) {
			    playstack[i]->addCard(card);
			    break;
			}
		    }
		} else {
		    cards[temp->suit][temp->rank+1]->getStack()->addCard(card);
		}
	    }
	    delete temp;
	    XFlush(dpy);	// For debugging.
	}
    } else {
	score->setMessage("Unsolvable.");
    }
    inautoplay = False;
    XUndefineCursor(dpy, toplevel);
}
\Rogue\Monster\
else
  echo "will not over write ./stack.C"
fi
if `test ! -s ./store.C`
then
echo "writing ./store.C"
cat > ./store.C << '\Rogue\Monster\'
#include "seahaven.h"

struct HashBucket {
  struct {
    Stack s;
    int y;		// hack, really want position w/in stack as an index
  } cardpos[52];
  HashBucket *next;
};

static const int NUMHASHSLOTS = 337;

HashBucket *hashtable[NUMHASHSLOTS] = {NULL};

void
InitHashTable()
{
    for (int i=0; i< NUMHASHSLOTS; i++) {
	if (hashtable[i]) {
	    HashBucket *t = hashtable[i], *n;
	    do {
		n = t->next;
		delete t;
	    } while (t = n);
	    hashtable[i] = NULL;
	}
    }
}

#ifdef notdef
// the single stacks are symmetric, so store them as singlestack[0] and y=0
inline void FoldStack(Stack reals, int realy, Stack &s, int &y)
{
	extern Stack singlestack[];
	if (reals == singlestack[0] || reals == singlestack[1]
		|| reals == singlestack[2] || reals == singlestack[3]) {
	  s = singlestack[0];
	  y = 0;
	} else {
	  s = reals;
	  y = realy;
	}
}
#endif

// retruns true if found it
Bool
hashlookup(int key)
{
    if (!hashtable[key]) return False;

    HashBucket *t = hashtable[key];
    do {
	int i;
	Card *c;
	Bool match;

	for (i=0, c = &cards[0][0]; i < 52; i++, c++) {
	    match = True;
	    if ( (*c)->getFoldedY() != t->cardpos[i].y ||
		(*c)->getFoldedStack() != t->cardpos[i].s ) {
		match = False;
		break;
	    }
	}
	if (match)
	    return True;
    } while (t = t->next);

    return False;

}

// returns true if new state
Bool
CheckNewState()
{
    unsigned int hashkey = 0;

    // compute key
    int i;
    Card *c;
    for (i=0, c = &cards[0][0]; i < 52; i++, c++) {
	hashkey += ((int) (*c)->getFoldedStack() << (*c)->getValue());
    }
    
    if (hashlookup(hashkey % NUMHASHSLOTS))
	return False;
    else
	return True;
    
}

void
hashinsert(int key, HashBucket *pail)
{
    pail->next = hashtable[key];
    hashtable[key] = pail;
}

void
SaveState()
{
    
    HashBucket *pail = new HashBucket;
    unsigned int hashkey = 0;
    
    int i;
    Card *c;
    for (i=0, c = &cards[0][0]; i < 52; i++, c++) {
	pail->cardpos[i].s = (*c)->getFoldedStack();
	pail->cardpos[i].y = (*c)->getFoldedY();
	hashkey += ((int) pail->cardpos[i].s << (*c)->getValue());
    }
    
    hashinsert(hashkey % NUMHASHSLOTS, pail);
    
}
\Rogue\Monster\
else
  echo "will not over write ./store.C"
fi
if `test ! -s ./util.C`
then
echo "writing ./util.C"
cat > ./util.C << '\Rogue\Monster\'
/*
 * Author:  Terry Weissman
 *          weissman@sgi.com
 */

#include "seahaven.h"

#include <string.h>



unsigned long GetColor(char *name, unsigned long def) {
    XColor col1, col2;
    if (hascolor && XAllocNamedColor(dpy, cmap, name, &col1, &col2)) {
	return col2.pixel;
    } else {
	return def;
    }
}


void GetInterestingEvent(XEvent *event) {
    XNextEvent(dpy, event);
    while (event->type == Expose) {
	if (event->xexpose.count == 0) score->repaint();
	XNextEvent(dpy, event);
    }
}
	

Window CreateButtonWindow(char *label, int x, int y, int gravity, int *width) {
    static GC textgc = NULL, cleargc = NULL;
    int w = XTextWidth(font, label, strlen(label)) + 4;
    int h = font->ascent + font->descent + 4;
    if (width) *width = w;
    Pixmap pixmap = XCreatePixmap(dpy, toplevel, w, h,
				  DefaultDepth(dpy, screen));
    if (textgc == NULL) {
	textgc = XCreateGC(dpy, toplevel, 0, NULL);
	XSetForeground(dpy, textgc, GetColor("black",
					     BlackPixel(dpy, screen)));
	XSetFont(dpy, textgc, font->fid);
	cleargc = XCreateGC(dpy, toplevel, 0, NULL);
	XSetForeground(dpy, cleargc,  backpixel);
    }
    XFillRectangle(dpy, pixmap, cleargc, 0, 0, w, h);
    XDrawString(dpy, pixmap, textgc, 2, 2 + font->ascent,
		label, strlen(label));

    XSetWindowAttributes attributes;
    long valuemask = CWEventMask | CWBackPixmap | CWWinGravity;
    attributes.event_mask = ButtonPressMask;
    attributes.background_pixmap = pixmap;
    attributes.win_gravity = gravity;
    Window window = XCreateWindow(dpy, toplevel, x, y,
				  w, h, 1, (int) CopyFromParent,
				  InputOutput, (Visual *) CopyFromParent,
				  valuemask, &attributes);
    XMapWindow(dpy, window);
    return window;
}
    
\Rogue\Monster\
else
  echo "will not over write ./util.C"
fi
if `test ! -s ./cardbitmaps.uue`
then
echo "writing ./cardbitmaps.uue"
cat > ./cardbitmaps.uue << '\Rogue\Monster\'
begin 444 cardbitmaps.C.Z
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
69`MS`)D0R-D'@=Q_\!P2PC4-9V!E`!#(
`
end
\Rogue\Monster\
else
  echo "will not over write ./cardbitmaps.uue"
fi
echo "Finished archive 2 of 2"
exit





--
Dan Heller
------------------------------------------------
O'Reilly && Associates 		      Zyrcom Inc
Senior Writer			       President
argv@ora.com			argv@zipcode.com