五子棋等级考试软件的开发(八)

本篇继续上篇的未完部分。前面介绍完了软件的背景、设计、实现,本篇主要做一些总结。

4. 测试

前面已经完成了编码工作,可以运行起来进行测试:

选择相应的评估等级,然后点击“开始评测”按钮:

输入用户名和密码并点击“登录”按钮进行登录,用户名和密码如果没有的话,可以点击“注册”按钮先注册用户,然后再登录。登录成功后即可正式开始评测:

当本局对弈结束后可点击“开始新游戏”进入下一局,若感觉本局无望获胜也可点击“开始新游戏”按钮来放弃本局并直接进入下一局 。

5. 文中所提的SDK(及案例的完整代码)可在如下地址下载:

官网下载:www.gnxxkj.com

github下载:https://github.com/wangdechang119

gitlab下载:https://gitlab.com/wangdechang119

gitee下载:https://gitee.com/wangdechang119

6. 完整代码如下


// testDlg.h : 头文件
//

#pragma once


// CtestDlg 对话框
class CtestDlg : public CDialogEx
{
// 构造
public:
	CtestDlg(CWnd* pParent = NULL);	// 标准构造函数

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_TEST_DIALOG };
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持


// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();

	afx_msg void OnSize(UINT nType, int cx, int cy);

	afx_msg void OnBnClickedBtnStart();
	afx_msg void OnBnClickedBtnNew();
	afx_msg void OnCbnSelchangeLevel();
	afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);

	DECLARE_MESSAGE_MAP()

public:
	void Show();
	void ShowResult();	//显示评估结果
	void ShowWin();		//显示胜负
	void ShowGameOver();	//显示游戏结束

public:
	CStatic m_objBoard;		//画图控件
	CComboBox m_objLevel;	//用于选择“评估等级”的下拉框
	int m_nCurSel;			//当前选中的等级索引

	bool m_bLogged;		//是否已登录

	bool m_bStarted;	//游戏是否已经开始
	bool m_bHumanPlay;	//是否该人/挑战者落子

	int m_nNumTotal;	//五子棋水平等级评估时的总局数:即每次评估需和AI对战m_nNumTotal局
	int m_nNumLeft;		//剩余局数
	int m_nNumWin;		//已胜的局数
	int m_nDepth;		//思维深度:N等级对应的标准深度为2N(合格,6),7和8为2N+1,9和10为2N+2,3、4、5为2N-1,0、1、2为2N-2
	double m_fConcern;	//专注度:百分比,参考基准为10局对弈中AI总耗时,人工总耗时/AI总耗时>=1时专注度100%,向下需考虑等级难度
};

// testDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "test.h"
#include "testDlg.h"
#include "afxdialogex.h"
#include "Login.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#include "Inter.h"
#pragma comment(lib, "AIWZQDll.lib")

// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_ABOUTBOX };
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CtestDlg 对话框



CtestDlg::CtestDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(IDD_TEST_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CtestDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LEVEL, m_objLevel);
	DDX_Control(pDX, IDC_BOARD, m_objBoard);
}

BEGIN_MESSAGE_MAP(CtestDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_SIZE()
	ON_BN_CLICKED(IDC_BTN_START, &CtestDlg::OnBnClickedBtnStart)
	ON_BN_CLICKED(IDC_BTN_NEW, &CtestDlg::OnBnClickedBtnNew)
	ON_CBN_SELCHANGE(IDC_LEVEL, &CtestDlg::OnCbnSelchangeLevel)
	ON_WM_SETCURSOR()
	ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()


// CtestDlg 消息处理程序

BOOL CtestDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码
	if (!InitFromModelFile("model.mod"))	//使用模型文件初始化
	{
		AfxMessageBox(_T("找不到网络模型,请确定考评用的标准模型存在且未经擅自修改"));
		PostQuitMessage(0);
	}

	GetDlgItem(IDC_BTN_START)->EnableWindow(true);
	GetDlgItem(IDC_BTN_NEW)->EnableWindow(false);

	GetDlgItem(IDC_NUM_TOTAL)->SetWindowTextW(_T("10"));
	GetDlgItem(IDC_NUM_LEFT)->SetWindowTextW(_T("10"));
	GetDlgItem(IDC_RATIO)->SetWindowTextW(_T("0/10"));
	GetDlgItem(IDC_DEPTH)->SetWindowTextW(_T(""));
	GetDlgItem(IDC_CONCERN)->SetWindowTextW(_T(""));

	m_objLevel.InsertString(0, _T("一级"));
	m_objLevel.InsertString(1, _T("二级"));
	m_objLevel.InsertString(2, _T("三级"));
	m_objLevel.InsertString(3, _T("四级"));
	m_objLevel.InsertString(4, _T("五级"));
	m_objLevel.InsertString(5, _T("六级"));
	m_objLevel.InsertString(6, _T("七级"));
	m_objLevel.InsertString(7, _T("八级"));
	m_objLevel.InsertString(8, _T("九级"));
	m_objLevel.InsertString(9, _T("十级"));
	m_nCurSel = 0;
	m_objLevel.SetCurSel(m_nCurSel);

	m_bLogged = false;
	m_bStarted = false;
	m_bHumanPlay = false;
	m_nNumTotal = 10;
	m_nNumLeft = 10;
	m_nNumWin = 0;
	m_nDepth = -1;
	m_fConcern = -1.;

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void CtestDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CtestDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();

		Show();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CtestDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CtestDlg::Show()
{
	CRect rect;	//对话框区域大小
	CRect rc;	//按钮区域大小
	CRect rc2;	//文本标签区域大小
	CRect rc3;	//复选框区域大小

	GetClientRect(&rect);
	CWnd* pBtn = GetDlgItem(IDC_BTN_START);
	if (pBtn != NULL)
	{
		pBtn->GetClientRect(&rc);
		GetDlgItem(IDC_LB_LEVEL)->GetClientRect(&rc2);
		GetDlgItem(IDC_LEVEL)->GetClientRect(&rc3);

		CRect rcd;	//调整后的按钮区域大小、文本标签区域大小
		rcd.left = rect.right - rc.Width()*1.25;
		rcd.right = rcd.left + rc.Width();
		rcd.top = rc.Height();
		rcd.bottom = rcd.top + rc.Height();
		pBtn->MoveWindow(&rcd);		//开始评测按钮

		rcd.top = rcd.bottom + rc.Height()*0.5;
		rcd.bottom = rcd.top + rc.Height();
		GetDlgItem(IDC_BTN_NEW)->MoveWindow(&rcd); //开始新游戏按钮

		rcd.top = rcd.bottom + rc.Height();
		rcd.bottom = rcd.top + rc2.Height();
		GetDlgItem(IDC_LB_LEVEL)->MoveWindow(&rcd);	//评估等级标签

		CRect rcd2;	//调整后的值标签区域大小
		rcd2.left = rcd.left + rcd.Width()*0.2;
		rcd2.right = rcd2.left + rc3.Width();
		rcd2.top = rcd.bottom + rcd.Height()*0.4;
		rcd2.bottom = rcd2.top + rc3.Height();
		GetDlgItem(IDC_LEVEL)->MoveWindow(&rcd2);	//评估等级复选框

		rcd.top = rcd2.bottom + rcd.Height()*0.5;
		rcd.bottom = rcd.top + rc2.Height();
		GetDlgItem(IDC_LB_NUM_TOTAL)->MoveWindow(&rcd);	//评估局数标签

		rcd2.top = rcd.bottom + rcd.Height()*0.4;
		rcd2.bottom = rcd2.top + rc2.Height();
		GetDlgItem(IDC_NUM_TOTAL)->MoveWindow(&rcd2);	//评估局数值

		rcd.top = rcd2.bottom + rcd.Height()*0.5;
		rcd.bottom = rcd.top + rc2.Height();
		GetDlgItem(IDC_LB_NUM_LEFT)->MoveWindow(&rcd);	//剩余局数标签

		rcd2.top = rcd.bottom + rcd.Height()*0.4;
		rcd2.bottom = rcd2.top + rc2.Height();
		GetDlgItem(IDC_NUM_LEFT)->MoveWindow(&rcd2);	//剩余局数值

		rcd.top = rcd2.bottom + rcd.Height()*0.5;
		rcd.bottom = rcd.top + rc2.Height();
		GetDlgItem(IDC_LB_RATIO)->MoveWindow(&rcd);		//胜率标签

		rcd2.top = rcd.bottom + rcd.Height()*0.4;
		rcd2.bottom = rcd2.top + rc2.Height();
		GetDlgItem(IDC_RATIO)->MoveWindow(&rcd2);		//胜率值

		rcd.top = rcd2.bottom + rcd.Height()*0.5;
		rcd.bottom = rcd.top + rc2.Height();
		GetDlgItem(IDC_LB_DEPTH)->MoveWindow(&rcd);		//思维深度标签

		rcd2.top = rcd.bottom + rcd.Height()*0.4;
		rcd2.bottom = rcd2.top + rc2.Height();
		GetDlgItem(IDC_DEPTH)->MoveWindow(&rcd2);		//思维深度值

		rcd.top = rcd2.bottom + rcd.Height()*0.5;
		rcd.bottom = rcd.top + rc2.Height();
		GetDlgItem(IDC_LB_CONCERN)->MoveWindow(&rcd);	//专注度标签

		rcd2.top = rcd.bottom + rcd.Height()*0.4;
		rcd2.bottom = rcd2.top + rc2.Height();
		GetDlgItem(IDC_CONCERN)->MoveWindow(&rcd2);		//专注度值
	}

	rect.right -= rc.Width()*1.5;
	CWnd* pBoard = GetDlgItem(IDC_BOARD);
	if (pBoard != NULL)
		pBoard->MoveWindow(&rect);	//棋盘区域

	DrawBoard(&m_objBoard);		//绘制棋盘
	DrawPieces(&m_objBoard);	//绘制棋子
}

void CtestDlg::OnSize(UINT nType, int cx, int cy)
{
	CDialogEx::OnSize(nType, cx, cy);

	// TODO:  在此处添加消息处理程序代码
	Show();
}

void CtestDlg::OnBnClickedBtnStart()
{
	if (!m_bLogged)		//判断是否已有用户登录
	{
		CLogin objLogin;
		if (objLogin.DoModal() != IDOK)
		{
			MessageBox(_T("请先登录"), _T("温馨提醒"));
			return;
		}
		m_bLogged = true;
	}

	char strTemp[10] = { 0 };
	m_nNumLeft = m_nNumTotal;
	sprintf(strTemp, "%d", m_nNumLeft);
	SetDlgItemText(IDC_NUM_LEFT, CA2CT(strTemp));	//重置剩余局数

	m_nNumWin = 0;
	sprintf(strTemp, "%d/%d", m_nNumWin, m_nNumTotal);
	SetDlgItemText(IDC_RATIO, CA2CT(strTemp));		//重置胜率

	m_nDepth = -1;
	m_fConcern = -1.;
	SetDlgItemText(IDC_DEPTH, _T(""));				//重置思维深度
	SetDlgItemText(IDC_CONCERN, _T(""));			//重置专注度

	GetDlgItem(IDC_BTN_START)->EnableWindow(false);
	GetDlgItem(IDC_BTN_NEW)->EnableWindow(true);

	StartNewGame();
	Invalidate(TRUE);

	m_bStarted = true;
	m_bHumanPlay = true;	//被测者(人)先落子
}

void CtestDlg::OnBnClickedBtnNew()
{
	m_nNumLeft -= m_bStarted ? 1 : 0;	//直接放弃当前未结束的局时减1,若当前局已结束则开始新局不再减1(因为在一局结束时已经减过了)

	char strTemp[10] = { 0 };
	sprintf(strTemp, "%d", m_nNumLeft);
	SetDlgItemText(IDC_NUM_LEFT, CA2CT(strTemp));	//更新剩余局数

	if (m_nNumLeft <= 1)	//还剩最后一局
	{
		GetDlgItem(IDC_BTN_NEW)->EnableWindow(false);
	}

	StartNewGame();
	Invalidate(TRUE);

	m_bStarted = true;
	m_bHumanPlay = true;
}

void CtestDlg::OnCbnSelchangeLevel()
{
	int nCurSel = m_objLevel.GetCurSel();
	if (nCurSel == m_nCurSel)
		return;

	if (m_bStarted && MessageBox(_T("确定要更换评测等级重新进行评测吗?这将会中止当前的操作"), _T("温馨提示"), MB_OKCANCEL) == IDCANCEL)
	{
		m_objLevel.SetCurSel(m_nCurSel);
		return;		//选择了取消更换
	}

	m_nCurSel = nCurSel;
	SetLayers4Pred((m_nCurSel + 1) * 2);	//第N等级:设置为使用2N层网络;即一级、二级、三级等依次使用两层、四层、六层等网络

	char strTemp[10] = { 0 };
	m_nNumLeft = m_nNumTotal;
	sprintf(strTemp, "%d", m_nNumLeft);
	SetDlgItemText(IDC_NUM_LEFT, CA2CT(strTemp));	//重置剩余局数

	m_nNumWin = 0;
	sprintf(strTemp, "%d/%d", m_nNumWin, m_nNumTotal);
	SetDlgItemText(IDC_RATIO, CA2CT(strTemp));		//重置胜率

	m_nDepth = -1;
	m_fConcern = -1.;
	SetDlgItemText(IDC_DEPTH, _T(""));				//重置思维深度
	SetDlgItemText(IDC_CONCERN, _T(""));			//重置专注度

	GetDlgItem(IDC_BTN_START)->EnableWindow(true);	//启用“开始评测”按钮
	GetDlgItem(IDC_BTN_NEW)->EnableWindow(false);	//禁用“开始新游戏”按钮

	m_bStarted = false;
}

BOOL CtestDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
	CPoint pos;
	GetCursorPos(&pos);		//在整个屏幕上的坐标
	CRect rc;
	GetDlgItem(IDC_BOARD)->GetWindowRect(&rc);	//在整个屏幕上的坐标
	if (rc.PtInRect(pos))
	{
		if (m_bStarted && m_bHumanPlay)
		{
			SetCursor(LoadCursor(NULL, IDC_HAND));	//设置成手状
		}
		else
		{
			SetCursor(LoadCursor(NULL, IDC_NO));	//设置成禁用
		}
		return TRUE;
	}

	return CDialogEx::OnSetCursor(pWnd, nHitTest, message);
}

void CtestDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
	CRect rect;
	m_objBoard.GetClientRect(&rect);
	if (rect.PtInRect(point))
	{
		if (!m_bStarted)
		{
			if (m_nNumLeft == m_nNumTotal)
				MessageBox(_T("请先点击开始评测按钮"), _T("温馨提示"), MB_OK | MB_ICONHAND);
			else 
				MessageBox(_T("请先点击开始新游戏按钮"), _T("温馨提示"), MB_OK | MB_ICONHAND);
		}
		else if (m_bHumanPlay)
		{
			if (SetPieceWithGUI(&m_objBoard, point.x, point.y))
			{
				m_bHumanPlay = false;
				if (IsGameOver())
				{
					ShowGameOver();
				}
				else
				{
					if (!SetPieceByAIAndShow(&m_objBoard))
					{
						AfxMessageBox(_T("积分不足或网络问题,请确保网络畅通且积分充足(若是积分不足,充值后可继续本次对局)"));
					}
					else
					{
						m_bHumanPlay = true;
						if (IsGameOver())
						{
							ShowGameOver();
						}
					}
				}
			}
		}
	}
	CDialogEx::OnLButtonDown(nFlags, point);
}

void CtestDlg::ShowResult()
{
	switch (m_nNumWin)
	{
	case 0:
	case 1:
	case 2:
		MessageBox(_T("不合格!建议去更低一级评估"), _T("评估结束"), MB_OK | MB_ICONINFORMATION);
		m_nDepth = (m_nCurSel + 1) * 2 - 2;
		break;
	case 3:
	case 4:
	case 5:
		MessageBox(_T("不合格!"), _T("评估结束"), MB_OK | MB_ICONINFORMATION);
		m_nDepth = (m_nCurSel + 1) * 2 - 1;
		break;
	case 6:
		MessageBox(_T("合格!"), _T("评估结束"), MB_OK | MB_ICONINFORMATION);
		m_nDepth = (m_nCurSel + 1) * 2;
		break;
	case 7:
	case 8:
		MessageBox(_T("良好!"), _T("评估结束"), MB_OK | MB_ICONINFORMATION);
		m_nDepth = (m_nCurSel + 1) * 2 + 1;
		break;
	case 9:
	case 10:
		MessageBox(_T("优秀!建议去更高一级评估"), _T("评估结束"), MB_OK | MB_ICONINFORMATION);
		m_nDepth = (m_nCurSel + 1) * 2 + 2;
		break;
	}
}

void CtestDlg::ShowWin()
{
	switch (GetWinner())
	{
	case 1:
		MessageBox(_T("很遗憾,您输了"), _T("温馨提示"), MB_OK | MB_ICONINFORMATION);
		break;
	case -1:
		m_nNumWin++;
		MessageBox(_T("恭喜,您赢了"), _T("温馨提示"), MB_OK | MB_ICONINFORMATION);
		break;
	default:	//0
		AfxMessageBox(_T("平局"));
		break;
	}
}

void CtestDlg::ShowGameOver()
{
	m_bStarted = false;		//本次对弈结束
	m_nNumLeft--;			//本次对弈已结束,剩余局数减一

	ShowWin();		//显示本局的输赢,并重新计算获胜局数

	char strTemp[10] = { 0 };
	sprintf(strTemp, "%d", m_nNumLeft);
	SetDlgItemText(IDC_NUM_LEFT, CA2CT(strTemp));	//更新剩余局数

	sprintf(strTemp, "%d/%d", m_nNumWin, m_nNumTotal);
	SetDlgItemText(IDC_RATIO, CA2CT(strTemp));		//更新胜率

	if (m_nNumLeft <= 0)
	{
		ShowResult();	//评估思维深度并显示结果

		sprintf(strTemp, "%d 层", m_nDepth);
		SetDlgItemText(IDC_DEPTH, CA2CT(strTemp));	//更新思维深度

		GetDlgItem(IDC_BTN_START)->EnableWindow(true);	//启用开始评测
	}
}
#pragma once

//Login.h

// CLogin 对话框

class CLogin : public CDialogEx
{
	DECLARE_DYNAMIC(CLogin)

public:
	CLogin(CWnd* pParent = NULL);   // 标准构造函数
	virtual ~CLogin();

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_DIALOG1 };
#endif

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

	virtual BOOL OnInitDialog();

	afx_msg void OnBnClickedBtnLogin();
	afx_msg void OnBnClickedBtnRegist();

	DECLARE_MESSAGE_MAP()

public:
	CEdit m_objEditLoginName;
	CEdit m_objEditLoginPassword;
};
// Login.cpp : 实现文件
//

#include "stdafx.h"
#include "test.h"
#include "Login.h"
#include "afxdialogex.h"

#include "Inter.h"
#pragma comment(lib, "AIWZQDll.lib")

// CLogin 对话框

IMPLEMENT_DYNAMIC(CLogin, CDialogEx)

CLogin::CLogin(CWnd* pParent /*=NULL*/)
	: CDialogEx(IDD_DIALOG1, pParent)
{

}

CLogin::~CLogin()
{
}

void CLogin::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_USER, m_objEditLoginName);
	DDX_Control(pDX, IDC_PASSWORD, m_objEditLoginPassword);
}


BEGIN_MESSAGE_MAP(CLogin, CDialogEx)
	ON_BN_CLICKED(IDOK, &CLogin::OnBnClickedBtnLogin)
	ON_BN_CLICKED(IDC_BTN_REGIST, &CLogin::OnBnClickedBtnRegist)
END_MESSAGE_MAP()


// CLogin 消息处理程序
BOOL CLogin::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	m_objEditLoginName.SetLimitText(32);
	m_objEditLoginPassword.SetLimitText(32);

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void CLogin::OnBnClickedBtnLogin()
{
	CString strName, strPsw;
	m_objEditLoginName.GetWindowText(strName);
	m_objEditLoginPassword.GetWindowText(strPsw);
	strName.Trim();
	strPsw.Trim();
	if (strName.IsEmpty() || strName.Find(_T("&")) >= 0 || strName.Find(_T("=")) >= 0 || strName.Find(_T("+")) >= 0)
	{
		MessageBox(_T("用户名错误"), _T("温馨提示"), MB_OK | MB_ICONINFORMATION);
		return;
	}
	if (strPsw.IsEmpty() || strPsw.Find(_T("&")) >= 0 || strPsw.Find(_T("=")) >= 0 || strPsw.Find(_T("+")) >= 0)
	{
		MessageBox(_T("密码错误"), _T("温馨提示"), MB_OK | MB_ICONINFORMATION);
		return;
	}

	char cstrName[255] = { 0 };
	char cstrPsw[255] = { 0 };
	int nLen = 0;
	nLen = WideCharToMultiByte(CP_ACP, 0, strName, -1, NULL, 0, NULL, NULL);
	WideCharToMultiByte(CP_ACP, 0, strName, -1, cstrName, nLen, NULL, NULL);
	nLen = WideCharToMultiByte(CP_ACP, 0, strPsw, -1, NULL, 0, NULL, NULL);
	WideCharToMultiByte(CP_ACP, 0, strPsw, -1, cstrPsw, nLen, NULL, NULL);
	if (!Login(cstrName, cstrPsw))
	{
		MessageBox(_T("用户名或密码错误,请在网络畅通的情况下重新输入"), _T("温馨提示"), MB_OK | MB_ICONINFORMATION);
		return;
	}

	CDialog::OnOK();
}

void CLogin::OnBnClickedBtnRegist()
{
	char strURL[1024] = { 0 };
	sprintf(strURL, "http://www.gnxxkj.com/app/wuziqi/register.php");
	CString wstrURL(strURL);
	ShellExecute(0, NULL, wstrURL, NULL, NULL, SW_NORMAL); //在外部打开网页
}
//Inter.h

typedef signed char TBOARD;

//以下函数在程序运行开始的时候调用,仅调用一次
extern "C" __declspec(dllexport) bool Login(char* strLoginName, char* strPassword);		//登录

extern "C" __declspec(dllexport) bool InitFromModelFile(char* strModelFileName);	//使用模型文件初始化
extern "C" __declspec(dllexport) bool InitWithoutModelFile(int nBoardWidth, int nBoardHeight, int nWinLen);		//无模型文件时初始化

//以下函数在每局游戏开始的时候调用,每局游戏调用一次
extern "C" __declspec(dllexport) bool StartNewGame();			//开始游戏,并重置相关数据

//以下函数在每步落子的时候调用,每步落子调用一次
extern "C" __declspec(dllexport) bool SetPieceWithCoord(int nX, int nY);	//根据坐标落子
extern "C" __declspec(dllexport) bool SetPieceWithGUI(CStatic* pCtrlBoard, int nCursorXInCtrl, int nCursorYInCtrl);		//根据界面组件及屏幕鼠标位置落子

extern "C" __declspec(dllexport) bool SetPieceByAI(void);					//AI落子,该函数返回失败表示所登录的用户积分不足
extern "C" __declspec(dllexport) bool SetPieceByAIAndShow(CStatic* pCtrlBoard);		//AI落子并在界面上显示

extern "C" __declspec(dllexport) bool IsGameOver();		//游戏是否已经结束
extern "C" __declspec(dllexport) int GetWinner();		//获胜者

extern "C" __declspec(dllexport) bool DrawBoard(CStatic* pCtrlBoard);		//绘制棋盘
extern "C" __declspec(dllexport) bool DrawPieces(CStatic* pCtrlBoard);		//绘制所有棋子

//以下函数在需要的时候调用,非必须调用
extern "C" __declspec(dllexport) TBOARD* GetBoardData(int* pnBoardWidth, int* pnBoardHeight);	//获得当前棋局数组的内存区首地址(及矩阵的宽和高,如果需要的话)
extern "C" __declspec(dllexport) int GetPoint();

extern "C" __declspec(dllexport) bool SaveSteps(char* strDataFileName);		//保存棋局数据
extern "C" __declspec(dllexport) bool SaveModel(char* strModelFileName);	//保存模型数据

//以下函数用于“五子棋水平等级评估”
extern "C" __declspec(dllexport) bool SetLayers4Pred(int nLayers);		//设置用于预测的层数,与之同时,将禁止神经网络的学习进化,仅使用指定的模型进行预测,可保证公平性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

De-Chang Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值