chess.h
#pragma once
#include <windows.h>
#include <gdiplus.h> // GDI+ 头文件
#pragma comment(lib,"gdiplus.lib")// GDI+ 静态库
using namespace Gdiplus; // GDI+ 命名空间
class Chess
{
private:
HWND m_hMainWnd; // 主窗口
int table[15][15]; //记录棋子
int Score[15][15]; //记录分数
int x;
int y;
int flag;
public:
Chess(void);
~Chess(void);
public:
void gethwnd(HWND hwnd);
void showback(Bitmap& clBmp);
int Victory();
void OnLButtonDown(POINT point);
void showchess(Bitmap& clBmp);
bool find_chess(int cx,int cy);
void AI();
};
chess.cpp
#include "Chess.h"
Chess::Chess(void)
{
memset(table,0,sizeof(int)*15*15);
x = -1;
y = -1;
flag = 1;
}
Chess::~Chess(void)
{
}
void Chess::showback(Bitmap& clBmp)
{ Image back(L"..\\back.png");
Image box_black(L"..\\box_black.png");
Image box_white(L"..\\box_white.png");
Image chessboard(L"..\\chess.png");
Graphics* graphics = Graphics::FromImage(&clBmp); // 创建GDI+绘图对象
graphics->DrawImage(&back, 0,0,1334,750); //显示的位置(100,100)和大小(71*71)
graphics->DrawImage(&box_black,44,44,200,200); //显示的位置(100,100)和大小(71*71)
graphics->DrawImage(&box_white,1090,506,200,200); //显示的位置(100,100)和大小(71*71)
graphics->DrawImage(&chessboard, 288,0,758,750);
::SetTimer(m_hMainWnd,1,100,0); // AI下棋定时器
}
int Chess::Victory()
{
if(x==-1||y==-1)return 0;
//四项遍历
int i,j;
//---------------------------------------------------横向
i = 0;
j = 0;
while(1)
{
if(table[x][y]==table[x+i][y]&&x+i<15)
{
i++;
}else
{
break;
}
}
while(1)
{
if(table[x][y]==table[x-j][y]&&x-j>0)
{
j++;
}else
{
break;
}
}
if(i+j>=6)
{
if(table[x][y]==1)
return 1;
else
return 2;
}
//----------------------------------------纵向
i = 0;
j = 0;
while(1)
{
if(table[x][y]==table[x][y+i]&&y+i<15)
{
i++;
}else
{
break;
}
}
while(1)
{
if(table[x][y]==table[x][y-j]&&y-j>0)
{
j++;
}else
{
break;
}
}
if(i+j>=6)
{
if(table[x][y]==1)
return 1;
else
return 2;
}
//--------------------------------------------左斜
i = 0;
j = 0;
while(1)
{
if(table[x][y]==table[x+i][y+i]&&x+i<15&&y+i<15)
{
i++;
}else
{
break;
}
}
while(1)
{
if(table[x][y]==table[x-j][y-j]&&x-j>0&&y-j>0)
{
j++;
}else
{
break;
}
}
if(i+j>=6)
{
if(table[x][y]==1)
return 1;
else
return 2;
}
//--------------------------------------------右斜
i = 0;
j = 0;
while(1)
{
if(table[x][y]==table[x+i][y-i]&&x+i<15&&y-i>0)
{
i++;
}else
{
break;
}
}
while(1)
{
if(table[x][y]==table[x-j][y+j]&&x-j>0&&y+j<15)
{
j++;
}else
{
break;
}
}
if(i+j>=6)
{
if(table[x][y]==1)
return 1;
else
return 2;
}
return 0;
}
void Chess::OnLButtonDown(POINT point)
{
point.x -=288;
if(point.x>0&&point.x<758&&point.y>0&&point.y<758)
{
int a,b;
a= (point.x-22)/47;
b=(point.y-11)/47;
if(table[a][b]!=0)return;
if(flag==1)
{
if(a<=14&&b<=14)
{
table[a][b]=1;
flag = 2;
x= a;
y = b;
RECT rect = {0,0,1334,750};
::InvalidateRect(m_hMainWnd,&rect,FALSE);
}
}
}
}
void Chess::gethwnd(HWND hwnd)
{
m_hMainWnd = hwnd;
}
void Chess::showchess(Bitmap& clBmp)
{
int i,j;
for(i=0;i<15;i++)
{
for(j=0;j<15;j++)
{
if(table[i][j]==1)
{
Image white(L"..\\white.png");
Graphics* graphics = Graphics::FromImage(&clBmp); // 创建GDI+绘图对象
graphics->DrawImage(&white, i*47+310,j*47+11,54,54); //显示的位置(100,100)和大小(71*71)
}
if(table[i][j]==2)
{
Image black(L"..\\black.png");
Graphics* graphicsb = Graphics::FromImage(&clBmp); // 创建GDI+绘图对象
graphicsb->DrawImage(&black, i*47+310,j*47+11,54,54); //显示的位置(100,100)和大小(71*71)
}
}
}
}
bool Chess::find_chess(int cx,int cy)
{
if(table[cx][cy]==0)
{
if(table[cx-1][cy-1]!=0)
{
if(cx-1>0&&cy-1>0)
{
return true;
}
}
if(table[cx][cy-1]!=0)
{
if(cy-1>0)
{
return true;
}
}
if(table[cx+1][cy-1]!=0)
{
if(cx+1<15&&cy-1>0)
{
return true;
}
}
if(table[cx+1][cy]!=0)
{
if(cx+1<15)
{
return true;
}
}
if(table[cx+1][cy+1]!=0)
{
if(cx+1<15&&cy+1<15)
{
return true;
}
}
if(table[cx][cy+1]!=0)
{
if(cy+1<15)
{
return true;
}
}
if(table[cx-1][cy+1]!=0)
{
if(cx-1>0&&cy+1<15)
{
return true;
}
}
if(table[cx-1][cy]!=0)
{
if(cx-1>0)
{
return true;
}
}
}
return false;
}
void Chess::AI()
{
if(flag == 2)
{
int i,j;
/*清空分数表*/
for(i=0;i<15;i++)
for(j=0;j<15;j++)
Score[i][j]=0;
/*计算分值*/
int personNum = 0; // 玩家连成子的个数
int botNum = 0; // AI连成子的个数
int emptyNum = 0; // 各方向空白位的个数
for (int row = 0; row < 15; row++)
{
for (int col = 0; col < 15; col++)
{
// 空白点就算
if (row > 0 && col > 0 &&table[row][col] == 0)
{
// 遍历周围八个方向
for (int y = -1; y <= 1; y++)
for (int x = -1; x <= 1; x++)
{
// 重置
personNum = 0;
botNum = 0;
emptyNum = 0;
// 原坐标不算
if (!(y == 0 && x == 0))
{
// 每个方向延伸4个子
// 对玩家白子评分(正反两个方向)
for (int i = 1; i <= 4; i++)
{
if (row + i * y > 0 && row + i * y < 15 &&
col + i * x > 0 && col + i * x < 15 &&
table[row + i * y][col + i * x] == 1) // 玩家的子
{
personNum++;
}
else if (row + i * y > 0 && row + i * y < 15 &&
col + i * x > 0 && col + i * x < 15 &&
table[row + i * y][col + i * x] == 0) // 空白位
{
emptyNum++;
break;
}
else // 出边界
break;
}
for (int i = 1; i <= 4; i++)
{
if (row - i * y > 0 && row - i * y < 15 &&
col - i * x > 0 && col - i * x < 15 &&
table[row - i * y][col - i * x] == 1) // 玩家的子
{
personNum++;
}
else if (row - i * y > 0 && row - i * y < 15 &&
col - i * x > 0 && col - i * x < 15 &&
table[row - i * y][col - i * x] == 0) // 空白位
{
emptyNum++;
break;
}
else // 出边界
break;
}
if (personNum == 1) // 杀二
Score[row][col] += 10;
else if (personNum == 2) // 杀三
{
if (emptyNum == 1)
Score[row][col] += 30;
else if (emptyNum == 2)
Score[row][col] += 40;
}
else if (personNum == 3) // 杀四
{
// 量变空位不一样,优先级不一样
if (emptyNum == 1)
Score[row][col] += 60;
else if (emptyNum == 2)
Score[row][col] += 110;
}
else if (personNum == 4) // 杀五
Score[row][col] += 10100;
// 进行一次清空
emptyNum = 0;
// 对AI黑子评分
for (int i = 1; i <= 4; i++)
{
if (row + i * y > 0 && row + i * y < 15 &&
col + i * x > 0 && col + i * x < 15 &&
table[row + i * y][col + i * x] == 1) // 玩家的子
{
botNum++;
}
else if (row + i * y > 0 && row + i * y < 15 &&
col + i * x > 0 && col + i * x < 15 &&
table[row +i * y][col + i * x] == 0) // 空白位
{
emptyNum++;
break;
}
else // 出边界
break;
}
for (int i = 1; i <= 4; i++)
{
if (row - i * y > 0 && row - i * y < 15 &&
col - i * x > 0 && col - i * x < 15 &&
table[row - i * y][col - i * x] == -1) // AI的子
{
botNum++;
}
else if (row - i * y > 0 && row - i * y < 15 &&
col - i * x > 0 && col - i * x < 15 &&
table[row - i * y][col - i * x] == 0) // 空白位
{
emptyNum++;
break;
}
else // 出边界
break;
}
if (botNum == 0) // 普通下子
Score[row][col] += 5;
else if (botNum == 1) // 活二
Score[row][col] += 10;
else if (botNum == 2)
{
if (emptyNum == 1) // 死三
Score[row][col] += 25;
else if (emptyNum == 2)
Score[row][col] += 50; // 活三
}
else if (botNum == 3)
{
if (emptyNum == 1) // 死四
Score[row][col] += 55;
else if (emptyNum == 2)
Score[row][col] += 110; // 活四
}
else if (botNum >= 4)
Score[row][col] += 10000; // 活五
}
}
}
}
}
int a,b;
a = 0;
b = 0;
for(i = 0;i<15;i++)
{
for(j = 0;j<15;j++)
{
if(Score[i][j]>Score[a][b])
{
a = i;
b = j;
}
}
}
table[a][b] = 2;
x= a;
y = b;
flag = 1;
RECT rect = {0,0,1334,750};
::InvalidateRect(m_hMainWnd,&rect,FALSE);
}
}
main.cpp
#include "Chess.h"
LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
HINSTANCE hIns = 0;
int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,LPSTR lpCmdLine,int nShowCmd)
{
//------------------初始化GDI+----------------------
GdiplusStartupInput m_gdiplusStartupInput;
ULONG_PTR m_pGdiToken;
GdiplusStartup(&m_pGdiToken,&m_gdiplusStartupInput,NULL);
//------------------初始化GDI+-----------------------------
//-----------------------------------------------------
HWND hwnd = 0;
MSG msg; // 装消息的结构体
WNDCLASSEX wndclass;
//-----------------------------------------------------
hIns = hInstance;
//----------------------创建窗口过程-----------------------------------
// 1. 设计
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.cbSize = sizeof(wndclass);
wndclass.hbrBackground = (HBRUSH)COLOR_WINDOW;
wndclass.hCursor = LoadCursor(0,MAKEINTRESOURCE(IDC_ARROW));
wndclass.hIcon = 0;
wndclass.hIconSm = 0;
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = WindowProc;
wndclass.lpszClassName = "lele";
wndclass.lpszMenuName = 0;
wndclass.style = CS_HREDRAW|CS_VREDRAW;
// 2. 注册
if(RegisterClassEx(&wndclass) == FALSE)
{
MessageBox(0,"注册失败","提示",MB_OK);
return 0;
}
// 3. 创建
hwnd = CreateWindow("lele","O(∩_∩)O哈哈~",WS_OVERLAPPEDWINDOW,0,0,1334,750+38,0,0,hInstance,0);
if(hwnd == 0)
{
MessageBox(0,"创建失败","提示",MB_OK);
return 0;
}
// 4. 显示窗口
ShowWindow(hwnd,SW_SHOW);
//---------------------------创建窗口过程------------------------------------------------
//----------------------------消息循环-------------------------------------------
while(GetMessage(&msg,0,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//----------------------------消息循环-------------------------------------------
//-------------卸载GDI+---------------------------
GdiplusShutdown(m_pGdiToken);
//-------------卸载GDI+----------------------------
return 0;
}
Chess my_game;
//=================================处理消息========================================================
LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
{
my_game.gethwnd(hwnd);
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc=BeginPaint(hwnd,&ps);
Graphics gr(hdc);
Rect rGdi;
gr.GetVisibleClipBounds(&rGdi);
Bitmap clBmp(rGdi.Width, rGdi.Height);
//----------------GDI+ 贴图-------------------------
my_game.showback(clBmp);
my_game.showchess(clBmp);
//--------------------------------------------------
gr.DrawImage(&clBmp, rGdi);
EndPaint(hwnd,&ps);
if(my_game.Victory()==1)
MessageBox(hwnd,"白胜","☆",MB_OK);
if(my_game.Victory()==2)
MessageBox(hwnd,"黑胜","☆",MB_OK);
}
break;
case WM_LBUTTONDOWN:
{
POINT point;
point.x = LOWORD(lParam);
point.y = HIWORD(lParam);
// 鼠标控制
my_game.OnLButtonDown(point);
}
break;
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_TIMER:
{
my_game.AI();
}
break;
}
return DefWindowProc( hwnd, uMsg, wParam, lParam);
}