This repository has been archived on 2024-12-16. You can view files and clone it, but cannot push or open issues or pull requests.
CodeBlocksPortable/WATCOM/samples/win/watzee/watzee.c

662 lines
20 KiB
C
Raw Permalink Normal View History

#include <windows.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "watzee.h"
static char *AppName = "Watzee";
static char ClassName[32]="Watzee";
static void DoScore( HDC, WORD );
static void DoScoreTotals( HDC );
static WORD GetDieCheck( HWND, POINT );
static WORD GetScoreCheck( POINT );
static void InitializeGameData( void );
static void NextPlayer( HWND, HDC );
long _EXPORT FAR PASCAL WndProc( HWND, UINT, WPARAM, LPARAM );
/*
* WinMain -- register the window class and call some initialization
* routines; then send a message to WndProc to start a new
* game
*/
int PASCAL WinMain( HINSTANCE instance, HINSTANCE previnstance,
LPSTR cmdline, int cmdshow )
/*******************************************************/
{
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
cmdline = cmdline;
previnstance = previnstance;
#ifdef __WINDOWS_386__
sprintf( ClassName,"Watzee%d",instance );
#else
if( !previnstance ) {
#endif
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = (LPVOID) WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 6 * sizeof( DWORD );
wndclass.hInstance = instance;
wndclass.hIcon = LoadIcon( instance, AppName );
wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
wndclass.hbrBackground = GetStockObject( WHITE_BRUSH );
wndclass.lpszMenuName = AppName;
wndclass.lpszClassName = ClassName;
RegisterClass( &wndclass );
#ifndef __WINDOWS_386__
}
#endif
InitializeGameData();
GetFontInfo();
CreateFonts();
hwnd = CreateWindow( ClassName, "WATZEE",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
CharWidth * 28 + CharWidth / 2, CharHeight * 28,
NULL, NULL, instance, NULL );
GetDiceBitmaps( hwnd );
ShowWindow( hwnd, cmdshow );
UpdateWindow( hwnd );
SendMessage( hwnd, WMW_START_NEW_GAME, 0, 0 );
while( GetMessage( &msg, NULL, 0, 0 ) ) {
TranslateMessage( &msg );
DispatchMessage( &msg );
}
return( msg.wParam );
}
/*
* WndProc -- process messages from Windows
*/
long _EXPORT FAR PASCAL WndProc( HWND hwnd, UINT message, WPARAM wparam,
LPARAM lparam )
/*********************************************************************/
{
static HANDLE hdlginstance;
static BOOL got_watzee_bonus;
PAINTSTRUCT ps;
FARPROC dlg_proc;
HDC hdc;
POINT point;
short x;
short y;
short dy;
short i;
switch( message ) {
case WM_CREATE :
hdlginstance = ((CREATESTRUCT far *) MK_FP32((void*)lparam))->hInstance;
x = CharWidth * 22 + CharWidth / 2;
y = CharHeight * 3;
dy = CharHeight * 3;
dy += dy / 7;
/* create the check marks for the dice bitmaps, and the ROLL and
OK buttons */
for( i = 0; i < 5; i++, y += dy ) {
CreateWindow( "BUTTON", "", WS_CHILD|WS_VISIBLE|BS_CHECKBOX,
x, y, CharWidth, CharHeight, hwnd,
(HMENU)(IDW_DICE1+i),
hdlginstance,
NULL );
}
CreateWindow( "BUTTON", "ROLL", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
x, CharHeight * 19, 9 * CharWidth / 2 ,
CharHeight * 2, hwnd, (HMENU)IDW_ROLL,
hdlginstance, NULL );
CreateWindow( "BUTTON", "OK", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
x, 43 * CharHeight / 2, 9 * CharWidth / 2,
CharHeight * 2, hwnd, (HMENU)IDW_OK,
hdlginstance, NULL );
return( 0 );
case WMW_START_NEW_GAME :
dlg_proc = MakeProcInstance( (FARPROC)GetNumPlayersDialogProc, hdlginstance );
DialogBox( hdlginstance, "GetNumPlayers", hwnd, (DLGPROC)dlg_proc );
FreeProcInstance( dlg_proc );
dlg_proc = MakeProcInstance( (FARPROC)GetInitialsDialogProc, hdlginstance );
DialogBox( hdlginstance, "GetPlayersInitials", hwnd, (DLGPROC)dlg_proc );
FreeProcInstance( dlg_proc );
EnableWindow( GetDlgItem( hwnd, IDW_OK ), FALSE );
EnableWindow( GetDlgItem( hwnd, IDW_ROLL ), TRUE );
PlayingGameYet = TRUE;
InvalidateRect( hwnd, NULL, FALSE );
for( i = 0; i < NumberOfPlayers; i++ ) {
if( Player[i][IS_COMPUTER] ) break;
}
if( i < NumberOfPlayers && !GotTimer ) {
while( !SetTimer( hwnd, ID_TIMER, TIMER_INTERVAL, NULL ) ) {
if( MessageBox( hwnd, "Too many clocks or timers are active",
AppName, MB_ICONEXCLAMATION|MB_RETRYCANCEL ) == IDCANCEL ) {
DestroyWindow( hwnd );
return( 0 );
}
}
GotTimer = TRUE;
}
if( i == 0 ) {
PCTurn = TRUE;
EnableWindow( GetDlgItem( hwnd, IDW_ROLL ), FALSE );
}
hdc = GetDC( hwnd );
RollDice( hwnd, hdc );
GetDiceInfo();
ReleaseDC( hwnd, hdc );
// SetFocus( hwnd );
return( 0 );
case WM_COMMAND :
switch( LOWORD( wparam ) ) {
case IDM_NEWGAME :
if( GotTimer ) {
KillTimer( hwnd, ID_TIMER );
}
if( MessageBox( hwnd, "Start New Game: Are you sure?", "WATZEE",
MB_YESNO | MB_ICONEXCLAMATION ) == IDYES ) {
InitializeGameData();
InvalidateRect( hwnd, NULL, TRUE );
SendMessage( hwnd, WMW_START_NEW_GAME, 0, 0 );
} else if( GotTimer ) {
SetTimer( hwnd, ID_TIMER, TIMER_INTERVAL, NULL );
}
break;
case IDM_OPTIONS :
if( GotTimer ) {
KillTimer( hwnd, ID_TIMER );
}
dlg_proc = MakeProcInstance( (FARPROC)OptionsDialogProc, hdlginstance );
DialogBox( hdlginstance, "Options", hwnd, (DLGPROC)dlg_proc );
FreeProcInstance( dlg_proc );
if( GotTimer ) {
SetTimer( hwnd, ID_TIMER, TIMER_INTERVAL, NULL );
}
break;
case IDM_EXIT :
DestroyWindow( hwnd );
break;
case IDM_SCORING :
if( GotTimer ) {
KillTimer( hwnd, ID_TIMER );
}
dlg_proc = MakeProcInstance( (FARPROC)HelpDialogProc, hdlginstance );
DialogBox( hdlginstance, "WatzeeHelp", hwnd, (DLGPROC)dlg_proc );
FreeProcInstance( dlg_proc );
if( GotTimer ) {
SetTimer( hwnd, ID_TIMER, TIMER_INTERVAL, NULL );
}
break;
case IDM_ABOUT :
if( GotTimer ) {
KillTimer( hwnd, ID_TIMER );
}
dlg_proc = MakeProcInstance( (FARPROC)AboutDialogProc, hdlginstance );
DialogBox( hdlginstance, "AboutWatzee", hwnd, (DLGPROC)dlg_proc );
FreeProcInstance( dlg_proc );
if( GotTimer ) {
SetTimer( hwnd, ID_TIMER, TIMER_INTERVAL, NULL );
}
break;
case IDW_DICE1 :
case IDW_DICE2 :
case IDW_DICE3 :
case IDW_DICE4 :
case IDW_DICE5 :
if( !PCTurn && CurrentRoll < 2 ) {
SendMessage( hwnd, WMW_DIE_CHECK, wparam, 0 );
}
break;
case IDW_ROLL :
SendMessage( hwnd, WMW_ROLL, 0, 0 );
break;
case IDW_OK :
SendMessage( hwnd, WMW_OK, 0, 0 );
break;
}
return( 0 );
case WM_LBUTTONUP :
if( !PCTurn ) {
MAKE_POINT( point, lparam );
if( point.x > CharWidth * 24
&& point.y < CharHeight * 20 ) {
wparam = GetDieCheck( hwnd, point );
if( wparam && CurrentRoll < 2 ) {
SendMessage( hwnd, WMW_DIE_CHECK, wparam, 0 );
}
} else {
wparam = GetScoreCheck( point );
if( wparam && Player[CurrentPlayer][wparam] == UNDEFINED ) {
SendMessage( hwnd, WMW_SCORE_CHECK, wparam, 0 );
}
}
}
return( 0 );
case WMW_DIE_CHECK :
i = LOWORD( wparam ) - IDW_DICE1;
Dice[i].is_checked = !Dice[i].is_checked;
CheckDlgButton( hwnd, wparam, (BOOL)Dice[i].is_checked );
// SetFocus( hwnd );
return( 0 );
case WMW_SCORE_CHECK :
hdc = GetDC( hwnd );
if( wparam != LastScoreSelection ) {
DoScore( hdc, wparam );
EnableWindow( GetDlgItem( hwnd, IDW_OK ), TRUE );
}
ReleaseDC( hwnd, hdc );
// SetFocus( hwnd );
return( 0 );
case WMW_ROLL :
hdc = GetDC( hwnd );
if( DieCheckMeansRoll ) {
for( i = 0; i < 5; i++ ) {
if( Dice[i].is_checked ) break;
}
} else {
for( i = 0; i < 5; i++ ) {
if( !Dice[i].is_checked ) break;
}
}
if( i < 5 ) {
if( LastScoreSelection ) {
Player[CurrentPlayer][LastScoreSelection] = UNDEFINED;
WriteScore( hdc, CurrentPlayer, LastScoreSelection );
DoScoreTotals( hdc );
LastScoreSelection = 0;
}
got_watzee_bonus = FALSE;
CurrentRoll++;
RollDice( hwnd, hdc );
GetDiceInfo();
if( DiceInfo.got_watzee && Player[CurrentPlayer][WATZEE] == 50 ) {
got_watzee_bonus = TRUE;
}
if( CurrentRoll == 2 ) {
EnableWindow( GetDlgItem( hwnd, IDW_ROLL ), FALSE );
}
}
ReleaseDC( hwnd, hdc );
// SetFocus( hwnd );
return( 0 );
case WMW_OK :
hdc = GetDC( hwnd );
LastScoreSelection = 0;
if( got_watzee_bonus ) {
DoScore( hdc, WATZEE_BONUS );
LastScoreSelection = 0;
got_watzee_bonus = FALSE;
}
NextPlayer( hwnd, hdc );
ReleaseDC( hwnd, hdc );
// SetFocus( hwnd );
return( 0 );
case WMW_GAME_OVER :
hdc = GetDC( hwnd );
WriteScoreOptions( hdc );
ReleaseDC( hwnd, hdc );
if( GotTimer ) {
KillTimer( hwnd, ID_TIMER );
GotTimer = FALSE;
}
if( MessageBox( hwnd, "Another Game ?", "WATZEE", MB_YESNO ) == IDYES ) {
InitializeGameData();
InvalidateRect( hwnd, NULL, TRUE );
SendMessage( hwnd, WMW_START_NEW_GAME, 0, 0 );
} else {
DestroyWindow( hwnd );
}
return( 0 );
case WM_TIMER :
if( PCTurn ) {
PCPlay( hwnd );
}
return( 0 );
case WM_PAINT :
hdc = BeginPaint( hwnd, &ps );
DrawDice( hwnd, hdc );
DrawScoreCard( hdc );
WriteScoreOptions( hdc );
if( PlayingGameYet ) {
WriteInitials( hdc );
HighliteName( hdc, CurrentPlayer );
WriteScores( hdc );
}
EndPaint( hwnd, &ps );
return( 0 );
case WM_DESTROY :
{
HBITMAP hbm;
if( GotTimer ) {
KillTimer( hwnd, ID_TIMER );
}
for( i = 0; i < 6; i++ ) {
hbm = (HBITMAP)GetWindowLong( hwnd, i * sizeof( DWORD ) );
DeleteObject( hbm );
}
PostQuitMessage( 0 );
return( 0 );
}
}
return( DefWindowProc( hwnd, message, wparam, lparam ) );
}
/*
* DoScore -- update the score card after a score selection
*/
static void DoScore( HDC hdc, WORD selection )
/********************************************/
{
HFONT hfont;
short score;
score = 0;
if( LastScoreSelection ) {
Player[CurrentPlayer][LastScoreSelection] = UNDEFINED;
WriteScore( hdc, CurrentPlayer, LastScoreSelection );
DoScoreTotals( hdc );
}
LastScoreSelection = selection;
switch( selection ) {
case ACES :
case TWOS :
case THREES :
case FOURS :
case FIVES :
case SIXES :
score = DiceInfo.count[selection] * selection;
break;
case THREE_KIND :
if( DiceInfo.got_three_kind ) {
score = DiceInfo.sum;
}
break;
case FOUR_KIND :
if( DiceInfo.got_four_kind ) {
score = DiceInfo.sum;
}
break;
case FULL_HOUSE :
if( DiceInfo.got_full_house ) {
score = 25;
}
break;
case SMALL_STRAIGHT :
if( DiceInfo.got_small_straight ) {
score = 30;
}
break;
case LARGE_STRAIGHT :
if( DiceInfo.got_large_straight ) {
score = 40;
}
break;
case WATZEE :
if( DiceInfo.got_watzee ) {
score = 50;
}
break;
case WATZEE_BONUS :
score = Player[CurrentPlayer][WATZEE_BONUS];
if( score == UNDEFINED ) {
score = 100;
} else {
score += 100;
}
break;
case CHANCE :
score = DiceInfo.sum;
break;
}
Player[CurrentPlayer][selection] = score;
hfont = SelectObject( hdc, CreateFontIndirect( &SmallBoldFont ) );
WriteScore( hdc, CurrentPlayer, selection );
DeleteObject( SelectObject( hdc, hfont ) );
DoScoreTotals( hdc );
}
/*
* DoScoreTotals -- update the current player's Upper Total, Bonus, Lower Total
* and Grand Total
*/
static void DoScoreTotals( HDC hdc )
/**********************************/
{
short upper_total;
short lower_total;
short i;
upper_total = 0;
lower_total = 0;
for( i = ACES; i <= SIXES; i++ ) {
if( Player[CurrentPlayer][i] != UNDEFINED ) {
upper_total += Player[CurrentPlayer][i];
}
}
if( upper_total >= 63 ) {
upper_total += 35;
Player[CurrentPlayer][BONUS] = 35;
}
Player[CurrentPlayer][UPPER_TOTAL] = upper_total;
for( i = THREE_KIND; i <= WATZEE_BONUS; i++ ) {
if( Player[CurrentPlayer][i] != UNDEFINED ) {
lower_total += Player[CurrentPlayer][i];
}
}
Player[CurrentPlayer][LOWER_TOTAL] = lower_total;
Player[CurrentPlayer][GRAND_TOTAL] = upper_total + lower_total;
SelectObject( hdc, GetStockObject( SYSTEM_FONT ) );
for( i = BONUS; i <= GRAND_TOTAL; i++ ) {
WriteScore( hdc, CurrentPlayer, i );
}
}
/*
* GetDieCheck -- determine where on the score card the user just clicked,
* and decide whether the user just checked one of the die;
* return a value between 1 and 5 indicating which die, or
* zero if a die was not clicked
*/
static WORD GetDieCheck( HWND hwnd, POINT point )
/***********************************************/
{
BITMAP bm;
RECT rect;
WORD die_checked;
short dy;
short i;
HBITMAP hbm;
die_checked = 0;
hbm = (HBITMAP)GetWindowLong( hwnd, 0 );
GetObject( hbm, sizeof( BITMAP ), (LPSTR) &bm );
rect.top = CharHeight * 2;
rect.bottom = rect.top + bm.bmHeight;
rect.left = CharWidth * 24;
rect.right = rect.left + bm.bmWidth;
dy = bm.bmHeight + bm.bmHeight / 7;
for( i = 0; i < 5; i++ ) {
if( PtInRect( &rect, point ) ) break;
rect.top += dy;
rect.bottom += dy;
}
if( i < 5 ) {
die_checked = IDW_DICE1 + i;
}
return( die_checked );
}
/*
* GetScoreCheck -- determine where on the score card the user just clicked,
* and decide whether the user just made a valid score
* selection; return the score option that was chosen, or
* zero if a score option was not clicked
*/
static WORD GetScoreCheck( POINT point )
/**************************************/
{
short x;
short y;
short char_height;
short char_width;
short score_option_vline;
short left_column;
short right_column;
short score_selection;
x = point.x;
y = point.y;
score_selection = 0;
char_height = CharHeight;
char_width = CharWidth;
score_option_vline = char_width * SCORE_OPTIONS_WIDTH + char_width;
left_column = score_option_vline + CurrentPlayer * char_width * 3;
right_column = left_column + char_width * 3;
if( ( x < score_option_vline && x > char_width )
|| ( x > left_column && x < right_column ) ) {
if( y < char_height * 9 && y > char_height * 3 ) {
if( y < char_height * 6 ) {
if( y < char_height * 4 ) {
score_selection = ACES;
} else if( y < char_height * 5 ) {
score_selection = TWOS;
} else {
score_selection = THREES;
}
} else {
if( y < char_height * 7 ) {
score_selection = FOURS;
} else if( y < char_height * 8 ) {
score_selection = FIVES;
} else {
score_selection = SIXES;
}
}
} else if( y > char_height * 12 && y < char_height * 19 ) {
if( y < char_height * 16 ) {
if( y < char_height * 14 ) {
if( y < char_height * 13 ) {
score_selection = THREE_KIND;
} else {
score_selection = FOUR_KIND;
}
} else if( y < char_height * 15 ) {
score_selection = FULL_HOUSE;
} else {
score_selection = SMALL_STRAIGHT;
}
} else if( y < char_height * 17 ) {
score_selection = LARGE_STRAIGHT;
} else if( y < char_height * 18 ) {
score_selection = WATZEE;
} else {
score_selection = CHANCE;
}
}
}
return( score_selection );
}
/*
* InitializeGameData -- initialize the scores, the player's initials, and
* other global variables
*/
static void InitializeGameData( void )
/************************************/
{
short i;
short j;
NumberOfPlayers = 0;
PlayingGameYet = FALSE;
CurrentTurn = 0;
CurrentPlayer = 0;
CurrentRoll = 0;
DieCheckMeansRoll = TRUE;
ResetDieChecks = TRUE;
GotTimer = FALSE;
LastScoreSelection = 0;
PCTurn = FALSE;
for( i = 0; i < MAX_PLAYERS; i++ ) {
Player[i][IS_COMPUTER] = FALSE;
for( j = ACES; j < LOWER_TOTAL; j++ ) {
Player[i][j] = UNDEFINED;
}
Player[i][UPPER_TOTAL] = 0;
Player[i][LOWER_TOTAL] = 0;
Player[i][GRAND_TOTAL] = 0;
sprintf( PlayerName[i], " " );
}
for( i = 0; i < 5; i++ ) {
Dice[i].value = i+1;
Dice[i].is_checked = TRUE;
}
}
/*
* NextPlayer -- determine if the game is over; if not, reset the
* CurrentTurn counter for the next player and initialize
* the dice
*/
static void NextPlayer( HWND hwnd, HDC hdc )
/******************************************/
{
BOOL reset_value;
short i;
PCTurn = FALSE;
HighliteName( hdc, CurrentPlayer );
CurrentPlayer++;
if( CurrentPlayer == NumberOfPlayers ) {
CurrentPlayer = 0;
CurrentTurn++;
if( CurrentTurn == 13 ) {
SendMessage( hwnd, WMW_GAME_OVER, 0, 0 );
return;
}
}
HighliteName( hdc, CurrentPlayer );
WriteScoreOptions( hdc );
CurrentRoll = 0;
reset_value = FALSE;
if( DieCheckMeansRoll ) {
reset_value = TRUE;
}
for( i = 0; i < 5; i++ ) {
Dice[i].is_checked = reset_value;
CheckDlgButton( hwnd, IDW_DICE1+i, reset_value );
}
RollDice( hwnd, hdc );
GetDiceInfo();
EnableWindow( GetDlgItem( hwnd, IDW_OK ), FALSE );
if( Player[CurrentPlayer][IS_COMPUTER] ) {
PCTurn = TRUE;
EnableWindow( GetDlgItem( hwnd, IDW_ROLL ), FALSE );
} else {
EnableWindow( GetDlgItem( hwnd, IDW_ROLL ), TRUE );
}
}