You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

278 lines
7.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "Chess.h"
#include <conio.h>
//修正png透明背景无法显示网上当的
void putimagePNG(int x, int y, IMAGE* picture) //x为载入图片的X坐标y为Y坐标
{
// 变量初始化
DWORD* dst = GetImageBuffer(); // GetImageBuffer()函数用于获取绘图设备的显存指针EASYX自带
DWORD* draw = GetImageBuffer();
DWORD* src = GetImageBuffer(picture); //获取picture的显存指针
int picture_width = picture->getwidth(); //获取picture的宽度EASYX自带
int picture_height = picture->getheight(); //获取picture的高度EASYX自带
int graphWidth = getwidth(); //获取绘图区的宽度EASYX自带
int graphHeight = getheight(); //获取绘图区的高度EASYX自带
int dstX = 0; //在显存里像素的角标
// 实现透明贴图 公式: Cp=αp*FP+(1-αp)*BP 贝叶斯定理来进行点颜色的概率计算
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); //0xAArrggbb;AA是透明度
int sr = ((src[srcX] & 0xff0000) >> 16); //获取RGB里的R
int sg = ((src[srcX] & 0xff00) >> 8); //G
int sb = src[srcX] & 0xff; //B
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) //公式: Cp=αp*FP+(1-αp)*BP αp=sa/255 , FP=sr , BP=dr
| ((sg * sa / 255 + dg * (255 - sa) / 255) << 8) //αp=sa/255 , FP=sg , BP=dg
| (sb * sa / 255 + db * (255 - sa) / 255); //αp=sa/255 , FP=sb , BP=db
}
}
}
}
Chess::Chess(int gradeSize, int marginX, int marginY, double chessSize)
{
this->gradeSize = gradeSize;
this->margin_x = marginX;
this->margin_y = marginY;
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::init()
{
//显示棋盘
loadimage(0, "graphics/map.png");
//显示棋子
loadimage(&chessBlackImg, "graphics/black.png", chessSize-2, chessSize-2, true);
loadimage(&chessWhiteImg, "graphics/white.png", chessSize-2, chessSize-2, true);
//清零棋盘
for (int i = 0; i < gradeSize; ++i)
for (int j = 0; j < gradeSize; ++j)
chessMap[i][j] = 0;
playerFlag = true;
}
bool Chess::clickBoard(int x, int y, ChessPos* pos)
{
int col = (x - margin_x) / chessSize;
int row = (y - margin_y) / chessSize;
int leftTopPosX = margin_x + chessSize * col;
int leftTopPosY = margin_y + chessSize * row;
int offset = chessSize * 0.4;
int len;
bool ret = false;
do {
//左上角
len = sqrt((x - leftTopPosX) * (x - leftTopPosX) + (y - leftTopPosY) * (y - leftTopPosY));
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((x - x2) * (x - x2) + (y - y2) * (y - y2));
if (len < offset)
{
pos->row = row;
pos->col = col+1;
if (chessMap[pos->row][pos->col] == 0)
ret = true;
break;
}
//左下角
int x3 = leftTopPosX;
int y3 = leftTopPosY + chessSize;
len = sqrt((x - x3) * (x - x3) + (y - y3) * (y - y3));
if (len < offset)
{
pos->row = row + 1;
pos->col = col;
if (chessMap[pos->row][pos->col] == 0)
ret = true;
break;
}
//右下角
int x4 = leftTopPosX + chessSize;
int y4 = leftTopPosY + chessSize;
len = sqrt((x - x4) * (x - x4) + (y - y4) * (y - y4));
if (len < offset)
{
pos->row = row + 1;
pos->col = col + 1;
if (chessMap[pos->row][pos->col] == 0)
ret = true;
break;
}
} while (0);
return ret;
}
void Chess::ChessMove(ChessPos* pos, chess_kind_t kind)
{
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);
}
int Chess::getGradeSize()
{
return gradeSize;
}
bool Chess::checkWin()
{
// 横竖斜四种大情况每种情况都根据当前落子往后遍历5个棋子有一种符合就算赢
// 水平方向
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])
{
setlinecolor(RED);
line(margin_x + (col - i) * chessSize, margin_y + (row) * chessSize, margin_x + (col - i + 4) * chessSize, margin_y + (row) * chessSize);
return true;
}
}
// 竖直方向(上下延伸4个)
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])
{
setlinecolor(RED);
line(margin_x + (col) * chessSize, margin_y + (row - i)*chessSize, margin_x + (col) * chessSize, margin_y + (row - i + 4)*chessSize);
return true;
}
}
// “/"方向
for (int i = 0; i < 5; i++)
{
if (row + i < gradeSize &&
row + i - 4 >= 0 &&
col - i >= 0 &&
col - i + 4 < gradeSize &&
// 第[row+i]行,第[col-i]的棋子与右上方连续4个棋子都相同
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])
{
setlinecolor(RED);
line(margin_x + (col - i)*chessSize, margin_y + (row + i) * chessSize, margin_x + (col - i + 4)*chessSize, margin_y + (row + i - 4) * chessSize);
return true;
}
}
// “\“ 方向
for (int i = 0; i < 5; i++)
{
// 第[row+i]行,第[col-i]的棋子与右下方连续4个棋子都相同
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])
{
setlinecolor(RED);
line(margin_x + (col - i) * chessSize, margin_y + (row - i) * chessSize, margin_x + (col - i + 4) * chessSize, margin_y + (row - i + 4) * chessSize);
return true;
}
}
return false;
}
bool Chess::checkOver()
{
if (checkWin())
{
Sleep(3000);
//赢棋
if (!playerFlag)
{
loadimage(0, "graphics/win.jpg",400,400,true);
}
//失败
else
{
loadimage(0, "graphics/fail.png", 400, 400, true);
}
Sleep(5000);
return true;
}
return false;
}
int Chess::getChessData(ChessPos* pos)
{
return chessMap[pos->row][pos->col];
}
int Chess::getChessData(int row, int col)
{
return chessMap[row][col];
}
void Chess::updateGameMap(ChessPos* pos)
{
lastPos = *pos;
chessMap[pos->row][pos->col] = playerFlag ? CHESS_BLACK : CHESS_WHITE;
playerFlag = !playerFlag;//换方
}