#include <iostream>
#include <string>
#include <climits>
#include <algorithm>
#include <array>
#include <set>
#include <iterator>
#include <numeric>
#include <vector>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <ctime>
#include <cstdio>
#include <iostream>
#include <locale>
#include <cmath>
#include <iomanip>
#include <unordered_map>
#include <sstream>
using namespace std;
enum class Color { WHITE, BLACK };
enum class Type { KING, QUEEN, ROOK, BISHOP, KNIGHT, PAWN, EMPTY };
class CPosition
{
public:
CPosition(long int x, long int y):m_X(x), m_Y(y){};
CPosition():m_X(-1), m_Y(-1){};
CPosition(const CPosition &src):m_X(src.m_X), m_Y(src.m_Y){};
CPosition(CPosition &&src):m_X(src.m_X), m_Y(src.m_Y){};
CPosition& operator = (const CPosition &src);
bool operator == (const CPosition &src) const;
bool operator != (const CPosition &src) const;
long int m_X;
long int m_Y;
};
CPosition& CPosition::operator = (const CPosition &src)
{
if(this == &src)
return *this;
m_X = src.m_X;
m_Y = src.m_Y;
return *this;
}
bool CPosition::operator == (const CPosition &src) const
{
return m_X == src.m_X && m_Y == src.m_Y;
}
bool CPosition::operator != (const CPosition &src) const
{
return !(*this == src);
}
bool operator < (const CPosition& lhs, const CPosition& rhs) {
if (lhs.m_X < rhs.m_X) return true;
if (lhs.m_X > rhs.m_X) return false;
return lhs.m_Y < rhs.m_Y;
}
class CPiece
{
public:
CPiece();
CPiece(Color color, Type type);
CPiece(const CPiece& src);
Color getColor() const;
Type getType() const;
void setType(Type type);
void setColor(Color color);
void print(ostream &os) const;
friend ostream& operator << (ostream &os, const CPiece &piece);
private:
Color m_Color;
Type m_Type;
};
CPiece::CPiece()
: m_Color(Color::WHITE), m_Type(Type::EMPTY)
{
}
CPiece::CPiece(Color color, Type type)
: m_Color(color), m_Type(type)
{
}
CPiece::CPiece(const CPiece& src)
: m_Color(src.m_Color), m_Type(src.m_Type)
{}
Color CPiece::getColor() const
{
return m_Color;
}
Type CPiece::getType() const
{
return m_Type;
}
void CPiece::setType(Type type)
{
m_Type = type;
}
void CPiece::setColor(Color color)
{
m_Color = color;
}
void CPiece::print(ostream &os) const
{
switch(m_Type)
{
case Type::KING: os << (m_Color == Color::WHITE ? "W\u2654" : "B\u265A"); break;
case Type::QUEEN: os << (m_Color == Color::WHITE ? "W\u2655" : "B\u265B"); break;
case Type::ROOK: os << (m_Color == Color::WHITE ? "W\u2656" : "B\u265C"); break;
case Type::BISHOP: os << (m_Color == Color::WHITE ? "W\u2657" : "B\u265D"); break;
case Type::KNIGHT: os << (m_Color == Color::WHITE ? "W\u2658" : "B\u265E"); break;
case Type::PAWN: os << (m_Color == Color::WHITE ? "W\u2659" : "B\u265F"); break;
case Type::EMPTY: os << " "; break;
}
}
ostream& operator << (ostream &os, const CPiece &piece)
{
piece.print(os);
return os;
}
class CBoard
{
public:
CBoard(long int size);
CBoard(const CBoard& other) : m_Board(other.m_Board), m_Size(other.m_Size) {};
void initSimpleChess();
void init5x5Chess();
void init4x4Chess();
vector<CPiece>& operator[](long int index) { return m_Board[index]; }
const vector<CPiece>& operator[](long int index) const { return m_Board[index]; }
long int getSize() const;
void findPossibleMoves(vector<pair<CPosition, CPosition>> &movesWhite, vector<pair<CPosition, CPosition>> &movesBlack, CPosition &whiteKing, CPosition &blackKing);
void findPieceMoves(vector<pair<CPosition, CPosition>> &movesWhite, vector<pair<CPosition, CPosition>> &movesBlack, long int i, long int j, vector<pair<long int, long int>> changes);
bool isPieceUnderAttack(const CPosition& position, Color color, vector<pair<CPosition, CPosition>> &whitePlayable, vector<pair<CPosition, CPosition>> &blackPlayable);
void setQueen(const CPosition &position, Color color);
void makeMove(CPosition &positionFrom, CPosition &positionTo, Color color);
void print(ostream &os) const;
friend ostream& operator<<(ostream &os, const CBoard& board);
private:
vector<vector<CPiece>> m_Board;
long int m_Size;
};
CBoard::CBoard(long int size)
:m_Size(size)
{
m_Board.resize(m_Size);
for(long int i = 0; i < m_Size; i++)
m_Board[i].resize(m_Size);
if(m_Size == 5)
init5x5Chess();
else if (m_Size == 4)
init4x4Chess();
else
initSimpleChess();
}
void CBoard::initSimpleChess()
{
vector<Type> backRow = { Type::ROOK, Type::KNIGHT, Type::BISHOP, Type::QUEEN, Type::KING, Type::BISHOP };
for(long int i = 0; i < m_Size; i++)
{
m_Board[0][i] = CPiece(Color::WHITE, backRow[i]);
m_Board[m_Size-1][i] = CPiece(Color::BLACK, backRow[i]);
m_Board[1][i] = CPiece(Color::WHITE, Type::PAWN);
m_Board[m_Size-2][i] = CPiece(Color::BLACK, Type::PAWN);
}
for(long int i = 2; i < m_Size - 2; i++)
{
for(long int k = 0; k < m_Size; k++)
{
if((i % 2 != 0 && k % 2 == 0) || (i % 2 == 0 && k % 2 != 0))
m_Board[i][k] = CPiece(Color::BLACK, Type::EMPTY);
else
m_Board[i][k] = CPiece(Color::WHITE, Type::EMPTY);
}
}
}
void CBoard::init5x5Chess()
{
vector<Type> backRow = { Type::ROOK, Type::KNIGHT, Type::BISHOP, Type::QUEEN, Type::KING };
for(long int i = 0; i < m_Size; i++)
{
m_Board[0][i] = CPiece(Color::WHITE, backRow[i]);
m_Board[m_Size-1][i] = CPiece(Color::BLACK, backRow[i]);
m_Board[1][i] = CPiece(Color::WHITE, Type::PAWN);
m_Board[m_Size-2][i] = CPiece(Color::BLACK, Type::PAWN);
}
for(long int i = 2; i < m_Size - 2; i++)
{
for(long int k = 0; k < m_Size; k++)
{
if((i % 2 != 0 && k % 2 == 0) || (i % 2 == 0 && k % 2 != 0))
m_Board[i][k] = CPiece(Color::BLACK, Type::EMPTY);
else
m_Board[i][k] = CPiece(Color::WHITE, Type::EMPTY);
}
}
}
void CBoard::init4x4Chess()
{
vector<Type> backRow = { Type::ROOK, Type::BISHOP, Type::QUEEN, Type::KING };
for(long int i = 0; i < m_Size; i++)
{
m_Board[0][i] = CPiece(Color::WHITE, backRow[i]);
m_Board[m_Size-1][i] = CPiece(Color::BLACK, backRow[i]);
m_Board[1][i] = CPiece(Color::WHITE, Type::PAWN);
m_Board[m_Size-2][i] = CPiece(Color::BLACK, Type::PAWN);
}
for(long int i = 2; i < m_Size - 2; i++)
{
for(long int k = 0; k < m_Size; k++)
{
if((i % 2 != 0 && k % 2 == 0) || (i % 2 == 0 && k % 2 != 0))
m_Board[i][k] = CPiece(Color::BLACK, Type::EMPTY);
else
m_Board[i][k] = CPiece(Color::WHITE, Type::EMPTY);
}
}
}
bool CBoard::isPieceUnderAttack(const CPosition& position, Color color, vector<pair<CPosition, CPosition>> &whitePlayable, vector<pair<CPosition, CPosition>> &blackPlayable)
{
const vector<pair<CPosition, CPosition>>& opponentMoves = (color == Color::WHITE) ? blackPlayable : whitePlayable;
for (const auto& move : opponentMoves)
{
if (move.second == position)
{
return true;
}
}
return false;
}
void CBoard::findPieceMoves(vector<pair<CPosition, CPosition>> &movesWhite, vector<pair<CPosition, CPosition>> &movesBlack, long int i, long int j, vector<pair<long int, long int>> changes)
{
if(m_Board[i][j].getType() == Type::PAWN)
{
if(m_Board[i][j].getColor() == Color::WHITE)
{
if(i+1 < m_Size && m_Board[i+1][j].getType() == Type::EMPTY)
movesWhite.push_back({{i,j}, {i+1, j}});
if(i+1 < m_Size && j+1 < m_Size && m_Board[i+1][j+1].getType() != Type::EMPTY && m_Board[i+1][j+1].getColor() != m_Board[i][j].getColor())
movesWhite.push_back({{i,j}, {i+1, j+1}});
if(i+1 < m_Size && j-1 >= 0 && m_Board[i+1][j-1].getType() != Type::EMPTY && m_Board[i+1][j-1].getColor() != m_Board[i][j].getColor())
movesWhite.push_back({{i,j}, {i+1, j-1}});
if(i == 1 && m_Board[i+2][j].getType() == Type::EMPTY && m_Board[i+1][j].getType() == Type::EMPTY)
movesWhite.push_back({{i,j}, {i+2, j}});
}
else if(m_Board[i][j].getColor() == Color::BLACK)
{
if(i-1 >= 0 && m_Board[i-1][j].getType() == Type::EMPTY)
movesBlack.push_back({{i,j}, {i-1, j}});
if(i-1 >=0 && j-1 >=0 && m_Board[i-1][j-1].getType() != Type::EMPTY && m_Board[i-1][j-1].getColor() != m_Board[i][j].getColor())
movesBlack.push_back({{i,j}, {i-1, j-1}});
if(i-1 >= 0 && j+1 < m_Size && m_Board[i-1][j+1].getType() != Type::EMPTY && m_Board[i-1][j+1].getColor() != m_Board[i][j].getColor())
movesBlack.push_back({{i,j}, {i-1, j+1}});
if(i == m_Size-2 && m_Board[i-2][j].getType() == Type::EMPTY && m_Board[i-1][j].getType() == Type::EMPTY)
movesBlack.push_back({{i,j}, {i-2, j}});
}
if(i == m_Size-1 && m_Board[i][j].getColor() == Color::WHITE)
m_Board[i][j].setType(Type::QUEEN);
else if(i == 0 && m_Board[i][j].getColor() == Color::BLACK)
m_Board[i][j].setType(Type::QUEEN);
return;
}
if(m_Board[i][j].getType() == Type::KING)
{
for(auto change : changes)
{
long int iPos = i+change.first;
long int jPos = j+change.second;
if(iPos < m_Size && iPos >= 0 && jPos < m_Size && jPos >= 0)
{
if(m_Board[iPos][jPos].getType() == Type::EMPTY )
{
if(m_Board[i][j].getColor() == Color::WHITE && !isPieceUnderAttack({iPos, jPos}, m_Board[i][j].getColor(), movesWhite, movesBlack))
movesWhite.push_back({{i,j},{iPos, jPos}});
else if(!isPieceUnderAttack({iPos, jPos}, m_Board[i][j].getColor(), movesWhite, movesBlack))
movesBlack.push_back({{i,j},{iPos, jPos}});
}
else
{
if(m_Board[i][j].getColor() == Color::WHITE && m_Board[iPos][jPos].getColor() == Color::BLACK && !isPieceUnderAttack({iPos, jPos}, m_Board[i][j].getColor(), movesWhite, movesBlack))
{
movesWhite.push_back({{i,j},{iPos, jPos}});
}
else if(m_Board[i][j].getColor() == Color::BLACK && m_Board[iPos][jPos].getColor() == Color::WHITE && !isPieceUnderAttack({iPos, jPos}, m_Board[i][j].getColor(), movesWhite, movesBlack))
{
movesBlack.push_back({{i,j},{iPos, jPos}});
}
}
}
}
return;
}
if(m_Board[i][j].getType() == Type::KNIGHT)
{
for(auto change : changes)
{
long int iPos = i+change.first;
long int jPos = j+change.second;
if(iPos < m_Size && iPos >= 0 && jPos < m_Size && jPos >= 0)
{
if(m_Board[iPos][jPos].getType() == Type::EMPTY )
{
if(m_Board[i][j].getColor() == Color::WHITE)
movesWhite.push_back({{i,j},{iPos, jPos}});
else
movesBlack.push_back({{i,j},{iPos, jPos}});
}
else
{
if(m_Board[i][j].getColor() == Color::WHITE && m_Board[iPos][jPos].getColor() == Color::BLACK)
{
movesWhite.push_back({{i,j},{iPos, jPos}});
}
else if(m_Board[i][j].getColor() == Color::BLACK && m_Board[iPos][jPos].getColor() == Color::WHITE)
{
movesBlack.push_back({{i,j},{iPos, jPos}});
}
}
}
}
return;
}
for(auto change : changes)
{
long int iPos = i;
long int jPos = j;
while(iPos + change.first < m_Size && iPos + change.first >= 0 && jPos + change.second < m_Size && jPos + change.second >= 0)
{
iPos += change.first;
jPos += change.second;
if(m_Board[iPos][jPos].getType() == Type::EMPTY)
{
if(m_Board[i][j].getColor() == Color::WHITE)
movesWhite.push_back({{i, j}, {iPos, jPos}});
else
movesBlack.push_back({{i, j}, {iPos, jPos}});
}
else if(m_Board[iPos][jPos].getColor() == m_Board[i][j].getColor())
{
break;
}
else if(m_Board[iPos][jPos].getColor() != m_Board[i][j].getColor())
{
if(m_Board[i][j].getColor() == Color::WHITE)
{
movesWhite.push_back({{i,j}, {iPos, jPos}});
break;
}
else
{
movesBlack.push_back({{i,j}, {iPos, jPos}});
break;
}
}
}
}
}
void CBoard::findPossibleMoves(vector<pair<CPosition, CPosition>> &movesWhite, vector<pair<CPosition, CPosition>> &movesBlack, CPosition &whiteKing, CPosition &blackKing)
{
for(long int i=0; i<m_Size; i++)
{
for(long int j=0; j<m_Size; j++)
{
if(m_Board[i][j].getType() == Type::PAWN)
{
findPieceMoves(movesWhite, movesBlack, i, j, {});
}
else if(m_Board[i][j].getType() == Type::ROOK)
{
findPieceMoves(movesWhite, movesBlack, i, j, {{1, 0}, {-1, 0}, {0, 1}, {0,-1}});
}
else if(m_Board[i][j].getType() == Type::QUEEN)
{
findPieceMoves(movesWhite, movesBlack, i, j, {{1, 0}, {-1, 0}, {0, 1}, {0,-1}, {1, 1}, {-1,-1}, {1, -1}, {-1, 1}});
}
else if(m_Board[i][j].getType() == Type::BISHOP)
{
findPieceMoves(movesWhite, movesBlack, i, j, {{1, 1}, {-1,-1}, {-1, 1}, {1, -1}});
}
else if(m_Board[i][j].getType() == Type::KNIGHT)
{
findPieceMoves(movesWhite, movesBlack, i, j, {{1, 2}, {1, -2}, {2, 1}, {2, -1}, {-1, 2}, {-1, -2}, {-2, 1}, {-2, -1}});
}
else if(m_Board[i][j].getType() == Type::KING)
{
if(m_Board[i][j].getColor() == Color::WHITE)
whiteKing = CPosition(i,j);
else
blackKing = CPosition(i,j);
}
}
}
// if(isPieceUnderAttack(whiteKing, Color::WHITE, movesWhite, movesBlack))
// movesWhite.clear();
// if(isPieceUnderAttack(blackKing, Color::BLACK, movesWhite, movesBlack))
// movesBlack.clear();
findPieceMoves(movesWhite, movesBlack, whiteKing.m_X, whiteKing.m_Y, {{1, 0}, {0, 1}, {1, 1}, {-1, 0}, {0, -1}, {-1, -1}, {-1, 1}, {1, -1}});
findPieceMoves(movesWhite, movesBlack, blackKing.m_X, blackKing.m_Y, {{1, 0}, {0, 1}, {1, 1}, {-1, 0}, {0, -1}, {-1, -1}, {-1, 1}, {1, -1}});
}
long int CBoard::getSize() const
{
return m_Size;
}
void CBoard::print(ostream &os) const
{
// Horizontal line
os << " ";
for (long int i = 0; i < m_Size; ++i) {
os << "-----";
}
os << endl;
for (long int i = m_Size - 1; i >= 0; --i) {
os << setw(2) << i << " |"; // Vertical numbering
for (long int j = 0; j < m_Size; ++j) {
os << " " << m_Board[i][j] << " |";
}
os << endl;
// Horizontal line
os << " ";
for (long int i = 0; i < m_Size; ++i) {
os << "-----";
}
os << endl;
}
os << " ";
for (long int i = 0; i < m_Size; ++i) {
os << setw(5) << i;
}
os << endl;
}
ostream& operator<<(ostream &os, const CBoard& board)
{
board.print(os);
return os;
}
class CGame
{
public:
CGame(const size_t size, const Color player, const Color computer);
void print(ostream &os) const;
friend ostream& operator << (ostream &os, const CGame &game);
void loadMove(Color color);
void makeMove(CPosition &positionFrom, CPosition &positionTo, Color color, bool rec);
int isFinished();
void movesNotAttackKing(bool rec, Color onMove);
void makeRandomMove(Color color);
void minimaxAlphaBeta(int depth, Color color, bool random);
int minimaxAlphaBetaAlg(CGame& game, int depth, int alpha, int beta, bool isMaximizingComputer, Color playerColor);
int evaluateBoard(Color color);
CBoard m_Board;
Color m_Player;
Color m_Computer;
CPosition m_WhiteKing;
CPosition m_BlackKing;
vector<pair<CPosition, CPosition>> m_WhitePlayable;
vector<pair<CPosition, CPosition>> m_BlackPlayable;
};
CGame::CGame(const size_t size, const Color player, const Color computer)
: m_Board(size), m_Player(player), m_Computer(computer)
{
m_WhitePlayable.clear();
m_BlackPlayable.clear();
m_Board.findPossibleMoves(m_WhitePlayable, m_BlackPlayable, m_WhiteKing, m_BlackKing);
}
void CGame::makeMove(CPosition &positionFrom, CPosition &positionTo, Color color, bool rec)
{
CPiece piece = m_Board[positionFrom.m_X][positionFrom.m_Y];
m_Board[positionTo.m_X][positionTo.m_Y] = piece;
m_Board[positionFrom.m_X][positionFrom.m_Y] = CPiece(piece.getColor(), Type::EMPTY);
m_WhitePlayable.clear();
m_BlackPlayable.clear();
m_Board.findPossibleMoves(m_WhitePlayable, m_BlackPlayable, m_WhiteKing, m_BlackKing);
if(rec)
movesNotAttackKing(false, color);
}
void CGame::movesNotAttackKing(bool rec, Color onMove)
{
vector<pair<CPosition, CPosition>> tmp;
if(onMove == Color::BLACK) // tj dalsi tah je BILA
{
for(auto x : m_WhitePlayable)
{
CGame copy = *this;
copy.makeMove(x.first, x.second, Color::WHITE, false);
if(!copy.m_Board.isPieceUnderAttack(copy.m_WhiteKing, Color::WHITE, copy.m_WhitePlayable, copy.m_BlackPlayable))
tmp.push_back(move(x));
}
m_WhitePlayable.clear();
m_WhitePlayable = tmp;
}
else
{
for(auto x : m_BlackPlayable)
{
CGame copy = *this;
copy.makeMove(x.first, x.second, Color::BLACK, false);
if(!copy.m_Board.isPieceUnderAttack(copy.m_BlackKing, Color::BLACK, copy.m_WhitePlayable, copy.m_BlackPlayable))
tmp.push_back(move(x));
}
m_BlackPlayable.clear();
m_BlackPlayable = tmp;
}
}
int CGame::isFinished()
{
if(m_Board.isPieceUnderAttack(m_WhiteKing, Color::WHITE, m_WhitePlayable, m_BlackPlayable) && m_WhitePlayable.empty())
return 1;
if(m_Board.isPieceUnderAttack(m_BlackKing, Color::BLACK, m_WhitePlayable, m_BlackPlayable) && m_BlackPlayable.empty())
return 2;
if(m_BlackPlayable.empty() || m_WhitePlayable.empty())
return 3;
return 0;
}
void CGame::loadMove(Color color)
{
size_t input;
while(cin >> input)
if((color == Color::WHITE && input >=0 && input < m_WhitePlayable.size()) || (color == Color::BLACK && input >=0 && input < m_BlackPlayable.size()))
break;
makeMove(
(color == Color::WHITE ? m_WhitePlayable[input].first : m_BlackPlayable[input].first),
(color == Color::WHITE ? m_WhitePlayable[input].second : m_BlackPlayable[input].second),
(color == Color::WHITE
? (m_Player == Color::WHITE ? m_Player : m_Computer)
: (m_Player == Color::BLACK ? m_Player : m_Computer)),
true
);
}
void CGame::makeRandomMove(Color color)
{
srand(time(nullptr));
if(color == Color::WHITE)
{
int random = rand() % m_WhitePlayable.size();
makeMove(m_WhitePlayable[random].first, m_WhitePlayable[random].second, Color::WHITE, true);
}
else
{
int random = rand() % m_BlackPlayable.size();
makeMove(m_BlackPlayable[random].first, m_BlackPlayable[random].second, Color::BLACK, true);
}
}
void CGame::minimaxAlphaBeta(int depth, Color color, bool random)
{
cout << *this << endl;
while(!isFinished())
{
if(color == m_Player)
{
if(random)
{
makeRandomMove(m_Player);
}
else
{
loadMove(m_Player);
}
cout << *this << endl;
}
else
{
int bestVal = INT_MIN;
CPosition bestFromPosition;
CPosition bestToPosition;
auto& playableMoves = (m_Computer == Color::WHITE) ? m_WhitePlayable : m_BlackPlayable;
for(auto &[from, to] : playableMoves)
{
CGame gameCopy = *this;
gameCopy.makeMove(from, to, m_Computer, true);
int val = gameCopy.minimaxAlphaBetaAlg(gameCopy, depth, INT_MIN, INT_MAX, false, gameCopy.m_Player);
cout << "val: " << val << endl;
if(val > bestVal)
{
bestVal = val;
bestFromPosition = from;
bestToPosition = to;
}
}
makeMove(bestFromPosition, bestToPosition, m_Computer, true);
cout << *this << endl;
}
color = (color == Color::WHITE) ? Color::BLACK : Color::WHITE;
}
}
int CGame::minimaxAlphaBetaAlg(CGame& game, int depth, int alpha, int beta, bool isMaximizingComputer, Color playerColor)
{
if(game.isFinished() || depth == 0)
return game.evaluateBoard(playerColor);
if(isMaximizingComputer)
{
int maxEval = INT_MIN;
auto& playableMoves = (m_Computer == Color::WHITE) ? game.m_WhitePlayable : game.m_BlackPlayable;
for (auto& [from, to] : playableMoves)
{
CGame gameCopy = game;
gameCopy.makeMove(from, to, m_Computer, true);
int eval = gameCopy.minimaxAlphaBetaAlg(gameCopy, depth - 1, alpha, beta, false, m_Player);
maxEval = max(maxEval, eval);
alpha = max(alpha, maxEval);
if(beta <= alpha)
break;
}
return maxEval;
}
else
{
int minEval = INT_MAX;
auto& playableMoves = (m_Player == Color::WHITE) ? game.m_WhitePlayable : game.m_BlackPlayable;
for (auto &[from, to] : playableMoves)
{
CGame gameCopy = game;
gameCopy.makeMove(from, to, m_Player, true);
int eval = gameCopy.minimaxAlphaBetaAlg(gameCopy, depth - 1, alpha, beta, true, m_Computer);
minEval = min(minEval, eval);
beta = min(beta, minEval);
if(beta <= alpha)
break;
}
return minEval;
}
}
int CGame::evaluateBoard(Color color)
{
int eval = 0;
for(long int i = 0; i < m_Board.getSize(); i++)
{
for (long int j = 0; j < m_Board.getSize(); j++)
{
if(m_Board[i][j].getType() == Type::QUEEN)
{
if(m_Board[i][j].getColor() == color)
eval += 50;
else
eval -= 50;
}
else if(m_Board[i][j].getType() == Type::ROOK)
{
if(m_Board[i][j].getColor() == color)
eval += 20;
else
eval -= 20;
}
else if(m_Board[i][j].getType() == Type::KNIGHT)
{
if(m_Board[i][j].getColor() == color)
eval += 10;
else
eval -= 10;
}
else if(m_Board[i][j].getType() == Type::BISHOP)
{
if(m_Board[i][j].getColor() == color)
eval += 10;
else
eval -= 10;
}
else if(m_Board[i][j].getType() == Type::PAWN)
{
if(m_Board[i][j].getColor() == color)
eval += 2;
else
eval -= 2;
}
}
}
if(m_Board.isPieceUnderAttack(m_WhiteKing, Color::WHITE, m_WhitePlayable, m_BlackPlayable) && m_WhitePlayable.empty())
return (color == Color::BLACK) ? eval += 1000 : eval -= 1000;
if(m_Board.isPieceUnderAttack(m_BlackKing, Color::BLACK, m_WhitePlayable, m_BlackPlayable) && m_BlackPlayable.empty())
return (color == Color::WHITE) ? eval += 1000 : eval -= 1000;
return eval;
}
void CGame::print(ostream &os) const
{
os << "White player possible moves:" << endl;
size_t i = 0;
for (const auto& move : m_WhitePlayable)
{
os << i++ << ") " << "From (" << move.first.m_X << ", " << move.first.m_Y << ") to ("
<< move.second.m_X << "," << move.second.m_Y << ")" << endl;
}
os << "Black player possible moves:" << endl;
i=0;
for (const auto& move : m_BlackPlayable)
{
os << i++ << ") " << "From (" << move.first.m_X << ", " << move.first.m_Y << ") to ("
<< move.second.m_X << ", " << move.second.m_Y << ")" << endl;
}
os << m_Board << endl;
}
ostream& operator << (ostream &os, const CGame &game)
{
game.print(os);
return os;
}
int main()
{
CGame game(4, Color::BLACK, Color::WHITE);
game.minimaxAlphaBeta(5, Color::WHITE, true);
} Write, Run & Share C++ code online using OneCompiler's C++ online compiler for free. It's one of the robust, feature-rich online compilers for C++ language, running on the latest version 17. Getting started with the OneCompiler's C++ compiler is simple and pretty fast. The editor shows sample boilerplate code when you choose language as C++ and start coding!
OneCompiler's C++ online compiler supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample program which takes name as input and print your name with hello.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string name;
cout << "Enter name:";
getline (cin, name);
cout << "Hello " << name;
return 0;
}
C++ is a widely used middle-level programming language.
When ever you want to perform a set of operations based on a condition If-Else is used.
if(conditional-expression) {
//code
}
else {
//code
}
You can also use if-else for nested Ifs and If-Else-If ladder when multiple conditions are to be performed on a single variable.
Switch is an alternative to If-Else-If ladder.
switch(conditional-expression){
case value1:
// code
break; // optional
case value2:
// code
break; // optional
......
default:
code to be executed when all the above cases are not matched;
}
For loop is used to iterate a set of statements based on a condition.
for(Initialization; Condition; Increment/decrement){
//code
}
While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.
while (condition) {
// code
}
Do-while is also used to iterate a set of statements based on a condition. It is mostly used when you need to execute the statements atleast once.
do {
// code
} while (condition);
Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increases re-usuability and modularity. Function gets run only when it is called.
return_type function_name(parameters);
function_name (parameters)
return_type function_name(parameters) {
// code
}