//Chessboard.h
#pragma once
////////////////
#define NUM 15
#define PLAYONE 1
#define PLAYTWO 2
#define NOCHESS 0
#define COMCHESS 1
#define OPPCHESS 2
////////////////
class CChessboard
{
public:
CChessboard(void);
public:
~CChessboard(void);
///////////用户自定义数据-开始///////////
public:
bool AllPlayOneChess[NUM][NUM];//用于存储所有电脑的棋子
bool AllPlayTwoChess[NUM][NUM];//用于存储所有对手的棋子
int SpaceBetween;//用于存储两条线之间的距离
int PlayOneChNum[NUM][NUM];
int PlayTwoChNum[NUM][NUM];
int AllPlayOneChNum;
int AllPlayTwoChNum;
///////////用户自定义数据-结束///////////
///////////用户自定义函数-开始///////////
bool UpdateSpaceBetween(int x,int y);//当窗口重画时,改变两条线之间的距离
bool DrawChessboard(CWnd *wnd);//绘制棋盘
bool AddNewChess(int x,int y,int flag);//添加新棋子
int JudgeCoordinate(int x,int y);//判断一个坐标的棋子是否已经被占用,若没被占用返回NOCHESS,
//若被computer的棋子占用返回COMCHESS,若被opp的棋子占用返回OPPCHESS
bool JudgeWiner();//判断是否已经有人胜利
bool ContinuumComNum(int x,int y,int &left,int &right,
int &top,int &bottom,int &leftT,int &leftB,int &rightT,int &rightB,int flag);//计算一个点在各个方向上各有几个点相连
bool JudgeCoordinate(int x,int y,int flag);//判断一个坐标是否已经被playerone或者playertwo的棋子所占用(没有占用返回true)
bool ClearAllChess();//将所有棋子清空
///////////用户自定义函数-结束///////////
};
//Client.h
//#pragma once
#include"NetDialog.h"
#ifndef _CClient_h_//用于防止头文件嵌套多次1
#define _CClient_h_//用于防止头文件嵌套多次2
class CNetDialog;
#include"Mmsystem.h"//用于录音的函数
#define BUFSIZE 1000
#define MAX_BUFFER_SIZE 2048
#define CHESSDATA 10
#define CHATDATA 20
class CNetDialog;
class CClient
{
public:
//////////////用于语音聊天定义-开始///////////////
SOCKET ClientSocket;
struct sockaddr_in ServerAddress;//服务器的ip地址以及端口号
struct sockaddr_in ClientAddress;//客户端的ip地址以及端口号
char SendBuf[BUFSIZE];//发送缓存大小
char ReceiveBuf[BUFSIZE];//接收缓存大小
//////////////用于语音聊天定义-结束///////////////
//////////////用于语音聊天定义-开始///////////////
SOCKET ClientSocketSound;//用于客户端的音频聊天的套接字
struct sockaddr_in ServerAddSound;//用于进行音频聊天的服务器的ip地址以及端口号
struct sockaddr_in ClientAddSound;//用于进行音频聊天的客户端的ip地址以及端口号
//////////////用于语音聊天定义-结束///////////////
////////////////用于传输棋子坐标数据定义-开始///////////////
// SOCKET ClientSocketChess; //服务器连接成功后,用于传输数据的套接字
// struct sockaddr_in ServerAddChess;//服务器的ip地址以及端口号
// struct sockaddr_in ClientAddChess;//客户端的ip地址以及端口号
// WORD SendChess;//发送缓存大小
// WORD ReceiveChess;//接收缓存大小
////////////////用于传输棋子坐标数据定义-结束///////////////
CNetDialog *m_dlg;
int ReceiveFlag;
WORD SendChess;//发送缓存大小
WORD ReceiveChess;//接收缓存大小
HWND hWnd;
public:
CClient(void);
~CClient(void);
bool AddSocketLib();//加载套接字库
bool CreateSocket();//创建监听套接字
bool ConnectSocket();//连接到服务器
bool SendData(WAVEHDR* p);//向客户端发送数据
bool ReceiveData(WAVEHDR* p,CNetDialog *dialog);//接收客户端发来的数据
bool InitM_dlg(CNetDialog *Dlg);//将CChatDlg的对象传递给m_dlg
bool GetServerAddress();//将ip控件框里面的ip地址赋值给ServerAddress
bool GetSendBuf(CString SendData);//将发送框里面的内容赋值给SendBuf
bool GetReceiveBuf(CString & RecData);//将ReceiveBuf中的数据保存到一个cstring类型中
bool SendMark(int mark);//发送标识,表示下一个收到的数据是文字数据还是,五子棋数据
// bool SendSound(char *buf,int len);//向服务器发送音频数据
////////////////用于传输棋子坐标数据定义-开始///////////////
// bool GetServerAddressChess();//将ip控件框里面的ip地址赋值给ServerAddressChess
// bool CreateSocketChess();
// bool ConnectSocketChess();//连接到服务器
// bool SendDataChess();
// bool ReceiveDataChess();
////////////////用于传输棋子坐标数据定义-结束///////////////
};
#endif
//Computer.h
//#include"RenjuView.h"
class CRenjuView;
#ifndef _Computer_h_//用于防止头文件嵌套多次1
#define _Computer_h_//用于防止头文件嵌套多次2
///////////////////////////////////
#define NUM 15
#define MAXPRI 500
#define DEFENPRI 90
#define NULL 0
///////////优先级定义////////////
#define PRI_0 0
#define PRI_1 1
#define PRI_2 2
#define PRI_3 3
#define PRI_4 4
#define PRI_5 5
/////////////////////////////////
#define COMCHESSMAN 1
#define OPPCHESSMAN 2
#define NOCHESSMAN 0
/////////////////////////////////
#define COMWIN 1
#define OPPWIN 2
#define NOWIN 0
#define PLAYONE 1
#define PLAYTWO 2
#include <windows.h>
#include<iostream>
#include "IPHlpApi.h"
#include "Iphlpapi.h"
#include "Iphlpapi.h"
#include <string.h>
#include <stdio.h>
#include<cstring>
#include "resource.h"
#include<atlstr.h>//使用cstring类用到
#pragma comment(lib,"Iphlpapi.lib")
using namespace std;
typedef struct
{
int x; //棋盘的x坐标
int y; //棋盘的y坐标
}Point;
typedef struct po
{
Point point;
struct po *next;
}*LPoint; //某一个优先级上的所有下一步可能下法
typedef struct
{
LPoint PRI[MAXPRI];
}NextPri; //在优先级0~MAXPRI-1上的所有下一步可能下法
class Computer
{
private:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Point ComExistChessman[(NUM*NUM)/2+1]; //棋盘上所有电脑已有棋子坐标
NextPri ComNext; //电脑一方下一步的所有可能下法,按优先级存储(用于计算下一步棋的进攻下法)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Point OppExistChessman[(NUM*NUM)/2+1];//棋盘上所有对手已有棋子坐标
NextPri OppNext; //对方下一步的所有可能下法,按优先级存储(用于计算防御下法)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public:
Computer(void);//构造函数,初始化该类的各数据成员
~Computer(void);
int ComCount;//棋盘上所有电脑已有棋子个数
int OppCount;//棋盘上所有对手已有棋子个数
int CoordinateR[NUM][NUM]; //在图形上面显示的所有棋子坐标
int CoordinateSNum[NUM][NUM];//各个棋子的先后序号
int Result;//表示胜利的为哪一方。初始值为0,表示比赛正在进行;如果电脑胜利者值为1;对手胜利则为2;
bool JudgeCoordinate(int x,int y);//判断一个坐标是否已经被占用(没有占用返回true)
int Max(int a,int b,int c,int d,int &count);//函数返回4各数的最大值,并计算出有几个值并列为最大值
int RandNum(int min,int max);//生成一个min到max的随机数(不包括max和min)
bool DeleCoordinateR();//清空图形上面显示的所有棋子坐标
///////////////////computer核心算法///////////////////////////
bool AttackNextPri();//计算computer的最优下一步棋子,并添加到ComNext数据成员中
bool AddComNewCh(CRenjuView * p);//添加确定最优的棋子为下一步,并且添加到ComExistChessman中
bool ContinuumComNum(int x,int y,int &left,int &right,
int &top,int &bottom,int &leftT,int &leftB,int &rightT,int &rightB);//计算一个点在各个方向上各有几个点相连
bool AddToComNext(int x,int y,int pri); //添加新的棋子到ComNext成员
bool DeleComNext();//清空ComNext数据成员中的所有内容
bool DeleComExistChessman();//清空ComExistChessman的所有内容
bool JudgeComCoordinate(int x,int y);//判断一个坐标是否已经被Computer的棋子所占用(没有占用返回true)
int GetComCount();//返回ComCount数据成员的值
bool JudgeComWin();//判断是computer是否已经胜利 胜利则返回true
///////////////////computer核心算法///////////////////////////
///////////////////Opp核心算法///////////////////////////
bool AddNewChessmanOpp(int x,int y,CRenjuView * p);//添加新的棋子到OppExistChessman数据成员
bool AddDefend();//在continuumChessmanOpp中确定防御下一步棋
bool ContinuumOppNum(int x,int y,int &left,int &right,
int &top,int &bottom,int &leftT,int &leftB,int &rightT,int &rightB);//计算一个点在各个方向上各有几个Opp的点相连
bool JudgeOppCoordinate(int x,int y);//判断一个坐标是否已经被Opp的棋子所占用(没有占用返回true)
bool DeleOppExistChessman();// 清空OppExistChessman的所有内容
int GetOppCount();//返回OppCount数据成员的值
bool JudgeOppWin();//判断是Opp是否已经胜利 胜利则返回true
///////////////////Opp核心算法///////////////////////////
};
//
//LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
//PMIB_TCPTABLE MyGetTcpTable(BOOL bOrder);
#endif
//MainFrm.h
// MainFrm.h : CMainFrame 类的接口
//
#include"NetDialog.h"
#pragma once
class CMainFrame : public CFrameWnd
{
protected: // 仅从序列化创建
CMainFrame();
DECLARE_DYNCREATE(CMainFrame)
// 属性
public:
// 操作
public:
// 重写
public:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
// 实现
public:
virtual ~CMainFrame();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected: // 控件条嵌入成员
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
// 生成的消息映射函数
protected:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
DECLARE_MESSAGE_MAP()
///////////////////用户自定义数据-开始///////////////////
///////////////////用户自定义数据-结束///////////////////
public:
afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
public:
afx_msg void OnMoving(UINT fwSide, LPRECT pRect);
};
//NetDialog.h
#pragma once
//#ifndef _CNetDialog_h_//用于防止头文件嵌套多次1
//#define _CNetDialog_h_//用于防止头文件嵌套多次2
#include"Resource.h"
#include"Sound.h"
#include"Server.h"
#include"Client.h"
#define WM_DATAREACH WM_APP+110
#define WM_SERVERBUILTED WM_APP+310
#define WM_LINKEDSERVER WM_APP+311
#define CLIENT 1
#define SERVER 2
class CServer;
class CClient;
class CSound;
// CNetDialog 对话框
class CNetDialog : public CDialog
{
DECLARE_DYNAMIC(CNetDialog)
public:
CNetDialog(CWnd* pParent = NULL); // 标准构造函数
virtual ~CNetDialog();
// 对话框数据
enum { IDD = IDD_VOICECHAT };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
////////////自定义数据/////////////////
public:
bool ServerFlag;//用于表示是否已经建立了服务器,没有则为false,已经建立则为true
bool ClientFlag;//用于表示是否已经连接了服务器,没有则为false,已经建立则为true
CServer Server;//用于服务器端的操作
CClient Client;//用于服务端的操作
CSound Sound;//用于音频操作
CString InPutCString;//用于保存输入窗口的文字数据
CString AllCString;//用于保存所有聊天记录的文字数据
int Mark;//用于标识是客户端还是服务器
bool SoundChat;//用于标识是否已经开始语音聊天,false表示没有,true表示已经建立语音聊天了
WAVEHDR *p;
HWND ViewHwnd;
////////////////////自定义消息响应函数-开始/////////////////////
LRESULT OnDataReach(WPARAM wParam, LPARAM lParam);//当有新数据到达时执行的代码
afx_msg LRESULT GetInBufferFull(WPARAM wp, LPARAM lp);//一个buffer满后调用
afx_msg LRESULT WriteOutBufferEmpty(WPARAM wp, LPARAM lp);//一个buffer播放完后调用
////////////////////自定义消息响应函数-结束/////////////////////
public:
afx_msg void OnBnClickedBuildserver();
afx_msg void OnBnClickedLinkserver();
afx_msg void OnPaint();
afx_msg void OnBnClickedSend();
afx_msg void OnBnClickedVoicechat();
public:
afx_msg void OnBnClickedAddip();
};
//#endif
//Renju.h
// Renju.h : Renju 应用程序的主头文件
//
#pragma once
#ifndef __AFXWIN_H__
#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
#endif
#include "resource.h" // 主符号
// CRenjuApp:
// 有关此类的实现,请参阅 Renju.cpp
//
class CRenjuApp : public CWinApp
{
public:
CRenjuApp();
// 重写
public:
virtual BOOL InitInstance();
// 实现
afx_msg void OnAppAbout();
DECLARE_MESSAGE_MAP()
};
extern CRenjuApp theApp;
//RenjuDoc.h
// RenjuDoc.h : CRenjuDoc 类的接口
//
#pragma once
class CRenjuDoc : public CDocument
{
protected: // 仅从序列化创建
CRenjuDoc();
DECLARE_DYNCREATE(CRenjuDoc)
// 属性
public:
// 操作
public:
// 重写
public:
virtual BOOL OnNewDocument();
virtual void Serialize(CArchive& ar);
// 实现
public:
virtual ~CRenjuDoc();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// 生成的消息映射函数
protected:
DECLARE_MESSAGE_MAP()
};
//RenjuView.h
// RenjuView.h : CRenjuView 类的接口
//
#include"Computer.h"
#include"RenjuDoc.h"
#ifndef _CRenjuView_h_//用于防止头文件嵌套多次1
#define _CRenjuView_h_//用于防止头文件嵌套多次2
//#pragma once
#include"Chessboard.h"
#include"NetDialog.h"
#define LANMATCH 10
#define COMMATCH 20
class CNetDialog;
class Computer;
class CRenjuView : public CView
{
protected: // 仅从序列化创建
CRenjuView();
DECLARE_DYNCREATE(CRenjuView)
// 属性
public:
CRenjuDoc* GetDocument() const;
// 操作
public:
// 重写
public:
virtual void OnDraw(CDC* pDC); // 重写以绘制该视图
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
// 实现
public:
virtual ~CRenjuView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// 生成的消息映射函数
protected:
DECLARE_MESSAGE_MAP()
////////////用户定义-开始////////////
public:
CChessboard chessboard;
int Turn;//表示当前该谁下下一步
CNetDialog *LanDialog;
bool InitTurn();//初始化Turn的值
Computer *computer;
int MatchType;
////////////用户定义-结束////////////
////////////////////自定义消息响应函数-开始/////////////////////
LRESULT RecChess(WPARAM wParam, LPARAM lParam);//接收发送来的棋子
LRESULT ServerBuilted(WPARAM wParam, LPARAM lParam);//当服务器已经建立后发送消息
LRESULT LinkedServer(WPARAM wParam, LPARAM lParam);//当客户端已经连接到服务器后发送消息
////////////////////自定义消息响应函数-结束/////////////////////
public:
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLanmatch(void);
afx_msg void OnComputermatch();
};
#ifndef _DEBUG // RenjuView.cpp 中的调试版本
inline CRenjuDoc* CRenjuView::GetDocument() const
{ return reinterpret_cast<CRenjuDoc*>(m_pDocument); }
#endif
#endif
//Resource.h
//{
{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by Renju.rc
//
#define IDD_ABOUTBOX 100
#define IDP_OLE_INIT_FAILED 100
#define IDR_MAINFRAME 128
#define IDR_RenjuTYPE 129
#define ID_LANMATCH 130
#define IDE_CHAT 1000
#define IDE_EDITCHAT 1001
#define IDD_VOICECHAT 1002
#define IDB_CLOSE 1003
#define IDB_SEND 1004
#define IDI_IPADDRESS 1005
#define IDE_PORT 1006
#define IDB_BUILDSERVER 1007
#define IDB_LINKSERVER 1008
#define IDE_BUILDSTATE 1009
#define IDE_LINKSTATE 1010
#define IDB_ADDIP 1011
#define ID_LANMATCH32771 32771
#define IDM_LANMATCH 32772
#define ID_LANMATCH2 32773
#define IDM_LANMATCH2 32774
#define ID_32775 32775
#define ID_32776 32776
#define IDM_COMPUTERMATCH 32777
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 131
#define _APS_NEXT_COMMAND_VALUE 32778
#define _APS_NEXT_CONTROL_VALUE 1010
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
//Server.h
//#pragma once
#include"NetDialog.h"
#ifndef _CServer_h_//用于防止头文件嵌套多次1
#define _CServer_h_//用于防止头文件嵌套多次2
class CNetDialog;
//class CRenjuView;
#include"Mmsystem.h"//用于录音的函数
#include<afxsock.h>//用于socket的相关定义
#include <string.h>
#define BUFSIZE 1000
#define MAX_BUFFER_SIZE 2048
#define CHESSDATA 1
#define CHATDATA 2
#define WM_CHESS WM_APP+210
class CNetDialog;
class CServer
{
public:
//////////////用于文字聊天定义-开始///////////////
SOCKET ListenSocket; //用于服务器进行监听的套接字
SOCKET ConnectSocket; //服务器连接成功后,用于传输数据的套接字
struct sockaddr_in ServerAddress;//服务器的ip地址以及端口号
struct sockaddr_in ClientAddress;//客户端的ip地址以及端口号
char SendBuf[BUFSIZE];//发送缓存大小
char ReceiveBuf[BUFSIZE];//接收缓存大小
//////////////用于文字聊天定义-结束///////////////
//////////////用于语音聊天定义-开始///////////////
SOCKET ListenSocketSound;//用于服务器的音频聊天进行监听的套接字
SOCKET ConnectSocketSound;//服务器连接成功后,用于传输音频聊天的套接字
struct sockaddr_in ServerAddSound;//用于进行音频聊天的服务器的ip地址以及端口号
struct sockaddr_in ClientAddSound;//用于进行音频聊天的客户端的ip地址以及端口号
//////////////用于语音聊天定义-结束///////////////
////////////////用于传输棋子坐标数据定义-开始///////////////
// SOCKET ListenSocketChess; //用于服务器进行监听的套接字
// SOCKET ConnectSocketChess; //服务器连接成功后,用于传输数据的套接字
// struct sockaddr_in ServerAddChess;//服务器的ip地址以及端口号
// struct sockaddr_in ClientAddChess;//客户端的ip地址以及端口号
// WORD SendChess;//发送缓存大小
// WORD ReceiveChess;//接收缓存大小
////////////////用于传输棋子坐标数据定义-结束///////////////
CNetDialog *m_dlg;
int ReceiveFlag;
WORD SendChess;//发送缓存大小
WORD ReceiveChess;//接收缓存大小
public:
CServer(void);
~CServer(void);
bool AddSocketLib();//加载套接字库
bool CreateSocket();//创建监听套接字
bool BindSocket();//绑定套接字到ServerAddress
bool ListeSocket();//将套接字设置为监听模式,准备接收客户请求
bool AcceptClient();//等待客户端请求
bool SendData(WAVEHDR* p);//向客户端发送数据
bool ReceiveData(WAVEHDR* p,CNetDialog *dialog);//接收客户端发来的数据
bool InitM_dlg(CNetDialog *Dlg);//将CChatDlg的对象传递给m_dlg
bool GetServerAddress();//将ip控件框里面的ip地址赋值给ServerAddress和ServerAddressSound
bool GetSendBuf(CString SendData);//将发送框里面的内容赋值给SendBuf
bool GetReceiveBuf(CString & RecData);//将ReceiveBuf中的数据保存到一个cstring类型中
// bool SendSound(char *buf,int len);//向客户端发送音频数据
bool SendMark(int mark);//发送标识,表示下一个收到的数据是文字数据还是,五子棋数据
HWND hWnd;
////////////////用于传输棋子坐标数据定义-开始///////////////
// bool GetServerAddressChess();//将ip控件框里面的ip地址赋值给ServerAddressChess
// bool CreateSocketChess();
// bool BindSocketChess();
// bool ListeSocketChess();
// bool AcceptClientChess();
// bool SendDataChess();
// bool ReceiveDataChess();
////////////////用于传输棋子坐标数据定义-结束///////////////
};
#endif
//Sound.h
//#pragma once
#include"NetDialog.h"
#ifndef _Sound_h_//用于防止头文件嵌套多次1
#define _Sound_h_//用于防止头文件嵌套多次2
class CNetDialog;
#include"Mmsystem.h"//用于录音的函数
#define BUFNUM 10
#define BUFSIZE 1000
#define MAX_BUFFER_SIZE 2048
class CSound
{
public:
CSound(void);
~CSound(void);
WAVEFORMATEX m_soundFormat;//存储录音以及播放格式的相关信息
HWAVEIN m_hWaveIn; //输入设备句柄
HWAVEOUT m_hWaveOut; //输出设备句柄
WAVEHDR* m_bufferIn[BUFNUM];//用于录音的内存的相关信息
WAVEHDR* m_bufferOut[BUFNUM];//用于播放的内存的相关信息
bool m_Outusingflag[BUFNUM];//标识m_bufferOut是否已经与输出设备联系起来!没有为false,有为true
bool Init(CNetDialog *m_dlg);//初始化音频输入、输出设备
bool Record();//录音
bool StopRecord();//停止录音
bool Play(WAVEHDR *pWaveData);//播放
bool FreeRecordBuffer(WAVEHDR *pWaveInBuffer);//释放音频输入设备和pWaveInBuffer指向缓存之间的联系
bool AddRecordBuffer(WAVEHDR *pWaveInBuffer);//添加音频输入设备和pWaveInBuffer指向缓存之间的联系
bool FreePlayBuffer(WAVEHDR *pWaveInBuffer);//释放音频输出设备和pWaveInBuffer指向缓存之间的联系
};
#endif//用于防止头文件嵌套多次3
//stdafx.h
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
#pragma once
#ifndef _SECURE_ATL
#define _SECURE_ATL 1
#endif
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN // 从 Windows 头中排除极少使用的资料
#endif
// 如果您必须使用下列所指定的平台之前的平台,则修改下面的定义。
// 有关不同平台的相应值的最新信息,请参考 MSDN。
#ifndef WINVER // 允许使用特定于 Windows XP 或更高版本的功能。
#define WINVER 0x0501 // 将此值更改为相应的值,以适用于 Windows 的其他版本。
#endif
#ifndef _WIN32_WINNT // 允许使用特定于 Windows XP 或更高版本的功能。
#define _WIN32_WINNT 0x0501 // 将此值更改为相应的值,以适用于 Windows 的其他版本。
#endif
#ifndef _WIN32_WINDOWS // 允许使用特定于 Windows 98 或更高版本的功能。
#define _WIN32_WINDOWS 0x0410 // 将它更改为适合 Windows Me 或更高版本的相应值。
#endif
#ifndef _WIN32_IE // 允许使用特定于 IE 6.0 或更高版本的功能。
#define _WIN32_IE 0x0600 // 将此值更改为相应的值,以适用于 IE 的其他版本。值。
#endif
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 某些 CString 构造函数将是显式的
// 关闭 MFC 对某些常见但经常可放心忽略的警告消息的隐藏
#define _AFX_ALL_WARNINGS
#include <afxwin.h> // MFC 核心组件和标准组件
#include <afxext.h> // MFC 扩展
#include <afxdisp.h> // MFC 自动化类
#ifndef _AFX_NO_OLE_SUPPORT
#include <afxdtctl.h> // MFC 对 Internet Explorer 4 公共控件的支持
#endif
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC 对 Windows 公共控件的支持
#endif // _AFX_NO_AFXCMN_SUPPORT
#ifdef _UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:/"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'/"")
#elif defined _M_IA64
#pragma comment(linker,"/manifestdependency:/"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'/"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:/"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'/"")
#else
#pragma comment(linker,"/manifestdependency:/"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'/"")
#endif
#endif
//Chessboard.cpp
#include "StdAfx.h"
#include "Chessboard.h"
CChessboard::CChessboard(void)
{
for(int i=0;i<NUM;i++)
for(int j=0;j<NUM;j++)
{
PlayOneChNum[i][j]=0;
PlayTwoChNum[i][j]=0;
AllPlayOneChess[i][j]=false;
AllPlayTwoChess[i][j]=false;
}
SpaceBetween=0;
AllPlayOneChNum=0;
AllPlayTwoChNum=0;
}
CChessboard::~CChessboard(void)
{
}
///////////////////////////////////////////////////////////////////////
// UpdateSpaceBetween函数-开始 //
// 当窗口重画时,改变两条线之间的距离 //
///////////////////////////////////////////////////////////////////////
bool CChessboard::UpdateSpaceBetween(int x,int y)
{
SpaceBetween=((NUM-2)*y/NUM)/(NUM-1);
return true;
}
///////////////////////////////////////////////////////////////////////
// UpdateSpaceBetween函数-结束 //
// 当窗口重画时,改变两条线之间的距离 //
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// DrawChessboard函数-开始 //
// 绘制棋盘 //
///////////////////////////////////////////////////////////////////////
bool CChessboard::DrawChessboard(CWnd *wnd)
{
HDC hdc;
CString tempI;
static int cxChar,cyChar;
TEXTMETRIC tm ;
///////////////获取字体的宽度-开始/////////////////
hdc=::GetDC (wnd->m_hWnd);
::GetTextMetrics (hdc, &tm);
cxChar=tm.tmAveCharWidth;
cyChar=tm.tmHeight+tm.tmExternalLeading;
::ReleaseDC (wnd->m_hWnd, hdc);
///////////////获取字体的宽度-结束/////////////////
///////////////绘制棋盘横竖线和边上的坐标-开始/////////////////
hdc =::GetDC(wnd->m_hWnd) ;
::Rectangle(hdc,SpaceBetween-1,SpaceBetween-1,SpaceBetween*NUM,SpaceBetween*NUM);
::TextOut(hdc,SpaceBetween*4/10,SpaceBetween*4/10,TEXT("0"),1);
for(int i=0;i<=NUM-1;i++)
{
::MoveToEx(hdc,SpaceBetween,SpaceBetween+SpaceBetween*i,NULL);//绘制棋盘横竖线条
::LineTo(hdc,SpaceBetween*NUM,SpaceBetween+SpaceBetween*i);//绘制棋盘横竖线条
::MoveToEx(hdc,SpaceBetween+SpaceBetween*i,SpaceBetween,NULL);//绘制棋盘横竖线条
::LineTo(hdc,SpaceBetween+SpaceBetween*i,SpaceBetween*NUM);//绘制棋盘横竖线条
tempI.Format("%d",i);
///////////绘制棋盘边上的数字-开始//////////
if(i!=0&&i<=9)
{
TextOut(hdc,SpaceBetween*(i+1)-cxChar/2,SpaceBetween*2/10,tempI,1);
TextOut(hdc,SpaceBetween*2/10,SpaceBetween*(i+1)-cxChar,tempI,1);
}
if(i!=0&&i>9)//大于9后为两位所以显示位置有改变
{
TextOut(hdc,SpaceBetween*(i+1)-cxChar,SpaceBetween*2/10,tempI,2);
TextOut(hdc,SpaceBetween*2/10,SpaceBetween*(i+1)-cxChar,tempI,2);
}
///////////绘制棋盘边上的数字-结束//////////
}
///////////////绘制棋盘横竖线和边上的坐标-结束/////////////////
///////////////绘制棋盘上的四个小矩形-开始/////////////////
HBRUSH hBrush;
hBrush=(HBRUSH)SelectObject(hdc,GetStockObject(BLACK_BRUSH));//保存原来的画刷用于恢复
Rectangle(hdc,4*SpaceBetween-SpaceBetween*1/5,4*SpaceBetween-SpaceBetween*1/5,
4*SpaceBetween+SpaceBetween*1/5,4*SpaceBetween+SpaceBetween*1/5);
Rectangle(hdc,12*SpaceBetween-SpaceBetween*1/5,4*SpaceBetween-SpaceBetween*1/5,
12*SpaceBetween+SpaceBetween*1/5,4*SpaceBetween+SpaceBetween*1/5);
Rectangle(hdc,4*SpaceBetween-SpaceBetween*1/5,12*SpaceBetween-SpaceBetween*1/5,
4*SpaceBetween+SpaceBetween*1/5,12*SpaceBetween+SpaceBetween*1/5);
Rectangle(hdc,12*SpaceBetween-SpaceBetween*1/5,12*SpaceBetween-SpaceBetween*1/5,
12*SpaceBetween+SpaceBetween*1/5,12*SpaceBetween+SpaceBetween*1/5);
SelectObject(hdc,hBrush);//恢复原来的画刷
///////////////绘制棋盘上的四个小矩形-结束/////////////////
///////////////绘制棋盘边的文字-开始/////////////////
::TextOut(hdc,SpaceBetween*(NUM+1),SpaceBetween*2,TEXT("Player time:"),12);
::TextOut(hdc,SpaceBetween*(NUM+1),SpaceBetween*3,TEXT("Computer time:"),14);
::TextOut(hdc,SpaceBetween*(NUM+1),SpaceBetween*5,TEXT("Step:"),5);
///////////////绘制棋盘边的文字-结束/////////////////
///////////////绘制棋盘上的棋子-开始/////////////////
for(int j=0;j<NUM;j++)
for(int i=0;i<NUM;i++)
{
if(AllPlayOneChess[i][j]==true)
{
int tempCooX=(i+1)*SpaceBetween;
int tempCooY=(j+1)*SpaceBetween;
//CString snum;
//snum.Format("%d",com.CoordinateSNum[i][j]);//com.GetComCount()+com.GetOppCount());
HBRUSH hBrush;
hBrush=(HBRUSH)::SelectObject(hdc,::GetStockObject(BLACK_BRUSH));//保存原来的画刷用于恢复
::Ellipse(hdc,tempCooX-(SpaceBetween/2)*18/20,tempCooY-(SpaceBetween/2)*18/20,
tempCooX+(SpaceBetween/2)*18/20,tempCooY+(SpaceBetween/2)*18/20);
::SelectObject(hdc,hBrush);//恢复原来的画刷
//////////////////改变字体颜色和字体背景颜色-开始////////////////////////
HDC hdc2;
hdc2 = GetDC (wnd->m_hWnd) ;
::SetBkColor(hdc2,RGB(0,0,0));
::SetTextColor(hdc2,RGB(255,255,255));
// if(ComChNum<10)
// ::TextOut(hdc2,tempCooX-cxChar/2-1,tempCooY-cyChar/2,snum,1);
// else if(com.CoordinateSNum[i][j]>=10&&com.CoordinateSNum[i][j]<100)
// ::TextOut(hdc2,tempCooX-cxChar-1,tempCooY-cyChar/2,snum,2);
// else
// ::TextOut(hdc2,tempCooX-cxChar*3/2,tempCooY-cyChar/2,snum,3);
::SetTextColor(hdc2,RGB(0,0,0));
::SetBkColor(hdc2,RGB(255,255,255));
::ReleaseDC(wnd->m_hWnd,hdc2);
//////////////////改变字体颜色和字体背景颜色-结束////////////////////////
}
if(AllPlayTwoChess[i][j]==true)
{
int tempCooX=(i+1)*SpaceBetween;
int tempCooY=(j+1)*SpaceBetween;
::Ellipse(hdc,tempCooX-(SpaceBetween/2)*18/20,tempCooY-(SpaceBetween/2)*18/20,
tempCooX+(SpaceBetween/2)*18/20,tempCooY+(SpaceBetween/2)*18/20);
}
}
///////////////绘制棋盘上的棋子-结束/////////////////
::ReleaseDC(wnd->m_hWnd,hdc);
return true;
}
///////////////////////////////////////////////////////////////////////
// DrawChessboard函数-结束 //
// 绘制棋盘 //
///////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// AddNewChess函数-开始 //
// 添加新棋子 //
///////////////////////////////////////////////////////////////////////
bool CChessboard::AddNewChess(int x,int y,int flag)
{
if(flag==PLAYONE)
{
AllPlayOneChess[x][y]=true;
AllPlayOneChNum++;
PlayOneChNum[x][y]=AllPlayOneChNum;
}
if(flag==PLAYTWO)
{
AllPlayTwoChess[x][y]=true;
AllPlayTwoChNum++;
PlayTwoChNum[x][y]=AllPlayTwoChNum;
}
return true;
}
///////////////////////////////////////////////////////////////////////
// AddNewChess函数-结束 //
// 添加新棋子 //
//////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// JudgeCoordinate函数-开始 //
// 判断一个坐标的棋子是否已经被占用,若没被占用返回 //
// NOCHESS,若被computer的棋子占用返回COMCHESS, //
// 若被opp的棋子占用返回OPPCHESS //
//////////////////////////////////////////////////////////////////////
int CChessboard::JudgeCoordinate(int x,int y)
{
if(AllPlayOneChess[x][y]==true)return COMCHESS;
if(AllPlayTwoChess[x][y]==true)return OPPCHESS;
if(AllPlayOneChess[x][y]==false&&AllPlayTwoChess[x][y]==false)return NOCHESS;
}
///////////////////////////////////////////////////////////////////////
// JudgeCoordinate函数-开始 //
// 判断一个坐标的棋子是否已经被占用,若没被占用返回 //
// NOCHESS,若被computer的棋子占用返回COMCHESS, //
// 若被opp的棋子占用返回OPPCHESS //
//////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// JudgeWin函数定义-开始 //
// 判断是否已经有人胜利 //
////////////////////////////////////////////////////////////////////////////
bool CChessboard::JudgeWiner()
{
int left,right,top,bottom,leftT,leftB,rightT,rightB;
for(int i=0;i<NUM;i++)
for(int j=0;j<NUM;j++)
{
if(AllPlayOneChess[i][j]==true)
{
ContinuumComNum(i,j,left,right,top,bottom,leftT,leftB,rightT,rightB,PLAYONE);//计算一个点在各个方向上各有几个点相连
if(left==4||right==4||top==4||bottom==4||leftT==4||rightB==4||leftB==4||rightT==4) //判断是否已经有连续五个棋子
{
::AfxMessageBox("Player One have win!");
return true;//结束程序的函数
}
}
if(AllPlayTwoChess[i][j]==true)
{
ContinuumComNum(i,j,left,right,top,bottom,leftT,leftB,rightT,rightB,PLAYTWO);//计算一个点在各个方向上各有几个点相连
if(left==4||right==4||top==4||bottom==4||leftT==4||rightB==4||leftB==4||rightT==4) //判断是否已经有连续五个棋子
{
::AfxMessageBox("Player Two have win!");
return true;//结束程序的函数
}
}
}
return true;
}
/////////////////////////////////////////////////////////////////////////////
// JudgeWin函数定义-结束 //
// 判断是否已经有人胜利 //
////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// ContinuumComNum函数定义-开始 //
// 计算一个点在各个方向上各有几个点相连 //
////////////////////////////////////////////////////////////////////////////
bool CChessboard::ContinuumComNum(int x,int y,int &left,int &right,int &top,
int &bottom,int &leftT,int &leftB,int &rightT,int &rightB,int flag)
{
int tempX,tempY;
left=0;
right=0;
top=0;
bottom=0;
leftT=0;
leftB=0;
rightT=0;
rightB=0;
tempX=x;
tempY=y;
if(x>=0&&x<NUM)
{
while(tempX>0&&!JudgeCoordinate(--tempX,tempY,flag))
left++;//tempX一定要放在!JudgeComCoordinate(--tempX,tempY)的前面
tempX=x;
tempY=y;
while(tempX<NUM&&!JudgeCoordinate(++tempX,tempY,flag))
right++;
tempX=x;
tempY=y;
while(tempY>0&&!JudgeCoordinate(tempX,--tempY,flag))
top++;
tempX=x;
tempY=y;
while(tempY<NUM&&!JudgeCoordinate(tempX,++tempY,flag))
bottom++;
tempX=x;
tempY=y;
while(tempX>0&&tempY>0&&!JudgeCoordinate(--tempX,--tempY,flag))
leftT++;
tempX=x;
tempY=y;
while(tempX<NUM&&tempY<NUM&&!JudgeCoordinate(++tempX,++tempY,flag))
rightB++;
tempX=x;
tempY=y;
while(tempX>0&&tempY<NUM&&!JudgeCoordinate(--tempX,++tempY,flag))
leftB++;
tempX=x;
tempY=y;
while(tempX<NUM&&tempY>0&&!JudgeCoordinate(++tempX,--tempY,flag))
rightT++;
}
return true;
}
/////////////////////////////////////////////////////////////////////////////
// ContinuumComNum函数定义-结束 //
// 计算一个点在各个方向上各有几个点相连 //
////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// JudgeCoordinate函数定义-开始 //
// 判断一个坐标是否已经被playerone或者 //
// playertwo的棋子所占用(没有占用返回true) //
////////////////////////////////////////////////////////////////////////////
bool CChessboard::JudgeCoordinate(int x,int y,int flag)
{
if(flag==PLAYONE)
{
int temp=0;
if(AllPlayOneChess[x][y]==true)
temp++;
if(temp==0)
return true;
else
return false;
}
if(flag==PLAYTWO)
{
int temp=0;
if(AllPlayTwoChess[x][y]==true)
temp++;
if(temp==0)
return true;
else
return false;
}
}
/////////////////////////////////////////////////////////////////////////////
// JudgeCoordinate函数定义-结束 //
// 判断一个坐标是否已经被playerone或者 //
// playertwo的棋子所占用(没有占用返回true) //
////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// ClearAllChess函数定义-开始 //
// 将所有棋子清空 //
////////////////////////////////////////////////////////////////////////////
bool CChessboard::ClearAllChess()
{
for(int i=0;i<NUM;i++)
for(int j=0;j<NUM;j++)
{
PlayOneChNum[i][j]=0;
PlayTwoChNum[i][j]=0;
AllPlayOneChess[i][j]=false;
AllPlayTwoChess[i][j]=false;
}
AllPlayOneChNum=0;
AllPlayTwoChNum=0;
return true;
}
/////////////////////////////////////////////////////////////////////////////
// ClearAllChess函数定义-结束 //
// 将所有棋子清空 //
////////////////////////////////////////////////////////////////////////////
//Client.cpp
#include "StdAfx.h"
#include "Client.h"
CClient::CClient(void)
{
ReceiveFlag=0;
}
CClient::~CClient(void)
{
}
///////////////////////////////////////////////////////////////////////////////////////////////
// AddSocketLib-开始 //
// 加载套接字库 //
//////////////////////////////////////////////////////////////////////////////////////////////
bool CClient::AddSocketLib()
{
WORD wVersion;
WSADATA wsaData;
int err;
wVersion=MAKEWORD(1,1);
err=::WSAStartup(wVersion,&wsaData);
if(err!=0)//如果调用失败
return false;
if(LOBYTE(wsaData.wVersion)!=1||HIBYTE(wsaData.wVersion)!=1)//如果调用失败
{
::WSACleanup();
return false;
}
return true;
}
///////////////////////////////////////////////////////////////////////////////////////////////
// AddSocketLib-结束 //
// 加载套接字库 //
//////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
// CreateSocket-开始 //
// 创建监听套接字 //
//////////////////////////////////////////////////////////////////////////////////////////////
bool CClient::CreateSocket()
{
//用于文字聊天
ClientSocket=::socket(AF_INET,SOCK_STREAM,0);
if(ClientSocket==INVALID_SOCKET)
return false;
//用于语音聊天
ClientSocketSound=::socket(AF_INET,SOCK_STREAM,0);
if(ClientSocketSound==INVALID_SOCKET)
return false;
return true;
}
///////////////////////////////////////////////////////////////////////////////////////////////
// CreateSocket-结束 &nb