home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Pier Shareware 6
/
The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso
/
035
/
pmics.zip
/
game.cc
< prev
next >
Wrap
C/C++ Source or Header
|
1994-11-23
|
8KB
|
323 lines
/*
PMICS -- PM interface for playing chess on internet chess server
Copyright (C) 1994 Kevin Nomura
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Author can be reached at email: chow@netcom.com
*/
typedef int Boolean;
#include "game.hh"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void AGame::initialize()
{
enum Piece initial_configuration[8][8] = {
W_ROO,W_KNI,W_BIS,W_QUE,W_KIN,W_BIS,W_KNI,W_ROO,
W_PAW,W_PAW,W_PAW,W_PAW,W_PAW,W_PAW,W_PAW,W_PAW,
EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,
EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,
EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,
EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,
B_PAW,B_PAW,B_PAW,B_PAW,B_PAW,B_PAW,B_PAW,B_PAW,
B_ROO,B_KNI,B_BIS,B_QUE,B_KIN,B_BIS,B_KNI,B_ROO
};
memcpy((void *)pieceArray,
initial_configuration,sizeof(initial_configuration));
setMoveNumber(1);
setOnMove(WHITE);
}
AGame::AGame()
{
fprintf(stderr,"AGame constructor\n");
initialize();
}
AGame::~AGame()
{
fprintf(stderr,"AGame destructor\n");
}
AGame *AGame::current()
{
static AGame *currentGame = NULL;
if (currentGame == NULL)
currentGame = new AGame;
return currentGame;
}
char *AGame::asString()
{
static char pieceMn[] = " RKBQKPrkbqkp";
static char s[64*2 + 8 + 1], *p;
p = s;
for (int file=0; file<8; file++) {
for (int rank=0; rank<8; rank++) {
*p++ = pieceMn[piece(file,rank)];
*p++ = ' ';
}
*p++ = '\n';
}
*p = 0;
return s;
}
AGame::Piece AGame::toPiece(char c)
{
Piece p;
switch(c) {
case 'R': p = AGame::W_ROO; break;
case 'N': p = AGame::W_KNI; break;
case 'B': p = AGame::W_BIS; break;
case 'Q': p = AGame::W_QUE; break;
case 'K': p = AGame::W_KIN; break;
case 'P': p = AGame::W_PAW; break;
case 'r': p = AGame::B_ROO; break;
case 'n': p = AGame::B_KNI; break;
case 'b': p = AGame::B_BIS; break;
case 'q': p = AGame::B_QUE; break;
case 'k': p = AGame::B_KIN; break;
case 'p': p = AGame::B_PAW; break;
default: p = AGame::EMPTY; break;
}
return p;
}
#ifdef MOO
void GAME::plot(HPS hps)
{
BITMAPINFO2 pbmi;
BITMAPINFO2 pbmi64;
HBITMAP hbm;
POINTL ptl[4] = {0,0,64,64,0,0,64,64};
POINTL ptl2[4] = {80,80};
POINTL p;
int rank, file;
pbmi.cbFix = 16;
pbmi.cx = 40;
pbmi.cy = 40;
pbmi.cPlanes = 1;
pbmi.cBitCount = 1;
pbmi64.cbFix = 16;
pbmi64.cx = 64;
pbmi64.cy = 64;
pbmi64.cPlanes = 1;
pbmi64.cBitCount = 1;
/* GpiDrawBits(hps, bishop64, &pbmi64, 4, ptl, ROP_SRCCOPY, 0);
hbm = GpiCreateBitmap(hps, (PBITMAPINFOHEADER2)&pbmi, CBM_INIT, (PBYTE)bishop40, &pbmi);
WinDrawBitmap(hps, hbm, NULL, ptl2, CLR_BLACK, CLR_WHITE, DBM_NORMAL);*/
for (rank=0; rank<8; rank++)
for (file=0; file<8; file++)
plot_piece(hps,piece(file,rank),rank,file);
}
void GAME::update(HPS hps)
{
register int rank, file;
/* incremental update: opiece represents what is on the screen; piece */
/* is the actual state of the board. make the screen look like piece */
/* and copy piece to opiece. all updates (flip, statusproc, etc). are */
/* made to piece. */
for (rank=0; rank<8; rank++)
for (file=0; file<8; file++)
if (piece[rank][file] != opiece[rank][file] ||
oAtTop != atTop)
plot_piece(hps, piece[rank][file],rank,file);
oAtTop = atTop;
}
void GAME::orient(char colour)
{
if (colour == ' ')
atTop = (atTop == 'B' ? 'W' : 'B');
else
atTop = colour;
}
/*************/
/* BoardInit */
/*************/
void GAME::init()
{
register int rank,file;
newboard();
for (rank=0; rank<8; rank++)
for (file=0; file<8; file++)
opiece[rank][file] = PI_EMPTY; // forces plot update
atTop = oAtTop = 'B';
strcpy(playerW, "White");
strcpy(playerB, "Black");
timeW = 3600;
timeB = 3600;
moveNum = 0;
clockRun = FALSE;
}
/*************/
/* BoardMove */
/*************/
void GAME::move(HPS hps,char rankFrom, char fileFrom, char rankTo, char fileTo)
{
register char temp; /* to handle error case of a1->a1, etc */
temp = piece[rankFrom][fileFrom];
piece[rankFrom][fileFrom] = PI_EMPTY;
piece[rankTo][fileTo] = temp;
plot_piece(hps, PI_EMPTY, rankFrom, fileFrom);
plot_piece(hps, piece[rankTo][fileTo], rankTo, fileTo);
addmove (MOVE(SQ(rankFrom, fileFrom), SQ(rankTo, fileTo)));
}
void GAME::addmove(int move) // in format: int = MOVE(fromSQ, toSQ)
{
fprintf(logfile, "move: added %d at position %d\n",
move,
gameCntr);
move_history[gameCntr++] = move;
if (viewCntr == gameCntr-1) viewCntr++;
}
void GAME::addmove(char *move, boolean white_on_move) // in format: "Na1-b1"
{
int m;
if (strcmp(move, "o-o") == 0)
m = (white_on_move) ? MOVE(SQ(0,4), SQ(0,6)) : MOVE(SQ(7,4), SQ(7,6));
else if (strcmp(move, "o-o-o") == 0)
m = (white_on_move) ? MOVE(SQ(0,4), SQ(0,2)) : MOVE(SQ(7,4), SQ(7,2));
else
m = MOVE(SQ(move[2]-'1', move[1]-'a'), SQ(move[5]-'1', move[4]-'a'));
move_history[gameCntr++] = m;
if (viewCntr == gameCntr-1) viewCntr++;
fprintf(logfile, "move: added %s %d (%d %d %d %d) at position %d\n",
move, m,
RANK(FROMSQ(m)), FILE(FROMSQ(m)), RANK(TOSQ(m)), FILE(TOSQ(m)),
gameCntr-1);
}
boolean GAME::advance_move_index(int by)
{
if (by > 0)
{
if (viewCntr >= gameCntr)
return FALSE; // no-op
viewCntr++;
return TRUE; // did something
}
else
{
if (viewCntr == 0)
return FALSE; // no-op
viewCntr--;
return TRUE;
}
}
void GAME::forward()
{
fprintf(logfile,"forward: viewCntr = %d\n", viewCntr);
if (advance_move_index(1))
apply(move_history[viewCntr]);
}
void GAME::backward()
{
register int i, j;
fprintf(logfile,"backward: viewCntr = %d\n", viewCntr);
if (IsInitialPosition())
return;
i = viewCntr;
j = gameCntr;
newboard();
viewCntr = i;
gameCntr = j;
for (i=0; i<viewCntr; i++)
apply(move_history[i]);
advance_move_index(-1);
}
void GAME::apply(int move) // apply specified move to piece[]
{ // no validity checking
register int r1 = RANK(FROMSQ(move));
register int f1 = FILE(FROMSQ(move));
register int r2 = RANK(TOSQ(move));
register int f2 = FILE(TOSQ(move));
if (r1==r2 && f1==4 && f2==6 &&
(piece[r1][f1]==PI_W_KIN || piece[r1][f1]==PI_B_KIN))
{
piece[r1][5] = piece[r1][7];
piece[r1][7] = PI_EMPTY;
}
else if (r1==r2 && f1==4 && f2==2 &&
(piece[r1][f1]==PI_B_KIN || piece[r1][f1]==PI_B_KIN))
{
piece[r1][3] = piece[r1][0];
piece[r1][0] = PI_EMPTY;
}
piece[r2][f2] = piece[r1][f1];
piece[r1][f1] = PI_EMPTY;
}
/*********/
/* TIMEL */
/*********/
static VOID timel(timel_parm *tp)
{
WinInitialize(0);
fprintf(logfile,"timel: ms=%d hwnd=%x\n", tp->ms, tp->hwnd);
while (1)
{
DosSleep(tp->ms);
WinPostMsg(tp->hwnd, IDM_TIMEL, NULL, NULL);
}
}
#endif