tmp: add harshit
This commit is contained in:
parent
db8e2596ef
commit
3ecbd34211
122
harshit/custom_player.cxx
Normal file
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
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user