📄 small.cpp
字号:
// ObjectWindows - (C) Copyright 1992 by Borland International
#include <windows.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include "wcdefs.h"
#include "wchess.h"
#include "externs.h"
/*
* Global Variables
*/
MOVETYPE ZeroMove = { 8, 8, 0, empty, empty };
CLOCKTYPE ChessTime[2];
MOVETYPE KeyMove;
BOOL Running;
COLORTYPE RunColor;
BOOL Analysis, Opan;
double WantedTime;
extern double AverageTime;
BOOL GameOver = FALSE;
char EndGameMessage[80];
void EndMessage(char *);
/*
* Initialize the chess clocks
*/
void InitChessTime()
{
InitTime(&ChessTime[white]);
InitTime(&ChessTime[black]);
}
void StopChessTime()
{
if (Running)
{
StopTime(&ChessTime[RunColor]);
KillTimer(hWndMain, TIMEID);
Running = FALSE;
}
}
/*
* Stop the running chess clock and start the clock for color
*/
void StartChessTime(COLORTYPE color)
{
RunColor = color;
Running = TRUE;
StartTime(&ChessTime[RunColor]);
SetTimer(hWndMain, TIMEID, 1000, NULL);
}
/*
* reset MovTab
*/
void ResetMoves()
{
Depth = -1;
MovTab[-1] = ZeroMove;
}
/*
* Clear HintLine
*/
void ClearHint()
{
HintLine[0] = ZeroMove;
HintEvalu = 0;
}
void InitNode(NODEVAL *nodes)
{
nodes->nodebase = 0;
nodes->nodeoffset = 0;
}
/*
* Test if the move is legal for Programcolor == player in the
* given position
*/
BOOL IllegalMove(MOVETYPE *move)
{
BOOL illegal;
Perform(move, 0);
illegal = Attacks(Opponent, PieceTab[Player][0].isquare);
Perform(move, 1);
return illegal;
}
/*
* Make move for programcolor = player and updates variables
*/
void MakeMove(MOVETYPE *move)
{
Depth++;
MoveNo++;
Perform(move, 0);
ProgramColor = Opponent;
Opponent = Player;
Player = ProgramColor;
}
/*
* Prints comment to the game (check, mate, draw, resign)
*/
void PrintComment(void)
{
extern char buf[];
short check, possiblemove, checkmate;
int nummoves;
Message("");
checkmate = 0;
Depth++;
possiblemove = 0;
InitMovGen();
do
{
MovGen();
if (Next.movpiece != empty)
if (!IllegalMove(&Next))
possiblemove = 1;
} while (Next.movpiece != empty && !possiblemove);
Depth--;
check = Attacks(Opponent, PieceTab[Player][0].isquare); /* calculate check */
/* No possible move means checkmate or stalemate */
if (!possiblemove)
{
if (check)
{
checkmate = 1;
EndMessage("CheckMate");
}
else
EndMessage("Stalemate!");
}
else
if (HintEvalu >= MATEVALUE - DEPTHFACTOR * 16)
{
nummoves = (MATEVALUE - HintEvalu + 0x40) / (DEPTHFACTOR * 2);
sprintf(buf, "Mate in %d Move%c", nummoves, (nummoves > 1) ? 's!':'!');
Message(buf);
}
if (check && !checkmate)
Message("Check!");
else /* test 50 move rule and repetition of moves */
{
if (FiftyMoveCnt() >= 100)
{
EndMessage("50 Move rule");
}
else
if (Repetition(0) >= 3)
{
EndMessage("3 fold Repetition");
}
else /* Resign if the position is hopeless */
if (-25500 < HintEvalu && HintEvalu < -0x880)
{
switch (Opponent)
{
case white :
EndMessage(" White resigns");
break;
case black :
EndMessage(" Black resigns");
}
}
}
}
void EnterMove(MOVETYPE *move)
{
StopChessTime();
PrintMove(MoveNo, ProgramColor, move, ChessTime[RunColor].totaltime);
MakeMove(move);
UpdateBoard();
PrintComment();
StartChessTime(ProgramColor);
}
void RemoveMove(MOVETYPE *move)
{
StopChessTime();
PrintMove(MoveNo, ProgramColor, move, ChessTime[RunColor].totaltime);
TakeBackMove(move);
UpdateBoard();
PrintComment();
StartChessTime(ProgramColor);
}
/*
* perform the move entered by the user
*/
void EnterKeyMove(void)
{
MovTab[Depth+1] = KeyMove;
PlayerMove = KeyMove;
ClearHint();
DragEnd(TRUE);
EnterMove(&MovTab[Depth+1]);
}
/*
* move movtab to depth = -1
*/
void AdjustMoves()
{
int i;
for (i = Depth; i>= BACK; i--)
MovTab[i - (Depth+1)] = MovTab[i];
Depth = -1;
}
/*
* Move movtab one move BACK
*/
void StoreMoves(void)
{
int i;
Depth--;
for (i = BACK; i <= Depth; i++)
MovTab[i] = MovTab[i+1];
MovTab[BACK] = ZeroMove;
}
/*
* Check to see if the input move is legal
*/
BOOL MoveCheck(SQUARETYPE startsq, SQUARETYPE endsq)
{
Depth++;
KeyMove = ZeroMove;
InitMovGen();
do
{
MovGen();
if (Next.new1 == endsq && Next.old == startsq)
{
KeyMove = Next;
break;
}
} while (Next.movpiece != empty);
if (KeyMove.movpiece == empty)
{
Warning("Impossible move");
Depth--;
return FALSE;
}
if (IllegalMove(&KeyMove))
{
Warning("Illegal move. Check!");
Depth--;
return FALSE;
}
Depth--;
if (!ComputerThinking)
{
AdjustMoves();
EnterKeyMove();
StoreMoves();
}
return TRUE;
}
/*
* calculate the WANTED response time
*/
void StartAnalysis()
{
int timecontrol;
extern HWND hWndMain;
extern HCURSOR hWaitCursor;
Analysis = 1;
Opan = 0;
SetClassWord(hWndMain, GCW_HCURSOR, WORD(hWaitCursor));
SetCursor(hWaitCursor);
switch (Level)
{
case easygame :
case normal :
/* Divides the Time left till nest time control
between moves left. There is a margin of
4 moves to make sure that the program does
not lose on time */
timecontrol = (((MoveNo >> 1) + 20) / 20) * 20;
if (timecontrol <= 40) timecontrol = 40;
WantedTime = (AverageTime * timecontrol -
ChessTime[ProgramColor].totaltime) /
(timecontrol + 4 - (MoveNo >> 1));
/* In the begining of the game the program thinks
around twice as long, since the early middle
game is normally the most crucial part of
a game */
if ((MoveNo >> 1) <= 40)
WantedTime = 5.0 + (WantedTime - 5.0) *
((80 - (MoveNo >> 1)) /40);
break;
case fullgametime :
/* Assumes that the game will last for around 40 moves and
divides the time left accordingly */
WantedTime = (AverageTime * 60.0 -
ChessTime[ProgramColor].totaltime) / 44;
/* In the begining of the game the program thinks
around twice as long, since the early middle
game is normally the most crucial part of
a game */
if ((MoveNo >> 1) <= 40)
WantedTime = 5.0 + (WantedTime - 5.0) *
((80 - (MoveNo >> 1)) /40);
break;
case matching :
/* Spend as much time as the Opponent does */
if (MoveNo >= 2)
WantedTime = ChessTime[Opponent].totaltime / (MoveNo >> 1);
else
WantedTime = 5.0;
WantedTime += (ChessTime[Opponent].totaltime -
ChessTime[ProgramColor].totaltime) * 0.25;
default :
WantedTime = 1000000.0;
}
}
/*
* take BACK move and update variables
*/
void TakeBackMove(MOVETYPE *move)
{
ProgramColor = Opponent;
Opponent = Player;
Player = ProgramColor;
Perform(move, 1);
MoveNo--;
Depth--;
}
void IncNode(NODEVAL *nodes)
{
if (nodes->nodeoffset >= MAXINT)
{
nodes->nodebase++;
nodes->nodeoffset = 0;
}
else
nodes->nodeoffset++;
}
void Wait(int tenths)
{
clock_t NumTicksToWait;
/* two ticks == approx. 1/10 second, since 18.2 clocks is approx a
second */
NumTicksToWait = (tenths * 2) + clock();
while (NumTicksToWait > clock()) ;
}
/*
* Flash a move once on the screen
*/
void FlashMove(MOVETYPE *move)
{
MakeMove(move);
UpdateBoard();
Wait(4);
TakeBackMove(move);
UpdateBoard();
Wait(4);
}
void DoSlideMove(MOVETYPE &move)
{
SQUARETYPE castsquare, cornersquare;
SlidePiece(move.new1, move.old);
if (move.spe)
{
if (move.movpiece == king)
{
GenCastSquare(move.new1, &castsquare, &cornersquare);
SlidePiece(castsquare, cornersquare);
}
}
}
void EndMessage(char *message)
{
strcpy(EndGameMessage, message);
GameOver = TRUE;
}
void ShowHint()
{
DEPTHTYPE dep = 0;
buf[0] = '\0';
Message(buf);
while (HintLine[dep].movpiece != empty)
{
strcat(buf, MoveStr(&HintLine[dep]));
strcat(buf, " ");
Message(buf);
MakeMove(&HintLine[dep]);
UpdateBoard();
Wait(6);
dep++;
}
while (dep > 0)
{
dep--;
TakeBackMove(&HintLine[dep]);
}
UpdateBoard();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -