📄 mainform1.~cpp
字号:
/*
主菜单项“忽略”事件处理函数
把主窗体中棋盘上编辑过的棋子全部作废。
*/
void __fastcall TMainForm::CancelClick(TObject *Sender)
{
memcpy(ChessBoard, SaveChessBoard, sizeof(BOARDTYPE) * 0x99);
ResetNewPos();
NormalSetup();
}
//---------------------------------------------------------------------------
/*
自定义正常设置函数
InfoForm->BringToFront()将信息子窗体InfoForm推到前端。
恢复棋子在主窗体上的原始位置。
*/
void TMainForm::NormalSetup()
{
InfoForm->BringToFront();
MainForm->Menu=TChessMenu; //动态设置主窗体主菜单
delete[] SaveChessBoard;
Editing = EditingChessBoard = false;
UpdateChessBoard();
}
//---------------------------------------------------------------------------
/*
主菜单项“演示模式”事件处理函数
程序轮流成为红方、黑方,即自己与自己对弈。
*/
void __fastcall TMainForm::DemoClick(TObject *Sender)
{
extern bool AutoPlay;
bool IsEasy = false;
if (Level == easygame)
{
IsEasy = true;
Level = normal;
HideAttacks();
}
AutoPlay = true;
ComputersTurn();
if (IsEasy)
{
Level = easygame;
UpdateChessBoard();
}
CurPlayer = Player;
ComputerColor = Opponent;
PrintCurLevel();
}
//---------------------------------------------------------------------------
/*
主菜单项“无限制”事件处理函数
改变信息窗体中信息提示为无限制
程序无限制地加大深度搜索最好的一步棋。
*/
void __fastcall TMainForm::InfiniteClick(TObject *Sender)
{
if (Level != infinite)
{
UnCheckLevelMenu(Level);
CheckMenuItem(TChessMenu->Handle, Infinite->Command, MF_CHECKED);
}
Level = infinite;
MaxLevel = MAXPLY;
PrintCurLevel();
}
//---------------------------------------------------------------------------
/*
主菜单项“将死搜索”事件处理函数
改变信息窗体中信息提示为将死搜索
程序无限制地加大深度直到搜索到能将死的一步棋。
当棋子比较多时,很难搜索到终局(将死)。
*/
void __fastcall TMainForm::MateClick(TObject *Sender)
{
if (Level != matesearch)
{
UnCheckLevelMenu(Level);
CheckMenuItem(TChessMenu->Handle, Mate->Command, MF_CHECKED);
}
Level = matesearch;
PrintCurLevel();
ComputersTurn();
}
//---------------------------------------------------------------------------
/*
主菜单项“回合搜索”事件处理函数
弹出“设置回合数”对话框。
在主菜单项“回合搜索”前打勾。
改变信息窗体中信息提示为所设置的回合数。
*/
void __fastcall TMainForm::Ply1Click(TObject *Sender)
{
char *PlySearchDepth = new char[40];
sprintf(PlySearchDepth, "%d", MaxLevel);
if (InputPlyDlg->ShowModal()== mrOk)
{
int NewPlyDepth = StrToInt(InputPlyDlg->Edit1->Text);
if (NewPlyDepth > 0)
{
if (Level != plysearch)
{
UnCheckLevelMenu(Level);
CheckMenuItem(TChessMenu->Handle, Ply1->Command, MF_CHECKED);
}
MaxLevel = (BYTE)((NewPlyDepth > MAXPLY) ? MAXPLY : NewPlyDepth);
Level = plysearch;
PrintCurLevel();
}
else
Error("数据不正确。请重输。");
}
delete PlySearchDepth;
}
//---------------------------------------------------------------------------
/*
主菜单项“两人对弈”事件处理函数
翻转主菜单项“两人对弈”为”单独对弈“
*/
void __fastcall TMainForm::TwoPlayerClick(TObject *Sender)
{
static LEVELTYPE OldLevel = normal;
MultiMove = !MultiMove;
if (MultiMove)
{
TwoPlayer->Caption= "单独对弈"; //动态改变菜单项文本
OldLevel = Level;
EnableMenuItem(TChessMenu->Handle, 2, MF_GRAYED | MF_BYPOSITION);
DrawMenuBar(MainForm->Handle);
Level = normal;
PrintCurLevel();
}
else
{
TwoPlayer->Caption = "两人对弈"; //动态改变菜单项文本
EnableMenuItem(TChessMenu->Handle, 2, MF_ENABLED | MF_BYPOSITION);
/*
第一个参数为菜单句柄,从菜单TChessMenu句柄属性Handle获取。
第二个参数指明菜单的位置,即第三项。
第三个参数是一个标志集合。它告诉菜单项是应该执行哪一些操作
和如何被指明的。在这种情况下,MF_ENABLED告诉EnableMenuItem菜单项激活
MF_BYPOSITION告诉EnableMenuItem菜单项是用位置指明的。
*/
DrawMenuBar(MainForm->Handle);
Level = OldLevel;
PrintCurLevel();
}
}
//---------------------------------------------------------------------------
/*
主菜单项“反转棋盘”事件处理函数
对换红方和黑方的棋盘。
*/
void __fastcall TMainForm::ReverseClick(TObject *Sender)
{
Turned = !Turned;
PrintChessBoard();
}
//---------------------------------------------------------------------------
/*
主菜单项“悔棋”事件处理函数
至少要动过一次棋子,该菜单项才由灰色变为黑色(激活状态)。
*/
void __fastcall TMainForm::UndoMoveClick(TObject *Sender)
{
if (ComputerThinking)
{
MessageToPost = IDM_UNDO;
return;
}
if (!Undo())
UndoMove->Enabled = false;
RedoUndo->Enabled = true;
CurPlayer = Player;
ComputerColor = Opponent;
}
//---------------------------------------------------------------------------
/*
主菜单项“重下”事件处理函数
至少要悔过一次棋子,该菜单项才由灰色变为黑色(激活状态)。
*/
void __fastcall TMainForm::RedoUndoClick(TObject *Sender)
{
if (ComputerThinking)
{
MessageToPost = IDM_REDO;
return;
}
if (!Redo())
RedoUndo->Enabled = false;
UndoMove->Enabled = true;
CurPlayer = Player;
ComputerColor = Opponent;
}
//---------------------------------------------------------------------------
/*
自定义子菜单项加勾函数
选中子菜单项”容易“、”每次移动时间“、”总时间“、”匹配“、
”无限制“、”回合搜索“、”将死搜索“ 之一时,在该项前打勾。
*/
void TMainForm::CheckLevelMenu(LEVELTYPE level)
{
int CheckItem = Easy->Command;
switch (level)
{
case normal :
CheckItem = MoveTime->Command;
break;
case fullgametime :
CheckItem = TotalTime->Command;
break;
case plysearch :
CheckItem = Ply1->Command;
break;
case easygame :
CheckItem = Easy->Command;
break;
case infinite :
CheckItem = Infinite->Command;
break;
case matesearch :
CheckItem = Mate->Command;
break;
case matching :
CheckItem = Matching->Command;
break;
}
CheckMenuItem(TChessMenu->Handle, CheckItem, MF_CHECKED);
}
/*
自定义子菜单项去勾函数
改变选中子菜单项”容易“、”每次移动时间“、”总时间“、”匹配“、
”无限制“、”回合搜索“、”将死搜索“ 之一时,在该项前去掉勾。
*/
void TMainForm::UnCheckLevelMenu(LEVELTYPE level)
{
int CheckItem = Easy->Command;
switch (level)
{
case normal :
CheckItem = MoveTime->Command;
break;
case fullgametime :
CheckItem = TotalTime->Command;
break;
case plysearch :
CheckItem = Ply1->Command;
break;
case easygame :
CheckItem = Easy->Command;
break;
case infinite :
CheckItem = Infinite->Command;
break;
case matesearch :
CheckItem = Mate->Command;
break;
case matching :
CheckItem = Matching->Command;
break;
}
CheckMenuItem(TChessMenu->Handle, CheckItem, MF_UNCHECKED);
}
//---------------------------------------------------------------------------
/*
主菜单项“容易”事件处理函数
选中子菜单项”容易“时,在该项前打勾。
对弈时在棋盘上对下一步要吃掉的棋子用正方形框住。
*/
void __fastcall TMainForm::EasyClick(TObject *Sender)
{
if (Level != easygame)
{
UnCheckLevelMenu(Level);
CheckMenuItem(TChessMenu->Handle, Easy->Command, MF_CHECKED);
}
Level = easygame;
AverageTime = 5.;
MaxLevel = MAXPLY;
PrintCurLevel();
}
//---------------------------------------------------------------------------
/*
主菜单项“完成”事件处理函数
测试棋盘中的棋子摆放是否正确。如果不正确,则弹出错误对话框,
直至正确才退出编辑状态。
*/
void __fastcall TMainForm::DoneClick(TObject *Sender)
{
SQUARETYPE sq;
int TotalCount[2] = { 0, 0 };
int KingCount[2] = { 0, 0 };
int AssistCount[2] = { 0, 0};
int BishopCount[2] = { 0, 0 };
int KnightCount[2] = { 0, 0 };
int RookCount[2] = { 0, 0 };
int GunnerCount[2] = { 0, 0 };
int PawnCount[2] = { 0, 0 };
bool Done = false;
bool RKingNumDone, BKingNumDone, RAssistNumDone, BAssistNumDone;
bool RBishopNumDone, BBishopNumDone, RKnightNumDone, BKnightNumDone;
bool RRookNumDone, BRookNumDone, RGunnerNumDone, BGunnerNumDone;
bool RPawnNumDone, BPawnNumDone;
RKingNumDone = BKingNumDone = RAssistNumDone = BAssistNumDone = true;
RBishopNumDone = BBishopNumDone = RKnightNumDone = BKnightNumDone = true;
RRookNumDone = BRookNumDone = RGunnerNumDone = BGunnerNumDone = true;
RPawnNumDone = BPawnNumDone = true;
bool RKingPosDone, BKingPosDone, RAssistPosDone, BAssistPosDone;
bool RBishopPosDone, BBishopPosDone, RPawnPosDone, BPawnPosDone;
RKingPosDone = BKingPosDone = RAssistPosDone = BAssistPosDone = true;
RBishopPosDone = BBishopPosDone = RPawnPosDone = BPawnPosDone = true;
AnsiString ErrorNumText = "";
AnsiString ErrorPosText = "";
if (Modified)
{
for (sq = 0; sq < 0x99; sq++)
if (((sq>>4)<10) && ((sq % 16)<9) && ((sq | 0xff)>=0))
{
if (ChessBoard[sq].piece != empty)
{
TotalCount[ChessBoard[sq].color]++;
if (ChessBoard[sq].piece == king)
KingCount[ChessBoard[sq].color]++;
if (ChessBoard[sq].piece == assist)
AssistCount[ChessBoard[sq].color]++;
if (ChessBoard[sq].piece == bishop)
BishopCount[ChessBoard[sq].color]++;
if (ChessBoard[sq].piece == knight)
KnightCount[ChessBoard[sq].color]++;
if (ChessBoard[sq].piece == rook)
RookCount[ChessBoard[sq].color]++;
if (ChessBoard[sq].piece == gunner)
GunnerCount[ChessBoard[sq].color]++;
if (ChessBoard[sq].piece == pawn)
PawnCount[ChessBoard[sq].color]++;
}
}
if (KingCount[red] != 1)
{
ErrorNumText = "帅";
RKingNumDone = false;
}
if (KingCount[black] != 1)
{
ErrorNumText = ErrorNumText + "将";
BKingNumDone = false;
}
if (AssistCount[red] > 2)
{
ErrorNumText = ErrorNumText + "仕";
RAssistNumDone = false;
}
if (AssistCount[black] > 2)
{
ErrorNumText = ErrorNumText + "士";
BAssistNumDone = false;
}
if (BishopCount[red] > 2)
{
ErrorNumText = ErrorNumText + "相";
RBishopNumDone = false;
}
if (BishopCount[black] > 2)
{
ErrorNumText = ErrorNumText + "象";
BBishopNumDone = false;
}
if ((KnightCount[red] > 2 ) ||( KnightCount[black] > 2))
{
ErrorNumText = ErrorNumText + "马";
RKnightNumDone = BKnightNumDone = false;
}
if ((RookCount[red] >2 )||( RookCount[black] >2 ))
{
ErrorNumText = ErrorNumText + "车";
RRookNumDone = BRookNumDone = false;
}
if ( GunnerCount[red] > 2)
{
ErrorNumText = ErrorNumText + "炮";
RGunnerNumDone = false;
}
if ( GunnerCount[black] > 2)
{
ErrorNumText = ErrorNumText + "砲";
BGunnerNumDone = false;
}
if (PawnCount[red] > 5)
{
ErrorNumText = ErrorNumText + "兵";
RPawnNumDone = false;
}
if (PawnCount[black] > 5)
{
ErrorNumText = ErrorNumText + "卒";
BPawnNumDone = false;
}
ErrorNumText = ErrorNumText + "的数目不正确";
for (sq = 0; sq < 0x99; sq++)
if (((sq>>4)<10) && ((sq % 16)<9) && ((sq | 0xff)>=0))
{
if (ChessBoard[sq].color == red)
if (ChessBoard[sq].piece == king)
if (((sq >> 4) > 2) || ((sq % 16) > 5) || ((sq % 16) < 3))
RKingPosDone = false;
if (ChessBoard[sq].color == black)
if (ChessBoard[sq].piece == king)
if (((sq >> 4) < 7) || ((sq % 16) > 5) || ((sq % 16) < 3))
BKingPosDone = false;
if (ChessBoard[sq].color == red)
if (ChessBoard[sq].piece == assist)
{
if (((sq >> 4) > 2) || ((sq % 16) > 5) || ((sq % 16) < 3))
RAssistPosDone = false;
if ((sq == 0x13) || (sq == 0x15)||(sq == 4)||(sq == 0x24))
RAssistPosDone = false;
}
if (ChessBoard[sq].color == black)
if (ChessBoard[sq].piece == assist)
{
if (((sq >> 4) < 7) || ((sq % 16) > 5) || ((sq % 16) < 3))
BAssistPosDone = false;
if ((sq == 0x83) || (sq == 0x55)||(sq == 0x94)||(sq == 0x74))
BAssistPosDone = false;
}
if (ChessBoard[sq].color == red)
if (ChessBoard[sq].piece == bishop)
if ((sq != 2) && (sq != 6) && (sq != 0x20) && (sq != 0x24)
&& (sq != 0x28) && (sq != 0x42) && (sq != 0x46))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -