167 lines
5.1 KiB
C++
167 lines
5.1 KiB
C++
#include "board.h"
|
|
#include <iostream>
|
|
|
|
#include "raii.h"
|
|
#include "utils.h"
|
|
|
|
using namespace std;
|
|
|
|
Board::Board(int rows, int cols) : rows(rows), cols(cols) {
|
|
// Allocate memory for the 2D board
|
|
board = (char**)alloc((2 * rows - 1) * sizeof(char*));
|
|
for (int i = 0; i < 2 * rows - 1; i++) {
|
|
board[i] = (char*)alloc((2 * cols - 1) * sizeof(char));
|
|
for (int j = 0; j < 2 * cols - 1; j++) {
|
|
// Initialize with dots at intersections and spaces elsewhere
|
|
board[i][j] = (i % 2 == 0 && j % 2 == 0) ? '.' : ' ';
|
|
}
|
|
}
|
|
}
|
|
|
|
Board::~Board() {
|
|
// Free dynamically allocated memory
|
|
for (int i = 0; i < 2 * rows - 1; i++) {
|
|
dealloc(board[i]);
|
|
}
|
|
dealloc(board);
|
|
}
|
|
|
|
char Board::get(const int row, const int col) const {
|
|
return board[row][col];
|
|
}
|
|
|
|
void Board::set(const int row, const int col, const char value) {
|
|
board[row][col] = value;
|
|
}
|
|
|
|
bool Board::isLineValid(const int row, const int col) const {
|
|
// A line is valid if it's in a valid position and not already occupied
|
|
return (row > - 1 && row < 2 * rows - 1 && col > -1 && col < 2 * cols - 1) &&
|
|
((row&1) != (col&1)) && (board[row][col] == ' ');
|
|
}
|
|
|
|
void Board::placeLine(const int row, const int col, const char player) {
|
|
if (isLineValid(row, col)) {
|
|
board[row][col] = toLowerCase(player); // Place the player's initial in lowercase
|
|
}
|
|
}
|
|
|
|
int Board::checkAndMarkBox(const int row, const int col, const char player) {
|
|
int completedBoxes = 0;
|
|
|
|
// Check if the move is horizontal or vertical
|
|
bool isHorizontal = (row % 2 == 0);
|
|
|
|
if (isHorizontal) {
|
|
// Check box above the line (if row > 0)
|
|
if (row > 0 &&
|
|
board[row - 2][col] != ' ' && // Top line
|
|
board[row][col] != ' ' && // Bottom line
|
|
board[row - 1][col - 1] != ' ' && // Left line
|
|
board[row - 1][col + 1] != ' ') { // Right line
|
|
board[row - 1][col] = player; // Mark box with player's initial
|
|
completedBoxes++;
|
|
}
|
|
|
|
// Check box below the line (if row < 2 * rows - 2)
|
|
if (row < 2 * rows - 2 &&
|
|
board[row + 2][col] != ' ' && // Bottom line
|
|
board[row][col] != ' ' && // Top line
|
|
board[row + 1][col - 1] != ' ' && // Left line
|
|
board[row + 1][col + 1] != ' ') { // Right line
|
|
board[row + 1][col] = player; // Mark box with player's initial
|
|
completedBoxes++;
|
|
}
|
|
} else {
|
|
// Check box to the left (if col > 0)
|
|
if (col > 0 &&
|
|
board[row - 1][col - 1] != ' ' && // Top line
|
|
board[row + 1][col - 1] != ' ' && // Bottom line
|
|
board[row][col - 2] != ' ' && // Left line
|
|
board[row][col] != ' ') { // Right line
|
|
board[row][col - 1] = player; // Mark box with player's initial
|
|
completedBoxes++;
|
|
}
|
|
|
|
// Check box to the right (if col < 2 * cols - 2)
|
|
if (col < 2 * cols - 2 &&
|
|
board[row - 1][col + 1] != ' ' && // Top line
|
|
board[row + 1][col + 1] != ' ' && // Bottom line
|
|
board[row][col + 2] != ' ' && // Right line
|
|
board[row][col] != ' ') { // Left line
|
|
board[row][col + 1] = player; // Mark box with player's initial
|
|
completedBoxes++;
|
|
}
|
|
}
|
|
|
|
return completedBoxes;
|
|
}
|
|
|
|
|
|
bool Board::isFull() const {
|
|
for (int i = 0; i < 2 * rows - 1; i++) {
|
|
for (int j = 0; j < 2 * cols - 1; j++) {
|
|
if (board[i][j] == ' ' && (i % 2 != j % 2)) {
|
|
return false; // There's at least one empty line
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void Board::printBoard() const {
|
|
// Function to print the board
|
|
// Print the tens and ones places of the column numbers
|
|
cout << " "; // Space for row numbers
|
|
for (int col = 0; col < cols * 2 - 1; ++col) {
|
|
if (!(col % 10)) {
|
|
cout << col / 10; // Tens place of column numbers
|
|
} else {
|
|
cout << " "; // For spaces between dots
|
|
}
|
|
}
|
|
cout << '\n';
|
|
|
|
// Print the ones place of the column numbers
|
|
cout << " "; // Space for row numbers
|
|
for (int col = 0; col < cols * 2 - 1; ++col) {
|
|
cout << (col) % 10; // Print ones place
|
|
}
|
|
cout << '\n';
|
|
|
|
// Print the board rows with row numbers
|
|
for (int row = 0; row < rows * 2 - 1; ++row) {
|
|
// Print row number on the left
|
|
if (row / 10 > 9) {
|
|
if (row % 10 == 0) {
|
|
cout << row / 10;
|
|
} else {
|
|
cout << " ";
|
|
}
|
|
} else {
|
|
if (row % 10 == 0) {
|
|
cout << row / 10;
|
|
} else {
|
|
cout << " ";
|
|
}
|
|
}
|
|
cout << row % 10 << " "; // Print the ones place of the row number
|
|
|
|
// Print the content of the row (dots, lines, spaces)
|
|
for (int col = 0; col < cols * 2 - 1; ++col) {
|
|
cout << board[row][col];
|
|
}
|
|
cout << '\n';
|
|
}
|
|
|
|
cout.flush();
|
|
}
|
|
|
|
int Board::getRows() const {
|
|
return rows;
|
|
}
|
|
|
|
int Board::getCols() const {
|
|
return cols;
|
|
}
|