📄 globalfun.cpp
字号:
#include <fstream.h>
#include <stdio.h>
#include <time.h>
#include "chess.h"
#include "CDefines.h"
#include "Global.h"
#include "MainForm1.h"
#include "InfoForm3.h"
#define AnimationSpeed 2
#undef max
#undef min
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
static HDC hSaveDC;
static POINT LastPoint;
static HBITMAP hOldBmp, hDragPiece, hDragMask;
static bool IsDragging = false;
static POINT StartPoint;
static POINT CurPoint;
MOVETYPE ZeroMove = { 10, 9, 0, empty, empty };
CHESSCLOCKTYPE ChessTime[2];
MOVETYPE KeyMove;
bool Running;
COLORTYPE RunColor;
bool Analysis, Opan;
double WantedTime;
extern double AverageTime;
bool GameOver = false;
char EndGameMessage[80];
PIECETABLE PieceTable[2][16];
COLORTYPE Player, Opponent;
DEPTHTYPE Depth;
PATHTYPE MainPath;
MAXTYPE MainEvaluat;
int MaxDepth;
extern bool ComputerThinking;
extern MOVETYPE *MoveTable;
extern int DirectionTab[];
extern bool GotValidMove;
extern HBRUSH hColorBrush;
struct SAVERESTORE
{
COLORTYPE Player, Opponent, ProgramColor;
bool Turned;
bool MultiMove, AutoPlay, SingleStep;
LEVELTYPE Level;
double AverageTime;
BYTE MaxLevel;
int MoveNumber;
double ChessClockTotalTime, BlackTotalTime, RedTotalTime;
int PieceValue[8];
};
char *INIFile = "chess.ini";
bool InLibrary; // 当程序从棋谱库搜索时值为true
bool MultiMove, // 处于multimove模式时为真
AutoPlay, // 自动对弈模式时为真
SingleStep; // 单步模式时为真
LEVELTYPE Level;
double AverageTime = 5.0;
PIECETYPE Pieces[9] = { rook, knight, bishop, assist,
king, assist, bishop, knight, rook};
BYTE MaxLevel;
bool Turned;
bool UseLib;
LIBTYPE OpeningSequ;
COLORTYPE ProgramColor;
int MoveNumber;
int PVTable[2][8][0x99];
MOVETYPE PlayerMove;
bool Logging;
NODEVAL Nodes; // 分析过的节点数
CHESSCLOCKTYPE ChessClock;
extern int LegalMoves;
PATHTYPE HintPath; /* 提示信息行 */
MAXTYPE HintEvaluat; /* 启发式估值 */
enum ANALYSISCONTROL {Start, Return, Continue};
int OpCount, LibNo;
static DEPTHTYPE LibDepth;
static bool Found;
static DEPTHTYPE dep;
ofstream *OutputFile;
typedef enum {readmove, checkmove, gamemove} CONTROLVAR;
static CONTROLVAR Control;
void EndMessage(char *);
extern BYTE ColorSquareColors[];
int OfficerNumber[2], PawnNumber[2];
BOARDIDTYPE Display[0x99];
char *PieceLetter = " KRGNABP";
char buffer[280]; // 存放字符串的缓冲区。好几个模块均用到它
static RECT ChessBoardRect;
/*
*清除棋盘和初始化棋盘
*/
void ClearChessBoard()
{
SQUARETYPE Square;
for (Square = 0; Square <= 0x98; Square++)
{
ChessBoard[Square].piece = empty;
ChessBoard[Square].color = red;
}
}
/*
* 清除棋盘索引和棋子表
*/
void ClearIndex(void)
{
SQUARETYPE square;
COLORTYPE col;
INDEXTYPE index;
int temp =0;
for (square = 0; square <= 0x98; square++)
ChessBoard[square].index = 16;
/*
在C++ Builder中枚举常量加一个常数,不能成为后一个常量。
只得采用整数间接来达到目的。
*/
for (temp = 0; temp <= 1; temp++)
{if (temp==0)
col = red;
if (temp==1)
col = black; }
for (index = 0; index < 16; index++)
PieceTable[col][index].ipiece = empty;
OfficerNumber[red] = PawnNumber[red] = -1;
OfficerNumber[black] = PawnNumber[black] = -1;
}
/*
* 根据变化的情况计算棋子表(10行9列)
*/
void CalcPieceTable(void)
{
SQUARETYPE square;
PIECETYPE piece1;
int i;
int temp;
ClearIndex();
/*
在C++ Builder中枚举常量加一个常数,不能成为后一个常量。
只得采用整数间接来达到目的。
*/
for ( temp = 0; temp <= 6; temp++)
{
{
if (temp==0)
piece1=king;
if (temp==1)
piece1=rook;
if (temp==2)
piece1=gunner;
if (temp==3)
piece1=knight;
if (temp==4)
piece1=assist;
if(temp==5)
piece1=bishop;
if (temp==6)
piece1=pawn;
}
if (piece1 == pawn)
{
OfficerNumber[red] = PawnNumber[red];
OfficerNumber[black] = PawnNumber[black];
}
square = 0;
do
{
if (ChessBoard[square].piece == piece1)
{
PawnNumber[ChessBoard[square].color]++;
PieceTable[ChessBoard[square].color][PawnNumber[ChessBoard[square].color]].ipiece
= piece1;
PieceTable[ChessBoard[square].color][PawnNumber[ChessBoard[square].color]].isquare
= square;
ChessBoard[square].index = short(PawnNumber[ChessBoard[square].color]);
}
square ^= 0x77;
if (!(square & 4))
{
if (square >= 0x70)
square = (square + 0x11) & 0x73;
else
square += 0x10;
}
} while (square);
for (i=0;i<=9;i++)
{
square=8+0x10*i;
if (ChessBoard[square].piece == piece1)
{
PawnNumber[ChessBoard[square].color]++;
PieceTable[ChessBoard[square].color][PawnNumber[ChessBoard[square].color]].ipiece
= piece1;
PieceTable[ChessBoard[square].color][PawnNumber[ChessBoard[square].color]].isquare
= square;
ChessBoard[square].index = short(PawnNumber[ChessBoard[square].color]);
}
}
for ( i=0;i<=7;i++)
{
square=0x80+i;
if (ChessBoard[square].piece == piece1)
{
PawnNumber[ChessBoard[square].color]++;
PieceTable[ChessBoard[square].color][PawnNumber[ChessBoard[square].color]].ipiece
= piece1;
PieceTable[ChessBoard[square].color][PawnNumber[ChessBoard[square].color]].isquare
= square;
ChessBoard[square].index = short(PawnNumber[ChessBoard[square].color]);
}
}
for ( i=0;i<=7;i++)
{
square=0x90+i;
if (ChessBoard[square].piece == piece1)
{
PawnNumber[ChessBoard[square].color]++;
PieceTable[ChessBoard[square].color][PawnNumber[ChessBoard[square].color]].ipiece
= piece1;
PieceTable[ChessBoard[square].color][PawnNumber[ChessBoard[square].color]].isquare
= square;
ChessBoard[square].index = short(PawnNumber[ChessBoard[square].color]);
}
}
}
}
/*
* 移动棋子到棋盘上新的位置
*/
inline void MovePiece(SQUARETYPE newpos1, SQUARETYPE oldpos)
{
BOARDTYPE b;
b = ChessBoard[newpos1];
ChessBoard[newpos1] = ChessBoard[oldpos];
ChessBoard[oldpos] = b;
PieceTable[ChessBoard[newpos1].color][ChessBoard[newpos1].index].isquare = newpos1;
}
/*
* 擦除棋子。这个函数在吃子时使用。要求擦除的方框内必须有一个棋子。
*/
inline void DeletePiece(SQUARETYPE insquare)
{
ChessBoard[insquare].piece = empty;
PieceTable[ChessBoard[insquare].color][ChessBoard[insquare].index].ipiece = empty;
}
/*
* 在棋子表中插入棋子。退回到吃子前时使用此函数
*/
inline void InsertPTabPiece(PIECETYPE inpiece, COLORTYPE incolor,
SQUARETYPE insquare)
{
ChessBoard[insquare].piece = PieceTable[incolor][ChessBoard[insquare].index].ipiece
= inpiece;
ChessBoard[insquare].color = incolor;
PieceTable[incolor][ChessBoard[insquare].index].isquare = insquare;
}
/*
如果允许回退的话,在棋盘上退回一步。更改棋盘和棋子表(包括玩家和对方)。
移动棋子、删除棋子、插入棋子和更改棋盘类型时都用到此函数。
*/
void Perform(MOVETYPE *move, bool resetmove)
{
if (resetmove)
{
MovePiece(move->oldpos, move->newpos1);
if (move->content != empty)
InsertPTabPiece(move->content, Opponent, move->newpos1);
}
else
{
if (move->content != empty)
DeletePiece(move->newpos1);
MovePiece(move->newpos1, move->oldpos);
}
}
/*
* 比较两次移动是否一样
*/
bool EqMove(MOVETYPE *a, MOVETYPE *b)
{
if (a->movpiece == b->movpiece)
if (a->newpos1 == b->newpos1)
if (a->oldpos == b->oldpos)
if (a->content == b->content)
if (a->spe == b->spe)
return true;
return false;
}
/*
* 获取当前棋子位图的句柄
*/
HBITMAP GetBitmapHandle(PIECETYPE piece, COLORTYPE pcolor)
{
if (piece == 0)
return 0;
return PieceBmpArray[piece - 1][pcolor];
}
/*
* 清除信息窗口中的所有信息
*/
void ClearInfoWindow()
{
InfoForm->Reset();
}
/*
* 显示当前对弈方
*/
void ColorToPlay(COLORTYPE color)
{
if (color == red)
InfoForm->SetTurnText("红方");
else
InfoForm->SetTurnText("黑方");
}
void Message(char *str)
{
InfoForm->SetMessageText(str);
}
/*
错误报告。有多媒体音响时喇叭会发音。
*/
void Error(char *str)
{
if (SoundOn)
MessageBeep(0);
strcpy(buffer, str);
SendMessage(MainForm->Handle, IDM_ERROR,0,0);
}
/*
警告报告。有多媒体音响时喇叭会发音。
*/
void Warning(char *str)
{
if (SoundOn)
MessageBeep(0);
Message(str);
}
/*
* 把棋子移动用记谱术语表达出来
*/
char *MoveStr(MOVETYPE *move)
{
static char str[10];
static char *str0 = " ";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -