🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: mod.mac.sources
1 messages
1 total messages Started by Paul DuBois Sun, 01 Feb 1987 07:00
BlobDemo4 - Blob Manager Demo source (part 4 of 5)
#38
Author: Paul DuBois
Date: Sun, 01 Feb 1987 07:00
1100 lines
25892 bytes
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	BlobDemo/DemoStates.c
#	BlobDemo/DemoSwap.c
#	BlobDemo/DemoToh.c
#	BlobDemo/DemoTtt.c
#	BlobDemo/DemoWind.c
mkdir BlobDemo
sed 's/^X//' << 'SHAR_EOF' > BlobDemo/DemoStates.c
X/*
X	Blob Manager Demonstration:  States and Capitals module
X
X	This module is an example of an extremely simple interrogative
X	scenario.  The original thirteen colonies of the United States must
X	be matched with their capital cities.  There is a single button that
X	says "Give Up?"  If the user clicks the button, the answer is shown,
X	the button's title changes to "Resume", and the scenario is frozen
X	until the button is clicked.  Then the answer is cleared, the capitals
X	are shuffled, and the user may start over.
X
X	If the correct answers are all gotten, the button again changes to
X	"Resume" and the scenario is frozen until the button is clicked.
X
X	The module is unexciting; it's meant as a basic illustration, rather
X	than anything useful.  There are lots of bells and whistles that
X	could be added.
X
X	26 July 1986		Paul DuBois
X*/
X
X
X# include	"BlobDemo.h"
X# include	<ControlMgr.h>
X
X
X# define	nStates		13
X
X# define	hState1		220
X# define	hState2		110
X# define	vState		16
X# define	stateXOff	10
X# define	stateYOff	5
X# define	hCapital	85
X# define	vCapital	16
X# define	capXOff		225
X# define	capYOff		5
X
X
Xstruct info
X{
X	char	*stateName;
X	char	*capName;
X};
X
X
X
Xstatic GrafPtr			statesPort;
Xstatic BlobSetHandle	donors;		/* donor blobs */
Xstatic BlobSetHandle	receptors;	/* receptor blobs */
Xstatic ControlHandle	giveUp;
Xstatic Boolean			paused = false;
X
Xstatic struct info		scPair[nStates] =
X{
X	{ "\pConnecticut",		"\pHartford" },
X	{ "\pDelaware",			"\pDover" },
X	{ "\pGeorgia",			"\pAtlanta" },
X	{ "\pMaryland",			"\pAnnapolis" },
X	{ "\pMassachusetts",	"\pBoston" },
X	{ "\pNew Hampshire",	"\pConcord" },
X	{ "\pNew Jersey",		"\pTrenton" },
X	{ "\pNorth Carolina",	"\pRaleigh" },
X	{ "\pNew York",			"\pAlbany" },
X	{ "\pPennsylvania",		"\pHarrisburg" },
X	{ "\pRhode Island",		"\pProvidence" },
X	{ "\pSouth Carolina",	"\pColumbia" },
X	{ "\pVirginia",			"\pRichmond" }
X};
X
X
Xstatic Activate (active)
XBoolean	active;
X{
X	if (active)
X	{
X		SetDragRects (statesPort);
X		SetBCPermissions (true, true, false, true, true);
X	}
X}
X
X
Xstatic Update ()
X{
X	DrawControls (statesPort);
X	DrawBlobSet (receptors);
X	DrawBlobSet (donors);
X}
X
X
Xstatic Mouse (pt, t, mods)
XPoint	pt;
Xlong	t;
Xint		mods;
X{
XBlobHandle	b, d;
XControlHandle	ctl;
X
X	if (FindControl	(pt, statesPort, &ctl))
X	{
X		if (TrackControl (ctl, pt, nil))
X		{
X			if (paused)		/* either all answers are correct, or we're */
X			{				/* showing the answer.  Either way, restore */
X				ThawBlobSet (receptors);	/* to start state */
X				ThawBlobSet (donors);
X				ZUnglueGlobSet (receptors);
X				ShuffleBlobSet (receptors);
X				ShuffleBlobSet (donors);
X				SetCTitle (giveUp, "\pGive Up?");
X				ValidRect (&statesPort->portRect);
X				paused = false;
X			}
X			else		/* user gives up - show answer */
X			{
X				for (b = FirstBlob (receptors); b != nil; b = NextBlob (b))
X					ZGlueGlob (FirstBMatch (b), b);
X				FreezeBlobSet (receptors);
X				FreezeBlobSet (donors);
X				SetCTitle (giveUp, "\pResume");
X				paused = true;
X			}
X		}
X	}
X	else
X	{
X		BlobClick (pt, t, donors, receptors);
X		if (!paused && BlobSetQuiet (receptors))	/* answers correct? */
X		{
X			FreezeBlobSet (receptors);
X			FreezeBlobSet (donors);
X			SetCTitle (giveUp, "\pResume");
X			paused = true;
X		}
X	}
X}
X
X
X/*
X	Make blobs
X*/
X
X
XMakeBlobs ()
X{
Xint			i;
XRect		r, r2;
XBlobHandle	b1, b2;
X
X	donors = NewBlobSet ();
X	receptors = NewBlobSet ();
X	for (i = 0; i < nStates; ++i)
X	{
X		b1 = NewBlob (donors, false, 1, false, 0L);
X		b2 = NewBlob (receptors, false, 0, true, 0L);
X		NewBlobMatch (b1, b2);		/* attach the answer */
X
X		OpenBlob ();	/* draw donor blob */
X		SetRect (&r, 0, 0, hCapital, vCapital);
X		TextBox (&scPair[i].capName[1], (long) scPair[i].capName[0], &r, 1);
X		CloseRectBlob (b1, &r, &r);
X		MoveBlob (b1, inFullBlob,  capXOff, capYOff + (vCapital + 1) * i);
X
X		OpenBlob ();
X		SetRect (&r, 0, 0, hState1, vState);
X		SetRect (&r2, 0, 0, hState2, vState);
X		TextBox (&scPair[i].stateName[1], (long) scPair[i].stateName[0], &r2, 1);
X		SetRect (&r2, 0, 0, hCapital, vCapital);
X		OffsetRect (&r2, hState2 + 5, 0);
X		EraseRect (&r2);
X		FrameRect (&r2);
X		CloseRectBlob (b2, &r2, &r);
X		MoveBlob (b2, inFullBlob,  stateXOff, stateYOff + (vState + 2) * i);
X	}
X	ShuffleBlobSet (donors);
X	EnableBlobSet (receptors);
X	EnableBlobSet (donors);
X}
X
X
XStatesInit	()
X{
XRect	r;
X
X	SkelWindow (statesPort = GetDemoWind (statesWindRes),
X				Mouse,			/* mouse clicks */
X				nil,			/* key clicks */
X				Update,			/* updates */
X				Activate,		/* activate/deactivate events */
X				nil,			/* close window */
X				DoWClobber,		/* dispose of window */
X				nil,			/* idle proc */
X				false);			/* irrelevant, since no idle proc */
X
X/*
X	Make blobs.  Generally have to make donors before receptors.
X*/
X	MakeBlobs ();
X
X	r = statesPort->portRect;
X	SetRect (&r, r.left + 5, r.bottom - 25, r.left + 75, r.bottom - 5);
X	giveUp = NewControl (statesPort, &r, "\pGive Up?", true, 0, 0, 0,
X							pushButProc, nil);
X
X	Update ();
X	ValidRect (&statesPort->portRect);
X}
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > BlobDemo/DemoSwap.c
X/*
X	Blob Manager Demonstration:  Coin Swap module
X
X	This has a linear board with either 5, 7 or 9 pieces.  The middle
X	piece is always empty, the pieces on one end are filled with black
X	coins, the pieces on the other end are filled with white coins.
X	The object is to swap the coins.  A coin can slide into an empty
X	piece next to it, or jump over a single coin to land on an empty
X	piece.
X
X	A menu allows the number of coins to be chosen.  To win, the coins
X	have to be swapped in a specific number of moves.
X
X	26 July 1986		Paul DuBois
X*/
X
X
X# include	"BlobDemo.h"
X# include	<MenuMgr.h>
X
X# define	vMessage	10
X# define	vPiece		30
X# define	maxPieces	9
X# define	pieceSize	24
X# define	pieceGap	1
X
X
Xstatic GrafPtr			swapPort;
Xstatic MenuHandle		cnfgMenu;
Xstatic BlobSetHandle	donors = nil;
Xstatic BlobSetHandle	receptors = nil;
Xstatic int				hMid;
Xstatic Str255			statusStr = "\p";
X
Xstatic int				nPieces = 5;
Xstatic int				nMoves = 8;
Xstatic BlobHandle		piece[maxPieces];
Xstatic int				moves;
Xstatic Boolean			pause;
X	
X
Xstatic StatusMesg (s)
XStr255	s;
X{
XRect	r;
X
X	SetRect (&r, hMid - 60, vMessage, hMid + 60, vMessage+16);
X	TextBox	(s+1, (long) s[0], &r, 1);
X	StrCpy (statusStr, s);
X}
X
X
X/*
X	Reset to start state.  This recreates the board each time.  All the
X	blobs in the board require explicit matches except the middle one.
X*/
X
Xstatic Reset ()
X{
XBlobHandle	b;
XRect		r;
Xint			i, h;
XStr255		s;
X
X	InvalRect (&swapPort->portRect);	/* force update when done resetting */
X	pause = false;
X	moves = nMoves;
X	MovesLeft (moves, s);
X	StatusMesg (s);
X
X	if (receptors != nil)				/* clobber any existing receptor set */
X	{
X		HideBlobSet (receptors);
X		DisposeBlobSet (receptors);
X	}
X	receptors = NewBlobSet ();
X
X	h = hMid - (nPieces * (pieceSize + pieceGap) - pieceGap) / 2;
X	for (i = 0; i < nPieces; ++i)
X	{
X		b = NewBlob (receptors, false, 0, i != (nPieces - 1) / 2, 0L);
X		piece[i] = b;
X		OpenBlob ();
X		SetRect (&r, h, vPiece, h + pieceSize, vPiece + pieceSize);
X		EraseRect (&r);
X		FrameRect (&r);
X		CloseRectBlob (b, &r, &r);
X		h += pieceSize + pieceGap;
X		if (i < (nPieces - 1) / 2)
X		{
X			GlueGlob (GetBlobHandle (donors, 0), b);
X			NewBlobMatch (GetBlobHandle (donors, 1), b);
X		}
X		else if (i > (nPieces - 1) / 2)
X		{
X			GlueGlob (GetBlobHandle (donors, 1), b);
X			NewBlobMatch (GetBlobHandle (donors, 0), b);
X		}
X	}
X	EnableBlobSet (receptors);
X}
X
X
Xstatic SwapPause (msg)
XStringPtr	msg;
X{
X	StatusMesg (msg);
X	pause = true;
X}
X
X
Xstatic Mouse (pt, t, mods)
XPoint	pt;
Xlong	t;
Xint		mods;
X{
XStr255			s;
Xregister int	i;
X
X/*
X	Freeze all the pieces that can't be moved, then call BlobClick.
X*/
X	for (i = 0; i < nPieces; ++i)
X	{
X		ThawBlob (piece[i]);
X		if (BGlob (piece[i]) == nil) continue;
X		if (i > 0 && BGlob (piece[i-1]) == nil) continue;
X		if (i > 1 && BGlob (piece[i-2]) == nil) continue;
X		if (i < nPieces - 1 && BGlob (piece[i+1]) == nil) continue;
X		if (i < nPieces - 2 && BGlob (piece[i+2]) == nil) continue;
X		FreezeBlob (piece[i]);
X	}
X	if (!pause)
X	{
X		BlobClick (pt, t, donors, receptors);
X		if (BClickResult () == bcXfer)
X		{
X			if (--moves == 0)
X			{
X				if (BlobSetQuiet (receptors))
X					SwapPause ("\pYou Win");
X				else
X					SwapPause ("\pYou Lose");
X			}
X			else
X			{
X				MovesLeft (moves, s);
X				StatusMesg (s);
X			}
X		}
X	}
X}
X
X
X/*
X	Select configuration:  4, 6, or 8 coins (2, 3, or 4 on each side).
X	If the number of coins on each side is n, the number of moves
X	to solve is (n+1)^2 - 1.
X*/
XDoConfiguration (item)
Xint		item;
X{
X	nPieces = 2 * item + 3;			/* 1->5, 2->7, 3->9 pieces */
X	nMoves = (item + 2) * (item + 2) - 1;
X	Reset ();
X}
X
X
Xstatic Activate (active)
XBoolean	active;
X{
X	if (active)
X	{
X		SetDragRects (swapPort);
X		SetBCPermissions (false, true, false, false, false);	/* xfer only */
X		cnfgMenu = GetMenu (swapCnfgMenuRes);
X		SkelMenu (cnfgMenu, DoConfiguration, DoMClobber);
X	}
X	else
X		SkelRmveMenu (cnfgMenu);
X}
X
X
Xstatic Update (resized)
XBoolean	resized;
X{
X	DrawBlobSet (receptors);
X	StatusMesg (statusStr);
X}
X
X
X/*
X	Make donor blobs.
X*/
X
Xstatic MakeDonors ()
X{
XBlobHandle	b;
XRect		r;
X
X	donors = NewBlobSet ();
X	b = NewBlob (donors, false, infiniteGlue, false, 0L);
X	OpenBlob ();
X	SetRect (&r, 0, 0, pieceSize, pieceSize);
X	EraseRect (&r);
X	FrameRect (&r);
X	InsetRect (&r, 2, 2);
X	PaintOval (&r);
X	InsetRect (&r, -2, -2);
X	CloseRectBlob (b, &r, &r);
X	b = NewBlob (donors, false, infiniteGlue, false, 0L);
X	OpenBlob ();
X	PaintRect (&r);
X	InsetRect (&r, 2, 2);
X	EraseOval (&r);
X	InsetRect (&r, -2, -2);
X	CloseRectBlob (b, &r, &r);
X}
X
X
XSwapInit	()
X{
X	SkelWindow (swapPort = GetDemoWind (swapWindRes),
X				Mouse,			/* mouse clicks */
X				nil,			/* key clicks */
X				Update,			/* updates */
X				Activate,		/* activate/deactivate events */
X				nil,			/* close window */
X				DoWClobber,		/* dispose of window */
X				nil,			/* idle proc */
X				false);			/* irrelevant, since no idle proc */
X
X	hMid = swapPort->portRect.right / 2;
X
X	MakeDonors ();
X	Reset ();
X	Update ();
X	ValidRect (&swapPort->portRect);
X}
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > BlobDemo/DemoToh.c
X/*
X	Blob Manager Demonstration:  Tower of Hanoi
X
X	26 July 1986	Paul DuBois
X*/
X
X# include	"BlobDemo.h"
X
X
X# define	xBase		17	/* upper left corner of apparatus base */
X# define	yBase		130
X# define	baseHeight	12	/* length is computed */
X# define	slotHeight	18	/* size of disk slots */
X# define	slotWidth	100
X# define	slotHGap	20	/* horiz. gap between slots	*/
X# define	slotVGap	0	/* vert. gap between slots */
X# define	hExtra		20	/* extra space at ends of base */
X# define	nDisks		6	/* number of disks */
X# define	postWidth	12	/* height is computed */
X	
X
Xstatic GrafPtr			tohPort;
Xstatic BlobSetHandle	donors;
Xstatic BlobSetHandle	receptors;
Xstatic BlobHandle		tower[3][nDisks];	/* induced data structure */
X
X
X
Xstatic DrawApparatus ()
X{
Xint	postHeight, baseWidth, h, v, i;
XRect	r;
X
X	postHeight = nDisks * (slotHeight + slotVGap) + postWidth/2;
X	h = xBase + hExtra + slotWidth/2 - postWidth/2;
X	SetRect (&r, h, yBase - postHeight, h + postWidth, yBase+postWidth/2);
X
X	for (i = 0; i < 3; ++i)
X	{
X		FillRoundRect (&r, postWidth, postWidth, gray);
X		FrameRoundRect (&r, postWidth, postWidth);
X		OffsetRect (&r, slotWidth + slotHGap, 0);
X	}
X
X	baseWidth = 3 * slotWidth + 2 * slotHGap + 2 * hExtra;
X	SetRect (&r, xBase, yBase, xBase + baseWidth, yBase + baseHeight);
X	FillRect (&r, dkGray);
X	FrameRect (&r);
X}
X
X
X/*
X	If a disk was moved onto a pile, but has empty slots under it,
X	drop it until it can't go any farther.
X*/
X
Xstatic DropDisk ()
X{
Xregister int	i, j;
X
X	for (i = 0; i < 3; ++i)
X	{
X		for (j = nDisks - 1; j > 0; --j)	/* don't check bottom pos */
X		{
X			if (BGlob (tower[i][j]) != nil)
X			{
X				if (BGlob (tower[i][j-1]) == nil)
X					TransferGlob (tower[i][j], tower[i][j-1]);
X			}
X		}
X	}
X}
X
X
Xstatic Mouse (pt, t, mods)
XPoint	pt;
Xlong	t;
Xint		mods;
X{
X
X	BlobClick (pt, t, nil, receptors);
X	DropDisk ();
X}
X
X
X/*
X	The advisory functions as follows:  receptor clicks are checked
X	and if the click isn't in the top disk of a pile, the click is
X	ignored (message advRClick).  When a receptor is dragged somewhere
X	else, it must be to a pile in which the disk under it is larger -
X	can't drag onto a smaller disk (message advXfer).
X*/
X
Xstatic Boolean Advisory (mesg, b)
Xint			mesg;
XBlobHandle	b;
X{
XBlobHandle	g;
Xint			index, pile, piece, i;
Xstatic int	srcRank;
X
X	index = GetBlobIndex (b, receptors);
X	pile = index / nDisks;		/* 0 .. 2 */
X	piece = index % nDisks;		/* 0 .. nDisks-1 */
X	
X	switch (mesg)
X	{
X		case advRClick:
X		{
X			if (piece < nDisks - 1 && BGlob (NextBlob (b)) != nil)
X				return (false);
X			srcRank = GetBRefCon (BGlob (b));	/* rank of dragged piece */
X			break;
X		}
X		case advXfer:
X		{
X			for (i = 0; i < piece; ++i)
X			{
X				if ((g = BGlob (tower[pile][i])) != nil)
X				{
X					if (GetBRefCon (g) > srcRank)
X						return (false);
X				}
X			}
X			break;
X		}
X	}
X	return (true);
X}
X
X
Xstatic Update (resized)
XBoolean	resized;
X{
X	DrawControls (tohPort);
X	DrawApparatus ();
X	DrawBlobSet (receptors);
X}
X
X
Xstatic Activate (active)
XBoolean	active;
X{
X	if (active)
X	{
X		SetDragRects (tohPort);
X		SetBCPermissions (false, true, false, false, false);
X		SetBCAdvisory (Advisory);
X	}
X	else
X		SetBCAdvisory (nil);
X}
X
X/*
X	Call this before static MakeDonors
X*/
X
Xstatic MakeReceptors ()
X{
Xint			i, j, h, v;
XBlobHandle	b;
XRect		r, r2, r3;
X
X	receptors = NewBlobSet ();
X	for (i = 0; i < 3; ++i)
X	{
X		for (j = 0; j < nDisks; ++j)
X		{
X			b = NewBlob (receptors, false, 0, false, 0L);
X			tower[i][j] = b;
X			OpenBlob ();
X			SetRect (&r, 0, 0, slotWidth, slotHeight);
X			h = slotWidth/2 - postWidth/2;
X			SetRect (&r2, h, -1, h + postWidth, slotHeight+1);
X			FillRect (&r2, gray);	/* fill in post area */
X			SetRect (&r3, 0, 0, h, slotHeight);	/* erase on sides of post */
X			EraseRect (&r3);
X			SetRect (&r3, h + postWidth, 0, slotWidth, slotHeight);
X			EraseRect (&r3);
X			FrameRect (&r2);
X			r2 = r;
X			InsetRect (&r2, 0, 1);
X			CloseRectBlob (b, &r2, &r);
X			h = xBase + hExtra + i * (slotWidth + slotHGap);
X			v = yBase - (j+1) * (slotHeight + slotVGap);
X			MoveBlob (b, inFullBlob, h, v);
X		}
X	}
X}
X
X
X/*
X	Make donors.  These are the pieces that get moved.  They're always
X	attached to some receptor, and just float from one receptor to
X	another.  The rank of each piece is stored in the reference constant
X	field.  The bottom piece is 0, the top is nDisks-1.
X*/
X
Xstatic MakeDonors ()
X{
Xint			i, j;
XBlobHandle	b;
XRect		r, r2;
X
X	donors = NewBlobSet ();
X	for (i = 0; i < nDisks; ++i)
X	{
X		b = NewBlob (donors, false, 1, false,
X									(long) i);	/* refCon is disk rank */
X		OpenBlob ();
X		SetRect (&r, 0, 0, slotWidth, slotHeight);
X		j = 20 + (nDisks-i-1) * 4;
X		SetRect (&r2, slotWidth/2 - j, 1, slotWidth/2 + j, slotHeight-1);
X		EraseRect (&r);
X		FrameRoundRect (&r2, slotHeight, slotHeight);
X		CloseRectBlob (b, &r, &r);
X		GlueGlob (b, tower[0][i]);	/* glue to first column */
X	}
X
X}
X
X
XTohInit ()
X{
X	SkelWindow (tohPort = GetDemoWind (tohWindRes),
X				Mouse,			/* mouse clicks */
X				nil,			/* key clicks */
X				Update,			/* updates */
X				Activate,		/* activate/deactivate events */
X				nil,			/* close window */
X				DoWClobber,		/* dispose of window */
X				nil,			/* idle proc */
X				false);			/* irrelevant, since no idle proc */
X				
X	MakeReceptors ();
X	MakeDonors ();
X	EnableBlobSet (receptors);
X	Update ();
X	ValidRect (&tohPort->portRect);
X}
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > BlobDemo/DemoTtt.c
X/*
X	Blob Manager Demonstration:  Tic-Tac-Toe
X	
X	25 July 1986	Paul DuBois
X*/
X
X# include	"BlobDemo.h"
X# include	<ControlMgr.h>
X
X
X# define	barWidth	3	/* board line size */
X# define	bSqSize		30	/* board square size */
X# define	pSqSize		28	/* playing piece square size */
X# define	yOffMesg	4
X# define	yOffPiece	24	/* offset of top of pieces */
X# define	xOffBoard	25
X# define	yOffBoard	59
X# define	xMid		73	/* xOffBoard + 1.5(bSqSize) + barWidth */
X# define	yOffBut		165
X
X
Xstatic GrafPtr			tttPort;
Xstatic BlobSetHandle	tttReceptors;	/* receptor blobs (board) */
Xstatic BlobSetHandle	tttDonors;		/* donor blobs (pieces) */
Xstatic BlobHandle		xBlob;			/* handles to each piece */
Xstatic BlobHandle		oBlob;
X
Xstatic Boolean			haveWin;
Xstatic Boolean			wait = false;
Xstatic ControlHandle	restartCtl;
Xstatic int				moves;
Xstatic int				firstPlayer = 0;
Xstatic Str255			statusStr;
X	
X
XTttStatusMesg (s)
XStr255	s;
X{
XRect	r;
X
X	SetRect (&r, xMid-40, yOffMesg, xMid+40, yOffMesg+20);
X	TextBox	(s+1, (long) s[0], &r, 1);
X	StrCpy (statusStr, s);
X}
X
X
XTttGameOver (mesg)
XStr255	mesg;
X{
X	HiliteControl (restartCtl, 0);
X	TttStatusMesg (mesg);
X	wait = true;
X}
X
X
X
XTttSelectPlayer	()
X{
XBlobHandle	b;
Xint			i;
X
X	i = (moves + firstPlayer) % 2;	   /* 0	= X, 1 = O */
X	HiliteBlob (GetBlobHandle (tttDonors, i), inFullBlob, normalDraw);
X	HiliteBlob (GetBlobHandle (tttDonors, 1 - i), inFullBlob, dimDraw);
X	if (i)
X		TttStatusMesg ("\pO's Move");
X	else
X		TttStatusMesg ("\pX's Move");
X/*
X	Freeze board except for positions occupied by current player and
X	empty positions.
X	This allows pieces to be played either by playing the piece at
X	the top, or by duplicating them on the board.  (Can't drag onto
X	another of own pieces, since replace transactions are disallowed.)
X*/
X	ThawBlobSet (tttReceptors);
X	for (b = FirstBlob (tttReceptors); b != nil; b = NextBlob (b))
X	{
X		if (BGlob (b) != nil && BGlob (b) != GetBlobHandle (tttDonors, i))
X			FreezeBlob (b);
X	}
X}
X
X
XTttRestart ()
X{
X	HiliteControl (restartCtl, 255);
X	ZUnglueGlobSet (tttReceptors);
X	HiliteBlobSet (tttReceptors, inFullBlob, normalDraw);
X	moves =	0;
X	TttSelectPlayer	();
X	wait = false;
X}
X
X
X/*
X	Dim the board positions that are not part of the win.  Dim them all
X	on "cat's game."
X*/
X
XTttShowWinner (pos)
Xint	pos;
X{
Xint	i;
XBlobHandle	b;
X
X	for (i = 0; i < 9; ++i)
X	{
X		b = GetBlobHandle (tttReceptors, i);
X		if ((pos % 2) == 0)		 /* this pos not part of win */
X			HiliteBlob (b, inFullBlob, dimDraw);	/* so dim it */
X		pos >>= 1;
X	}
X}
X
XTttTestConfig (pos,	testPos)
Xint	pos, testPos;
X{
Xint	i;
XBlobHandle	b;
X
X	if ((pos & testPos) == testPos) /*	have a win */
X	{
X		haveWin	= true;
X		TttShowWinner (testPos);
X	}
X}
X
X
XTttTestWin (b, boardPos)
XBlobHandle	b;
Xint		boardPos;
X{
X	if (!haveWin)	 /*	don't bother if	other player already won */
X	{
X		TttTestConfig (boardPos, 0x007); /*	top row	*/
X		TttTestConfig (boardPos, 0x038); /*	middle row */
X		TttTestConfig (boardPos, 0x1c0); /*	bottom row */
X		TttTestConfig (boardPos, 0x049); /*	left column	*/
X		TttTestConfig (boardPos, 0x092); /*	middle column */
X		TttTestConfig (boardPos, 0x124); /*	right column */
X		TttTestConfig (boardPos, 0x111); /*	diagonal */
X		TttTestConfig (boardPos, 0x054); /*	diagonal */
X		if (haveWin)
X		{
X			if (b == xBlob)
X			{
X				TttGameOver ("\pX Wins"); /* loser goes	first next time	*/
X				firstPlayer = 1;
X			}
X			else
X			{
X				TttGameOver ("\pO Wins");
X				firstPlayer = 0;
X			}
X		}
X	}
X}
X
X
XTttBoardPos (b)
XBlobHandle	b;
X{
Xint	i, mask, result;
XBlobHandle	b2;
X
X	result = 0;
X	mask = 1;
X	for (i = 0; i < 9; ++i)
X	{
X		b2 = GetBlobHandle (tttReceptors, i);
X		if ((**b2).glob == b)		 /* board occupied by desired piece	*/
X			result |= mask;
X		mask <<= 1;
X	}
X	return (result);
X}
X
X
XTttCheckStatus ()
X{
Xint	xbPos, obPos;
X
X	haveWin = false;
X	xbPos = TttBoardPos (xBlob);
X	obPos = TttBoardPos (oBlob);
X	TttTestWin (xBlob, xbPos);
X	TttTestWin (oBlob, obPos);
X	if (!haveWin)			 /* no win, but board might be full now */
X	{
X		if ((xbPos | obPos) == 0x1ff)
X		{
X			TttShowWinner (0);
X			TttGameOver ("\pCat's Game");
X			firstPlayer = 1 - firstPlayer; /* alternate on a draw */
X		}
X	}
X}
X
X
XTttMouse (pt, t, mods)
XPoint	pt;
Xlong	t;
Xint	mods;
X{
Xint				result;
XControlHandle	ctl;
X
X	if (FindControl	(pt, tttPort, &ctl))
X	{
X		if (TrackControl (ctl, pt, nil))
X		{
X			TttRestart ();
X		}
X	}
X	else if	(!wait)
X	{
X		BlobClick (pt, t, tttDonors, tttReceptors);
X		result = BClickResult ();
X		if (result == bcGlue || result == bcDup)
X		{
X			++moves;
X			TttCheckStatus ();
X			if (!wait)	 /*	no win yet */
X			{
X				TttSelectPlayer	();
X			}
X		}
X	}
X}
X
XTttUpdate (resized)
XBoolean	resized;
X{
X	DrawControls (tttPort);
X	TttStatusMesg (statusStr);
X	DrawGrid (3, 3,	xOffBoard, yOffBoard, bSqSize, bSqSize,	barWidth, barWidth);
X	DrawBlobSet (tttDonors);
X	DrawBlobSet (tttReceptors);
X}
X
X
XTttActivate	(active)
XBoolean	active;
X{
X	if (active)
X	{
X		SetDragRects (tttPort);
X		SetBCPermissions (false, false, true, false, false);
X	}
X}
X
X
X/*
X	Make receptor blobs
X*/
X	
XTttMakeRBlob (r)
XRect	*r;
X{
XBlobHandle	b;
X
X	b = NewBlob (tttReceptors, false, 0, false, 0L);
X	OpenBlob ();
X	EraseRect (r);
X	InsetRect (r, 1, 1);
X	FrameRect (r);
X	InsetRect (r, 2, 2);
X	FrameRect (r);
X	InsetRect (r, -2, -2);
X	CloseRectBlob (b, r, r);
X}
X
X
XTttMakeReceptors ()
X{
X	tttReceptors =	NewBlobSet ();
X	MakeBlobGrid (3, 3, xOffBoard, yOffBoard, bSqSize, bSqSize,
X					barWidth, barWidth, &TttMakeRBlob);
X}
X
X
X/*
X	Make donor blobs
X*/
X
XTttMakeDBlob (b, ch, x, y)
XBlobHandle	*b;
Xint		ch, x, y;
X{
XRect	r;
X
X	*b = NewBlob (tttDonors, false, 9, false, 0L);
X	OpenBlob ();
X	SetRect (&r, 0, 0, pSqSize, pSqSize);
X	OffsetRect (&r, x, y);
X	EraseRect (&r);
X	PenSize	(2, 2);
X	FrameRect (&r);
X	PenNormal ();
X	MoveTo (r.left+pSqSize/2-4, r.bottom-pSqSize/2+5);
X	DrawChar ((char) ch);
X	CloseRectBlob (*b, &r, &r);
X}
X
X
XTttMakeDonors ()
X{
X	tttDonors = NewBlobSet ();
X	TttMakeDBlob (&xBlob, 'X', xMid-pSqSize-5, yOffPiece);
X	TttMakeDBlob (&oBlob, 'O', xMid+5, yOffPiece);
X}
X
X
XTttInit	()
X{
XRect	r;
X
X	tttPort = GetDemoWind (tttWindRes);
X	SkelWindow (tttPort,
X				TttMouse,		/* mouse clicks */
X				nil,			/* key clicks */
X				TttUpdate,		/* updates */
X				TttActivate,	/* activate/deactivate events */
X				nil,			/* close window */
X				DoWClobber,		/* dispose of window */
X				nil,			/* idle proc */
X				false);			/* irrelevant, since no idle proc */
X
X	TttMakeReceptors ();
X	TttMakeDonors ();
X	EnableBlobSet (tttReceptors);
X	EnableBlobSet (tttDonors);
X	SetRect (&r, xMid-45, yOffBut, xMid+45, yOffBut+20);
X	restartCtl = NewControl (tttPort, &r, "\pRestart", true, 0, 0, 0,
X								pushButProc, nil);
X	TttRestart ();
X	TttUpdate ();
X	ValidRect (&tttPort->portRect);
X}
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > BlobDemo/DemoWind.c
X/*
X	Blob Manager Demonstration:  Window routines
X*/
X
X# include	"BlobDemo.h"
X# include	<WindowMgr.h>
X
X
X
X
X/*
X	Get a window for a demo module.  Pass the resource number of the
X	window.  Set the font to Chicago 12-point, and add the window's
X	title to the Windows menu.
X*/
X
XGrafPtr GetDemoWind (resNum)
Xint		resNum;
X{
XGrafPtr	thePort;
X
X	thePort = (GrafPtr) GetNewWindow (resNum, nil, -1L);
X	SetPort (thePort);
X	TextFont (0);
X	TextSize (0);
X	return (thePort);
X}
X
X
X/*
X	Generic window handler clobber proc for TransSkel stuff
X*/
X
XDoWClobber ()
X{
XWindowPtr	theWind;
X
X	GetPort ((GrafPtr *) &theWind);
X	CloseWindow (theWind);				/* should be DisposeWindow? */
X}
X
X
X/*
X	Set window's default blob dragging rects:  limit rect is portRect
X	of window's grafPort, slop rect is wide open rectangle.
X*/
X
XSetDragRects (thePort)
XGrafPtr	thePort;
X{
XRect	rSlop;
X
X	SetRect (&rSlop, -30000, -30000, 30000, 30000);
X	SetBDragRects (&thePort->portRect, &rSlop);
X}SHAR_EOF
exit
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads