📄 ffview.cpp
字号:
// ffView.cpp : implementation of the CFfView class
//
#include "stdafx.h"
#include "ff.h"
#include "LinkDialog.h"
#include "ffDoc.h"
#include "ffView.h"
#pragma comment(lib, "winmm.lib")
#define ID_TIMER 1
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CFfView
IMPLEMENT_DYNCREATE(CFfView, CView)
BEGIN_MESSAGE_MAP(CFfView, CView)
//{{AFX_MSG_MAP(CFfView)
ON_WM_PAINT()
ON_WM_SETCURSOR()
ON_WM_TIMER()
ON_COMMAND(ID_ACTION_DISLINK, OnActionDislink)
ON_COMMAND(ID_ACTION_LINK, OnActionLink)
ON_COMMAND(ID_ACTION_NEW, OnActionNew)
ON_COMMAND(ID_ACTION_SURRENDER, OnActionSurrender)
ON_COMMAND(ID_MUSIC_MUSIC, OnMusicMusic)
ON_UPDATE_COMMAND_UI(ID_MUSIC_MUSIC, OnUpdateMusicMusic)
ON_UPDATE_COMMAND_UI(ID_ACTION_DISLINK, OnUpdateActionDislink)
ON_UPDATE_COMMAND_UI(ID_ACTION_LINK, OnUpdateActionLink)
ON_UPDATE_COMMAND_UI(ID_ACTION_NEW, OnUpdateActionNew)
ON_UPDATE_COMMAND_UI(ID_ACTION_SURRENDER, OnUpdateActionSurrender)
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
ON_MESSAGE(WM_USER_NEWGAME, OnNewGame)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFfView construction/destruction
CFfView::CFfView()
{
// TODO: add construction code here
m_bMusicOn = FALSE;
m_pListenSocket = NULL;
m_pClientSocket = NULL;
m_pClientSocket2 = NULL;
m_bMyTurn = FALSE;
m_bLinked = FALSE;
m_bOpponentWin = FALSE;
m_bInGame = FALSE;
m_bFlag = FALSE;
ResetCoords();
CreateListenSocket();
}
CFfView::~CFfView()
{
DestroyListenSocket();
DestroyClientSocket();
DestroyClientSocket2();
m_bLinked = FALSE;
if(m_bMusicOn)
KillTimer(ID_TIMER);
}
BOOL CFfView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CFfView drawing
void CFfView::OnDraw(CDC* pDC)
{
CFfDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
/////////////////////////////////////////////////////////////////////////////
// CFfView printing
BOOL CFfView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CFfView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CFfView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CFfView diagnostics
#ifdef _DEBUG
void CFfView::AssertValid() const
{
CView::AssertValid();
}
void CFfView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CFfDoc* CFfView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CFfDoc)));
return (CFfDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CFfView message handlers
void CFfView::ResetCoords()
{
for(int i = 0; i < DIVISIONS; i++)
{
for(int j = 0; j < DIVISIONS; j++)
m_nCoords[i][j] = 0;
}
if (m_bFlag)
{
Invalidate(FALSE);
UpdateWindow();
}
}
void CFfView::RequestAccepted(int accept)
{//处理连接请求
if(!m_pClientSocket)
{//在socket连接没有创建时,创建新的连接
m_pClientSocket = new CClientSocket(this);
if(!m_pListenSocket->Accept(*m_pClientSocket))
{//释放资源
DestroyClientSocket();
GetParent()->SetWindowText(_T("Ygj - Ready"));
AfxMessageBox(_T("You cannot accept this request!"));
}
if(accept == IDYES)
{//接收连接请求,开始创建连接
int buf[3] = {ACCEPT, 0, 0};
if(m_pClientSocket->Send(buf, 3 * sizeof(int)) == SOCKET_ERROR)
{//发送接受连接请求,
AfxMessageBox(_T("Connection interrupted!\n"
"Cannot open the new game."));
m_bLinked = FALSE;
m_bInGame = FALSE;
DestroyClientSocket();
GetParent()->SetWindowText(_T("Ygj - Ready"));
return;
}
m_bMyTurn = TRUE;
m_bLinked = TRUE;
m_bOpponentWin = FALSE;
m_bInGame = TRUE;
m_bFlag = TRUE;
ResetCoords();
m_nColor = 1;
GetParent()->SetWindowText(_T("Ygj - Your turn"));
}
else
{
int buf[3] = {DECLINE, 0, 0};//拒绝对方连接请求
m_pClientSocket->Send(buf, 3 * sizeof(int));
GetParent()->SetWindowText(_T("Ygj - Ready"));//等待下次连接
DestroyClientSocket();
}
return;
}
//创建备用连接,当程序已经创建好连接,开始游戏时,会创建备用连接,用于响应
//其他连接请求
if(m_pClientSocket2)
DestroyClientSocket2();
m_pClientSocket2 = new CClientSocket(this);
if(!m_pListenSocket->Accept(*m_pClientSocket2))
{
DestroyClientSocket2();
GetParent()->SetWindowText(_T("Ygj - Ready"));
AfxMessageBox(_T("You cannot accept this request!"));
}
int buf[3] = {DECLINE, 0, 0};
m_pClientSocket2->Send(buf, 3 * sizeof(int));
GetParent()->SetWindowText(_T("Ygj - Ready"));
DestroyClientSocket2();
}
LRESULT CFfView::OnNewGame(WPARAM wParam, LPARAM lParam)
{
int result = AfxMessageBox(_T("Do you want to play a new game?"),
MB_YESNO);
if(result == IDYES)
{
int buf[3] = {ACCEPT, 0, 0};
if(m_pClientSocket->Send(buf, 3 * sizeof(int)) == SOCKET_ERROR)
{
AfxMessageBox(_T("Connection interrupted!\n"
"Cannot open the new game."));
m_bLinked = FALSE;
m_bInGame = FALSE;
DestroyClientSocket();
GetParent()->SetWindowText(_T("Ygj - Ready"));
return 1;
}
m_bMyTurn = TRUE;
m_bLinked = TRUE;
m_bOpponentWin = FALSE;
m_bInGame = TRUE;
m_bFlag = TRUE;
ResetCoords();
m_nColor = 1;
GetParent()->SetWindowText(_T("Ygj - Your turn"));
}
else
{
int buf[3] = {NONEWGAME, 0, 0};
if(m_pClientSocket->Send(buf, 3 * sizeof(int)) == SOCKET_ERROR)
{
AfxMessageBox(_T("Connection interrupted!\n"
"Cannot open the new game."));
m_bLinked = FALSE;
m_bInGame = FALSE;
DestroyClientSocket();
GetParent()->SetWindowText(_T("Ygj - Ready"));
return 1;
}
GetParent()->SetWindowText(_T("Ygj - Game over"));
}
return 0;
}
void CFfView::DrawPieces()
{//绘制棋盘棋子
CClientDC dc(this);//载入黑白棋子背景画到位图图象,棋子为矩形
CBitmap bmWhite, bmBlack, bmMask;
bmWhite.LoadBitmap(IDB_WHITEPIECE);
bmBlack.LoadBitmap(IDB_BLACKPIECE);
bmMask.LoadBitmap(IDB_MASK);
CDC dcMemWhite;
dcMemWhite.CreateCompatibleDC(&dc);
CBitmap* pOld1 = dcMemWhite.SelectObject(&bmWhite);//白棋子绘制对象
CDC dcMemBlack;
dcMemBlack.CreateCompatibleDC(&dc);
CBitmap* pOld2 = dcMemBlack.SelectObject(&bmBlack);//黑棋子绘制对象
CDC dcMemMask;
dcMemMask.CreateCompatibleDC(&dc);
CBitmap* pOld3 = dcMemMask.SelectObject(&bmMask);//用黑色覆盖棋子边缘部分,使其成为圆形
dcMemWhite.BitBlt(0, 0, 36, 36, &dcMemMask, 0, 0, SRCAND);
dcMemBlack.BitBlt(0, 0, 36, 36, &dcMemMask, 0, 0, SRCAND);
//拷贝覆盖部分带黑白棋子部分,并进行与运算,得到圆形棋子
for(int i = 0; i < DIVISIONS; i++)
for(int j = 0; j < DIVISIONS; j++)
{
if(m_nCoords[i][j] == -1)
{//m_nCoords用来保存游戏中各个棋子的状态,1为黑,-1为白,0为无棋子
dc.BitBlt((i + 1) * CELLSIZE - 18,
(j + 1) * CELLSIZE - 18,
36, 36, &dcMemMask,
0, 0, 0x220326);
dc.BitBlt((i + 1) * CELLSIZE - 18,
(j + 1) * CELLSIZE - 18,
36, 36, &dcMemWhite,
0, 0, SRCPAINT);
}
if(m_nCoords[i][j] == 1)
{
dc.BitBlt((i + 1) * CELLSIZE - 18,
(j + 1) * CELLSIZE - 18,
36, 36, &dcMemMask,
0, 0, 0x220326);
dc.BitBlt((i + 1) * CELLSIZE - 18,
(j + 1) * CELLSIZE - 18,
36, 36, &dcMemBlack,
0, 0, SRCPAINT);
}
if(i == m_ptLastStep.x &&
j == m_ptLastStep.y &&
m_nCoords[i][j] != 0)
{
CPen pen(PS_SOLID, 1, RGB(192, 0, 0));
CPen* pOldPen = dc.SelectObject(&pen);
dc.SelectStockObject(NULL_BRUSH);
dc.Rectangle((i + 1) * CELLSIZE - 18,
(j + 1) * CELLSIZE - 18,
(i + 1) * CELLSIZE + 18,
(j + 1) * CELLSIZE + 18);
dc.SelectObject(pOldPen);
}
}
dcMemWhite.SelectObject(pOld1);
dcMemBlack.SelectObject(pOld2);
dcMemMask.SelectObject(pOld3);
}
void CFfView::CreateClientSocket(CString &strAddress)
{
if(m_pClientSocket)
DestroyClientSocket();
m_pClientSocket = new CClientSocket(this);
if(!m_pClientSocket->Create())
{
DestroyClientSocket();
GetParent()->SetWindowText(_T("Ygj - Ready"));
AfxMessageBox(_T("Port creation failed!\n"
"Please try again later."));
return;
}
while(!m_pClientSocket->Connect(strAddress, PORT_NUM))
{
if(AfxMessageBox(_T("Cannot reach your partner right now.\n"),
MB_RETRYCANCEL) == IDCANCEL)
{
DestroyClientSocket();
GetParent()->SetWindowText(_T("Ygj - Ready"));
return;
}
}
}
void CFfView::CreateListenSocket()
{
if(m_pListenSocket)
DestroyListenSocket();
m_pListenSocket = new CListenSocket(this);
if(!m_pListenSocket->Create(PORT_NUM))
{
DestroyListenSocket();
AfxMessageBox(_T("Port creation failed!\n"
"Please try again later."));
return;
}
if(!m_pListenSocket->Listen())
{
DestroyClientSocket();
AfxMessageBox(_T("Due to socket problems on your machine,\n"
"you cannot respond to incoming request.\n"
"You can only request a new game to others."));
}
}
void CFfView::DestroyClientSocket()
{
if(m_pClientSocket)
{
delete m_pClientSocket;
m_pClientSocket = NULL;
}
}
void CFfView::DestroyClientSocket2()
{
if(m_pClientSocket2)
{
delete m_pClientSocket2;
m_pClientSocket2 = NULL;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -