📄 bwchessdlg.cpp
字号:
wsp.push (i,j);
}
}
else
{
if(btp_x!=i || btp_y!=j)
{
btp_x=i,btp_y=j;
bn++;
bsp.push (i,j);
}
}
break;
}
}
}
//斜向左下
if(Check(i+1,j-1) && Check(i+2,j-2))
{
x=i,y=j;
temp=kernel[x+1][y-1];
for(x+=2,y-=2;(x<NUM) && (y>=0);x++,y--)
{
temp2=kernel[x][y];
if(temp2==0)
break;
if(temp2!=temp)
{
if(temp2==1)
{
if(wtp_x!=i || wtp_y!=j)
{
wtp_x=i,wtp_y=j;
wn++;
wsp.push (i,j);
}
}
else
{
if(btp_x!=i || btp_y!=j)
{
btp_x=i,btp_y=j;
bn++;
bsp.push (i,j);
}
}
break;
}
}
}
//斜向右下
if(Check(i+1,j+1) && Check(i+2,j+2))
{
x=i,y=j;
temp=kernel[x+1][y+1];
for(x+=2,y+=2;(x<NUM) && (y<NUM);x++,y++)
{
temp2=kernel[x][y];
if(temp2==0)
break;
if(temp2!=temp)
{
if(temp2==1)
{
if(wtp_x!=i || wtp_y!=j)
{
wtp_x=i,wtp_y=j;
wn++;
wsp.push (i,j);
}
}
else
{
if(btp_x!=i || btp_y!=j)
{
btp_x=i,btp_y=j;
bn++;
bsp.push (i,j);
}
}
break;
}
}
}
}//end if
}//end second for
if((bn==0) && (wn==0))
return -1;//return -1 for both
if((bn>=2) && (wn>=2))
return 2;///return 2 for have more than one
switch(whogo)
{
//whogo 1:代表黑色,2代表白色
case 1://代表黑色
if(wn==0)
return 0;//return 0 for the int have no position
break;
case 2://2代表白色
if(bn==0)
return 0;//return 0 for the int have no position
break;
}
return 2;//return 2 for have more than one
}
int CBWChessDlg::Check(int x, int y)
{
if(x<0 || x>=NUM || y<0 || y>=NUM)
return 0;//越界为0
if(kernel[x][y]==0)
return 0;//无子为0
return 1;
}
int CBWChessDlg::Walk1(int *x1, int *y1, int flag)//寻找最佳位置给(x1,x2)
{
int fv=flag;//棋子颜色 2 黑 1 白
int k,n;
if(fv==1)//1:白色
n=wsp.Len();
else// 2:黑色
n=bsp.Len();
srand( (unsigned)time( NULL ) );
k=rand()%n+1;
//算法开始!! 本算法采用随机法
for(n=1;n<=k;n++)
{
if(fv==1)//1:白色
wsp.pop(x1,y1);
else// 2:黑色
bsp.pop(x1,y1);
//i,j是可以放棋子的坐标
}
if(fv==1)//1:白色
wsp. destroy();
else// 2:黑色
bsp. destroy();
return 0;
}
void CBWChessDlg::Calcu_BW()//棋子计数
{
int nw=0,nb=0;
int i,j;
for(i=0;i<NUM;i++)
for(j=0;j<NUM;j++)
if(kernel[i][j]==1)
nw++;
else if(kernel[i][j]==2)
nb++;
num_black=nb;
num_white=nw;
}
int CBWChessDlg::IsInPanel(CPoint &pt)//判断是否在棋盘上
{
if(pt.x<=m_wXNull || pt.x>=(m_wXNull + NUM*m_wStoneWidth))
return 0;
if(pt.y<=m_wYNull || pt.y>=(m_wYNull + NUM*m_wStoneHeight))
return 0;
return 1;
}
void CBWChessDlg::ShowNumber(int isTime)//刷新 时间和棋子的个数
{
BCount.SetNumber(num_black);
WCount.SetNumber(num_white);
if(isTime)
{
TimeCount.SetNumber(m_PassedTime);
TimeCount0.SetNumber(m_PassedTime0);
}
}
void CBWChessDlg::OnTimer(UINT nIDEvent) //计时
{
if(nIDEvent==PASSEDTIME)//尚未更新
{
if(!m_byColor)//白色
m_PassedTime++;
else//黑色
m_PassedTime0++;
ShowNumber(1);//“1”代表时间也要刷新
if(g_nRunMode == MODE_2PLAYER && !g_nIsNoTimeLimit)//人对人,限时
{
if((m_PassedTime>=g_nTimeLimit) || (m_PassedTime0>=g_nTimeLimit))
{//超时!!游戏结束
m_bGameOver=TRUE;
if(m_TimerOn)
{
KillTimer(PASSEDTIME);
m_TimerOn=0;
}
m_pMenu->EnableMenuItem(IDM_HINT,MF_GRAYED);
m_pMenu->EnableMenuItem(IDM_UNDO,MF_GRAYED);
m_pMenu->EnableMenuItem(IDM_CANPLACE,MF_GRAYED);
AddStringToList(0,0,0,(m_PassedTime>=g_nTimeLimit)? 1 : 2);
PlaySounds(IDSOUND_USERWIN);
//弹出游戏结束的对话框
MsgBox((m_PassedTime>=g_nTimeLimit)? IDS_BLACK_LIMIT : IDS_WHITE_LIMIT ,IDS_TITLE_CHINESE);
}
}
}
CDialog::OnTimer(nIDEvent);
}
void CBWChessDlg::OnUndo()
{
if(g_nRunMode==MODE_NETWORK)//网络2
{
AfxMessageBox("你不能作弊!");
return;
}
m_PeekOnce=0;
if(m_UndoPoint.IsEmpty())//已为空,m_UndoPoint的类名是 Cundo
{
PlaySounds(IDSOUND_ERROR);
MsgBox(IDS_CANNOT_UNDO1_CHINESE, IDS_TITLE_CHINESE);//弹出无法悔棋的对话框
return;
}
if (m_bGameOver)
return;
int c1,c2,i,j,k=0;
c1=m_UndoPoint.GetTopColor();//获取颜色
int temp[NUM*NUM];
m_UndoPoint.pop(temp);//获取棋盘
RemoveStringFromList();
if(g_nRunMode == MODE_WITH_COMPUTER)//人机对战
{
if(c1==m_byColor)
{
while(!m_UndoPoint.IsEmpty())
{
c2=m_UndoPoint.GetTopColor();
RemoveStringFromList();
if(c1!=c2)
{
m_UndoPoint.pop(temp);
break;
}
else
{
int again_pop[NUM*NUM];
m_UndoPoint.pop(again_pop);
}
}// end while
}//end if
}
else
{
if(m_UndoPoint.IsEmpty())
{
if(g_bUserBlack)
m_byColor=0;
else
m_byColor=1;
}
else
{
m_byColor=m_UndoPoint.GetTopColor ();
}
}
for(i=0;i<NUM;i++)
for(j=0;j<NUM;j++)
{
kernel[i][j]=temp[k];
k++;
}
IsEnd(!m_byColor+1);
if(!m_bGameOver && g_bPeepOften)
OnCanplace();
m_HintOnce=0;
Calcu_BW();
ShowNumber();
PlaySounds(IDSOUND_UNDO);
InvalidateRect(m_Client, TRUE);
UpdateWindow();
}
void CBWChessDlg::duplicate()//保存当前棋盘和当前颜色,为悔棋作准备
{
int temp[NUM*NUM];
int i,j,k=0;
for(i=0;i<NUM;i++)
for(j=0;j<NUM;j++)
temp[k++]=kernel[i][j];
m_UndoPoint.push(temp,m_byColor);
}
void CBWChessDlg::Place(int *x, int *y,int color)
{//获取最佳位置
int mx=0,my=0;
Walk1(&mx,&my,color);
*x=mx;
*y=my;
}
void CBWChessDlg::OnBest() //显示英雄榜
{
CBestDlg bestDlg;
bestDlg.DoModal();
}
void CBWChessDlg::OnHint() // 响应“提示”
{
const int HINTSIZE=7;
if (m_bGameOver)
return;
if(m_HintOnce)
return;
if(g_nRunMode == MODE_2PLAYER)//人对人
{
if(((m_HintTime0>=g_nCanHintTimeW) && m_byColor) ||
((m_HintTime1>=g_nCanHintTimeB) && !m_byColor))
{
CString str1,str2;
TCHAR s[200];
str1.LoadString(IDS_MORETHANTHREE_CHINESE);//代表“我已提示了你%d次,不能再提示了!”
str2.LoadString(IDS_TITLE_CHINESE);//代表“黑白棋”
if(m_HintTime0>=g_nCanHintTimeW)
wsprintf(s,str1.GetBuffer(256),g_nCanHintTimeW);
else
wsprintf(s,str1.GetBuffer(256),g_nCanHintTimeB);
CString str(s);
MsgBox(str,str2);//给出对话框
return;// 退出提示
}
if(m_byColor)//次数累加
m_HintTime0++;
else
m_HintTime1++;
}
else // 人对机
{
if(m_HintTime0>=g_nCanHintTimeW || m_HintTime1>=g_nCanHintTimeB)//0 白 1黑
{
CString str1,str2;
TCHAR s[200];
str1.LoadString(IDS_MORETHANTHREE_CHINESE);
str2.LoadString(IDS_TITLE_CHINESE);
if(m_HintTime0>=g_nCanHintTimeW)
wsprintf(s,str1.GetBuffer(256),g_nCanHintTimeW);
else
wsprintf(s,str1.GetBuffer(256),g_nCanHintTimeB);
CString str(s);
MsgBox(str,str2);
return;
}
else
{
if(m_byColor)
m_HintTime0++;
else
m_HintTime1++;
}
}
int px,py;
Walk1(&py,&px,!m_byColor+1);//寻找最佳点
x1 = px*m_wStoneWidth + m_wXNull-HINTSIZE + m_wStoneWidth / 2;
y1 = py*m_wStoneHeight + m_wYNull-HINTSIZE + m_wStoneHeight / 2;
x2 = px*m_wStoneWidth + m_wXNull+HINTSIZE + m_wStoneWidth / 2;
y2 = py*m_wStoneHeight + m_wYNull+HINTSIZE + m_wStoneHeight / 2;
//矩形:(x1,y1,x2,y2)
CClientDC dc(this);//画 “X"
COLORREF crColor = m_byColor ? RGB(255,255,255) : RGB(0,0,0);//1 画 白
CPen pen(PS_SOLID, 2, crColor);
CPen *pOldPen = dc.SelectObject(&pen);
dc.MoveTo(x1, y1);
dc.LineTo(x2, y1);
dc.LineTo(x2, y2);
dc.LineTo(x1, y2);
dc.LineTo(x1, y1);
dc.LineTo(x2, y2);
dc.MoveTo(x2, y1);
dc.LineTo(x1, y2);
dc.SelectObject(pOldPen);
m_HintOnce=1;
}
void CBWChessDlg::MoveCursor(int x, int y)
{//从当前(m,n)位置向(x,y)走,x,y 是以像素为单位的,所使用的平面是窗口平面
//每次移动鼠标之前,系统都会根据 m_byColor 的值载入光标,0载入黑手,1载入白手,之所以相反(0白1黑),
//是因为系统载入光标时,用户还没有点击棋盘,m_byColor代表的前一个棋手的颜色。
//但是本函数在调用时,m_byColor代表的是当前棋手的颜色
//轮流到计算机下时,在计算机下棋之前,由于计算机不移动鼠标,也不敲击键盘,因此光标不会更新,
//仍使用前一个棋手的光标,故在此处必须修正!!
m_byColor=!m_byColor;
::SetCursor(AfxGetApp()->LoadCursor(m_byColor ? IDC_WHITE_HAND:IDC_BLACK_HAND));//修正部分
m_byColor=!m_byColor;
if(!g_bMovePlace)
{
return;
}
CPoint pt;
GetCursorPos(&pt);
int m,n;
int sleep_interval=2;
m=pt.x ;
n=pt.y ;
if(m >x)
{
while(m>x)//向左走
{
m-=g_nMoveSpeeds;
Sleep(sleep_interval);
SetCursorPos(m,n);
}
}
else if(m<x)//向右走
{
while(m<x)
{
m+=g_nMoveSpeeds;
Sleep(sleep_interval);
SetCursorPos(m,n);
}
}
if(n >y)
{
while(n>y)//向上走
{
n-=g_nMoveSpeeds;
Sleep(sleep_interval);
SetCursorPos(m,n);
}
}
else if(n < y)//向下走
{
while(n < y)
{
n+=g_nMoveSpeeds;
Sleep(sleep_interval);
SetCursorPos(m,n);
}
}
}
void CBWChessDlg::OnCanplace() //本函数计算当前棋手可下的位置,并标志出来!(X)
{
if (m_bGameOver)
return;
if(m_PeekOnce)
return;
int px,py;
int xx1,yy1;
int length,hy;
//CClientDC dc(this);;
CDC *dc=GetDC();
if(m_byColor)//判断是否有位置可填
length=wsp.isempty();
else
length=bsp.isempty();
if(length)//无,结束
return;
do
{
if(m_byColor)
length=wsp.GetNextPos(&py,&px,&hy);
else
length=bsp.GetNextPos(&py,&px,&hy);
xx1 = px*m_wStoneWidth + m_wXNull;//-4 + m_cxGrid / 2;
yy1 = py*m_wStoneHeight + m_wYNull;//-4 + m_cyGrid / 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -