📄 pentedlg.cpp
字号:
// PenteDlg.cpp : implementation file
//
#include "stdafx.h"
#include <math.h>
#include <mmsystem.h>
#include "Pente.h"
#include "dib.h"
#include "setupdlg.h"
#include "AboutDlg.h"
#include "RecordDlg.h"
#include "BestDlg.h"
#include "Globalvar0.h"
#include "HelperAPI.h"
#include "PenteDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CPenteDlg dialog
CPenteDlg::CPenteDlg(CWnd* pParent /*=NULL*/)
: CDialog(CPenteDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CPenteDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_pMenu = new CMenu();
m_pDibBoard = new CDib;
m_pDibMask = new CDib;
m_pDibBlack = new CDib;
m_pDibWhite = new CDib;
InitParams();
//////////////////////////////////////////
char szVer[512];
///int nVer = GetWindowsVersion((LPSTR)szVer);
///if (stricmp(szVer, "Simplified Chinese")&&stricmp(szVer, "Chinese (PRC)")&&
/// stricmp(szVer, "中文")&&stricmp(szVer, "简体中文"))
/// g_bChinese = FALSE;
//////////////////////////////////////////
g_nSkill = AfxGetApp()->GetProfileInt("Settings", "Skill", 1);
g_bSoundOn = AfxGetApp()->GetProfileInt("Settings", "SoundOn", 1);
g_bUserBlack = AfxGetApp()->GetProfileInt("Settings", "UserUseBlackStone", 1);
g_nRunMode = AfxGetApp()->GetProfileInt("Settings", "Player", MODE_WITH_COMPUTER);
g_nTime1 = AfxGetApp()->GetProfileInt("Settings", "Time1", 225);
g_nTime2 = AfxGetApp()->GetProfileInt("Settings", "Time2", 225);
g_nTime3 = AfxGetApp()->GetProfileInt("Settings", "Time3", 225);
g_strName1 = AfxGetApp()->GetProfileString("Settings", "Name1", "Anonymous");
g_strName2 = AfxGetApp()->GetProfileString("Settings", "Name2", "Anonymous");
g_strName3 = AfxGetApp()->GetProfileString("Settings", "Name3", "Anonymous");
}
CPenteDlg::~CPenteDlg()
{
delete m_pMenu;
delete m_pDibBoard;
delete m_pDibMask;
delete m_pDibBlack;
delete m_pDibWhite;
AfxGetApp()->WriteProfileInt("Settings", "Skill", g_nSkill);
AfxGetApp()->WriteProfileInt("Settings", "SoundOn", g_bSoundOn);
AfxGetApp()->WriteProfileInt("Settings", "UserUseBlackStone", g_bUserBlack);
AfxGetApp()->WriteProfileInt("Settings", "Player", g_nRunMode);
AfxGetApp()->WriteProfileInt("Settings", "Time1", g_nTime1);
AfxGetApp()->WriteProfileInt("Settings", "Time2", g_nTime2);
AfxGetApp()->WriteProfileInt("Settings", "Time3", g_nTime3);
AfxGetApp()->WriteProfileString("Settings", "Name1", g_strName1);
AfxGetApp()->WriteProfileString("Settings", "Name2", g_strName2);
AfxGetApp()->WriteProfileString("Settings", "Name3", g_strName3);
}
void CPenteDlg::InitParams()
{
for (int i=0; i<BOARD_LINE_NUMBER;++i)
for (int j=0; j<BOARD_LINE_NUMBER; j++)
m_Board[i][j] = 0;
m_bGameOver = FALSE;
m_byColor = 0;
m_bCanUndo = FALSE;
m_bCanHint = TRUE;
m_wWhiteUndo = 0;
m_wBlackUndo = 0;
g_nStoneNum = 0;
m_rcCur1.SetRectEmpty();
m_rcCur2.SetRectEmpty();
m_rcHint.SetRectEmpty();
}
void CPenteDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CPenteDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CPenteDlg, CDialog)
//{{AFX_MSG_MAP(CPenteDlg)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_COMMAND(IDM_NEW, OnNew)
ON_COMMAND(IDM_SOUND, OnSound)
ON_COMMAND(IDM_BEST, OnBest)
ON_COMMAND(IDM_GRADE1, OnSkill1)
ON_COMMAND(IDM_GRADE2, OnSkill2)
ON_COMMAND(IDM_GRADE3, OnSkill3)
ON_COMMAND(IDM_EXIT, OnExit)
ON_COMMAND(IDM_ABOUT, OnAbout)
ON_COMMAND(IDM_HINT, OnHint)
ON_COMMAND(IDM_UNDO, OnUndo)
ON_COMMAND(IDM_LANGUAGE, OnLanguage)
ON_WM_SETCURSOR()
ON_WM_QUERYDRAGICON()
ON_WM_PALETTECHANGED()
ON_WM_QUERYNEWPALETTE()
ON_WM_SYSCOMMAND()
ON_WM_CONTEXTMENU()
ON_COMMAND(IDM_HELP_CONTEXT, OnHelp)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPenteDlg message handlers
BOOL CPenteDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// Check system display ability
CDC *pDC = GetDC();
int nSystemColors = pDC->GetDeviceCaps(BITSPIXEL);
if (nSystemColors<8) // 2**8 == 256
{
CString str1, str2;
str1.LoadString(g_bChinese ? IDS_COLOR_LESS_CHINESE:IDS_COLOR_LESS_ENGLISH);
str2.LoadString(g_bChinese ? IDS_TITLE_CHINESE:IDS_TITLE_ENGLISH);
if (MessageBox(str1, str2, MB_ICONQUESTION|MB_YESNO) != IDYES)
{
CDialog::EndDialog(0);
return TRUE; // return from InitDialog
}
}
// Load Dibs
m_pDibBoard->LoadDib(IDDIB_BOARD);
m_pDibMask->LoadDib(IDDIB_MASK);
m_pDibBlack->LoadDib(IDDIB_BLACK);
m_pDibWhite->LoadDib(IDDIB_WHITE);
m_pDibBoard->MakeBitmap(pDC);
m_pDibMask->MakeBitmap(pDC);
m_pDibBlack->MakeBitmap(pDC);
m_pDibWhite->MakeBitmap(pDC);
m_pDibBoard->GetPalette();
m_pDibMask->GetPalette();
m_pDibBlack->GetPalette();
m_pDibWhite->GetPalette();
ReleaseDC(pDC);
////////////////////////////////////////
CSetupDlg setupDlg(this);
if (setupDlg.DoModal()==IDCANCEL)
{
CDialog::EndDialog(0);
return TRUE; // return from InitDialog
}
CString str;
if (g_nRunMode==MODE_WITH_COMPUTER && g_bUserBlack)
str.LoadString(g_bChinese ? IDS_SINGLE_USER_CHINESE:IDS_SINGLE_USER_ENGLISH);
else if (g_nRunMode==MODE_WITH_COMPUTER && !g_bUserBlack)
str.LoadString(g_bChinese ? IDS_SINGLE_COMPUTER_CHINESE:IDS_SINGLE_COMPUTER_ENGLISH);
else if (g_nRunMode==MODE_2PLAYER)
str.LoadString(g_bChinese ? IDS_DOUBLE_CHINESE:IDS_DOUBLE_ENGLISH);
SetWindowText(str);
m_pMenu->DestroyMenu();
m_pMenu->LoadMenu(g_bChinese ? IDR_MENU_CHINESE : IDR_MENU_ENGLISH);
SetMenu(m_pMenu);
m_pMenu->CheckMenuItem(IDM_SOUND, g_bSoundOn ? MF_CHECKED : MF_UNCHECKED);
m_pMenu->EnableMenuItem(IDM_UNDO, m_bCanUndo ? MF_ENABLED : MF_GRAYED);
m_pMenu->EnableMenuItem(IDM_HINT, m_bCanHint&&(g_nRunMode==MODE_WITH_COMPUTER) ? MF_ENABLED : MF_GRAYED);
m_pMenu->EnableMenuItem(IDM_GRADE1, (g_nRunMode==MODE_WITH_COMPUTER) ? MF_ENABLED : MF_GRAYED);
m_pMenu->EnableMenuItem(IDM_GRADE2, (g_nRunMode==MODE_WITH_COMPUTER) ? MF_ENABLED : MF_GRAYED);
m_pMenu->EnableMenuItem(IDM_GRADE3, (g_nRunMode==MODE_WITH_COMPUTER) ? MF_ENABLED : MF_GRAYED);
if (g_nSkill == 1)
{
m_pMenu->CheckMenuItem(IDM_GRADE1, MF_BYCOMMAND | MF_CHECKED);
m_pMenu->CheckMenuItem(IDM_GRADE2, MF_BYCOMMAND | MF_UNCHECKED);
m_pMenu->CheckMenuItem(IDM_GRADE3, MF_BYCOMMAND | MF_UNCHECKED);
}
else if (g_nSkill == 2)
{
m_pMenu->CheckMenuItem(IDM_GRADE2, MF_BYCOMMAND | MF_CHECKED);
m_pMenu->CheckMenuItem(IDM_GRADE1, MF_BYCOMMAND | MF_UNCHECKED);
m_pMenu->CheckMenuItem(IDM_GRADE3, MF_BYCOMMAND | MF_UNCHECKED);
}
else if (g_nSkill == 3)
{
m_pMenu->CheckMenuItem(IDM_GRADE3, MF_BYCOMMAND | MF_CHECKED);
m_pMenu->CheckMenuItem(IDM_GRADE1, MF_BYCOMMAND | MF_UNCHECKED);
m_pMenu->CheckMenuItem(IDM_GRADE2, MF_BYCOMMAND | MF_UNCHECKED);
}
// Adjust the 4 values to suit board
m_wXNull = 13;
m_wYNull = 13;
m_cxGrid = 23;
m_cyGrid = 23;
// Stone size
m_wStoneWidth = m_pDibMask->GetWidth();
m_wStoneHeight = m_pDibMask->GetHeight();
int cxScreen = ::GetSystemMetrics(SM_CXSCREEN);
int cyScreen = ::GetSystemMetrics(SM_CYSCREEN);
int cxDlgFrame = ::GetSystemMetrics(SM_CXDLGFRAME);
int cyDlgFrame = ::GetSystemMetrics(SM_CYDLGFRAME);
int cxCaption = ::GetSystemMetrics(SM_CYCAPTION);
int cyMenu = ::GetSystemMetrics(SM_CYMENU);
int nWidth = m_pDibBoard->GetWidth() + 2*cxDlgFrame;
int nHeight = m_pDibBoard->GetHeight() + cxCaption + 2*cyDlgFrame + cyMenu;
MoveWindow((cxScreen-nWidth)/2, (cyScreen-nHeight)/2,
nWidth, nHeight);
PlaySound(IDSOUND_WELCOME);
if (g_nRunMode==MODE_WITH_COMPUTER && !g_bUserBlack)
{
CPoint pt; // Computer first
m_byColor = !m_byColor; // 1-Black 0-White
m_Board[7][7]=m_byColor+1;
pt.x = 7*m_cxGrid + m_wXNull;
pt.y = 7*m_cyGrid + m_wYNull;
InvalidateRect(GetCurStoneArea(pt), FALSE);
UpdateWindow();
ClientToScreen(&pt);
SetCursorPos(pt.x, pt.y);
PlaySound(IDSOUND_PUTSTONE);
Judge(7, 7, m_Board[7][7]);
Ring();
}
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CPenteDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
if (IsIconic())
{
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
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;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
m_pDibBoard->Display(&dc, CPoint(0,0));
for (int i=0; i<BOARD_LINE_NUMBER; ++i)
for (int j=0; j<BOARD_LINE_NUMBER; ++j)
if (m_Board[i][j])
PutStone(m_Board[i][j]-1, CPoint(i,j), &dc);
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CPenteDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CPenteDlg::OnLButtonDown(UINT nFlag, CPoint point)
{
CPoint pt;
if (PointToStonePos(point, pt))
{
int nX = pt.x;
int nY = pt.y;
if (m_Board[nX][nY]==0 && !m_bGameOver)
{
if (g_nRunMode == MODE_WITH_COMPUTER)
{
if ((g_bUserBlack && m_byColor==0) ||
(!g_bUserBlack && m_byColor==1))
{
// User
m_byColor = !m_byColor; // 1-Black 0-White
m_Board[nX][nY]=m_byColor+1;
m_wXCur1 = nX;
m_wYCur1 = nY;
CPoint pt(nX*m_cxGrid + m_wXNull, nY*m_cyGrid + m_wYNull);
m_rcCur1 = GetCurStoneArea(pt);
InvalidateRect(m_rcCur1, FALSE);
InvalidateRect(m_rcHint, FALSE);
UpdateWindow();
PlaySound(IDSOUND_PUTSTONE);
Judge(nX, nY, m_Board[nX][nY]);
Ring();
// Computer
if (!m_bGameOver)
{
m_byColor = !m_byColor; // 1-Black 0-White
CPoint ptBest = UrgentPoint(m_byColor);
m_Board[ptBest.x][ptBest.y]=m_byColor+1;
m_wXCur2 = (WORD)ptBest.x;
m_wYCur2 = (WORD)ptBest.y;
pt.x = ptBest.x*m_cxGrid + m_wXNull;
pt.y = ptBest.y*m_cyGrid + m_wYNull;
m_rcCur2 = GetCurStoneArea(pt);
InvalidateRect(m_rcCur2, FALSE);
UpdateWindow();
ClientToScreen(&pt);
SetCursorPos(pt.x, pt.y);
PlaySound(IDSOUND_PUTSTONE);
m_bCanUndo = TRUE;
m_pMenu->EnableMenuItem(IDM_UNDO, m_bCanUndo ? MF_ENABLED : MF_GRAYED);
Judge(ptBest.x, ptBest.y, m_Board[ptBest.x][ptBest.y]);
Ring();
}
}
}
else if (g_nRunMode == MODE_2PLAYER) // Users
{
m_byColor = !m_byColor; // 1-Black 0-White
m_Board[nX][nY]=m_byColor+1;
m_wXCur1 = m_wXCur2;
m_wYCur1 = m_wYCur2;
m_wXCur2 = nX;
m_wYCur2 = nY;
CPoint pt(nX*m_cxGrid + m_wXNull, nY*m_cyGrid + m_wYNull);
m_rcCur1 = m_rcCur2;
m_rcCur2 = GetCurStoneArea(pt);
InvalidateRect(m_rcCur2, FALSE);
UpdateWindow();
PlaySound(IDSOUND_PUTSTONE);
if (!m_rcCur1.IsRectEmpty())
{
m_bCanUndo = TRUE;
m_pMenu->EnableMenuItem(IDM_UNDO, m_bCanUndo ? MF_ENABLED : MF_GRAYED);
}
Judge(nX, nY, m_Board[nX][nY]);
Ring();
}
}
else
PlaySound(IDSOUND_ERROR);
}
else
PlaySound(IDSOUND_ERROR);
CDialog::OnLButtonDown(nFlag, point);
}
int CPenteDlg::Distance(CPoint pt1, CPoint pt2)
{
return (int)sqrt((double)(pt1.x-pt2.x)*(pt1.x-pt2.x) + (double)(pt1.y-pt2.y)*(pt1.y-pt2.y));
}
BOOL CPenteDlg::IsStonePoint(CPoint& ptStone)
{
if (ptStone.x<0 || ptStone.x>=BOARD_LINE_NUMBER || ptStone.y<0 || ptStone.y>=BOARD_LINE_NUMBER)
{
if (ptStone.x<0)
ptStone.x = 0;
else if (ptStone.x>=BOARD_LINE_NUMBER)
ptStone.x = BOARD_LINE_NUMBER-1;
if (ptStone.y<0)
ptStone.y = 0;
else if (ptStone.y>=BOARD_LINE_NUMBER)
ptStone.y = BOARD_LINE_NUMBER-1;
return FALSE;
}
return TRUE;
}
BOOL CPenteDlg::PointToStonePos(CPoint pt, CPoint& ptStone)
{
int nPosX = (pt.x - m_wXNull)/m_cxGrid;
int nPosY = (pt.y - m_wYNull)/m_cyGrid;
CPoint pt0(nPosX*m_cxGrid+m_wXNull, nPosY*m_cyGrid+m_wYNull);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -