📄 c15_1f.cpp
字号:
//---------------------------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop
#include "C15_1f.h"
//---------------------------------------------------------------------------
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void TForm1::NewGameDraw()
{
int i;
PaintBox1->Canvas->FillRect(Form1->Canvas->ClipRect); // 清屏
for(i=1;i<5;i++)
{ // 画棋盘格
PaintBox1->Canvas->MoveTo(OneStepX, i*OneStepY);
PaintBox1->Canvas->LineTo(4*OneStepX, i*OneStepY);
PaintBox1->Canvas->MoveTo(i*OneStepX, OneStepY);
PaintBox1->Canvas->LineTo(i*OneStepX, 4*OneStepY);
}
memset(Block, NoPlayer, sizeof(short)*25); // 清内存
for(i=0;i<5;i++)
{ // 初始化数组边界
Block[0][i] = OtherPlayer;
Block[4][i] = OtherPlayer;
Block[i][0] = OtherPlayer;
Block[i][4] = OtherPlayer;
}
StatusBar1->Panels->Items[0]->Text = "";
StatusBar1->Panels->Items[2]->Text = "";
}
//---------------------------------------------------------------------------
void TForm1::GameDraw()
{
int i;
PaintBox1->Canvas->FillRect(Form1->Canvas->ClipRect); // 清屏
for(i=1;i<5;i++)
{ // 画棋盘格
PaintBox1->Canvas->MoveTo(OneStepX, i*OneStepY);
PaintBox1->Canvas->LineTo(4*OneStepX, i*OneStepY);
PaintBox1->Canvas->MoveTo(i*OneStepX, OneStepY);
PaintBox1->Canvas->LineTo(i*OneStepX, 4*OneStepY);
}
}
//---------------------------------------------------------------------------
void TForm1::DrawRed(int X, int Y)
{ // 画红棋子
int x, y;
Block[X][Y] = RedPlayer; // 设置当前格为红方棋子
if(IsWon(RedPlayer))
{ // 已经胜利
StatusBar1->SimpleText = "你赢了!";
Gaming = false;
}
Timer1->Enabled = false; // 记时
x = X * OneStepX + OneStepX / 2; // 计算棋子中心位置
y = Y * OneStepY + OneStepY / 2;
int dx = OneStepX / 3; // 计算棋子范围
int dy = OneStepY / 3;
int OneStep = OneStepX > OneStepY ? OneStepY : OneStepX;
long RawColor = PaintBox1->Canvas->Pen->Color; // 保存画笔原设置
long RawWidth = PaintBox1->Canvas->Pen->Width;
PaintBox1->Canvas->Pen->Color = clRed; // 设置画笔属性
PaintBox1->Canvas->Pen->Width = OneStep / 5;
PaintBox1->Canvas->Ellipse(x-dx, y-dy, x+dx, y+dy); // 画圆
PaintBox1->Canvas->Pen->Color = RawColor; // 恢复画笔设置
PaintBox1->Canvas->Pen->Width = RawWidth;
}
//---------------------------------------------------------------------------
void TForm1::DrawBlue(int X, int Y)
{
int x, y;
Block[X][Y] = BluePlayer; // 设置当前格为蓝方棋子
x = X * OneStepX + OneStepX / 2; // 计算棋子中心位置
y = Y * OneStepY + OneStepY / 2;
int dx = OneStepX / 3; // 计算棋子大小
int dy = OneStepY / 3;
int OneStep = OneStepX > OneStepY ? OneStepY : OneStepX;
long RawColor = PaintBox1->Canvas->Pen->Color; // 保存画笔原设置
long RawWidth = PaintBox1->Canvas->Pen->Width;
PaintBox1->Canvas->Pen->Color = clBlue; // 设置画笔属性
PaintBox1->Canvas->Pen->Width = OneStep / 5;
PaintBox1->Canvas->MoveTo(x-dx, y-dy); // 画十字
PaintBox1->Canvas->LineTo(x+dx, y+dy);
PaintBox1->Canvas->MoveTo(x-dx, y+dy);
PaintBox1->Canvas->LineTo(x+dx, y-dy);
PaintBox1->Canvas->Pen->Color = RawColor; // 恢复画笔设置
PaintBox1->Canvas->Pen->Width = RawWidth;
}
//---------------------------------------------------------------------------
// 该函数用于判断是否结束游戏(胜利)。
bool TForm1::IsWon(int Player)
{
int i, j;
for(i=1;i<4;i++)
for(j=1;j<4;j++)
{ // 遍历各点
if(WonAt(Player, i, j))
{ // 已经获胜
Gaming = false;
Drawable = false;
return(true);
}
}
return(false);
}
//---------------------------------------------------------------------------
bool TForm1::WonAt(int Player, int X, int Y)
{
int i, j;
for(i=-1;i<1;i++) // 遍历指定棋子的四周
for(j=-1;j<2;j++)
if(i || j)
if( Block[X-i][Y-j] == Player &&
Block[X][Y] == Player &&
Block[X+i][Y+j] == Player)
return(true); // 判断棋子是否连成一线
return(false);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::NewGameClick(TObject *Sender)
{
NewGameDraw();
StatusBar1->Panels->Items[2]->Text = "开始新游戏,你先走";
Timer1->Enabled = true;
//BlueMove();
Drawable = true;
Gaming = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::PaintBox1Paint(TObject *Sender)
{
GameDraw(); // 重画棋盘
PaintDraw(); // 重画棋子
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormResize(TObject *Sender)
{
OneStepX = PaintBox1->Width / 5;
OneStepY = PaintBox1->Height / 5;
}
//---------------------------------------------------------------------------
void TForm1::PaintDraw()
{
int i, j;
for(i=1;i<4;i++)
for(j=1;j<4;j++)
if(Block[i][j] == RedPlayer)
DrawRed(i,j);
else if(Block[i][j] == BluePlayer)
DrawBlue(i,j);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::PaintBox1MouseUp(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
X /= OneStepX;
Y /= OneStepY;
if(X>0 && X<4 && Y>0 && Y<4)
if(IsNot(X, Y))
{ // 鼠标点在棋盘格内
if(Drawable)
{ // 由用户走棋
Timer1->Enabled = false;
DrawRed(X, Y);
Drawable = false;
if(!IsWon(RedPlayer))
{ // 红方未胜
StatusBar1->Panels->Items[2]->Text = "计算机走,稍等";
BlueMove();
if(IsWon(BluePlayer))
{ // 蓝方胜
StatusBar1->Panels->Items[2]->Text = "对不起,计算机胜!";
Gaming = false;
return;
}
}
else
{ // 红方胜
StatusBar1->Panels->Items[2]->Text = "祝贺,你赢了!";
Gaming = false;
return;
}
if(NoWon())
{ // 和棋
StatusBar1->Panels->Items[2]->Text = "和棋!";
Gaming = false;
return;
}
else
{
Drawable = true;
Timer1->Enabled = true;
StatusBar1->Panels->Items[2]->Text = "你走";
}
}
}
}
//---------------------------------------------------------------------------
bool TForm1::NoWon()
{
int i, j;
for(i=1;i<4;i++)
for(j=1;j<4;j++)
if(Block[i][j] == NoPlayer)
return(false);
return(true);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Gaming = false;
Drawable = false;
NewGameClick(NULL); // 开始新游戏
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{ // 该函数用于记时
// 当定时器产生Timer事件时,自动增加记时读数
AnsiString str = StatusBar1->Panels->Items[0]->Text;
char* p = str.c_str(); // 类型转换
// 不能使用 str.ToInt() 函数转换,
// 当该字符串为空时,str.ToInt() 出错。
int i = atoi(p) + 1; // 读数加1
char buf[10];
sprintf(buf, "%d ", i);
StatusBar1->Panels->Items[0]->Text = buf; // 修改读数
}
//---------------------------------------------------------------------------
bool TForm1::IsBlue(int X, int Y)
{ // 判断当前位置是否有蓝棋
if(X>3 || X<1)
return(false); // X 超界
else if(Y>3 || Y<1) // Y 超界
return(false);
else if(Block[X][Y] != BluePlayer)
return(false);
else
return(true); // 当前位置是蓝棋
}
//---------------------------------------------------------------------------
bool TForm1::IsRed(int X, int Y)
{ // 判断当前位置是否有红棋
if(X>3 || X<1)
return(false); // X 超界
else if(Y>3 || Y<1) // Y 超界
return(false);
else if(Block[X][Y] != RedPlayer)
return(false);
else
return(true); // 当前位置是红棋
}
//---------------------------------------------------------------------------
bool TForm1::IsNot(int X, int Y)
{ // 判断当前位置是否无棋子
if(X>3 || X<1)
return(false); // X 超界
else if(Y>3 || Y<1)
return(false); // Y 超界
else if(Block[X][Y] != NoPlayer)
return(false);
else
return(true); // 当前位置无棋子
}
//---------------------------------------------------------------------------
void TForm1::BlueMove()
{ // 计算机走棋(蓝棋)函数
int x, y;
int dx, dy;
int BlockX, BlockY;
bool BlockCount = false;
int MoveCount = 0;
int MaxMoveCount=0;
int MaxX, MaxY;
int OneCount = 0;
int MaxOneCount = 0;
int OneX, OneY;
bool X_Y = false;
int X, Y;
for(x=1;x<4;x++)
for(y=1;y<4;y++)
if(Block[x][y] == NoPlayer)
{
MoveCount = 0;
OneCount = 0;
for(dx=-1;dx<2;dx++)
for(dy=-1;dy<2;dy++)
if(dx || dy)
{
if(IsBlue(x+dx, y+dy))
if(IsBlue(x+2*dx, y+2*dy) || IsBlue(x-dx, y-dy))
{ // 蓝方胜
DrawBlue(x, y);
return;
}
if(IsRed(x+dx, y+dy))
if(IsRed(x+2*dx, y+2*dy) || IsRed(x-dx, y-dy))
{ // 如果红方走在(X,Y)处,将获胜
BlockX = x;
BlockY = y;
BlockCount = true;
}
// 以下计算当前点大可能获胜数
if(IsBlue(x+dx, y+dy))
if(IsNot(x+2*dx, y+2*dy) || IsNot(x-dx, y-dy))
MoveCount++;
else if(IsNot(x+dx, y+dy))
if(IsBlue(x+2*dx, y+2*dy) || IsBlue(x-dx, y-dy))
MoveCount++;
// 以下计算当前位置周围的空缺数
if(IsNot(x+dx, y+dy))
OneCount++;
}
if(MoveCount>MaxMoveCount)
{ // 保存最大可能获胜数及走法
MaxMoveCount = MoveCount;
MaxX = x;
MaxY = y;
}
if(OneCount > MaxOneCount)
{
MaxOneCount = OneCount;
OneX = x;
OneY = y;
}
if(IsNot(x, y))
{ // 当前位置为空
X_Y = true;
X = x;
Y = y;
}
}
if(BlockCount)
// 阻止红方胜
DrawBlue(BlockX, BlockY);
else if(MaxMoveCount)
// 蓝方最有可能获胜
DrawBlue(MaxX, MaxY);
else if(MaxOneCount)
// 最好走的位置(周围的棋子少)
DrawBlue(OneX, OneY);
else if(X_Y)
// 空位置
DrawBlue(X, Y);
// 如果以上条件都不满足,说明棋盘上已经放满了棋子,
// 如果仍无获胜方,为和棋。
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ExitClick(TObject *Sender)
{
Application->Terminate();
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -