From db8e2596efa2543cd6d0180713adbc7b2c36e286 Mon Sep 17 00:00:00 2001 From: Sandipsinh Rathod Date: Fri, 6 Dec 2024 20:40:19 -0500 Subject: [PATCH] add better method --- strategic_player1.cxx | 88 ++++++++++++++++++++++++++++--------------- strategic_player1.h | 3 ++ 2 files changed, 60 insertions(+), 31 deletions(-) diff --git a/strategic_player1.cxx b/strategic_player1.cxx index 5ff5e58..ba6573d 100644 --- a/strategic_player1.cxx +++ b/strategic_player1.cxx @@ -1,19 +1,13 @@ -#include -#include #include "strategic_player1.h" -#include "common.h" -extern "C" IPlayer* PlayerFactory() -{ +extern "C" IPlayer *PlayerFactory() { return new StrategicPlayer1(); } - - using namespace std; string StrategicPlayer1::PlayerInfo() { - return "Big MAN Smol PP"; + return "Sandipsinh Rathod (sdr5549@psu.edu), Sapan Shah (scs6041@psu.edu)"; } void StrategicPlayer1::Init(int board_rows, int board_cols, char box_type, char line_type) { @@ -28,57 +22,73 @@ void StrategicPlayer1::Close() { board.FreeBoard(); } -void StrategicPlayer1::EventAddLine(char bar, const Loc& loc) { +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) { +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 + vector empty_lines; + ListEmptyLines(empty_lines); + + // Step 1: Look for a move to complete a box + Loc move = FindBoxCompletingMove(); + if (move.row != -1) { + return move; } - return FindOptimalMove(); // Fall back to a heuristic-based optimal move + // Step 2: Force opponent into bad moves + move = ForceOpponentMistake(empty_lines); + if (move.row != -1) { + return move; + } + + // Step 3: Fall back to the optimal move + return FindOptimalMove(); } StrategicPlayer1::~StrategicPlayer1() { Close(); } -// Private helper functions Loc StrategicPlayer1::FindBoxCompletingMove() { vector empty_lines; ListEmptyLines(empty_lines); - for (const Loc& loc : 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 - } + if (DoesMoveCompleteBox(row, col)) { + return loc; } } - return Loc(-1, -1); // No box-completing move found + return Loc(-1, -1); } 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::ForceOpponentMistake(const vector &empty_lines) { + Loc best_move(-1, -1); + + for (const Loc &loc: empty_lines) { + if (!DoesMoveCreateChain(loc.row, loc.col)) { + return loc; // Choose the first safe move + } + } + + return best_move; +} + Loc StrategicPlayer1::FindOptimalMove() { vector empty_lines; ListEmptyLines(empty_lines); @@ -86,7 +96,7 @@ Loc StrategicPlayer1::FindOptimalMove() { int min_cost = numeric_limits::max(); Loc best_move(-1, -1); - for (const Loc& loc : empty_lines) { + for (const Loc &loc: empty_lines) { int cost = EvaluateMoveCost(loc.row, loc.col); if (cost < min_cost) { min_cost = cost; @@ -97,10 +107,28 @@ Loc StrategicPlayer1::FindOptimalMove() { return best_move; } +bool StrategicPlayer1::DoesMoveCreateChain(int row, int col) { + board(row, col) = name; + + bool creates_chain = false; + + if (row % 2 == 0 && col % 2 == 1) { + if (CountBoxLines(row - 1, col) == 2 || CountBoxLines(row + 1, col) == 2) { + creates_chain = true; + } + } else if (row % 2 == 1 && col % 2 == 0) { + if (CountBoxLines(row, col - 1) == 2 || CountBoxLines(row, col + 1) == 2) { + creates_chain = true; + } + } + + board(row, col) = ' '; + return creates_chain; +} + 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); @@ -113,13 +141,11 @@ int StrategicPlayer1::EvaluateMoveCost(int row, int col) { } 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 @@ -128,12 +154,12 @@ int StrategicPlayer1::CountBoxLines(int row, int col) { return count; } -void StrategicPlayer1::ListEmptyLines(vector& empty_lines) { +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 + empty_lines.push_back(loc); } } } diff --git a/strategic_player1.h b/strategic_player1.h index bdb97ac..d46e697 100644 --- a/strategic_player1.h +++ b/strategic_player1.h @@ -5,6 +5,7 @@ #include "board.h" #include "player.h" #include +#include class StrategicPlayer1 : public IPlayer { char name; @@ -26,6 +27,8 @@ public: void ListEmptyLines(vector& empty_lines); bool DoesMoveCompleteBox(int row, int col); Loc FindBoxCompletingMove(); + bool DoesMoveCreateChain(int row, int col); + Loc ForceOpponentMistake(const vector& empty_lines); ~StrategicPlayer1(); };