📄 puzzleapp.c
字号:
{
RectangleType rect;
Int16 i;
FrameBitsType frameBits;
// Draw the board frame
rect.topLeft.x = boardX;
rect.topLeft.y = boardY;
rect.extent.x = (boardColumns * pieceWidth) + (boardFrameMargin * 2) +
((boardColumns - 1) * pieceSpace);
rect.extent.y = (boardRows * pieceHeight) + (boardFrameMargin * 2) +
((boardRows - 1) * pieceSpace);
WinEraseRectangle( &rect, 0/*cornerDiam*/ );
frameBits.word = 0; // initialize the entire structure
frameBits.bits.cornerDiam = 0;
frameBits.bits.threeD = 0;
frameBits.bits.shadowWidth = 0;
frameBits.bits.width = boardFrameWidth;
WinDrawGrayRectangleFrame ( frameBits.word, &rect );
// Draw the game pieces
for ( i=0; i < numPositions; i++ )
DrawPiece(i);
}
/***********************************************************************
*
* FUNCTION: MoveOnePiece
*
* DESCRIPTION: Move a game piece to the empty position
*
* PARAMETERS: from -- piece position (0-based)
* draw -- non-zero to update visually
*
* RETURNED: nothing
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* vmk 8/19/95 Initial Version
*
***********************************************************************/
static void MoveOnePiece(Int16 from, Boolean draw)
{
Int16 newPos;
ErrFatalDisplayIf( from >= numPositions, "from position out of bounds" );
ErrFatalDisplayIf( EmptyPos != GetEmptyPos(), "EmptyPos is invalid" );
newPos = EmptyPos;
GameBoard.square[newPos] = GameBoard.square[from];
GameBoard.square[from] = emptySquareID;
EmptyPos = from;
// Update display
if ( draw )
{
DrawPiece( from );
DrawPiece( newPos );
}
}
/***********************************************************************
*
* FUNCTION: MoveRange
*
* DESCRIPTION: Shift game pieces to the empty position
*
* Enforces rules for moving:
* the from piece must be in the same row or column
* as the empty square
*
* PARAMETERS: from -- first piece position (0-based)
* draw -- non-zero to update visually
*
* RETURNED: nothing
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* vmk 8/19/95 Initial Version
*
***********************************************************************/
static void MoveRange(Int16 from, Boolean draw)
{
PieceCoordType emptyCoord;
PieceCoordType fromCoord;
Int16 movePos;
Int16 increment;
ErrFatalDisplayIf( from >= numPositions, "from position out of bounds" );
ErrFatalDisplayIf( EmptyPos != GetEmptyPos(), "EmptyPos is invalid" );
if ( from == EmptyPos )
return;
// Make sure the from piece is in the same row or the same column
// as the empty square
fromCoord = PositionToCoord( from );
emptyCoord = PositionToCoord( EmptyPos );
// Are we in the same row as the empty square ?
if ( fromCoord.row == emptyCoord.row )
{
// Are we to the left of the empty square ?
if ( fromCoord.col < emptyCoord.col )
{
emptyCoord.col--; // trash empty square coord
movePos = CoordToPosition( emptyCoord );
increment = -1;
}
// nope, we're to the right of the empty square
else
{
emptyCoord.col++; // trash empty square coord
movePos = CoordToPosition( emptyCoord );
increment = 1;
}
} // Are we in the same row as the empty square ?
// Are we in the same column as the empty square ?
else if ( fromCoord.col == emptyCoord.col )
{
// Are we above the empty square ?
if ( fromCoord.row < emptyCoord.row )
{
emptyCoord.row--; // trash empty square coord
movePos = CoordToPosition( emptyCoord );
increment = -1 * boardColumns;
}
// nope, we're below the empty square
else
{
emptyCoord.row++; // trash empty square coord
movePos = CoordToPosition( emptyCoord );
increment = boardColumns;
}
} // Are we in the same column as the empty square ?
// Illegal move
else
{
return;
}
// Move the pieces
do {
MoveOnePiece( movePos, draw );
if ( movePos == from )
break;
movePos += increment;
}
while (true);
}
/***********************************************************************
*
* FUNCTION: StartApplication
*
* DESCRIPTION: Initialize application.
*
* Load board from features, or generate a new board
*
* PARAMETERS: none
*
* RETURNED: 0 on success
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* vmk 8/19/95 Initial Version
*
***********************************************************************/
static UInt16 StartApplication (void)
{
// Initialize the random number seed;
SysRandom( TimGetSeconds() );
LoadGameBoard();
return( 0 );
}
/***********************************************************************
*
* FUNCTION: StopApplication
*
* DESCRIPTION: Save the current state of the application and close all
* forms.
*
* PARAMETERS: none
*
* RETURNED: nothing
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* vmk 8/19/95 Initial Version
*
***********************************************************************/
static void StopApplication (void)
{
SaveGameBoard();
FrmCloseAllForms ();
}
/***********************************************************************
*
* FUNCTION: RomVersionCompatible
*
* DESCRIPTION: This routine checks that a ROM version is meet your
* minimum requirement.
*
* PARAMETERS: requiredVersion - minimum rom version required
* (see sysFtrNumROMVersion in SystemMgr.h
* for format)
* launchFlags - flags that indicate if the application
* UI is initialized.
*
* RETURNED: error code or zero if rom is compatible
*
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 11/15/96 Initial Revision
*
***********************************************************************/
static Err RomVersionCompatible (UInt32 requiredVersion, UInt16 launchFlags)
{
UInt32 romVersion;
// See if we're on in minimum required version of the ROM or later.
FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion);
if (romVersion < requiredVersion)
{
if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) ==
(sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp))
{
FrmAlert (RomIncompatibleAlert);
// Pilot 1.0 will continuously relaunch this app unless we switch to
// another safe one.
if (romVersion < 0x02000000)
{
AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL);
}
}
return (sysErrRomIncompatible);
}
return (0);
}
/***********************************************************************
*
* FUNCTION: MainFormDoCommand
*
* DESCRIPTION: This routine performs the menu command specified.
*
* PARAMETERS: command - menu item id
*
* RETURNED: true if the command was handled
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* vmk 8/19/95 Initial Version
*
***********************************************************************/
static Boolean MainFormDoCommand (UInt16 command)
{
Boolean handled = false;
MenuEraseStatus (0);
switch (command)
{
case MainOptionsAboutCmd:
AbtShowAbout (puzzleAppCreator);
handled = true;
break;
case MainOptionsInstructions:
FrmHelp (InstructionsStr);
break;
case MainOptionsSolvePuzzleCmd:
InitGameBoard();
DrawGameBoard();
handled = true;
break;
}
return handled;
}
/***********************************************************************
*
* FUNCTION: MainFormInit
*
* DESCRIPTION: This routine initializes the "Main View"
*
* PARAMETERS: frm - a pointer to the MainForm form
*
* RETURNED: nothing.
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* vmk 8/19/95 Initial Version
* baj 6/22/04 Avoid unused parameter warning.
*
***********************************************************************/
static void MainFormInit (FormPtr frm)
{
frm = NULL; // Avoid unused parameter warning
}
/***********************************************************************
*
* FUNCTION: MainFormHandleEvent
*
* DESCRIPTION: This routine is the event handler for the "Main View"
*
* PARAMETERS: event - a pointer to an EventType structure
*
* RETURNED: true if the event has handle and should not be passed
* to a higher level handler.
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* roger 8/7/95 Initial Revision
*
***********************************************************************/
static Boolean MainFormHandleEvent (EventPtr event)
{
FormPtr frm;
Boolean handled = false;
if (event->eType == ctlSelectEvent)
{
switch (event->data.ctlSelect.controlID)
{
case MainFormNewPuzzleButton:
ShuffleGameBoard( numShuffleMoves );
DrawGameBoard();
handled = true;
break;
default:
break;
}
}
else if ( event->eType == penDownEvent )
{
Int16 from;
from = MapPenPosition( event->screenX, event->screenY );
if ( from >= 0 )
{
MoveRange( from, true/*draw*/ );
handled = true;
}
}
else if (event->eType == menuEvent)
{
return MainFormDoCommand (event->data.menu.itemID);
}
else if (event->eType == frmUpdateEvent)
{
FrmDrawForm (FrmGetActiveForm());
DrawGameBoard();
handled = true;
}
else if (event->eType == frmOpenEvent)
{
frm = FrmGetActiveForm();
MainFormInit (frm);
FrmDrawForm (frm);
DrawGameBoard();
handled = true;
}
else if (event->eType == frmCloseEvent)
{
}
return (handled);
}
/***********************************************************************
*
* FUNCTION: AppHandleEvent
*
* DESCRIPTION: This routine loads form resources and set the event
* handler for the form loaded.
*
* PARAMETERS: event - a pointer to an EventType structure
*
* RETURNED: true if the event has handle and should not be passed
* to a higher level handler.
*
* REVISION HISTORY:
*
*
***********************************************************************/
static Boolean AppHandleEvent( EventPtr eventP)
{
UInt16 formId;
FormPtr frmP;
if (eventP->eType == frmLoadEvent)
{
// Load the form resource.
formId = eventP->data.frmLoad.formID;
frmP = FrmInitForm(formId);
FrmSetActiveForm(frmP);
// Set the event handler for the form. The handler of the currently
// active form is called by FrmHandleEvent each time is receives an
// event.
switch (formId)
{
case MainForm:
FrmSetEventHandler(frmP, MainFormHandleEvent);
break;
default:
ErrNonFatalDisplay("Invalid Form Load Event");
break;
}
return true;
}
return false;
}
/***********************************************************************
*
* FUNCTION: AppEventLoop
*
* DESCRIPTION: This routine is the event loop for the application.
*
* PARAMETERS: nothing
*
* RETURNED: nothing
*
* REVISION HISTORY:
*
*
***********************************************************************/
static void AppEventLoop(void)
{
UInt16 error;
EventType event;
do {
EvtGetEvent(&event, evtWaitForever);
if (! SysHandleEvent(&event))
if (! MenuHandleEvent(0, &event, &error))
if (! AppHandleEvent(&event))
FrmDispatchEvent(&event);
// Check the heaps after each event
#if EMULATION_LEVEL != EMULATION_NONE
MemHeapCheck(0);
MemHeapCheck(1);
#endif
} while (event.eType != appStopEvent);
}
/***********************************************************************
*
* FUNCTION: PilotMain
*
* DESCRIPTION: This is the main entry point for the Puzzle
* application.
*
* PARAMETERS: nothing
*
* RETURNED: 0
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* vmk 8/19/95 Initial Revision
* baj 6/22/04 Avoid unused parameter warning.
*
***********************************************************************/
UInt32 PilotMain (UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags)
{
UInt16 error;
cmdPBP = NULL; // Avoid variable unused warning
error = RomVersionCompatible (version20, launchFlags);
if (error) return (error);
if ( cmd == sysAppLaunchCmdNormalLaunch )
{
error = StartApplication ();
if (error) return (error);
FrmGotoForm (MainForm);
AppEventLoop ();
StopApplication ();
}
return (0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -