diff --git a/Chess.cpp b/Chess.cpp new file mode 100644 index 0000000..754a9d0 --- /dev/null +++ b/Chess.cpp @@ -0,0 +1,278 @@ +#include "Chess.h" +#include +//修正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) + { + vectorrow; + 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;//换方 +} \ No newline at end of file