📄 mantischess.cpp
字号:
/***************************************************************
MantisChess.cpp : 程序入口 JiaJu 2004.10.16
******************************************************************/
#include "StdAfx.h"
#include "resource.h"
#include "MantisChessDef.h"
#include "MantisChessDraw.h"
#include "MantisChessStd.h"
#include "MantisChessThink.h"
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
//----------------------------
void OnCreate(HWND hWnd);
void Reset();
void ShowRect(HDC hdc,LPRECT prect);
void ShowPoint(HDC hdc,POINT point);
void Think(HWND hWnd);
BOOL Go(HWND hWnd,int man,POINT targetpoint);
void OnMouseMove(POINT point);
void OnLButtonDown(HWND hWnd,POINT point);
BOOL FaceToPoint(POINT &point);
void OnBack(HWND hWnd);
//--------------------------------------
static POINT g_pointChessman[6]; //棋子坐标
static int g_iChessmanMap[6][13]; //棋位状态
static int g_iSide; //轮到哪放走
static HCURSOR g_hCurCantGo; //不可以点击时显示的鼠标
static HCURSOR g_hCurHand; //可以点击时显示的鼠标
static HCURSOR g_hCurThinking; //计算时显示的鼠标
static HICON g_hIconChessman[6]; //棋子的图像
static HDC g_hdcChessboard; //棋盘的设备描述表
static HBITMAP g_hbmpChessboard; //棋盘的位图
static int g_iChessmanSelect; //选择的棋子
static int g_iComputerSide; //电脑的颜色
static BOOL g_bEndGame; //游戏结束标志
//--------------------------------------
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_MANTIS, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage is only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_MANTIS);
wcex.hCursor = NULL;
wcex.hbrBackground = NULL;
wcex.lpszMenuName = (LPCSTR)IDC_MANTIS;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, "MathGame", WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU,,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
POINT point;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
RECT rect1;
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case IDM_NEW:
Reset();
g_iComputerSide=BLACK;
rect1.left=0;
rect1.top=0;
rect1.right=XBW;
rect1.bottom=YBW;
hdc=GetDC(hWnd);
ShowRect(hdc,&rect1);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
RECT rect;
GetClientRect(hWnd, &rect);
ShowRect(hdc,&rect);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
DeleteObject(g_hbmpChessboard);
DeleteDC(g_hdcChessboard);
PostQuitMessage(0);
break;
case WM_CREATE:
OnCreate(hWnd);
break;
case WM_LBUTTONDOWN:
point.x=LOWORD(lParam);
point.y=HIWORD(lParam);
OnLButtonDown(hWnd,point);
break;
case WM_MOUSEMOVE:
point.x=LOWORD(lParam);
point.y=HIWORD(lParam);
OnMouseMove(point);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
/******************************************************************
OnCreate: WM_CREATE 消息响应函数,建立窗口时进行初始化
参数:
hWnd: 窗口句柄
返回值: 无
******************************************************************/
void OnCreate(HWND hWnd)
{
g_hCurHand=LoadCursor(hInst,MAKEINTRESOURCE(IDC_HAND));
g_hCurThinking=LoadCursor(hInst,MAKEINTRESOURCE(IDC_THINKING));
g_hCurCantGo=LoadCursor(hInst,MAKEINTRESOURCE(IDC_CANTGO));
g_hIconChessman[RED_1]=LoadIcon(hInst,MAKEINTRESOURCE(IDI_R_K));
g_hIconChessman[RED_2]=LoadIcon(hInst,MAKEINTRESOURCE(IDI_R_K));
g_hIconChessman[RED_3]=LoadIcon(hInst,MAKEINTRESOURCE(IDI_R_K));
g_hIconChessman[BLACK_1]=LoadIcon(hInst,MAKEINTRESOURCE(IDI_B_K));
g_hIconChessman[BLACK_2]=LoadIcon(hInst,MAKEINTRESOURCE(IDI_B_K));
g_hIconChessman[BLACK_3]=LoadIcon(hInst,MAKEINTRESOURCE(IDI_B_K));
Reset();
HDC hdc=GetDC(hWnd);
g_hdcChessboard=CreateCompatibleDC(hdc);
g_hbmpChessboard=CreateCompatibleBitmap(hdc,XBW,YBW);
SelectObject(g_hdcChessboard,g_hbmpChessboard);
int nCurTime=(int)::GetTickCount();
MakeBoard(g_hdcChessboard,RGB(180,180+nCurTime%30,160));
RECT rect={0,0,XBW,YBW};
//以下创建窗口并置于center
AdjustWindowRect(&rect,WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU,TRUE);
POINT lefttop;
lefttop.x=(GetSystemMetrics(SM_CXSCREEN)-(rect.right-rect.left))/2;
lefttop.y=(GetSystemMetrics(SM_CYSCREEN)-(rect.bottom-rect.top))/2;
rect.left+=lefttop.x;
rect.right+=lefttop.x;
rect.top+=lefttop.y;
rect.bottom+=lefttop.y;
MoveWindow(hWnd,rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top,TRUE);
}
/******************************************************************
Reset: 把数据恢复为初始值
参数: 无
返回值: 无
******************************************************************/
void Reset()
{
g_pointChessman[0].x=1;g_pointChessman[0].y=11; //帅
g_pointChessman[1].x=2;g_pointChessman[1].y=11; //士
g_pointChessman[2].x=3;g_pointChessman[2].y=11;
g_pointChessman[3].x=1;g_pointChessman[3].y=1; //相
g_pointChessman[4].x=2;g_pointChessman[4].y=1;
g_pointChessman[5].x=3;g_pointChessman[5].y=1; //马
g_iSide=RED;
FixManMap(g_iChessmanMap,g_pointChessman,g_iSide);
g_iChessmanSelect=6;
g_iComputerSide=1;
g_bEndGame=FALSE;
}
/******************************************************************
ShowRect: 重画 prect 指向的区域
参数:
hdc: 设备描述表句柄
prect: 重画区域的指针
返回值: 无
******************************************************************/
void ShowRect(HDC hdc,LPRECT prect)
{
RECT rc1={0,0,XBW,YBW};
//取得真正要更新的区域:
IntersectRect(&rc1,&rc1,prect);
BitBlt(hdc,rc1.left,rc1.top,rc1.right-rc1.left,rc1.bottom-rc1.top,g_hdcChessboard,rc1.left,rc1.top,SRCCOPY);
int left=(rc1.left)/BWA,top=(rc1.top)/BWA,right=(rc1.right)/BWA,bottom=(rc1.bottom)/BWA;
for(int i=left;i<=right;i++)
for(int j=top;j<=bottom;j++)
{
if(g_iChessmanMap[i][j+1]!=6)
DrawIcon(hdc,i*BWA+SW,j*BWA+SW,g_hIconChessman[ManToIcon[g_iChessmanMap[i][j+1]]]);
}
}
/******************************************************************
ShowPoint: 重画point棋位
参数:
hdc: 设备描述表句柄
point: 棋位坐标
返回值: 无
******************************************************************/
void ShowPoint(HDC hdc,POINT point)
{
RECT rect;
rect.left=(point.x)*BWA;
rect.top=(point.y-1)*BWA;
rect.right=rect.left+BWA;
rect.bottom=rect.top+BWA;
ShowRect(hdc,&rect);
}
/******************************************************************
Think: 求最佳走法并根据结果走棋
参数:
hWnd: 窗口句柄
返回值: 无
******************************************************************/
void Think(HWND hWnd)
{
int i,j;
POINT tmanposition[6];
int tside;
int tmap[6][13];
for(i=0;i<6;i++)
{
tmanposition[i]=g_pointChessman[i];
}
tside=g_iSide;
for(i=0;i<6;i++)
for(j=0;j<13;j++)
{
tmap[i][j]=g_iChessmanMap[i][j];
}
int resultman=6;
POINT resultpoint={0,0};
BOOL flag=Think(tmap,tmanposition,tside,resultman,resultpoint);
if(flag)
{
Go(hWnd,resultman,resultpoint);
}
else
{
g_bEndGame=TRUE;
MessageBox(hWnd,"Game over!","MantisChess",MB_OK);
}
}
/******************************************************************
Go: 走棋
参数:
hWnd: 窗口句柄
man: 所移动的棋子
targetpoint: 目标位置
返回值: 成功返回TRUE,否则返回FALSE
******************************************************************/
BOOL Go(HWND hWnd,int man, POINT targetpoint)
{
HDC hdc =GetDC(hWnd);
if(g_bEndGame)return FALSE;
if(!CanGo(g_pointChessman,g_iChessmanMap,man,g_pointChessman[man],targetpoint,g_iSide))return FALSE;
POINT oldselect;
oldselect=g_pointChessman[man];
g_pointChessman[man]=targetpoint;
FixManMap(g_iChessmanMap,g_pointChessman,g_iSide);
g_iChessmanSelect=6;
g_iSide=!g_iSide;
ShowPoint(hdc,oldselect);
ShowPoint(hdc,targetpoint);
if((g_pointChessman[0].y+g_pointChessman[1].y+g_pointChessman[2].y-g_pointChessman[3].y-g_pointChessman[4].y-g_pointChessman[5].y)==3)
{
if(g_iSide==g_iComputerSide)
::MessageBox(hWnd,"^_^You Win!^_^","MantisChess",MB_OK);
else
::MessageBox(hWnd,"^_^You Lost!^_^","MantisChess",MB_OK);
g_bEndGame=TRUE;
return TRUE;
}
if(g_iComputerSide==g_iSide&&!g_bEndGame)
{
SetCursor(g_hCurThinking);
Think(hWnd);
SetCursor(g_hCurCantGo);
}
return TRUE;
}
/******************************************************************
FaceToPoint: 把鼠标位置转换成对应的棋盘坐标
参数:
point: 鼠标位置
返回值: 鼠标位置在棋盘内返回TRUE,否则返回FALSE
******************************************************************/
BOOL FaceToPoint(POINT &point)
{
if((point.x)%BWA<SW||(point.x)%BWA>BWA-SW)return FALSE;
if((point.y)%BWA<SW||(point.y)%BWA>BWA-SW)return FALSE;
POINT p;
p.x=(point.x)/BWA;
p.y=(point.y)/BWA+1;
if(p.x<1||p.x>3||p.y<1||p.y>11)return FALSE;
point=p;
return TRUE;
}
/******************************************************************
OnLButtonDown: WM_LBUTTONDOWN 消息响应函数
参数:
hWnd: 窗口句柄
point: 鼠标坐标
返回值: 无
******************************************************************/
void OnLButtonDown(HWND hWnd,POINT point)
{
if(g_bEndGame)
{
MessageBox(hWnd,"Game over!","MantisChess",MB_OK);
}
else if(FaceToPoint(point))
{
if(SideOfMan[g_iChessmanMap[point.x][point.y]]==!g_iComputerSide)
{
HDC hdc=GetDC(hWnd);
g_iChessmanSelect=g_iChessmanMap[point.x][point.y];
ShowPoint(hdc,g_pointChessman[g_iChessmanSelect]);
}
else if(g_iChessmanSelect!=6)
{
Go(hWnd,g_iChessmanSelect,point);
}
}
}
/******************************************************************
OnMouseMove: WM_MOUSEMOVE 消息响应函数
参数:
point: 鼠标坐标
返回值: 无
******************************************************************/
void OnMouseMove(POINT point)
{
if(FaceToPoint(point))
{
if(g_iChessmanSelect!=6)
{
if(CanGo(g_pointChessman,g_iChessmanMap,g_iChessmanSelect,g_pointChessman[g_iChessmanSelect],point,0))
{
SetCursor(g_hCurHand);
}
else
{
SetCursor(g_hCurCantGo);
}
}
else
{
if(SideOfMan[g_iChessmanMap[point.x][point.y]]==!g_iComputerSide)
{
SetCursor(g_hCurHand);
}
else
{
SetCursor(g_hCurCantGo);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -