tmp: add harshit

This commit is contained in:
Sandipsinh Rathod 2024-12-06 20:52:13 -05:00
parent db8e2596ef
commit 3ecbd34211
No known key found for this signature in database
3 changed files with 185 additions and 9 deletions

122
harshit/custom_player.cxx Normal file

@ -0,0 +1,122 @@
#include "custom_player.h"
#include <iostream>
#include <cstdlib> // for rand
#include <ctime> // for time
using namespace std;
// Factory function for dynamic library loading
extern "C" IPlayer* PlayerFactory() {
return new CustomPlayer();
}
// Constructor
CustomPlayer::CustomPlayer() {
srand(time(0));
}
// Destructor
CustomPlayer::~CustomPlayer() {}
// Initializes the player with the board size and player symbols
void CustomPlayer::Init(int dots_in_rows, int dots_in_cols, char _player_box, char _player_line) {
board.AllocateBoard(dots_in_rows, dots_in_cols);
player_box = _player_box;
player_line = _player_line;
empty_lines = new Loc[board.GetRows() * board.GetCols()];
}
// Cleans up dynamically allocated memory
void CustomPlayer::Close() {
board.FreeBoard();
delete[] empty_lines;
}
// Returns the player info
std::string CustomPlayer::PlayerInfo() {
return "Custom Strategic Player";
}
// Updates the board when a line is added
void CustomPlayer::EventAddLine(char bar, const Loc& loc) {
board(loc) = bar;
}
// Updates the board when a box is completed
void CustomPlayer::EventAddBox(char box, const Loc& loc) {
board(loc) = box;
}
// Updates the list of available line locations
void CustomPlayer::ListEmptyLines() {
empty_lines_count = 0;
for (int r = 0; r < board.GetRows(); r++) {
for (int c = 0; c < board.GetCols(); c++) {
if (board(r, c) == ' ' && Loc(r, c).IsLineLocation()) {
empty_lines[empty_lines_count++] = Loc(r, c);
}
}
}
}
// Helper function to check if a line completes a box
bool CustomPlayer::DoesLineCompleteBox(const Loc& loc) {
if (loc.IsLineHorizontalLocation()) {
if (loc.row > 0 && board(loc.row - 1, loc.col) != ' ' &&
board(loc.row - 1, loc.col - 1) != ' ' && board(loc.row - 1, loc.col + 1) != ' ')
return true;
if (loc.row < board.GetRows() - 1 && board(loc.row + 1, loc.col) != ' ' &&
board(loc.row + 1, loc.col - 1) != ' ' && board(loc.row + 1, loc.col + 1) != ' ')
return true;
} else if (loc.IsLineVerticalLocation()) {
if (loc.col > 0 && board(loc.row, loc.col - 1) != ' ' &&
board(loc.row - 1, loc.col - 1) != ' ' && board(loc.row + 1, loc.col - 1) != ' ')
return true;
if (loc.col < board.GetCols() - 1 && board(loc.row, loc.col + 1) != ' ' &&
board(loc.row - 1, loc.col + 1) != ' ' && board(loc.row + 1, loc.col + 1) != ' ')
return true;
}
return false;
}
// Helper function to avoid giving the opponent a chance to complete a box
bool CustomPlayer::WouldGiveOpponentBox(const Loc& loc) {
// Temporarily add the line to the board
board(loc) = player_line;
// Check if the opponent can complete a box in the next move
for (int r = 0; r < board.GetRows(); r++) {
for (int c = 0; c < board.GetCols(); c++) {
if (board(r, c) == ' ' && Loc(r, c).IsLineLocation() &&
DoesLineCompleteBox(Loc(r, c))) {
board(loc) = ' '; // Revert the move
return true;
}
}
}
// Revert the move
board(loc) = ' ';
return false;
}
// Determines the next move
Loc CustomPlayer::SelectLineLocation() {
ListEmptyLines();
// Strategy: Prioritize moves that complete a box
for (int i = 0; i < empty_lines_count; i++) {
if (DoesLineCompleteBox(empty_lines[i])) {
return empty_lines[i];
}
}
// Avoid moves that give the opponent a chance to complete a box
for (int i = 0; i < empty_lines_count; i++) {
if (!WouldGiveOpponentBox(empty_lines[i])) {
return empty_lines[i];
}
}
// Otherwise, pick a random move
return empty_lines[rand() % empty_lines_count];
}

54
harshit/custom_player.h Normal file

@ -0,0 +1,54 @@
#ifndef __CUSTOM_PLAYER__
#define __CUSTOM_PLAYER__
#include "player.h"
#include "common.h"
#include "board.h"
#include <string>
#include <vector>
class CustomPlayer : public IPlayer {
private:
Board board; // Game board to track state
char player_box; // Character representing the player's boxes
char player_line; // Character representing the player's lines
Loc* empty_lines; // Array to store available line locations
int empty_lines_count; // Number of available line locations
public:
CustomPlayer();
~CustomPlayer();
// Initializes the player with board details and player symbols
void Init(int dots_in_rows, int dots_in_cols, char player_box, char player_line) override;
// Cleans up dynamically allocated memory
void Close() override;
// Returns the player information
std::string PlayerInfo() override;
// Called when a line is added to the board
void EventAddLine(char bar, const Loc& loc) override;
// Called when a box is completed on the board
void EventAddBox(char box, const Loc& loc) override;
// Determines the next move based on the current state of the board
Loc SelectLineLocation() override;
private:
// Updates the list of available line locations
void ListEmptyLines();
// Helper function to check if a line completes a box
bool DoesLineCompleteBox(const Loc& loc);
// Helper function to avoid giving the opponent a chance to complete a box
bool WouldGiveOpponentBox(const Loc& loc);
// Evaluate the best line location strategically
Loc GetBestStrategicMove();
};
#endif

@ -23,11 +23,11 @@ void StrategicPlayer1::Close() {
}
void StrategicPlayer1::EventAddLine(char bar, const Loc &loc) {
board(loc) = bar; // Update the board with the added line
board(loc) = bar;
}
void StrategicPlayer1::EventAddBox(char box, const Loc &loc) {
board(loc) = box; // Update the board with the assigned box
board(loc) = box;
}
Loc StrategicPlayer1::SelectLineLocation() {
@ -69,9 +69,9 @@ Loc StrategicPlayer1::FindBoxCompletingMove() {
}
bool StrategicPlayer1::DoesMoveCompleteBox(int row, int col) {
if (row % 2 == 0 && col % 2 == 1) { // Horizontal line
if (!(row & 1) && col & 1) {
return (CountBoxLines(row - 1, col) == 3 || CountBoxLines(row + 1, col) == 3);
} else if (row % 2 == 1 && col % 2 == 0) { // Vertical line
} else if (row & 1 && !(col & 1)) {
return (CountBoxLines(row, col - 1) == 3 || CountBoxLines(row, col + 1) == 3);
}
return false;
@ -82,7 +82,7 @@ Loc StrategicPlayer1::ForceOpponentMistake(const vector<Loc> &empty_lines) {
for (const Loc &loc: empty_lines) {
if (!DoesMoveCreateChain(loc.row, loc.col)) {
return loc; // Choose the first safe move
return loc;
}
}
@ -112,11 +112,11 @@ bool StrategicPlayer1::DoesMoveCreateChain(int row, int col) {
bool creates_chain = false;
if (row % 2 == 0 && col % 2 == 1) {
if (!(row & 1) && col & 1) {
if (CountBoxLines(row - 1, col) == 2 || CountBoxLines(row + 1, col) == 2) {
creates_chain = true;
}
} else if (row % 2 == 1 && col % 2 == 0) {
} else if (row & 1 && !(col & 1)) {
if (CountBoxLines(row, col - 1) == 2 || CountBoxLines(row, col + 1) == 2) {
creates_chain = true;
}
@ -129,10 +129,10 @@ bool StrategicPlayer1::DoesMoveCreateChain(int row, int col) {
int StrategicPlayer1::EvaluateMoveCost(int row, int col) {
int cost = 0;
if (row % 2 == 0 && col % 2 == 1) { // Horizontal line
if (!(row & 1) && col & 1) { // Horizontal line
cost += CountBoxLines(row - 1, col);
cost += CountBoxLines(row + 1, col);
} else if (row % 2 == 1 && col % 2 == 0) { // Vertical line
} else if (row & 1 && !(col & 1)) { // Vertical line
cost += CountBoxLines(row, col - 1);
cost += CountBoxLines(row, col + 1);
}