cmpsc330hw2/main.cpp

267 lines
6.3 KiB
C++
Raw Normal View History

#include <algorithm>
2024-10-09 23:39:24 +00:00
#include <iostream>
#include <map>
2024-10-09 23:39:24 +00:00
#include <sstream>
2024-10-10 00:36:29 +00:00
#include <vector>
2024-10-09 23:39:24 +00:00
#define pt cout <<
#define nl '\n'
#define in cin >>
using namespace std;
// -------- START RAII HELPERS--------
unsigned long allocatedMem = 0;
2024-10-09 23:39:24 +00:00
void *alloc(size_t size) {
void *ptr = malloc(size);
if (ptr == nullptr) {
cerr << "Memory allocation failed" << nl;
2024-10-09 23:39:24 +00:00
return nullptr;
}
allocatedMem += 1;
2024-10-09 23:39:24 +00:00
return ptr;
}
void dealloc(void *ptr) {
if (ptr) free(ptr);
allocatedMem -= 1;
2024-10-09 23:39:24 +00:00
}
bool assert_alloc() {
return !allocatedMem;
2024-10-09 23:39:24 +00:00
}
// -------- END RAII HELPERS--------
struct Move {
char player;
2024-10-10 00:36:29 +00:00
int moveX;
int moveY;
2024-10-09 23:39:24 +00:00
};
struct Moves {
2024-10-10 00:36:29 +00:00
int x;
int y;
2024-10-09 23:39:24 +00:00
vector<Move> moves;
};
bool isValidPlayer(char c) {
return c >= 'A' && c <= 'Z' && c != 'X';
}
2024-10-09 23:39:24 +00:00
Moves serialize(const string &s) {
Moves result;
istringstream iss(s);
iss >> result.x >> result.y;
2024-10-10 00:36:29 +00:00
result.x <<= 1;
result.y <<= 1;
2024-10-09 23:39:24 +00:00
string player;
int x, y;
while (iss >> player >> x >> y) {
if (player == "END") break;
if (!isValidPlayer(player[0])) {
string err = "Invalid player: " + player;
throw std::invalid_argument(err);
}
2024-10-09 23:39:24 +00:00
result.moves.push_back({player[0], x, y});
}
return result;
}
2024-10-10 00:36:29 +00:00
void initBoard(char **board, int x, int y) {
for (int i = 0; i < x; ++i) {
for (int j = 0; j < y; j++) {
board[i][j] = (j & 1 || i & 1) ? ' ' : '.';
2024-10-10 00:36:29 +00:00
}
}
2024-10-09 23:39:24 +00:00
}
2024-10-10 00:36:29 +00:00
char **allocAndInitBoard(int x, int y) {
char **board = static_cast<char **>(alloc(sizeof(char *) * x));
for (int i = 0; i < x; ++i) {
board[i] = static_cast<char *>(alloc(sizeof(char) * y));
}
initBoard(board, x, y);
return board;
}
void deallocBoard(char **board, int x) {
for (int i = 0; i < x; ++i) {
dealloc(board[i]);
2024-10-09 23:39:24 +00:00
}
2024-10-10 00:36:29 +00:00
dealloc(board);
}
void printBoard(char **board, int x, int y) {
for (int i = 0; i < x; ++i) {
for (int j = 0; j < y; ++j) {
pt board[i][j];
}
pt nl;
}
}
2024-10-09 23:39:24 +00:00
char toLowerCase(char c) {
return c | 32;
}
int normalizePlayer(char c) {
return toLowerCase(c) - 'a';
}
void printScores(map<char, int> &points) {
// TODO: change this to custom sort before submission
vector<pair<char, int> > ranking(points.begin(), points.end());
sort(ranking.begin(), ranking.end(), [](const pair<char, int> &a, const pair<char, int> &b) {
return a.second < b.second;
});
// Print the ranks
for (const auto &rank: ranking) {
pt rank.first << ": " << rank.second << " boxes" << nl;
}
}
bool isValidMove(int x, int y) {
// TODO: simplify this
return !(x & 1 != y & 1 && !(x & 1));
}
2024-10-10 00:36:29 +00:00
void solve(Moves moves, char **board) {
map<char, int> points;
for (Move &move: moves.moves) {
int moveX = move.moveX;
int moveY = move.moveY;
char player = move.player;
if (!isValidMove(moveX, moveY)) {
pt "Invalid move by: " << player << " at (x, y): (" << moveX << ", " << moveY << ")" << nl;
board[moveX][moveY] = 'X';
printBoard(board, moves.x, moves.y);
printScores(points);
pt "Exiting.." << nl;
return;
}
board[moveX][moveY] = toLowerCase(player);
// TODO:
if (moveX % 2 == 0 && moveY % 2 == 1) {
} else if (moveX % 2 == 1 && moveY % 2 == 0) {
2024-10-10 00:36:29 +00:00
}
}
printScores(points);
printBoard(board, moves.x, moves.y);
2024-10-10 00:36:29 +00:00
}
/*
void solve(Moves moves, char **board) {
/*
TODO: use custom arr for points over map
*int *points = static_cast<int *>(alloc(26));
for (int i = 0; i < 26; i++) {
points[i] = 0;
}#1#
map<char, int> points;
for (const auto &move: moves.moves) {
int moveX = move.moveX;
int moveY = move.moveY;
char player = move.player;
board[moveX][moveY] = toLowerCase(player);
if (moveX % 2 == 0 && moveY % 2 == 1) {
if (moveX > 0 && board[moveX - 1][moveY] == '|' && board[moveX - 1][moveY - 1] == '-' && board[moveX - 1][moveY + 1] == '-') {
points[player]++;
}
if (moveX < moves.x - 1 && board[moveX + 1][moveY] == '|' && board[moveX + 1][moveY - 1] == '-' && board[moveX + 1][moveY + 1] == '-') {
points[player]++;
}
} else if (moveX % 2 == 1 && moveY % 2 == 0) {
if (moveY > 0 && board[moveX][moveY - 1] == '-' && board[moveX - 1][moveY - 1] == '|' && board[moveX + 1][moveY - 1] == '|') {
points[player]++;
}
if (moveY < moves.y - 1 && board[moveX][moveY + 1] == '-' && board[moveX - 1][moveY + 1] == '|' && board[moveX + 1][moveY + 1] == '|') {
points[player]++;
}
}
}
vector<pair<char, int> > ranking(points.begin(), points.end());
sort(ranking.begin(), ranking.end(), [](const pair<char, int> &a, const pair<char, int> &b) {
return a.second < b.second;
});
for (const auto &rank: ranking) {
pt rank.first << ": " << rank.second << " boxes" << nl;
}
printBoard(board, moves.x, moves.y);
// dealloc(points);
}
*/
2024-10-10 00:36:29 +00:00
int init(char *fileName) {
// --- IO START ---
2024-10-09 23:39:24 +00:00
FILE *inp = fopen(fileName, "r");
if (inp == nullptr) {
cerr << "File not found" << nl;
2024-10-09 23:39:24 +00:00
return 1;
}
fseek(inp, 0L, SEEK_END);
2024-10-10 00:36:29 +00:00
const long sz = ftell(inp);
2024-10-09 23:39:24 +00:00
fseek(inp, 0L, SEEK_SET);
char *fileInpPtr = static_cast<char *>(alloc(sz + 1 * sizeof(char)));
fileInpPtr[sz] = '\0';
for (int i = 0; i < sz; ++i) {
fscanf(inp, "%c", &fileInpPtr[i]);
}
2024-10-10 00:36:29 +00:00
// --- IO END ---
2024-10-09 23:39:24 +00:00
2024-10-10 00:36:29 +00:00
// --- ALGORITHM START ---
Moves moves = serialize(fileInpPtr);
char **board = allocAndInitBoard(moves.x, moves.y);
solve(moves, board);
// --- ALGORITHM END ---
2024-10-09 23:39:24 +00:00
2024-10-10 00:36:29 +00:00
// --- CLEANUP START ---
2024-10-09 23:39:24 +00:00
dealloc(fileInpPtr);
2024-10-10 00:36:29 +00:00
deallocBoard(board, moves.x);
2024-10-09 23:39:24 +00:00
fclose(inp);
if (!assert_alloc()) {
cerr << "Memory leak detected" << nl;
2024-10-09 23:39:24 +00:00
return 1;
}
2024-10-10 00:36:29 +00:00
// --- CLEANUP END ---
2024-10-09 23:39:24 +00:00
return 0;
}
2024-10-10 00:36:29 +00:00
int main(int argc, char **argv) {
if (argc < 2) {
cerr << "No input file provided" << nl;
return 1;
}
try {
return init(argv[1]);
} catch (const std::invalid_argument &e) {
cerr << e.what() << nl;
2024-10-10 00:36:29 +00:00
return 1;
}
}