需要源码和资源请点赞关注收藏后评论区留言私信~~~
棋盘窗口类主要负责显示棋盘和棋子,同时还要处理鼠标输入信息,是整个游戏中的重点
通过分析用户的需求后,可以得出棋盘窗口类应该支持如下几个功能
能够显示棋盘和棋子图片
能够接受用户输入,并把相应的坐标转换为行列数据填充到棋子数组中,实现棋子的显示
能够处理来自网络通信的各种数据
能够调用规则类对象来判断游戏的胜负
能够支持清空游戏棋盘上的棋子
有了支持的功能列表,就需要声明一个棋盘类,代码如下所示
#ifndef __BOARD_H__
#define __BOARD_H__
#include "stdafx.h"
class CBoard:public CWnd
{
private:
CImageList m_iml; // 棋子图像
int m_color; // 玩家颜色
BOOL m_bWait; // 等待标志
BOOL m_bOldWait; //原来的等待状态
public:
CBoard();
virtual ~CBoard();
void RestoreWait();
void Clear( BOOL bWait );
void SetColor(int color);
int GetColor() const;
void SetWait( BOOL bWait );
void SetData( int x, int y, int color );
void DrawGame();
void Draw(int x, int y, int color);
void Receive();
void Over(int x, int y);
protected:
afx_msg void OnPaint();
afx_msg void OnLButtonUp( UINT nFlags, CPoint point );
DECLARE_MESSAGE_MAP()
};
#endif
从上面的代码中可以看到,这个期盼类已经包含了前面设计的内容,每一个功能都由一个成员函数来实现,下面来看这个类的基础函数实现
#include "board.h"
#include "Resource.h"
#include "ConnectData.h"
#include "Rule.h"
#include "FiveChessDlg.h"
#define MAX_LEN 256 /*定义最大长度*/
//
// 构造函数,初始化棋盘数据以及图像数据
//
m_iml.Create( 24, 24, ILC_COLOR24 | ILC_MASK, 0, 2 );
// 载入黑、白棋子掩码位图
CB
{
}
// 消息映射表
BEGIN_MESSAGE_MAP( CBoard, CWnd )
tObject( &bmp );
MemDC.SelectObject( &pen );
MemDC.SetROP2( R2_NOTXORPEN );
// 根据棋盘数据绘制棋子
int x, y;
POINT pt;
for ( y = 0; y < 15; y++ )
{
for ( x = 0; x < 15; x++ )
{
if ( -1 != m_data[x][y] )
{
pt.x = 12 + 25 * x;
pt.y = 84 + 25 * y;
m_iml.Draw( &MemDC, m_data[x][y], pt, ILD_TRANSPARENT );
}
}
}
// 完成绘制
if(pDlg->m_bIsConnect)
{
int x, y;
x = ( point.x - 12 ) / 25;
y = ( point.y - 84 ) / 25;
// 如果在(0, 0)~(14, 14)范围内,且该坐标没有落子,
// 则落子于此,否则发声警告并退出过程
if ( x < 0 || x > 14 || y < 0 || y > 14 || m_data[x][y] != -1 )
{
MessageBeep( MB_OK );
return;
}
else
{
}
//
// 清空棋盘
//
void CBoard::Clear( BOOL bWait )
{
int x, y;
for ( y = 0; y < 15; y++ )
{
for ( x = 0; x < 15; x++ )
{
m_data[x][y] = -1;
}
}
// 设置等待标志
m_bWait = bWait;
Invalidate(
//
// 接收来自对方的数据
//
void CBoard::Receive()
{
CFiveChessDlg * pDlg = (CFiveChessDlg*)AfxGetMainWnd();
MSGSTRUCT msg;
if(pDlg->m_sock.Receive((LPVOID)&msg, sizeof(MSGSTRUCT)) == SOCKET_ERROR)
{
AfxGetMainWnd()->MessageBox( _T("接收数据时发生错误,请检查您的网络连接。"), _T("错误"), MB_ICONSTOP );
return;
}
switch(msg.msgType
// 发送拒绝和棋消息
MSGSTRUCT msg;
msg.msgType = MSG_REFUSE_DRAW;
pDlg->m_sock.Send( (LPCVOID)&msg, sizeof( MSGSTRUCT ) );
}
break;
case MSG_AGREE_DRAW:
pDlg->MessageBox( _T("看来真是棋逢对手,对方接受了您的和棋请求。"), _T("和棋"), MB_ICONINFORMATION );
// 和棋后,使“重玩”菜单生效
pDlg->SetMenuState(TRUE);
break;
case MSG_REFUSE_DRAW:
pDlg->MessageBox( _T("看来对方很有信心取得胜利,所以拒绝了您的和棋请求。"),
_T("和棋"), MB_ICONINFORMATION );
RestoreWait();
pDlg->SetMenuState(FALSE);
break;
case MSG_EXTERN:
break;
default:
break;
}
}
//
// 和棋操作
//
void CBoard::DrawGame()
{
CFiveChessDlg * pDlg = (CFiveChessDlg*)AfxGetMainWnd();
// 设置等待标志
SetWait( TRUE );
MSGSTRUCT msg;
msg.msgType = MSG_DRAW;
pDlg->m_sock.Send( (LPCVOID)&msg, sizeof( MSGSTRUCT ) );
}
//
// 处理对方落子后的工作
//
void CBoard::Over(int x, int y)
{
CRule rule;
CFiveChessDlg *pDlg = (CFiveChessDlg *)GetParent();
// 判断对方是否胜利
if ( rule.Win( 1 - m_color, x, y ) == _WIN)
{
pDlg->MessageBox( _T("您输了,不过不要灰心,失败乃成功之母哦!"), _T("失败"), MB_ICONINFORMATION );
// 如果是网络对战,则生效“重玩”
if ( pDlg->m_bIsConnect )
{
pDlg->SetMenuState(TRUE);
}
return;
}
//判断对方是否出现禁手
else if(rule.Win(1 - m_color, x, y) == _LOST)
{
pDlg->MessageBox( _T("恭喜您, 对方出现禁手输了!"), _T("胜利"), MB_ICONINFORMATION );
// 如果是网络对战,则生效“重玩”
if ( pDlg->m_bIsConnect )
{
pDlg->SetMenuState(TRUE);
}
return;
}
m_bWait = FALSE;
}
//
// 重新设置先前的等待标志
//
void CBoard::RestoreWait()
{
SetWait( m_bOldWait );
}
不过要使用这个棋盘类,还必须在应用程序类的初始化函数中,注册棋盘窗口类,代码如下
// FiveChess.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "FiveChess.h"
#include "FiveChessDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CFiveChessApp
BEGIN_MESSAGE_MAP(CFiveChessApp, CWinApp)
//{{AFX_MSG_MAP(CFiveChessApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
/
// CFiveChessApp construction
CFiveChessApp::CFiveChessApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/
// The one and only CFiveChessApp object
CFiveChessApp theApp;
/
// CFiveChessApp initialization
BOOL CFiveChessApp::InitInstance()
{
if (!AfxSocketInit())
{
AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
return FALSE;
}
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
// 注册棋盘窗口类
WNDCLASS wc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
wc.hCursor = LoadCursor( IDC_ARROW );
wc.hIcon = NULL;
wc.hInstance = AfxGetInstanceHandle();
wc.lpfnWndProc = ::DefWindowProc;
wc.lpszClassName = _T("ChessBoard");
wc.lpszMenuName = NULL;
wc.style = 0;
AfxRegisterClass( &wc );
CFiveChessDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
网络交互类是整个游戏的核心内容之一,其主要提供双击通信的基础,并且控制游戏的交互过程
为了方便使用和实现,游戏中的网络交互类采用继承CAsyncSocket类的方法实现,通过这种方式就可以很方便的进行Winsock网络通信,而且实现的代码也比较精简
网络交互的算法实现如下
#ifndef __CONNECT_H__
#define __CONNECT_H__
#include <afxsock.h>
class CConnect: public CAsyncSocket
{
public:
CConnect(); //构造函数
virtual ~CConnect(); //析构函数
// Implementation
protected:
virtual void OnAccept( int nErrorCode );
virtual void OnConnect( int nErrorCode );
virtual void OnReceive( int nErrorCode );
virtual void OnClose( int nErrorCode );
};
#endif
#include "Connect.h"
#include "FiveChessDlg.h"
#include "Board.h"
CConnect::CConnect()
{
}
CConnect::~CConnect()
{
}
/
// CFiveSocket member functions
void CConnect::OnAccept( int nErrorCode )
{
CFiveChessDlg * pDlg = (CFiveChessDlg*)AfxGetMainWnd();
pDlg->Accept();
pDlg->SetMenuState(FALSE);
}
void CConnect::OnClose( int nErrorCode )
{
CFiveChessDlg * pDlg = (CFiveChessDlg*)AfxGetMainWnd();
pDlg->MessageBox( _T("对方已经离开游戏,改日再较量不迟。"), _T("五子棋"), MB_ICONINFORMATION);
pDlg->SetMenuState(TRUE);
pDlg->m_board.SetWait(TRUE);
pDlg->m_conncet.Close();
pDlg->m_sock.Close();
pDlg->m_bIsConnect = FALSE;
}
void CConnect::OnConnect( int nErrorCode )
{
CFiveChessDlg * pDlg = (CFiveChessDlg*)AfxGetMainWnd();
pDlg->Connect();
pDlg->SetMenuState(FALSE);
}
void CConnect::OnReceive( int nErrorCode )
{
CBoard *pBoard = (CBoard *)AfxGetMainWnd()->GetDlgItem( IDC_BOARD );
pBoard->Receive();
}
值得注意的是,在设计这个类时,一定要同时设计客户端与主机端的功能,这样才能在游戏中进行客户机与主机的通信



创作不易 觉得有帮助请点赞关注收藏~~~
这可能是个愚蠢的问题。但是,我是一个新手......你怎么能在交互式rubyshell中有多行代码?好像你只能有一条长线。按回车键运行代码。无论如何我可以在不运行代码的情况下跳到下一行吗?再次抱歉,如果这是一个愚蠢的问题。谢谢。 最佳答案 这是一个例子:2.1.2:053>a=1=>12.1.2:054>b=2=>22.1.2:055>a+b=>32.1.2:056>ifa>b#Thecode‘if..."startsthedefinitionoftheconditionalstatement.2.1.2:057?>puts"f
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
我在app/helpers/sessions_helper.rb中有一个帮助程序文件,其中包含一个方法my_preference,它返回当前登录用户的首选项。我想在集成测试中访问该方法。例如,这样我就可以在测试中使用getuser_path(my_preference)。在其他帖子中,我读到这可以通过在测试文件中包含requiresessions_helper来实现,但我仍然收到错误NameError:undefinedlocalvariableormethod'my_preference'.我做错了什么?require'test_helper'require'sessions_hel
当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub
我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO
@作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors 1、什么是behaviors 2、behaviors的工作方式 3、创建behavior 4、导入并使用behavior 5、behavior中所有可用的节点 6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors 1、什么是behaviorsbehaviors是小程序中,用于实现
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg