home *** CD-ROM | disk | FTP | other *** search
- /*==============================================================*\
- * Svrpgame.c - game processing routine: processing of client
- * messages and game algorithm.
- * Copyright 1992, IBM Corp.
- *
- * DISCLAIMER OF WARRANTIES. The following [enclosed] code is
- * sample code created by IBM Corporation. This sample code is not
- * part of any standard or IBM product and is provided to you solely
- * for the purpose of assisting you in the development of your
- * applications. The code is provided "AS IS", without
- * warranty of any kind. IBM shall not be liable for any damages
- * arising out of your use of the sample code, even if they have been
- * advised of the possibility of such damages. *
- *
- *
- \*==============================================================*/
-
-
- #define INCL_DOSPROCESS
- #define INCL_DOSNMPIPES
- #define INCL_DOSMEMMGR
- #define INCL_WINMESSAGEMGR
- #define INCL_DOSERRORS
- #define INCL_DOSFILEMGR
-
- #include <os2.h>
-
- #include <stddef.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include "namepipe.h"
- #include "svrpglbl.h"
- #include "svrpmain.h"
- #include "svrpxtrn.h"
-
-
- VOID GameThread(VOID *hpTempPipe)
- {
- HPIPE hpGamePipe;
- BOOL fQuit=FALSE;
- PPIB dummy;
- PTIB ptibThrdInfo;
- ULONG ulID;
- USHORT usMsg, usData, GameBoard[DIVISIONS][DIVISIONS], usTotalMoves=0;
-
- /* save pipe handle in own memory */
- hpGamePipe = *(HPIPE *)hpTempPipe;
-
- /* get thread ID for use in displaying messages */
- if((BOOL)DosGetInfoBlocks(&ptibThrdInfo, &dummy))
- {
- ulID = 0;
- }
-
- else
- {
- ulID = ptibThrdInfo->tib_ptib2->tib2_ultid;
- }
-
- InitBoard(GameBoard);
-
- /* initialize random number generator */
- srand((unsigned) ulID);
-
- if(!(BOOL)DosConnectNPipe(hpGamePipe))
- {
- while (!fAppExit &&
- !fQuit &&
- !(BOOL)(Pipe_IO(CLIENT, hpGamePipe, &usMsg, &usData, ulID)) &&
- !fAppExit)
- {
- switch (usMsg)
- {
- case CLIENT_MOVE:
- /* enter move from message */
- *((USHORT *)GameBoard + usData) = CLIENT_NUM;
- usTotalMoves++;
-
- /* test for win if total moves >= DIVISIONS*2-1 */
- if (usTotalMoves >= DIVISIONS*2-1 &&
- ((BOOL)(usData=WinTest(GameBoard)) ||
- usTotalMoves == DIVISIONS*DIVISIONS))
- {
- /* notify of win or draw, and break (switch) on return */
- if (!usData)
- {
- usData = DIVISIONS*DIVISIONS;
- usMsg = WIN_DRAW;
- }
-
- else
- {
- usMsg = WIN_CLIENT;
- }
-
- if ((BOOL)Pipe_IO(SERVER, hpGamePipe, &usMsg, &usData, ulID))
- {
- WinPostMsg(hwndMain, WM_MSG, MPFROMLONG(IDMSG_PIPE_WRITE_FAILED), MPVOID);
- fQuit = TRUE;
- break;
- }
-
- /* call InitBoard on win */
- InitBoard(GameBoard);
- usTotalMoves = 0;
-
- break; /* switch */
- }
-
- /* NO BREAK */
-
- case YOU_FIRST:
- /* get move if there are moves left */
- usData = GetMove(GameBoard, usTotalMoves);
- usTotalMoves++;
-
- /* test for win if total moves >= DIVISIONS*2-1 */
- if (usTotalMoves >= DIVISIONS*2-1 &&
- ((BOOL)(usMsg=WinTest(GameBoard)) ||
- usTotalMoves == DIVISIONS*DIVISIONS))
- {
- /* write game_won message with winning move */
- if (!usMsg)
- {
- usMsg = WIN_DRAW;
- }
-
- else
- {
- usMsg = WIN_SERVER;
- }
-
- if ((BOOL)Pipe_IO(SERVER, hpGamePipe, &usMsg, &usData, ulID))
- {
- WinPostMsg(hwndMain, WM_MSG, MPFROMLONG(IDMSG_PIPE_WRITE_FAILED), MPVOID);
- fQuit = TRUE;
- break;
- }
-
- /* call InitBoard on win */
- InitBoard(GameBoard);
- usTotalMoves = 0;
- }
-
- /* else */
- else
- {
- /* write move to client */
- usMsg = SERVER_MOVE;
- if ((BOOL)Pipe_IO(SERVER, hpGamePipe, &usMsg, &usData, ulID))
- {
- WinPostMsg(hwndMain, WM_MSG, MPFROMLONG(IDMSG_PIPE_WRITE_FAILED), MPVOID);
- fQuit = TRUE;
- }
- }
- break;
-
- case ERROR_MSG:
- /* post the error to message queue */
- WinPostMsg(hwndMain, WM_MSG, MPFROMSHORT(usData), MPVOID);
-
- case CLIENT_QUIT:
- /* quit while */
- fQuit = TRUE;
- }
- }
-
- DosDisConnectNPipe(hpGamePipe);
- }
-
- DosClose(hpGamePipe);
- }
-
-
- /*
- * Check for pieces owning entire row, column, or diagonal.
- */
- USHORT WinTest(USHORT GameBoard[DIVISIONS][DIVISIONS])
- {
- USHORT usWinner=0, usTotal1=0, usTotal2=0, usTotal3=0, usTotal4=0;
- int i, j;
-
- for (i = 0; i < DIVISIONS && !(BOOL)usWinner; i++)
- {
- for (j = 0; j < DIVISIONS && !(BOOL)usWinner; j++)
- {
- usTotal1 += GameBoard[i][j];
- usTotal2 += GameBoard[j][i];
- }
-
- if (SERVER_NUM * DIVISIONS == usTotal1 || CLIENT_NUM * DIVISIONS == usTotal1)
- {
- usWinner = usTotal1/(USHORT)DIVISIONS;
- }
-
- else if (SERVER_NUM * DIVISIONS == usTotal2 || CLIENT_NUM * DIVISIONS == usTotal2)
- {
- usWinner = usTotal2/(USHORT)DIVISIONS;
- }
-
- else
- {
- usTotal1 = usTotal2 = 0;
- usTotal3 += GameBoard[i][i];
- usTotal4 += GameBoard[i][DIVISIONS-i-1];
- }
- }
-
- if (SERVER_NUM * DIVISIONS == usTotal3 || CLIENT_NUM * DIVISIONS == usTotal3)
- {
- usWinner = usTotal3/(USHORT)DIVISIONS;
- }
-
- else if (SERVER_NUM * DIVISIONS == usTotal4 || CLIENT_NUM * DIVISIONS == usTotal4)
- {
- usWinner = usTotal4/(USHORT)DIVISIONS;
- }
-
- return(usWinner);
- }
-
-
- USHORT GetMove(USHORT GameBoard[DIVISIONS][DIVISIONS], USHORT usTotalMoves)
- {
- USHORT usMovesLeft;
- int i, j;
-
- usMovesLeft = (USHORT)((USHORT)DIVISIONS * (USHORT)DIVISIONS - usTotalMoves);
-
- /* a poor man's AI */
- usMovesLeft = (USHORT)((usMovesLeft * rand()) / (RAND_MAX + 1));
-
- for (i = 0; i < DIVISIONS; i++)
- {
- for (j = 0; j < DIVISIONS; j++)
- {
- if (0 == GameBoard[i][j] && 0 == usMovesLeft--)
- {
- GameBoard[i][j] = SERVER_NUM;
- return((USHORT)(i * DIVISIONS + j));
- }
- }
- }
- }
-
-
- /*
- * Reset game board.
- */
- VOID InitBoard(USHORT GameBoard[DIVISIONS][DIVISIONS])
- {
- int i, j;
-
- for (i = 0; i < DIVISIONS; i++)
- for (j = 0; j < DIVISIONS; j++)
- GameBoard[i][j] = 0;
- }
-