Files
BasicsOfComputerSoftwareEng…/OOP/FiveInARow/chessBoard.cpp
2023-03-01 20:45:53 +08:00

217 lines
6.2 KiB
C++

#include "fiveInARow.h"
// clang-format off
char ChessBoard::emptyBoardString[3][4][4] = {
{
"", "", "", ""
},
{
"", "", "", ""
},
{
"", "", "", "",
}
};
// clang-format on
char ChessBoard::toHex(int num) {
if (num < 10) {
return num + '0';
}
else {
return num - 10 + 'A';
}
}
void ChessBoard::makeTitle() {
std::cout << " ";
for (int i = 1; i <= this->size; i++) {
std::cout << " " << this->toHex(i);
}
std::cout << std::endl;
}
ChessBoard::ChessBoard() {
this->chessCount = 0;
this->size = 15;
}
ChessBoard::ChessBoard(int boardSize) {
this->chessCount = 0;
this->size = boardSize;
}
ChessBoard::~ChessBoard() {
}
void ChessBoard::show() {
this->makeTitle();
for (int i = 0; i < this->size; i++) {
std::cout << this->toHex(i + 1) << ' ';
char(*emptyLineRef)[4][4] = NULL;
if (i == 0) {
emptyLineRef = &emptyBoardString[0];
}
else if (i == this->size - 1) {
emptyLineRef = &emptyBoardString[2];
}
else {
emptyLineRef = &emptyBoardString[1];
}
int j = 0;
for (; j < this->size; j++) {
if (this->ChessPieces[i][j].isEmpty()) {
// std::cout << (*emptyLineRef)[j * 2];
if (j == 0) {
std::cout << (*emptyLineRef)[0];
}
else if (j == this->size - 1) {
std::cout << (*emptyLineRef)[3];
}
else {
std::cout << (*emptyLineRef)[2];
}
}
else {
std::cout << this->ChessPieces[i][j].show();
}
if (j < this->size - 1) {
std::cout << (*emptyLineRef)[1];
}
}
std::cout << std::endl;
}
}
bool ChessBoard::setChess(bool color, int row, int column) {
if (row > this->size - 1 || row < 0 || column > this->size - 1 ||
column < 0) {
std::cout << "Out of border!" << std::endl;
return false;
}
if (!this->ChessPieces[row][column].isEmpty()) {
std::cout << "There already is a chess piece!" << std::endl;
return false;
}
this->ChessPieces[row][column].setColor(color);
this->chessCount++;
return true;
}
void ChessBoard::reset() {
for (int i = 0; i < this->size; i++) {
for (int j = 0; j < this->size; j++) {
this->ChessPieces[i][j].reset();
}
}
this->chessCount = 0;
}
bool ChessBoard::isFull() {
return this->chessCount == this->size * this->size;
}
bool ChessBoard::checkWinner(int row, int column, bool color) {
int connetCount = 0;
int i = row, j = column;
int possiblePieces[9][2] = {0};
// vertical
this->countWinningPiece(
color, row + 1, column, [=](int i) { return i + 1; },
[=](int j) { return j; }, possiblePieces, &connetCount);
this->countWinningPiece(
color, row - 1, column, [=](int i) { return i - 1; },
[=](int j) { return j; }, possiblePieces, &connetCount);
if (connetCount >= 4) {
// 最后现在下的这个点没有算在这个里面,要手动设置成成功
this->ChessPieces[row][column].setWin();
this->setWinPiece(connetCount, possiblePieces);
return true;
}
// horizontal
connetCount = 0;
this->countWinningPiece(
color, row, column + 1, [=](int i) { return i; },
[=](int j) { return j + 1; }, possiblePieces, &connetCount);
this->countWinningPiece(
color, row, column - 1, [=](int i) { return i; },
[=](int j) { return j - 1; }, possiblePieces, &connetCount);
if (connetCount >= 4) {
// 最后现在下的这个点没有算在这个里面,要手动设置成成功
this->ChessPieces[row][column].setWin();
this->setWinPiece(connetCount, possiblePieces);
return true;
}
// left-up
connetCount = 0;
this->countWinningPiece(
color, row + 1, column + 1, [=](int i) { return i + 1; },
[=](int j) { return j + 1; }, possiblePieces, &connetCount);
this->countWinningPiece(
color, row - 1, column - 1, [=](int i) { return i - 1; },
[=](int j) { return j - 1; }, possiblePieces, &connetCount);
if (connetCount >= 4) {
// 最后现在下的这个点没有算在这个里面,要手动设置成成功
this->ChessPieces[row][column].setWin();
this->setWinPiece(connetCount, possiblePieces);
return true;
}
// right-up
connetCount = 0;
this->countWinningPiece(
color, row + 1, column - 1, [=](int i) { return i + 1; },
[=](int j) { return j - 1; }, possiblePieces, &connetCount);
this->countWinningPiece(
color, row - 1, column + 1, [=](int i) { return i - 1; },
[=](int j) { return j + 1; }, possiblePieces, &connetCount);
if (connetCount >= 4) {
// 最后现在下的这个点没有算在这个里面,要手动设置成成功
this->ChessPieces[row][column].setWin();
this->setWinPiece(connetCount, possiblePieces);
return true;
}
return false;
}
int ChessBoard::getSize() {
return this->size;
}
void ChessBoard::countWinningPiece(bool color, int row, int column,
std::function<int(int)> const &rowFunc,
std::function<int(int)> const &columnFunc,
int possiblePieces[][2], int *connectCount) {
int i = row, j = column;
while (0 <= i && i <= 15 && 0 <= j && j <= 15) {
if (this->ChessPieces[i][j].isEmpty()) {
break;
}
if (this->ChessPieces[i][j].getColor() == color) {
possiblePieces[*connectCount][0] = i;
possiblePieces[*connectCount][1] = j;
*connectCount += 1;
}
else {
break;
}
i = rowFunc(i);
j = columnFunc(j);
}
}
void ChessBoard::setWinPiece(int connectCount, int winningPieces[][2]) {
int count = connectCount;
for (count--; count >= 0; count--) {
this->ChessPieces[winningPieces[count][0]][winningPieces[count][1]]
.setWin();
}
}