From b081f21fd9b399b5944d12a8a2c4b19be1f0b626 Mon Sep 17 00:00:00 2001 From: Sandipsinh Rathod Date: Fri, 6 Dec 2024 19:04:43 -0500 Subject: [PATCH] big man --- strategic_player1.cxx | 140 ++++++++++++++++++++++++++++++++++++++++++ strategic_player1.h | 32 ++++++++++ 2 files changed, 172 insertions(+) create mode 100644 strategic_player1.cxx create mode 100644 strategic_player1.h diff --git a/strategic_player1.cxx b/strategic_player1.cxx new file mode 100644 index 0000000..5ff5e58 --- /dev/null +++ b/strategic_player1.cxx @@ -0,0 +1,140 @@ +#include +#include +#include "strategic_player1.h" +#include "common.h" + +extern "C" IPlayer* PlayerFactory() +{ + return new StrategicPlayer1(); +} + + + +using namespace std; + +string StrategicPlayer1::PlayerInfo() { + return "Big MAN Smol PP"; +} + +void StrategicPlayer1::Init(int board_rows, int board_cols, char box_type, char line_type) { + this->box_name = box_type; + this->name = line_type; + + int blank_line_count = 0; + board.AllocateBoard(board_rows, board_cols, blank_line_count); +} + +void StrategicPlayer1::Close() { + board.FreeBoard(); +} + +void StrategicPlayer1::EventAddLine(char bar, const Loc& loc) { + board(loc) = bar; // Update the board with the added line +} + +void StrategicPlayer1::EventAddBox(char box, const Loc& loc) { + board(loc) = box; // Update the board with the assigned box +} + +Loc StrategicPlayer1::SelectLineLocation() { + Loc box_completing_move = FindBoxCompletingMove(); + if (box_completing_move.row != -1 && box_completing_move.col != -1) { + return box_completing_move; // Prioritize moves that complete a box + } + + return FindOptimalMove(); // Fall back to a heuristic-based optimal move +} + +StrategicPlayer1::~StrategicPlayer1() { + Close(); +} + +// Private helper functions +Loc StrategicPlayer1::FindBoxCompletingMove() { + vector empty_lines; + ListEmptyLines(empty_lines); + + for (const Loc& loc : empty_lines) { + int row = loc.row, col = loc.col; + + // Check if adding a line at this location completes a box + if ((row % 2 == 0 && col % 2 == 1) || (row % 2 == 1 && col % 2 == 0)) { + if (DoesMoveCompleteBox(row, col)) { + return loc; // Return the first box-completing move found + } + } + } + + return Loc(-1, -1); // No box-completing move found +} + +bool StrategicPlayer1::DoesMoveCompleteBox(int row, int col) { + // Check adjacent boxes based on the move's orientation + if (row % 2 == 0 && col % 2 == 1) { // Horizontal line + return (CountBoxLines(row - 1, col) == 3 || CountBoxLines(row + 1, col) == 3); + } else if (row % 2 == 1 && col % 2 == 0) { // Vertical line + return (CountBoxLines(row, col - 1) == 3 || CountBoxLines(row, col + 1) == 3); + } + + return false; +} + +Loc StrategicPlayer1::FindOptimalMove() { + vector empty_lines; + ListEmptyLines(empty_lines); + + int min_cost = numeric_limits::max(); + Loc best_move(-1, -1); + + for (const Loc& loc : empty_lines) { + int cost = EvaluateMoveCost(loc.row, loc.col); + if (cost < min_cost) { + min_cost = cost; + best_move = loc; + } + } + + return best_move; +} + +int StrategicPlayer1::EvaluateMoveCost(int row, int col) { + int cost = 0; + + // Evaluate the "cost" of the move by summing the number of sides completed for adjacent boxes + if (row % 2 == 0 && col % 2 == 1) { // Horizontal line + cost += CountBoxLines(row - 1, col); + cost += CountBoxLines(row + 1, col); + } else if (row % 2 == 1 && col % 2 == 0) { // Vertical line + cost += CountBoxLines(row, col - 1); + cost += CountBoxLines(row, col + 1); + } + + return cost; +} + +int StrategicPlayer1::CountBoxLines(int row, int col) { + // Ensure the location is within bounds + if (row < 0 || row >= board.GetRows() || col < 0 || col >= board.GetCols()) { + return 0; + } + + int count = 0; + // Check all four sides of the box + if (board(row - 1, col) != ' ') count++; // Top + if (board(row + 1, col) != ' ') count++; // Bottom + if (board(row, col - 1) != ' ') count++; // Left + if (board(row, col + 1) != ' ') count++; // Right + + return count; +} + +void StrategicPlayer1::ListEmptyLines(vector& empty_lines) { + for (int r = 0; r < board.GetRows(); r++) { + for (int c = 0; c < board.GetCols(); c++) { + Loc loc(r, c); + if (loc.IsLineLocation() && board(r, c) == ' ') { + empty_lines.push_back(loc); // Add all empty line locations to the list + } + } + } +} diff --git a/strategic_player1.h b/strategic_player1.h new file mode 100644 index 0000000..a05d2b5 --- /dev/null +++ b/strategic_player1.h @@ -0,0 +1,32 @@ +#ifndef HW4_STRATEGIC_PLAYER1_H +#define HW4_STRATEGIC_PLAYER1_H + +#include "common.h" +#include "board.h" +#include "player.h" + +class StrategicPlayer1 : public IPlayer { + char name; + char box_name; + + Board board; + +public: + string PlayerInfo() override; + void Init(int board_rows, int board_cols, char box_type, char line_type) override; + void Close() override; + void EventAddLine(char bar, const Loc& loc) override; + void EventAddBox(char box, const Loc& loc) override; + Loc SelectLineLocation() override; + + int EvaluateMoveCost(int row, int col); + int CountBoxLines(int row, int col); + Loc FindOptimalMove(); + void ListEmptyLines(vector& empty_lines); + bool DoesMoveCompleteBox(int row, int col); + Loc FindBoxCompletingMove(); + + ~StrategicPlayer1(); +}; + +#endif // HW4_STRATEGIC_PLAYER1_H