📄 ffview.cpp
字号:
void CFfView::DestroyListenSocket()
{
if(m_pListenSocket)
{
delete m_pListenSocket;
m_pListenSocket = NULL;
}
}
BOOL CFfView::IsWin(int x, int y)
{
int xMin=max(0, x - 4);//x最近4个棋子坐标的最小值
int xMax=min(DIVISIONS - 1, x + 4);//最大值
int yMin=max(0, y - 4);//y的最小值
int yMax=min(DIVISIONS - 1, y + 4);//最大值
int i, j, p, q, sum1, sum2, sum3, sum4;
for(j=xMin; j<=xMax-4; j++)
{//判断横坐标是否已有4个棋子连续
for(i=j, sum1=0; i<j+5; i++)
if(m_nCoords[i][y]==m_nCoords[x][y])
sum1++;
if(sum1==5)
return TRUE;
}
for(i=yMin; i<=yMax-4; i++)
{//判断纵坐标是否已有4个棋子连续
for(j=i, sum2=0; j<i+5; j++)
if(m_nCoords[x][j]==m_nCoords[x][y])
sum2++;
if(sum2==5)
return TRUE;
}
for(i=x, j=y; i>xMin && j>yMin; i--, j--);
for(; i<=xMax-4 && j<=yMax-4; i++, j++)
{//判断上半部分是否已有4个棋子连续
for(sum3=0, p=i, q=j; p<i+5; p++, q++)
if(m_nCoords[p][q]==m_nCoords[x][y])
sum3++;
if(sum3==5)
return TRUE;
}
for(i=x, j=y; i>xMin && j<yMax; i--, j++);
for(; i<=xMax-4 && j>=yMin+4; i++, j--)
{//下半部分是否已有4个棋子连续
for(sum4=0, p=i, q=j; p<i+5; p++, q--)
if(m_nCoords[p][q]==m_nCoords[x][y])
sum4++;
if(sum4==5)
return TRUE;
}
return FALSE;
}
void CFfView::OneStep(int x, int y)
{//重画新走的一步棋
CRect invalidOldRect((m_ptLastStep.x + 1) * CELLSIZE - CELLSIZE / 2,
(m_ptLastStep.y + 1) * CELLSIZE - CELLSIZE / 2,
(m_ptLastStep.x + 1) * CELLSIZE + CELLSIZE / 2,
(m_ptLastStep.y + 1) * CELLSIZE + CELLSIZE / 2);
InvalidateRect(&invalidOldRect, FALSE);
m_ptLastStep.x = x;//新走棋的坐标
m_ptLastStep.y = y;
m_nCoords[x][y] = -m_nColor;//棋子颜色
PlaySound(_T("down.wav"), NULL, SND_FILENAME | SND_ASYNC);
CRect invalidRect((x + 1) * CELLSIZE - CELLSIZE / 2,
(y + 1) * CELLSIZE - CELLSIZE / 2,
(x + 1) * CELLSIZE + CELLSIZE / 2,
(y + 1) * CELLSIZE + CELLSIZE / 2);
InvalidateRect(&invalidRect, FALSE);
}
void CFfView::OnPaint()
{//绘制设备上下文
CPaintDC dc(this);
CBitmap bitmap;
bitmap.LoadBitmap (IDB_BKWOOD);
CDC dcMem;//创建DC
dcMem.CreateCompatibleDC(&dc);
CBitmap* pOldBitmap = dcMem.SelectObject(&bitmap);
CRect rect(0, 0, 0, 0);
GetClientRect(&rect);
dc.StretchBlt(0, 0, rect.Width(), rect.Height(), &dcMem,
0, 0, 640, 640, SRCCOPY);
for(int i = 1; i <= DIVISIONS; i++)
{
dc.MoveTo(CELLSIZE, i * CELLSIZE);//移到鼠标指定的点上
dc.LineTo(DIVISIONS * CELLSIZE, i * CELLSIZE);//从指定点画线到目前的点
dc.MoveTo(i * CELLSIZE, CELLSIZE);
dc.LineTo(i * CELLSIZE, DIVISIONS * CELLSIZE);
}
dc.SelectStockObject(BLACK_BRUSH);
int nRadius = 4;
dc.Ellipse(CELLSIZE + CELLSIZE * 3 - nRadius,
CELLSIZE + CELLSIZE * 3 - nRadius,
CELLSIZE + CELLSIZE * 3 + nRadius,
CELLSIZE + CELLSIZE * 3 + nRadius);
dc.Ellipse(CELLSIZE + CELLSIZE * (DIVISIONS - 3 - 1) - nRadius,
CELLSIZE + CELLSIZE * 3 - nRadius,
CELLSIZE + CELLSIZE * (DIVISIONS - 3 - 1) + nRadius,
CELLSIZE + CELLSIZE * 3 + nRadius);
dc.Ellipse(CELLSIZE + CELLSIZE * (DIVISIONS / 2) - nRadius,
CELLSIZE + CELLSIZE * (DIVISIONS / 2) - nRadius,
CELLSIZE + CELLSIZE * (DIVISIONS / 2) + nRadius,
CELLSIZE + CELLSIZE * (DIVISIONS / 2) + nRadius);
dc.Ellipse(CELLSIZE + CELLSIZE * 3 - nRadius,
CELLSIZE + CELLSIZE * (DIVISIONS - 3 - 1) - nRadius,
CELLSIZE + CELLSIZE * 3 + nRadius,
CELLSIZE + CELLSIZE * (DIVISIONS - 3 - 1) + nRadius);
dc.Ellipse(CELLSIZE + CELLSIZE * (DIVISIONS - 3 - 1) - nRadius,
CELLSIZE + CELLSIZE * (DIVISIONS - 3 - 1) - nRadius,
CELLSIZE + CELLSIZE * (DIVISIONS - 3 - 1) + nRadius,
CELLSIZE + CELLSIZE * (DIVISIONS - 3 - 1) + nRadius);
//绘制五个关键点
dc.SelectStockObject(NULL_BRUSH);
CPen pen(PS_SOLID, 4, RGB(0, 0, 0));
CPen* pOldPen = dc.SelectObject(&pen);
CRect rectFrame(CELLSIZE, CELLSIZE, DIVISIONS * CELLSIZE + 2, DIVISIONS * CELLSIZE + 2);
rectFrame.InflateRect(5, 5);
dc.Rectangle(&rectFrame);
dc.SelectObject(pOldPen);
dc.SelectObject(pOldBitmap);
//绘制边框
DrawPieces();
// Do not call CView::OnPaint() for painting messages
}
BOOL CFfView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default
if(nHitTest == HTCLIENT && m_bLinked && m_bInGame)
{
if((m_bMyTurn && (m_nColor == 1)) ||
(!m_bMyTurn && (m_nColor == -1)))
::SetCursor(AfxGetApp()->LoadCursor(IDC_BLACK));
else
::SetCursor(AfxGetApp()->LoadCursor(IDC_WHITE));
return TRUE;
}
return CView::OnSetCursor(pWnd, nHitTest, message);
}
void CFfView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
PlayBGMusic(_T("bgmusic.mid"));
CView::OnTimer(nIDEvent);
}
void CFfView::PlayBGMusic(LPCSTR FileName)
{
m_midi.Open(FileName);
m_midi.Play();
}
void CFfView::OnActionDislink()
{
// TODO: Add your command handler code here
int result = AfxMessageBox(_T("Are you sure you want to disconnect?"),
MB_YESNO);
if(result == IDYES)
{
int buf[3] = {DISCONNECT, 0, 0};
m_pClientSocket->Send(buf, 3 * sizeof(int));
m_bLinked = FALSE;
m_bInGame = FALSE;
DestroyClientSocket();
m_bFlag = TRUE;
ResetCoords();
GetParent()->SetWindowText(_T("Ygj - Ready"));
}
}
void CFfView::OnActionLink()
{
// TODO: Add your command handler code here
CLinkDialog dlg;
if(dlg.DoModal() == IDOK)
{
GetParent()->SetWindowText(_T("Ygj - Waiting for reply"));
CreateClientSocket(dlg.m_strAddress);
}
}
void CFfView::OnActionNew()
{
// TODO: Add your command handler code here
int buf[3] = {NEWGAME, 0, 0};
if(m_pClientSocket->Send(buf, 3 * sizeof(int)) == SOCKET_ERROR)
{
AfxMessageBox(_T("Connection interrupted!\n"
"Cannot connect to your partner."));
m_bLinked = FALSE;
DestroyClientSocket();
GetParent()->SetWindowText(_T("Ygj - Ready"));
return;
}
GetParent()->SetWindowText(_T("Ygj - Waiting for reply"));
}
void CFfView::OnActionSurrender()
{//强制退出
// TODO: Add your command handler code here
int result = AfxMessageBox(_T("Are you sure you want to surrender?"),
MB_YESNO);
if(result == IDYES)
{
m_bMyTurn = FALSE;
m_bInGame = FALSE;
int buf[3] = {SURRENDER, 0, 0};
if(m_pClientSocket->Send(buf, 3 * sizeof(int)) == SOCKET_ERROR)
{
AfxMessageBox(_T("Connection interrupted!\n"
"Cannot connect to your partner."));
m_bLinked = FALSE;
m_bInGame = FALSE;
DestroyClientSocket();
GetParent()->SetWindowText(_T("Ygj - Ready"));
return;
}
GetParent()->SetWindowText(_T("Ygj - Game over"));
}
}
void CFfView::OnMusicMusic()
{
// TODO: Add your command handler code here
m_bMusicOn = !m_bMusicOn;
if(m_bMusicOn)
{
PlayBGMusic(_T("bgmusic.mid"));
SetTimer(ID_TIMER, m_midi.GetMidiLen() + 500, NULL);
}
else
{
KillTimer(ID_TIMER);
PlayBGMusic(NULL);
}
}
void CFfView::OnUpdateMusicMusic(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_bMusicOn);
}
void CFfView::OnUpdateActionDislink(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(m_bLinked);
}
void CFfView::OnUpdateActionLink(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(!m_bLinked);
}
void CFfView::OnUpdateActionNew(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(m_bLinked && !m_bInGame);
}
void CFfView::OnUpdateActionSurrender(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(m_bLinked && m_bInGame);
}
void CFfView::OnLButtonDown(UINT nFlags, CPoint point)
{//获得棋子的具体位置信息
// TODO: Add your message handler code here and/or call default
if(m_bLinked && m_bMyTurn)
{//判断是否连接并轮到当前机器走棋
int x = (point.x - CELLSIZE / 2) / CELLSIZE;
int y = (point.y - CELLSIZE / 2) / CELLSIZE;//具体位置信息
if(x >= 0 && x < DIVISIONS && y >= 0 && y < DIVISIONS)
{//判断按键是否在棋盘内部
if(m_nCoords[x][y] == 0)
{ //判断当前位置是否已经有棋子
CRect invalidOldRect((m_ptLastStep.x + 1) * CELLSIZE - CELLSIZE / 2,
(m_ptLastStep.y + 1) * CELLSIZE - CELLSIZE / 2,
(m_ptLastStep.x + 1) * CELLSIZE + CELLSIZE / 2,
(m_ptLastStep.y + 1) * CELLSIZE + CELLSIZE / 2);
InvalidateRect(&invalidOldRect, FALSE);
PlaySound(_T("down.wav"), NULL, SND_FILENAME | SND_ASYNC);
m_ptLastStep.x = x;
m_ptLastStep.y = y;
m_nCoords[x][y] = m_nColor;
m_bMyTurn = FALSE;
CRect invalidRect((x + 1) * CELLSIZE - CELLSIZE / 2,
(y + 1) * CELLSIZE - CELLSIZE / 2,
(x + 1) * CELLSIZE + CELLSIZE / 2,
(y + 1) * CELLSIZE + CELLSIZE / 2);
//当前一步棋子的位置
InvalidateRect(&invalidRect, FALSE);
int buf[3] = {0, x, y};
if(IsWin(x, y))
{//判断一方是否已经获胜
if(m_nColor == -1)
{
if(m_bOpponentWin)
{//如果对方获胜
buf[0] = EVEN; // even and game over
m_bInGame = FALSE;
GetParent()->SetWindowText(_T("Ygj - Game over"));
}
else
{//对方输
buf[0] = ULOSE; // white win and game over
m_bInGame = FALSE;
GetParent()->SetWindowText(_T("Ygj - Game over"));
}
}
else
{//对方获胜,等待最后一步
buf[0] = IWIN; // black temp win, waiting for white's last step
GetParent()->SetWindowText(_T("Ygj - Opponent's turn"));
}
}
else
{//如果没有分出胜负
if(m_bOpponentWin)
{
buf[0] = UWIN; // I lose and game over
m_bInGame = FALSE;
GetParent()->SetWindowText(_T("Ygj - Game over"));
}
else
{//等待对方下棋
GetParent()->SetWindowText(_T("Ygj - Opponent's turn"));
buf[0] = COORDS; // nobody wins, just an ordinary step
}
}
if(m_pClientSocket->Send(buf, 3 * sizeof(int)) == SOCKET_ERROR)
{//如果属于连接错误
AfxMessageBox(_T("Connection interrupted!\n"
"Cannot continue with the game."));
m_bLinked = FALSE;
m_bInGame = FALSE;
DestroyClientSocket();
GetParent()->SetWindowText(_T("Ygj - Ready"));
return;
}
// show game result messagebox if gameover
if(buf[0] == EVEN)
{
AfxMessageBox(_T("Even game!"));
}
else if(buf[0] == ULOSE)
{
AfxMessageBox(_T("Congratulations!\n"
"You won this game."));
}
else if(buf[0] == UWIN)
{
AfxMessageBox(_T("Sorry!\n"
"You lost this game."));
}
}
}
else
{
::MessageBeep(MB_ICONEXCLAMATION);
}
}
CView::OnLButtonDown(nFlags, point);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -