主函数
#include <iostream>
#include "ChessGame.h"
int main(void)
{
Man man;
Chess chess(13,44,43,67.3);
AI ai;
ChessGame game(&man, &ai, &chess);
game.play();
return 0;
}
棋盘类
#pragma once
#include<graphics.h>
#include<vector>
#include <wincrypt.h>
#include <wincrypt.h>
#include <conio.h>
using namespace std;
struct ChessPos {
int row;
int col;
ChessPos(int r = 0,int c = 0) :row(r),col(c) {}
};
typedef enum {
CHESS_WHITE = -1,
CHESS_BLACK = 1
}chess_kind_t;
class Chess
{
public:
Chess(int gradeSize, int margin_x, int margin_y, float chessSize);
void chessDwon(ChessPos* pos, chess_kind_t kind);
bool clickBroad(int x, int y, ChessPos* pos);
void init();
int getGradeSize();
bool checkOver();
int getChessData(int row,int col);
int getChessData(ChessPos* pos);
private:
IMAGE chessBlackImg;
IMAGE chessWhiteImg;
int gradeSize;
int margin_x;
int margin_y;
float chessSize;
vector<vector<int>> chessMap;
bool playerFlag;
ChessPos lastPos;
bool checkWin();
void updateGameMap(ChessPos* pos);
};
#include "Chess.h"
#include<mmsystem.h>
#include<math.h>
#pragma comment(lib,"winmm.lib")
void putimagePNG(int x, int y, IMAGE* picture)
{
DWORD* dst = GetImageBuffer();
DWORD* draw = GetImageBuffer();
DWORD* src = GetImageBuffer(picture);
int picture_width = picture->getwidth();
int picture_height = picture->getheight();
int graphWidth = getwidth();
int graphHeight = getheight();
int dstX = 0;
for (int iy = 0; iy < picture_height; iy++)
{
for (int ix = 0; ix < picture_width; ix++)
{
int srcX = ix + iy * picture_width;
int sa = ((src[srcX] & 0xff000000) >> 24);
int sr = ((src[srcX] & 0xff0000) >> 16);
int sg = ((src[srcX] & 0xff00) >> 8);
int sb = src[srcX] & 0xff;
if (ix >= 0 && ix <= graphWidth && iy >= 0 && iy <= graphHeight && dstX <= graphWidth * graphHeight)
{
dstX = (ix + x) + (iy + y) * graphWidth;
int dr = ((dst[dstX] & 0xff0000) >> 16);
int dg = ((dst[dstX] & 0xff00) >> 8);
int db = dst[dstX] & 0xff;
draw[dstX] = ((sr * sa / 255 + dr * (255 - sa) / 255) << 16)
| ((sg * sa / 255 + dg * (255 - sa) / 255) << 8)
| (sb * sa / 255 + db * (255 - sa) / 255);
}
}
}
}
Chess::Chess(int gradeSize, int margin_x, int margin_y, float chessSize)
{
this->gradeSize = gradeSize;
this->margin_x = margin_x;
this->margin_y = margin_y;
this->chessSize = chessSize;
playerFlag = CHESS_BLACK;
for (int i = 0; i < gradeSize; i++)
{
vector<int>row;
for (int j = 0; j < gradeSize; j++)
{
row.push_back(0);
}
chessMap.push_back(row);
}
}
void Chess::chessDwon(ChessPos* pos, chess_kind_t kind)
{
mciSendString("play down7.WAV", 0, 0, 0);
int x = margin_x + chessSize * pos->col - 0.5 * chessSize;
int y = margin_y + chessSize * pos->row - 0.5 * chessSize;
if (kind == CHESS_WHITE) {
putimagePNG(x,y,&chessWhiteImg);
}
else {
putimagePNG(x,y, &chessBlackImg);
}
updateGameMap(pos);
}
bool Chess::clickBroad(int x, int y, ChessPos* pos)
{
int col = (x - margin_x) / chessSize;
int row = (y - margin_y) / chessSize;
int leftTopPosX = margin_x + col * chessSize;
int leftTopPosY = margin_y + row * chessSize;
int offset = chessSize * 0.4;
float len;
bool ret = false;
do {
len = sqrt((leftTopPosX - x) * (leftTopPosX - x) + (leftTopPosY - y) * (leftTopPosY - y));
if (len < offset) {
pos->row = row;
pos->col = col;
if (chessMap[pos->row][pos->col] == 0) {
ret = true;
}
break;
}
int x2 = leftTopPosX + chessSize;
int y2 = leftTopPosY;
len = sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y));
if (len < offset) {
pos->row = row;
pos->col = col+1;
if (chessMap[pos->row][pos->col] == 0) {
ret = true;
}
break;
}
x2 = leftTopPosX + chessSize;
y2 = leftTopPosY + chessSize;
len = sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y));
if (len < offset) {
pos->row = row+1;
pos->col = col+1;
if (chessMap[pos->row][pos->col] == 0) {
ret = true;
}
break;
}
x2 = leftTopPosX ;
y2 = leftTopPosY + chessSize;
len = sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y));
if (len < offset) {
pos->row = row+1;
pos->col = col;
if (chessMap[pos->row][pos->col] == 0) {
ret = true;
}
break;
}
} while (0);
return ret;
}
void Chess::init()
{
initgraph(897,895, EX_SHOWCONSOLE);
loadimage(0, "棋盘2.jpg");
mciSendString("play start.wav", 0, 0, 0);
loadimage(&chessBlackImg,"black.png",chessSize, chessSize,true);
loadimage(&chessWhiteImg, "white.png", chessSize, chessSize, true);
for (int i = 0; i < gradeSize; i++)
{
for (int j = 0; j < gradeSize; j++)
{
chessMap[i][j] = 0;
}
}
}
int Chess::getGradeSize()
{
return gradeSize;
}
bool Chess::checkOver()
{
if (checkWin()) {
Sleep(1500);
if (playerFlag == false) {
mciSendString("play 不错.mp3", 0, 0, 0);
loadimage(0, "胜利.jpg");
}
else {
mciSendString("play 失败.mp3", 0, 0, 0);
loadimage(0, "失败.jpg");
}
_getch();
return true;
}
return false;
}
int Chess::getChessData(int row, int col)
{
return chessMap[row][col];
}
int Chess::getChessData(ChessPos* pos)
{
return chessMap[pos->row][pos->col];
}
bool Chess::checkWin()
{
int row = lastPos.row;
int col = lastPos.col;
for (int i = 0; i < 5; i++)
{
if (col-i >=0 &&
col-i +4 < gradeSize &&
chessMap[row][col - i] == chessMap[row][col - i + 1] &&
chessMap[row][col - i] == chessMap[row][col - i + 2] &&
chessMap[row][col - i] == chessMap[row][col - i + 3] &&
chessMap[row][col - i] == chessMap[row][col - i + 4])
return true;
}
for (int i = 0; i < 5; i++)
{
if (row - i >= 0 &&
row - i + 4 < gradeSize &&
chessMap[row-i][col] == chessMap[row - i + 1][col] &&
chessMap[row-i][col] == chessMap[row - i + 2][col] &&
chessMap[row-i][col] == chessMap[row - i + 3][col] &&
chessMap[row-i][col] == chessMap[row - i + 4][col])
return true;
}
for (int i = 0; i < 5; i++)
{
if (row + i <gradeSize && row+i-4 >=0 &&
col -i >=0 && col-i+4 < gradeSize &&
chessMap[row + i][col - i] == chessMap[row + i - 1][col-i+1] &&
chessMap[row + i][col - i] == chessMap[row + i - 2][col-i+2] &&
chessMap[row + i][col - i] == chessMap[row + i - 3][col-i+3] &&
chessMap[row + i][col - i] == chessMap[row + i - 4][col-i+4])
return true;
}
for (int i = 0; i < 5; i++)
{
if (row - i >= 0 && row + i - 4 < gradeSize &&
col - i >= 0 && col - i + 4 < gradeSize &&
chessMap[row - i][col - i] == chessMap[row - i + 1][col - i + 1] &&
chessMap[row - i][col - i] == chessMap[row - i + 2][col - i + 2] &&
chessMap[row - i][col - i] == chessMap[row - i + 3][col - i + 3] &&
chessMap[row - i][col - i] == chessMap[row - i + 4][col - i + 4])
return true;
}
return false;
}
void Chess::updateGameMap(ChessPos* pos)
{
lastPos = *pos;
chessMap[pos->row][pos->col] = playerFlag ? CHESS_BLACK : CHESS_WHITE;
playerFlag = !playerFlag;
}
Al棋手类
#pragma once
#include "Chess.h"
class AI
{
public:
void init(Chess* chess);
void go();
private:
Chess* chess;
vector<vector<int>> scoreMap;
private:
void calculateScore();
ChessPos think();
};
#include "AI.h"
void AI::init(Chess* chess)
{
this->chess = chess;
for (int i = 0; i < chess->getGradeSize(); i++)
{
vector<int> row;
for (int j = 0; j < chess->getGradeSize(); j++)
{
row.push_back(0);
}
scoreMap.push_back(row);
}
}
void AI::go()
{
ChessPos pos = think();
Sleep(1000);
chess->chessDwon(&pos, CHESS_WHITE);
}
void AI::calculateScore()
{
int personNum = 0;
int aiNum = 0;
int emptyNum = 0;
for (int i = 0; i < scoreMap.size(); i++) {
for (int j = 0; j < scoreMap[i].size(); j++) {
scoreMap[i][j] = 0;
}
}
int size = chess->getGradeSize();
for (int row = 0; row < size; row++) {
for (int col = 0; col < size; col++) {
if (chess->getChessData(row, col)) continue;
for (int y = -1; y <= 0; y++) {
for (int x = -1; x <= 1; x++) {
if (y == 0 && x == 0) continue;
if (y == 0 && x != 1) continue;
personNum = 0;
aiNum = 0;
emptyNum = 0;
for (int i = 1; i <= 4; i++) {
int curRow = row + i * y;
int curCol = col + i * x;
if (curRow >= 0 && curRow < size &&
curCol >= 0 && curCol < size &&
chess->getChessData(curRow, curCol) == 1) {
personNum++;
}
else if (curRow >= 0 && curRow < size &&
curCol >= 0 && curCol < size &&
chess->getChessData(curRow, curCol) == 0) {
emptyNum++;
break;
}
else {
break;
}
}
for (int i = 1; i <= 4; i++) {
int curRow = row - i * y;
int curCol = col - i * x;
if (curRow >= 0 && curRow < size &&
curCol >= 0 && curCol < size &&
chess->getChessData(curRow, curCol) == 1) {
personNum++;
}
else if (curRow >= 0 && curRow < size &&
curCol >= 0 && curCol < size &&
chess->getChessData(curRow, curCol) == 0) {
emptyNum++;
break;
}
else {
break;
}
}
if (personNum == 1) {
scoreMap[row][col] += 10;
}
else if (personNum == 2) {
if (emptyNum == 1) {
scoreMap[row][col] += 30;
}
else if (emptyNum == 2) {
scoreMap[row][col] += 40;
}
}
else if (personNum == 3) {
if (emptyNum == 1) {
scoreMap[row][col] = 60;
}
else if (emptyNum == 2) {
scoreMap[row][col] = 5000;
}
}
else if (personNum == 4) {
scoreMap[row][col] = 20000;
}
emptyNum = 0;
for (int i = 1; i <= 4; i++) {
int curRow = row + i * y;
int curCol = col + i * x;
if (curRow >= 0 && curRow < size &&
curCol >= 0 && curCol < size &&
chess->getChessData(curRow, curCol) == -1) {
aiNum++;
}
else if (curRow >= 0 && curRow < size &&
curCol >= 0 && curCol < size &&
chess->getChessData(curRow, curCol) == 0) {
emptyNum++;
break;
}
else {
break;
}
}
for (int i = 1; i <= 4; i++) {
int curRow = row - i * y;
int curCol = col - i * x;
if (curRow >= 0 && curRow < size &&
curCol >= 0 && curCol < size &&
chess->getChessData(curRow, curCol) == -1) {
aiNum++;
}
else if (curRow >= 0 && curRow < size &&
curCol >= 0 && curCol < size &&
chess->getChessData(curRow, curCol) == 0) {
emptyNum++;
break;
}
else {
break;
}
}
if (aiNum == 0) {
scoreMap[row][col] += 5;
}
else if (aiNum == 1) {
scoreMap[row][col] += 10;
}
else if (aiNum == 2) {
if (emptyNum == 1) {
scoreMap[row][col] += 25;
}
else if (emptyNum == 2) {
scoreMap[row][col] += 50;
}
}
else if (aiNum == 3) {
if (emptyNum == 1) {
scoreMap[row][col] += 55;
}
else if (emptyNum == 2) {
scoreMap[row][col] += 10000;
}
}
else if (aiNum >= 4) {
scoreMap[row][col] += 30000;
}
}
}
}
}
}
ChessPos AI::think()
{
calculateScore();
vector< ChessPos> maxPoint;
int maxScore = 0;
int size = chess->getGradeSize();
for (int row = 0; row < size; row++){
for (int col = 0; col < size; col++) {
if (chess->getChessData(row, col) == 0) {
if (scoreMap[row][col] > maxScore) {
maxScore = scoreMap[row][col];
maxPoint.clear();
maxPoint.push_back(ChessPos(row, col));
}
else if (scoreMap[row][col] == maxScore){
maxPoint.push_back(ChessPos(row, col));
}
}
}
}
int index = rand() % maxPoint.size();
return maxPoint[index];
}
人
#pragma once
#include "Chess.h"
class Man
{
public:
void init(Chess* chess);
void go();
private:
Chess *chess;
};
#include "Man.h"
void Man::init(Chess* chess)
{
this->chess = chess;
}
void Man::go()
{
MOUSEMSG msg;
ChessPos pos;
while (1) {
msg = GetMouseMsg();
if (msg.uMsg == WM_LBUTTONDOWN && chess->clickBroad(msg.x, msg.y, &pos))
{
break;
}
}
chess->chessDwon(&pos, CHESS_BLACK);
}
棋盘控制类
#pragma once
#include "Chess.h"
#include "Man.h"
#include "AI.h"
class ChessGame
{
public:
ChessGame(Man* man, AI* ai, Chess* chess);
void play();
private:
Man *man;
AI* ai;
Chess* chess;
};
#include "ChessGame.h"
void ChessGame::play()
{
chess->init();
while (1)
{
man->go();
if (chess->checkOver()) {
chess->init();
continue;
}
ai->go();
if (chess->checkOver()) {
chess->init();
continue;
}
}
}
ChessGame::ChessGame(Man* man, AI* ai, Chess* chess)
{
this->man = man;
this->ai = ai;
this->chess = chess;
man->init(chess);
ai->init(chess);
}