Commit 02eedc0b authored by Tyler Ehgoetz's avatar Tyler Ehgoetz
Browse files

Level Four agent added

parent e55bb95e
CXX=g++
CXXFLAGS=-std=c++14 -MMD -g
OBJECTS=bitboard.o debugDisplay.o levelOne.o levelTwo.o levelThree.o game.o main.o position.o subject.o textDisplay.o boardGUI.o window.o
OBJECTS=bitboard.o debugDisplay.o levelOne.o levelTwo.o levelThree.o levelFour.o game.o main.o position.o subject.o textDisplay.o boardGUI.o window.o
DEPENDS=${OBJECTS:.o=.d}
EXEC=kingbit
......
......@@ -3,6 +3,7 @@
#include <vector>
#include <random>
extern const int CHECK;
inline Position::Move levelOneEvaluate(Position p) {
std::vector<Position::Move> moves = p.generateMoves();
......@@ -13,20 +14,21 @@ inline Position::Move levelOneEvaluate(Position p) {
}
inline int levelTwoEvaluate(Position p) {
Color p_side = p.getSideToMove();
int p_val = 0;
int op_val = 0;
int white_val = 0;
int black_val = 0;
for (Piece piece = wP; piece < OFFBOARD; Piece(piece + 1)) {
int num = p.getPieceList(piece).count;
int val = num * PieceVal[piece];
if (PieceColor[piece] == p_side) p_val += val;
else op_val += val;
if (PieceColor[piece] == WHITE) white_val += val;
else black_val += val;
}
p.switchSideToMove(); // switch side to move to see if opponent is in check
if (p.kingInCheck()) p_val += CHECK;
if (p.kingInCheck()) white_val += CHECK; // this will widen the gap and return a better value for either side
return p_val - op_val;
int perspective = (p.getSideToMove() == WHITE) ? 1 : -1;
return (white_val - black_val) * perspective;
}
inline int levelThreeEvaluate(Position p) {
......@@ -38,3 +40,26 @@ inline int levelThreeEvaluate(Position p) {
}
return val;
}
inline int levelFourEvaluate(int depth, int alpha, int beta, Position p) {
if (depth == 0) {
return levelTwoEvaluate(p);
}
std::vector<Position::Move> moves = p.generateMoves();
if (p.isCheckmate()) return std::numeric_limits<int>::min();
if (p.isStalemate()) return 0;
for (auto m : moves) {
p.makeMove(m);
int evaluation = -levelFourEvaluate(depth - 1, -beta, -alpha, p);
p.undoLastMove();
// Move was too good and the opponent will avoid this position
// skip remaining moves
if (evaluation >= beta) return beta;
alpha = std::max(alpha, evaluation);
}
return alpha;
}
......@@ -4,6 +4,7 @@
#include "levelOne.h"
#include "levelTwo.h"
#include "levelThree.h"
#include "levelFour.h"
#include <string>
#include <sstream>
#include <iostream>
......@@ -152,7 +153,7 @@ void Game::setPlayer(std::string player, int i) {
if (player.back() == '1') agents[i] = std::make_unique<LevelOne>();
else if (player.back() == '2') agents[i] = std::make_unique<LevelTwo>();
else if (player.back() == '3') agents[i] = std::make_unique<LevelThree>();
else ;
else agents[i] = std::make_unique<LevelFour>();
}
}
......
......@@ -50,17 +50,20 @@ class Game: public Subject {
void standardPosition();
// Makes the human players move that has been specified
// Takes in a promotion piece if the move is a pawn promotion
void makePlayerMove(Square, Square, Piece);
// Makes a computer player move
void makeComputerMove(Color);
// makeMove executed the given move on the current position
// makeMove executes the given move on the current position
void makeMove(Position::Move);
// Undos the number of moves specified
void undoMoves(int);
// Sets the player type specified by string as the player
// white or balck specified by int
void setPlayer(std::string, int);
};
......
#include "levelFour.h"
#include "position.h"
#include "algorithms.h"
#include <vector>
#include <algorithm>
#include <limits>
Position::Move LevelFour::search(Position p) {
std::vector<Position::Move> moves = p.generateMoves();
std::vector<int> values;
for (auto m : moves) {
// make a copy for the move
Position copy{p};
copy.makeMove(m);
// If there is a checkmate move then make it.
if (copy.isCheckmate()) return m;
values.push_back(levelFourEvaluate(depth, std::numeric_limits<int>::min(), std::numeric_limits<int>::max(), copy));
}
int index;
if (p.getSideToMove() == WHITE) index = std::max_element(values.begin(), values.end()) - values.begin();
else index = std::min_element(values.begin(),values.end()) - values.begin();
return moves.at(index);
}
#ifndef LEVEL_FOUR_H
#define LEVEL_FOUR_H
#include "position.h"
#include "agent.h"
#include "piece.h"
const int DEFAULT_DEPTH = 3;
class LevelFour: public Agent {
int depth;
public:
LevelFour() : depth{DEFAULT_DEPTH} {};
LevelFour(int depth) : depth{depth} {};
Position::Move search(Position p) override;
};
#endif
......@@ -4,8 +4,6 @@
#include "agent.h"
#include "piece.h"
extern const int CHECK;
class LevelThree: public Agent {
public:
Position::Move search(Position p) override;
......
......@@ -4,8 +4,6 @@
#include "agent.h"
#include "piece.h"
extern const int CHECK;
class LevelTwo: public Agent {
public:
Position::Move search(Position p) override;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment