#include #include #define BLACK false #define WHITE true // 还没有实现判定输赢 // todo: 棋盘满时判定和棋 // clang-format off std::string boardTitle = " 1 2 3 4 5 6 7 8 9 A B C D E F"; char emptyBoardString[3][29][4] = { { "┏", "━", "┯", "━", "┯", "━", "┯", "━", "┯", "━", "┯", "━", "┯", "━", "┯", "━", "┯", "━", "┯", "━", "┯", "━", "┯", "━", "┯", "━", "┯", "━", "┓" }, { "┠", "─", "┼", "─", "┼", "─", "┼", "─", "┼", "─", "┼", "─", "┼", "─", "┼", "─", "┼", "─", "┼", "─", "┼", "─", "┼", "─", "┼", "─", "┼", "─", "┨" }, { "┗", "━", "┷", "━", "┷", "━", "┷", "━", "┷", "━", "┷", "━", "┷", "━", "┷", "━", "┷", "━", "┷", "━", "┷", "━", "┷", "━", "┷", "━", "┷", "━", "┛", } }; // clang-format on enum putChessPieceResult { failed, success, win, fullBoard }; class ChessPiece { private: bool color; bool isEmptyStatus; bool isWinStatus; public: void init() { this->isEmptyStatus = true; this->isWinStatus = false; this->color = BLACK; } void setColor(bool newColor) { this->isEmptyStatus = false; this->color = newColor; } void setWin() { this->isWinStatus = true; } bool isEmpty() { return this->isEmptyStatus; } bool getColor() { return this->color; } std::string show() { if (this->isWinStatus) { return "X"; } if (this->color == BLACK) { return "⬤"; } else { return "◯"; } } }; class ChessBoard { private: ChessPiece ChessPieces[15][15]; int chessCount; char toHex(int num) { if (num < 10) { return num + '0'; } else { return num - 10 + 'A'; } } public: void init() { for (int i = 0; i < 15; i++) { for (int j = 0; j < 15; j++) { this->ChessPieces[i][j].init(); } } this->chessCount = 0; } void show() { std::cout << boardTitle << std::endl; for (int i = 0; i < 15; i++) { std::cout << this->toHex(i + 1) << ' '; char(*emptyLineRef)[29][4] = NULL; if (i == 0) { emptyLineRef = &emptyBoardString[0]; } else if (i == 14) { emptyLineRef = &emptyBoardString[2]; } else { emptyLineRef = &emptyBoardString[1]; } int j = 0; for (; j < 15; j++) { if (this->ChessPieces[i][j].isEmpty()) { std::cout << (*emptyLineRef)[j * 2]; } else { std::cout << this->ChessPieces[i][j].show(); } if (j < 14) { std::cout << (*emptyLineRef)[j * 2 + 1]; } } std::cout << std::endl; } } // Returns true if success, returns false if not bool setChess(bool color, int row, int column) { if (row > 14 || row < 0 || column > 14 || 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 reset() { this->init(); } bool isFull() { return this->chessCount == 15 * 15; } bool checkWinner(int row, int column, bool color) { int connetCount = 0; int i = row, j = column; int possiblePieces[9][2] = {0}; // vertical for (; i < 15; i++) { if (this->ChessPieces[i][j].isEmpty()) { break; } if (this->ChessPieces[i][j].getColor() == color) { possiblePieces[connetCount][0] = i; possiblePieces[connetCount][1] = j; connetCount++; } else { break; } } for (i = row - 1; i >= 0; i--) { if (this->ChessPieces[i][j].isEmpty()) { break; } if (this->ChessPieces[i][j].getColor() == color) { possiblePieces[connetCount][0] = i; possiblePieces[connetCount][1] = j; connetCount++; } else { break; } } if (connetCount >= 5) { for (connetCount--; connetCount >= 0; connetCount--) { this->ChessPieces[possiblePieces[connetCount][0]] [possiblePieces[connetCount][1]] .setWin(); } return true; } // horizontal i = row; j = column; connetCount = 0; for (; j < 15; j++) { if (this->ChessPieces[i][j].isEmpty()) { break; } if (this->ChessPieces[i][j].getColor() == color) { possiblePieces[connetCount][0] = i; possiblePieces[connetCount][1] = j; connetCount++; } else { break; } } for (j = column - 1; j >= 0; j--) { if (this->ChessPieces[i][j].isEmpty()) { break; } if (this->ChessPieces[i][j].getColor() == color) { possiblePieces[connetCount][0] = i; possiblePieces[connetCount][1] = j; connetCount++; } else { break; } } if (connetCount >= 5) { for (connetCount--; connetCount >= 0; connetCount--) { this->ChessPieces[possiblePieces[connetCount][0]] [possiblePieces[connetCount][1]] .setWin(); } return true; } // left-up i = row; j = column; connetCount = 0; while (i < 15 && j < 15) { if (this->ChessPieces[i][j].isEmpty()) { break; } if (this->ChessPieces[i][j].getColor() == color) { possiblePieces[connetCount][0] = i; possiblePieces[connetCount][1] = j; connetCount++; } else { break; } i++; j++; } i = row - 1; j = column - 1; while (i >= 0 && j >= 0) { if (this->ChessPieces[i][j].isEmpty()) { break; } if (this->ChessPieces[i][j].getColor() == color) { possiblePieces[connetCount][0] = i; possiblePieces[connetCount][1] = j; connetCount++; } else { break; } i--; j--; } if (connetCount >= 5) { for (connetCount--; connetCount >= 0; connetCount--) { this->ChessPieces[possiblePieces[connetCount][0]] [possiblePieces[connetCount][1]] .setWin(); } return true; } // right-up i = row; j = column; connetCount = 0; while (i >= 0 && j < 15) { if (this->ChessPieces[i][j].isEmpty()) { break; } if (this->ChessPieces[i][j].getColor() == color) { possiblePieces[connetCount][0] = i; possiblePieces[connetCount][1] = j; connetCount++; } else { break; } i--; j++; } i = row + 1; j = column - 1; while (i < 15 && j >= 0) { if (this->ChessPieces[i][j].isEmpty()) { break; } if (this->ChessPieces[i][j].getColor() == color) { possiblePieces[connetCount][0] = i; possiblePieces[connetCount][1] = j; connetCount++; } else { break; } i++; j--; } if (connetCount >= 5) { for (connetCount--; connetCount >= 0; connetCount--) { this->ChessPieces[possiblePieces[connetCount][0]] [possiblePieces[connetCount][1]] .setWin(); } return true; } return false; } }; class Player { private: ChessBoard *board; std::string playerName; bool chessType; int toInt(char input) { if ('1' <= input && input <= '9') { return input - '1'; } else if ('A' <= input && input <= 'F') { return input - 'A' + 9; } else if ('a' <= input && input <= 'f') { return input - 'a' + 9; } else { return -1; } } public: void init(std::string name, bool type, ChessBoard *chessBoard) { this->playerName = name; this->chessType = type; this->board = chessBoard; } std::string getName() { return this->playerName; } bool getColor() { return this->chessType; } putChessPieceResult setChess(char row, char column) { int rowCount, columnCount; rowCount = toInt(row); columnCount = toInt(column); if (!this->board->setChess(chessType, rowCount, columnCount)) { return failed; } if (this->board->checkWinner(rowCount, columnCount, this->chessType)) { std::cout << "\n####################\n" << this->playerName << " wins!" << std::endl << "####################\n"; return win; } if (this->board->isFull()) { std::cout << "Board is full. Tie!" << std::endl; return fullBoard; } else { return success; } } }; int main() { ChessBoard aBoard; aBoard.init(); aBoard.show(); Player players[2]; { std::string temp = ""; std::cout << "Player 1 name: "; std::cin >> temp; players[0].init(temp, BLACK, &aBoard); std::cout << "Player 2 name: "; std::cin >> temp; players[1].init(temp, WHITE, &aBoard); } putChessPieceResult result; bool nowMovePlayerIndex = false; do { std::cout << players[nowMovePlayerIndex].getName() << " [" << (players[nowMovePlayerIndex].getColor() ? "◯White" : "⬤Black") << "]: " << "Please enter the coordinate of your new chess piece." << std::endl; char row, column; std::cout << "Row No. "; std::cin >> row; fflush(stdin); while (!(('1' <= row && row <= '9') || ('A' <= row && row <= 'F') || ('a' <= row && row <= 'f'))) { std::cout << "Not a valid row number. Try again." << std::endl; std::cout << "Row No. "; std::cin >> row; fflush(stdin); } std::cout << "Column No. "; std::cin >> column; fflush(stdin); while (!(('1' <= row && row <= '9') || ('A' <= row) && (row <= 'F') || ('a' <= row && row <= 'f'))) { std::cout << "Not a valid column number. Try again." << std::endl; std::cout << "Column No. "; std::cin >> column; fflush(stdin); } result = players[nowMovePlayerIndex].setChess(row, column); if (result == failed) { continue; } else if (result == success) { nowMovePlayerIndex ^= 1; aBoard.show(); continue; } else { aBoard.show(); char input; do { std::cout << "Reset for another round? (y/n) "; input = getchar(); fflush(stdin); } while (input != 'y' && input != 'Y' && input != 'n' && input != 'N'); if (input == 'y' || input == 'Y') { aBoard.reset(); aBoard.show(); continue; } else { break; } } } while (true); return 0; }