//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#include <algorithm>
#include <cassert>
#include <iostream>
#include <stdexcept>
//---------------------------------------------------------------------------
//#include <boost/bind.hpp>
#include <boost/foreach.hpp>
//#include <boost/lambda/lambda.hpp>
//---------------------------------------------------------------------------
#include "chessboard.h"
//#include "chessmove.h"
#include "chesspiece.h"
#include "trace.h"
//---------------------------------------------------------------------------
namespace Chess {
//---------------------------------------------------------------------------
Board2d::Board2d()
: m_pieces(GetInitialSetup())
{
}
//---------------------------------------------------------------------------
///Find a chesspiece on a certain square
const Board2d::PiecePtr Board2d::Find(const Square& square) const
{
auto p = std::find_if(m_pieces.begin(),m_pieces.end(),
[square](const PiecePtr& p) { return p->GetSquare() == square; } );
if (p == m_pieces.end()) return PiecePtr(new PieceEmpty);
else return *p;
}
//---------------------------------------------------------------------------
Color Board2d::GetActivePlayer() const
{
return (m_moves.size() % 2 ? Color::black : Color::white);
}
//---------------------------------------------------------------------------
Color Board2d::GetColor(const Square& s) const
{
return this->Find(s)->GetColor();
}
//---------------------------------------------------------------------------
const Board2d::Pieces Board2d::GetInitialSetup()
{
//C++0x initializer list
Board2d::Pieces v =
{
PiecePtr(new PieceRook(Color::white,Square(0,0))),
PiecePtr(new PieceKnight(Color::white,Square(1,0))),
PiecePtr(new PieceBishop(Color::white,Square(2,0))),
PiecePtr(new PieceQueen(Color::white,Square(3,0))),
PiecePtr(new PieceKing(Color::white,Square(4,0))),
PiecePtr(new PieceBishop(Color::white,Square(5,0))),
PiecePtr(new PieceKnight(Color::white,Square(6,0))),
PiecePtr(new PieceRook(Color::white,Square(7,0))),
PiecePtr(new PiecePawn(Color::white,Square(0,1))),
PiecePtr(new PiecePawn(Color::white,Square(1,1))),
PiecePtr(new PiecePawn(Color::white,Square(2,1))),
PiecePtr(new PiecePawn(Color::white,Square(3,1))),
PiecePtr(new PiecePawn(Color::white,Square(4,1))),
PiecePtr(new PiecePawn(Color::white,Square(5,1))),
PiecePtr(new PiecePawn(Color::white,Square(6,1))),
PiecePtr(new PiecePawn(Color::white,Square(7,1))),
PiecePtr(new PieceRook(Color::black,Square(0,7))),
PiecePtr(new PieceKnight(Color::black,Square(1,7))),
PiecePtr(new PieceBishop(Color::black,Square(2,7))),
PiecePtr(new PieceQueen(Color::black,Square(3,7))),
PiecePtr(new PieceKing(Color::black,Square(4,7))),
PiecePtr(new PieceBishop(Color::black,Square(5,7))),
PiecePtr(new PieceKnight(Color::black,Square(6,7))),
PiecePtr(new PieceRook(Color::black,Square(7,7))),
PiecePtr(new PiecePawn(Color::black,Square(0,6))),
PiecePtr(new PiecePawn(Color::black,Square(1,6))),
PiecePtr(new PiecePawn(Color::black,Square(2,6))),
PiecePtr(new PiecePawn(Color::black,Square(3,6))),
PiecePtr(new PiecePawn(Color::black,Square(4,6))),
PiecePtr(new PiecePawn(Color::black,Square(5,6))),
PiecePtr(new PiecePawn(Color::black,Square(6,6))),
PiecePtr(new PiecePawn(Color::black,Square(7,6)))
};
return v;
}
//---------------------------------------------------------------------------
/*
const boost::tribool Board2d::HasColor(
const Square& s,
const Color& c) const
{
if (IsType<Empty>(s)) return boost::logic::indeterminate;
const auto piece = this->Find(s).get();
assert(piece);
return boost::tribool(piece->GetColor() == c);
}
*/
//---------------------------------------------------------------------------
/*
const Piece Board2d::GetPiece(const int x, const int y) const
{
return mPieces[x][y];
}
//---------------------------------------------------------------------------
void Board2d::SetPiece(const Piece& piece, const int x, const int y)
{
mPieces[x][y] = piece;
assert(this->GetPiece(x,y) == piece);
}
//---------------------------------------------------------------------------
bool Board2d::IsGameOver() const
{
bool whiteHasKing = false;
bool blackHasKing = false;
for (int y=0; y!=8; ++y)
{
for (int x=0; x!=8; ++x)
{
const Piece piece = this->GetPiece(x,y);
if (piece.IsNull()==false && piece.GetType()==Piece::king)
{
if (piece.GetColor() == Piece::white)
whiteHasKing = true;
else
blackHasKing = true;
}
}
}
return (whiteHasKing == false || blackHasKing == false);
}
//---------------------------------------------------------------------------
Piece::Color Board2d::GetWinner() const
{
assert(this->IsGameOver()==true);
for (int y=0; y!=8; ++y)
{
for (int x=0; x!=8; ++x)
{
const Piece piece = this->GetPiece(x,y);
if (piece.GetType()==Piece::king)
{
if (piece.GetColor() == Piece::white)
return Piece::white;
else
return Piece::black;
}
}
}
assert(!"Should not get here");
throw std::logic_error("Cannot find winner");
}
//---------------------------------------------------------------------------
bool Board2d::CanDoMove(const Move& move) const
{
const Piece piece = this->GetPiece(move.GetX1(),move.GetY1());
//Is there a chesspiece?
if (piece.IsNull())
{
TRACE("Invalid move: source square is empty");
return false;
}
//Is it of the right type?
if (piece.GetType()!=move.GetType())
{
TRACE("Invalid move: difference between piece on square and in move");
return false;
}
//Is it of the right color? ->Checked by ChessGame
//Is the destination free or is there an enemy?
const Piece destination = this->GetPiece(move.GetX2(),move.GetY2());
if ( destination.IsNull()
&& move.GetIsCapture())
{
TRACE("Invalid move: cannot capture a free space");
return false; //Free space && capture
}
if (!destination.IsNull())
{
//Cannot capture own pieces
if (destination.GetColor()==piece.GetColor())
{
TRACE("Invalid move: cannot capture own piece");
return false;
}
if (destination.GetColor()!=piece.GetColor()
&& move.GetIsCapture() == false)
{
TRACE("Invalid move: cannot move on enemy without capture");
return false; //An enemy && no capture
}
}
return this->IsValidMove(move);
}
//---------------------------------------------------------------------------
void Board2d::DoMove(const Move& move)
{
assert(this->CanDoMove(move)==true);
const Piece piece = this->GetPiece(move.GetX1(),move.GetY1());
if (piece.GetType()==Piece::king
&& move.GetX1() == 4
&& (move.GetX2() == 2 || move.GetX2() == 6) )
{
const Piece::Color color = piece.GetColor();
assert( (color == Piece::white && move.GetY1() == 0 && move.GetY2() == 0)
|| (color == Piece::black && move.GetY1() == 7 && move.GetY2() == 7) );
const int y = move.GetY2();
//Castling
if (move.GetX2() == 2)
{
//Castling long
this->SetPiece(Piece(color,Piece::king),2,y); //Move King
this->SetPiece(Piece(color,Piece::rook),3,y); //Move rook
this->SetPiece(Piece(),4,y); //Erase old king
this->SetPiece(Piece(),0,y); //Erase old rook
}
else
{
//Castling short
this->SetPiece(Piece(color,Piece::king),6,y); //Move King
this->SetPiece(Piece(color,Piece::rook),5,y); //Move rook
this->SetPiece(Piece(),4,y); //Erase old king
this->SetPiece(Piece(),7,y); //Erase old rook
}
}
else if (piece.GetType()==Piece::pawn
&& this->GetPiece(move.GetX2(),move.GetY2()).IsNull()==true
&& move.GetX1() != move.GetX2()
&& move.GetY1() != move.GetY2())
{
//En passant
this->SetPiece(Piece(piece.GetColor(),Piece::pawn),move.GetX2(),move.GetY2()); //Move pawn
this->SetPiece(Piece(),move.GetX1(),move.GetY1()); //Erase old pawn
this->SetPiece(Piece(),move.GetX2(),move.GetY1()); //Capture pawn
}
else if (piece.GetType()==Piece::pawn
&& (move.GetY2() == 0 || move.GetY2() == 7) )
{
//Promotion to queen
this->SetPiece(Piece(),move.GetX1(),move.GetY1()); //Overwrite old piece by NullType
this->SetPiece(Piece(piece.GetColor(),Piece::queen),move.GetX2(),move.GetY2());
}
else
{
//Regular move (i.e. non-castling)
this->SetPiece(Piece(),move.GetX1(),move.GetY1()); //Overwrite old piece by NullType
this->SetPiece(piece,move.GetX2(),move.GetY2());
}
mMoves.push_back(move);
}
//---------------------------------------------------------------------------
bool Board2d::CanDoCastlingShort(const Piece::Color color) const
{
//Determine the y
const int y = (color == Piece::white ? 0 : 7);
//King must be in place
if(this->GetPiece(4,y).GetType() != Piece::king) return false;
//Is the rook in place?
if(this->GetPiece(7,y).GetType() != Piece::rook) return false;
//Is nothing in between?
if(this->GetPiece(5,y).IsNull() == false) return false;
if(this->GetPiece(6,y).IsNull() == false) return false;
typedef std::vector<Move>::const_iterator Iter;
const Iter j = mMoves.end();
for (Iter i = mMoves.begin(); i!=j; ++i)
{
//Check if king has moved
if ( (*i).GetType() == Piece::king && (*i).GetY1() == y) return false;
//Check if kingside rook has moved
if ( (*i).GetType() == Piece::rook && (*i).GetY1() == y && (*i).GetX1() == 7) return false;
}
return true;
}
//---------------------------------------------------------------------------
bool Board2d::CanDoCastlingLong(const Piece::Color color) const
{
//Determine the y
const int y = (color == Piece::white ? 0 : 7);
//King must be in place
if(this->GetPiece(4,y).GetType() != Piece::king) return false;
//Is the rook in place?
if(this->GetPiece(0,y).GetType() != Piece::rook) return false;
//Is nothing in between?
if(this->GetPiece(1,y).IsNull() == false) return false;
if(this->GetPiece(2,y).IsNull() == false) return false;
if(this->GetPiece(3,y).IsNull() == false) return false;
typedef std::vector<Move>::const_iterator Iter;
const Iter j = mMoves.end();
for (Iter i = mMoves.begin(); i!=j; ++i)
{
//Check if king has moved
if ( (*i).GetType() == Piece::king && (*i).GetY1() == y) return false;
//Check if kingside rook has moved
if ( (*i).GetType() == Piece::rook && (*i).GetY1() == y && (*i).GetX1() == 0) return false;
}
return true;
}
//---------------------------------------------------------------------------
//Color denotes the player who's turn it is, i.e. the player looking at the board
void Board2d::CoutPieces(
const Piece::Color color) const
{
const int yBegin = (color == Piece::black ? 0 : 7);
const int yEnd = (color == Piece::black ? 8 : -1);
const int yStep = (color == Piece::black ? 1 : -1);
const int xBegin = (color == Piece::white ? 0 : 7);
const int xEnd = (color == Piece::white ? 8 : -1);
const int xStep = (color == Piece::white ? 1 : -1);
if (color == Piece::white)
std::cout << " A B C D E F G H " << std::endl;
else
std::cout << " H G F E D C B A " << std::endl;
for (int y=yBegin; y!=yEnd; y+=yStep)
{
std::cout << " -------------------------" << std::endl;
std::cout << (y+1) << " ";
for (int x=xBegin; x!=xEnd; x+=xStep)
{
std::cout << "|" << this->GetPiece(x,y);
}
std::cout << "| " << (y+1) << std::endl;
}
std::cout << " -------------------------" << std::endl;
if (color == Piece::white)
std::cout << " A B C D E F G H " << std::endl;
else
std::cout << " H G F E D C B A " << std::endl;
}
//---------------------------------------------------------------------------
//Color denotes the player who's turn it is, i.e. the player looking at the board
void Board2d::CoutSight(
const Piece::Color color) const
{
//
const BoardVisibleType inSight = this->GetInSight(color);
const int yBegin = (color == Piece::black ? 0 : 7);
const int yEnd = (color == Piece::black ? 8 : -1);
const int yStep = (color == Piece::black ? 1 : -1);
const int xBegin = (color == Piece::white ? 0 : 7);
const int xEnd = (color == Piece::white ? 8 : -1);
const int xStep = (color == Piece::white ? 1 : -1);
if (color == Piece::white)
std::cout << " A B C D E F G H " << std::endl;
else
std::cout << " H G F E D C B A " << std::endl;
for (int y=yBegin; y!=yEnd; y+=yStep)
{
std::cout << " -------------------------" << std::endl;
std::cout << (y+1) << " ";
for (int x=xBegin; x!=xEnd; x+=xStep)
{
std::cout << "|" << (inSight[x][y]==true ? this->GetPiece(x,y) : Piece() );
}
std::cout << "| " << (y+1) << std::endl;
}
std::cout << " -------------------------" << std::endl;
if (color == Piece::white)
std::cout << " A B C D E F G H " << std::endl;
else
std::cout << " H G F E D C B A " << std::endl;
}
//---------------------------------------------------------------------------
const Board2d::BoardVisibleType Board2d::GetInSight(const Piece::Color color) const
{
BoardVisibleType inSight(boost::extents[8][8]);
for (int y=0; y!=8; ++y)
{
for (int x=0; x!=8; ++x)
{
inSight[x][y] = false;
}
}
for (int y=0; y!=8; ++y)
{
for (int x=0; x!=8; ++x)
{
//Get the piece there
const Piece piece = this->GetPiece(x,y);
//Empty or occupied by enemy? Then continue
if (piece.IsNull()==true || piece.GetColor()!=color) continue;
//Occupied by this color
inSight[x][y] = true;
//Then get all its valid moves
const std::vector<Move> moves = this->GetAllValidMoves(x,y);
const std::vector<Move>::const_iterator j = moves.end();
for (std::vector<Move>::const_iterator i = moves.begin(); i!=j; ++i)
{
inSight[(*i).GetX2()][(*i).GetY2()] = true;
}
//Special treatment of pawns
if (piece.GetType() == Piece::pawn)
{
if (piece.GetColor()== Piece::white)
{
//Always look a single square forward
inSight[x][y+1] = true;
//Look two squares forward, if the first is not occupied
if (y==1 && GetPiece(x,y+1).IsNull()==true)
{
inSight[x][y+2] = true;
}
//Look sideways left
if (x > 0 && GetPiece(x-1,y+1).IsNull()==true)
{
inSight[x-1][y+1] = true;
}
//Look sideways right
if (x < 7 && GetPiece(x+1,y+1).IsNull()==true)
{
inSight[x+1][y+1] = true;
}
//Look sideways if en passant is possible
if (y == 4 //4th row
&& this->mMoves.back().GetType() == Piece::pawn //Black moved a pawn
&& this->mMoves.back().GetY1() == 6 //Black moved two places
&& this->mMoves.back().GetY2() == 4) //Black moved two places
{
if (this->mMoves.back().GetX1() == x-1)
inSight[x-1][y] = true;
else if (this->mMoves.back().GetX1() == x+1)
inSight[x+1][y] = true;
}
}
else
{
//Always look a single square forward
inSight[x][y-1] = true;
//Look two squares forward, if the first is not occupied
if (y==6 && GetPiece(x,y-1).IsNull()==true)
{
inSight[x][y-2] = true;
}
//Look sideways left
if (x > 0 && GetPiece(x-1,y-1).IsNull()==true)
{
inSight[x-1][y-1] = true;
}
//Look sideways right
if (x < 7 && GetPiece(x+1,y-1).IsNull()==true)
{
inSight[x+1][y-1] = true;
}
//Look sideways if en passant is possible
if (y == 3 //3rd row
&& this->mMoves.back().GetType() == Piece::pawn //White moved a pawn
&& this->mMoves.back().GetY1() == 1 //White moved two places
&& this->mMoves.back().GetY2() == 3) //White moved two places
{
if (this->mMoves.back().GetX1() == x-1)
inSight[x-1][y] = true;
else if (this->mMoves.back().GetX1() == x+1)
inSight[x+1][y] = true;
}
}
}
}
}
return inSight;
}
//---------------------------------------------------------------------------
bool Board2d::IsValidMove(const Move& move) const
{
const std::vector<Move> moves = this->GetAllValidMoves(move.GetX1(), move.GetY1());
if (std::find(moves.begin(),moves.end(),move)!=moves.end())
return true;
else
{
TRACE("Invalid move: IsValidMove");
return false;
}
}
//---------------------------------------------------------------------------
const std::vector<Move> Board2d::GetAllPossibleMoves(
const Piece::Color whoseTurn) const
{
std::vector<Move> allMoves;
for (int y=0; y!=8; ++y)
{
for (int x=0; x!=8; ++x)
{
if (this->GetPiece(x,y).IsNull() == false
&& this->GetPiece(x,y).GetColor()==whoseTurn)
{
//Get all valid moves of this player's piece here
const std::vector<Move> thisPieceMoves = GetAllValidMoves(x,y);
//Append it to allMoves
std::copy(
thisPieceMoves.begin(),thisPieceMoves.end(),
std::back_inserter(allMoves));
}
}
}
return allMoves;
}
//---------------------------------------------------------------------------
///GetAllValidMoves returns all valid move for a piece
///at a certain square. If there is no piece present,
///or if there are no valid moves, an empty std::vector
///is returned;
const std::vector<Move> Board2d::GetAllValidMoves(
const int x, const int y) const
{
const Piece piece = GetPiece(x,y);
if (piece.IsNull())
{
return std::vector<Move>();
}
switch (piece.GetType())
{
case Piece::pawn : return GetAllValidMovesPawn(x,y);
case Piece::knight: return GetAllValidMovesKnight(x,y);
case Piece::bishop: return GetAllValidMovesBishop(x,y);
case Piece::rook : return GetAllValidMovesRook(x,y);
case Piece::queen : return GetAllValidMovesQueen(x,y);
case Piece::king : return GetAllValidMovesKing(x,y);
default: assert(!"Should not get here");
}
assert(!"Should not get here");
throw std::logic_error("Unknown EnumPieceType");
}
//---------------------------------------------------------------------------
const std::vector<Move> Board2d::GetAllValidMovesPawn(
const int x, const int y) const
{
const Piece piece = GetPiece(x,y);
assert(piece.IsNull()==false);
assert(piece.GetType() == Piece::pawn);
std::vector<Move> moves;
if (piece.GetColor()==Piece::white)
{
//Move single square forward
if (GetPiece(x,y+1).IsNull()==true)
{
moves.push_back(
Move(
Piece::pawn,
Square(x,y),
false,
Square(x,y+1)));
}
//Move two squares forward
if (y==1
&& GetPiece(x,y+1).IsNull()==true
&& GetPiece(x,y+2).IsNull()==true)
{
moves.push_back(
Move(
Piece::pawn,
Square(x,y),
false,
Square(x,y+2)));
}
//Capture left
if (x > 0
&& GetPiece(x-1,y+1).IsNull()==false
&& GetPiece(x-1,y+1).GetColor()==Piece::black)
{
moves.push_back(
Move(
Piece::pawn,
Square(x,y),
true,
Square(x-1,y+1)));
}
//Capture right
if (x < 7
&& GetPiece(x+1,y+1).IsNull()==false
&& GetPiece(x+1,y+1).GetColor()==Piece::black)
{
moves.push_back(
Move(
Piece::pawn,
Square(x,y),
true,
Square(x+1,y+1)));
}
//En passant
if (y == 4
&& mMoves.back().GetY1() == 6 //Black had moved two squares
&& mMoves.back().GetY2() == 4)
{
if (mMoves.back().GetX1() == x - 1) //To the left
{
//Note: En passant is not regarded as a capture, as the spot moved to is empty
moves.push_back(
Move(
Piece::pawn,
Square(x,y),
false, //note
Square(x-1,y+1)));
}
else if (mMoves.back().GetX1() == x + 1) //To the right
{
//Note: En passant is not regarded as a capture, as the spot moved to is empty
moves.push_back(
Move(
Piece::pawn,
Square(x,y),
false, // note
Square(x+1,y+1)));
}
}
}
else
{
//Move single square forward
if (GetPiece(x,y-1).IsNull()==true)
{
moves.push_back(
Move(
Piece::pawn,
Square(x,y),
false,
Square(x,y-1)));
}
//Move two squares forward
if (y==6
&& GetPiece(x,y-1).IsNull()==true
&& GetPiece(x,y-2).IsNull()==true)
{
moves.push_back(
Move(
Piece::pawn,
Square(x,y),
false,
Square(x,y-2)));
}
//Capture left
if (x > 0
&& GetPiece(x-1,y-1).IsNull()==false
&& GetPiece(x-1,y-1).GetColor()==Piece::white)
{
moves.push_back(
Move(
Piece::pawn,
Square(x,y),
true,
Square(x-1,y-1)));
}
//Capture right
if (x < 7
&& GetPiece(x+1,y-1).IsNull()==false
&& GetPiece(x+1,y-1).GetColor()==Piece::white)
{
moves.push_back(
Move(
Piece::pawn,
Square(x,y),
true,
Square(x+1,y-1)));
}
//En passant
if (y == 3
&& mMoves.back().GetY1() == 1 //White had moved two squares
&& mMoves.back().GetY2() == 3)
{
if (mMoves.back().GetX1() == x - 1) //To the left
{
//Note: En passant is not regarded as a capture, as the spot moved to is empty
moves.push_back(
Move(
Piece::pawn,
Square(x,y),
false, //note
Square(x-1,y-1)));
}
else if (mMoves.back().GetX1() == x + 1) //To the right
{
//Note: En passant is not regarded as a capture, as the spot moved to is empty
moves.push_back(
Move(
Piece::pawn,
Square(x,y),
false, //note
Square(x+1,y-1)));
}
}
}
return moves;
}
//---------------------------------------------------------------------------
const std::vector<Move> Board2d::GetAllValidMovesKnight(
const int x, const int y) const
{
const Piece piece = GetPiece(x,y);
assert(piece.IsNull()==false);
assert(piece.GetType() == Piece::knight);
std::vector<Move> moves;
//-2 -1
if (x > 1 && y > 0)
{
//Is it a capture?
if (GetPiece(x-2,y-1).IsNull() == true)
{
moves.push_back(
Move(
Piece::knight,
Square(x,y),
false,
Square(x-2,y-1))); //No capture
}
else if (GetPiece(x-2,y-1).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::knight,
Square(x,y),
true,
Square(x-2,y-1))); //Capture of enemy
}
}
//-1 -2
if (x > 0 && y > 1)
{
//Is it a capture?
if (GetPiece(x-1,y-2).IsNull() == true)
{
moves.push_back(
Move(
Piece::knight,
Square(x,y),
false,
Square(x-1,y-2))); //No capture
}
else if (GetPiece(x-1,y-2).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::knight,
Square(x,y),
true,
Square(x-1,y-2))); //Capture of enemy
}
}
//+2 -1
if (x < 6 && y > 0)
{
//Is it a capture?
if (GetPiece(x+2,y-1).IsNull() == true)
{
moves.push_back(
Move(
Piece::knight,
Square(x,y),
false,
Square(x+2,y-1))); //No capture
}
else if (GetPiece(x+2,y-1).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::knight,
Square(x,y),
true,
Square(x+2,y-1))); //Capture of enemy
}
}
//-1 +2
if (x > 0 && y < 6)
{
//Is it a capture?
if (GetPiece(x-1,y+2).IsNull() == true)
{
moves.push_back(
Move(
Piece::knight,
Square(x,y),
false,
Square(x-1,y+2))); //No capture
}
else if (GetPiece(x-1,y+2).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::knight,
Square(x,y),
true,
Square(x-1,y+2))); //Capture of enemy
}
}
//-2 +1
if (x > 1 && y < 7)
{
//Is it a capture?
if (GetPiece(x-2,y+1).IsNull() == true)
{
moves.push_back(
Move(
Piece::knight,
Square(x,y),
false,
Square(x-2,y+1))); //No capture
}
else if (GetPiece(x-2,y+1).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::knight,
Square(x,y),
true,
Square(x-2,y+1))); //Capture of enemy
}
}
//+1 -2
if (x < 7 && y > 1)
{
//Is it a capture?
if (GetPiece(x+1,y-2).IsNull() == true)
{
moves.push_back(
Move(
Piece::knight,
Square(x,y),
false,
Square(x+1,y-2))); //No capture
}
else if (GetPiece(x+1,y-2).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::knight,
Square(x,y),
true,
Square(x+1,y-2))); //Capture of enemy
}
}
//+2 +1
if (x < 6 && y < 7)
{
//Is it a capture?
if (GetPiece(x+2,y+1).IsNull() == true)
{
moves.push_back(
Move(
Piece::knight,
Square(x,y),
false,
Square(x+2,y+1))); //No capture
}
else if (GetPiece(x+2,y+1).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::knight,
Square(x,y),
true,
Square(x+2,y+1))); //Capture of enemy
}
}
//+1 +2
if (x < 7 && y < 6)
{
//Is it a capture?
if (GetPiece(x+1,y+2).IsNull() == true)
{
moves.push_back(
Move(
Piece::knight,
Square(x,y),
false,
Square(x+1,y+2))); //No capture
}
else if (GetPiece(x+1,y+2).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::knight,
Square(x,y),
true,
Square(x+1,y+2))); //Capture of enemy
}
}
return moves;
}
//---------------------------------------------------------------------------
const std::vector<Move> Board2d::GetAllValidMovesBishop(
const int x, const int y) const
{
const Piece piece = GetPiece(x,y);
assert(piece.IsNull()==false);
assert(piece.GetType() == Piece::bishop);
std::vector<Move> moves;
//+x +x
for (int i=1; x+i<8 && y+i<8; ++i)
{
//Is it a capture
if (GetPiece(x+i,y+i).IsNull() == true)
{
moves.push_back(
Move(
Piece::bishop,
Square(x,y),
false,
Square(x+i,y+i))); //No capture
}
else if (GetPiece(x+i,y+i).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::bishop,
Square(x,y),
true,
Square(x+i,y+i))); //Capture of enemy
break;
}
else
{
break; //Own color
}
}
//-x +x
for (int i=1; x-i>-1 && y+i<8; ++i)
{
//Is it a capture
if (GetPiece(x-i,y+i).IsNull() == true)
{
moves.push_back(
Move(
Piece::bishop,
Square(x,y),
false,
Square(x-i,y+i))); //No capture
}
else if (GetPiece(x-i,y+i).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::bishop,
Square(x,y),
true,
Square(x-i,y+i))); //Capture of enemy
break;
}
else
{
break; //Own color
}
}
//+x -x
for (int i=1; x+i<8 && y-i>-1; ++i)
{
//Is it a capture
if (GetPiece(x+i,y-i).IsNull() == true)
{
moves.push_back(
Move(
Piece::bishop,
Square(x,y),
false,
Square(x+i,y-i))); //No capture
}
else if (GetPiece(x+i,y-i).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::bishop,
Square(x,y),
true,
Square(x+i,y-i))); //Capture of enemy
break;
}
else
{
break; //Own color
}
}
//-x -x
for (int i=1; x-i>-1 && y-i>-1; ++i)
{
//Is it a capture
if (GetPiece(x-i,y-i).IsNull() == true)
{
moves.push_back(
Move(
Piece::bishop,
Square(x,y),
false,
Square(x-i,y-i))); //No capture
}
else if (GetPiece(x-i,y-i).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::bishop,
Square(x,y),
true,
Square(x-i,y-i))); //Capture of enemy
break;
}
else
{
break; //Own color
}
}
return moves;
}
//---------------------------------------------------------------------------
const std::vector<Move> Board2d::GetAllValidMovesRook(
const int x, const int y) const
{
const Piece piece = GetPiece(x,y);
assert(piece.IsNull()==false);
assert(piece.GetType() == Piece::rook);
std::vector<Move> moves;
//+x +0
for (int i=1; x+i<8; ++i)
{
//Is it a capture
if (GetPiece(x+i,y+0).IsNull() == true)
{
moves.push_back(
Move(
Piece::rook,
Square(x,y),
false,
Square(x+i,y+0))); //No capture
}
else if (GetPiece(x+i,y+0).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::rook,
Square(x,y),
true,
Square(x+i,y+0))); //Capture of enemy
break;
}
else
{
break; //Own color
}
}
//-x +0
for (int i=1; x-i>-1; ++i)
{
//Is it a capture
if (GetPiece(x-i,y+0).IsNull() == true)
{
moves.push_back(
Move(
Piece::rook,
Square(x,y),
false,
Square(x-i,y+0))); //No capture
}
else if (GetPiece(x-i,y+0).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::rook,
Square(x,y),
true,
Square(x-i,y+0))); //Capture of enemy
break;
}
else
{
break; //Own color
}
}
//+0 +x
for (int i=1; y+i<8; ++i)
{
//Is it a capture
if (GetPiece(x+0,y+i).IsNull() == true)
{
moves.push_back(
Move(
Piece::rook,
Square(x,y),
false,
Square(x+0,y+i))); //No capture
}
else if (GetPiece(x+0,y+i).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::rook,
Square(x,y),
true,
Square(x+0,y+i))); //Capture of enemy
break;
}
else
{
break; //Own color
}
}
//+0 -x
for (int i=1; y-i>-1; ++i)
{
//Is it a capture
if (GetPiece(x-0,y-i).IsNull() == true)
{
moves.push_back(
Move(
Piece::rook,
Square(x,y),
false,
Square(x-0,y-i))); //No capture
}
else if (GetPiece(x-0,y-i).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::rook,
Square(x,y),
true,
Square(x-0,y-i))); //Capture of enemy
break;
}
else
{
break; //Own color
}
}
return moves;
}
//---------------------------------------------------------------------------
const std::vector<Move> Board2d::GetAllValidMovesQueen(
const int x, const int y) const
{
const Piece piece = GetPiece(x,y);
assert(piece.IsNull()==false);
assert(piece.GetType() == Piece::queen);
std::vector<Move> moves;
//+x +x
for (int i=1; x+i<8 && y+i<8; ++i)
{
//Is it a capture
if (GetPiece(x+i,y+i).IsNull() == true)
{
moves.push_back(
Move(
Piece::queen,
Square(x,y),
false,
Square(x+i,y+i))); //No capture
}
else if (GetPiece(x+i,y+i).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::queen,
Square(x,y),
true,
Square(x+i,y+i))); //Capture of enemy
break;
}
else
{
break; //Own color
}
}
//-x +x
for (int i=1; x-i>-1 && y+i<8; ++i)
{
//Is it a capture
if (GetPiece(x-i,y+i).IsNull() == true)
{
moves.push_back(
Move(
Piece::queen,
Square(x,y),
false,
Square(x-i,y+i))); //No capture
}
else if (GetPiece(x-i,y+i).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::queen,
Square(x,y),
true,
Square(x-i,y+i))); //Capture of enemy
break;
}
else
{
break; //Own color
}
}
//+x -x
for (int i=1; x+i<8 && y-i>-1; ++i)
{
//Is it a capture
if (GetPiece(x+i,y-i).IsNull() == true)
{
moves.push_back(
Move(
Piece::queen,
Square(x,y),
false,
Square(x+i,y-i))); //No capture
}
else if (GetPiece(x+i,y-i).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::queen,
Square(x,y),
true,
Square(x+i,y-i))); //Capture of enemy
break;
}
else
{
break; //Own color
}
}
//-x -x
for (int i=1; x-i>-1 && y-i>-1; ++i)
{
//Is it a capture
if (GetPiece(x-i,y-i).IsNull() == true)
{
moves.push_back(
Move(
Piece::queen,
Square(x,y),
false,
Square(x-i,y-i))); //No capture
}
else if (GetPiece(x-i,y-i).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::queen,
Square(x,y),
true,
Square(x-i,y-i))); //Capture of enemy
break;
}
else
{
break; //Own color
}
}
//+x +0
for (int i=1; x+i<8; ++i)
{
//Is it a capture
if (GetPiece(x+i,y+0).IsNull() == true)
{
moves.push_back(
Move(
Piece::queen,
Square(x,y),
false,
Square(x+i,y+0))); //No capture
}
else if (GetPiece(x+i,y+0).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::queen,
Square(x,y),
true,
Square(x+i,y+0))); //Capture of enemy
break;
}
else
{
break; //Own color
}
}
//-x +0
for (int i=1; x-i>-1; ++i)
{
//Is it a capture
if (GetPiece(x-i,y+0).IsNull() == true)
{
moves.push_back(
Move(
Piece::queen,
Square(x,y),
false,
Square(x-i,y+0))); //No capture
}
else if (GetPiece(x-i,y+0).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::queen,
Square(x,y),
true,
Square(x-i,y+0))); //Capture of enemy
break;
}
else
{
break; //Own color
}
}
//+0 +x
for (int i=1; y+i<8; ++i)
{
//Is it a capture
if (GetPiece(x+0,y+i).IsNull() == true)
{
moves.push_back(
Move(
Piece::queen,
Square(x,y),
false,
Square(x+0,y+i))); //No capture
}
else if (GetPiece(x+0,y+i).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::queen,
Square(x,y),
true,
Square(x+0,y+i))); //Capture of enemy
break;
}
else
{
break; //Own color
}
}
//+0 -x
for (int i=1; y-i>-1; ++i)
{
//Is it a capture
if (GetPiece(x-0,y-i).IsNull() == true)
{
moves.push_back(
Move(
Piece::queen,
Square(x,y),
false,
Square(x-0,y-i))); //No capture
}
else if (GetPiece(x-0,y-i).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::queen,
Square(x,y),
true,
Square(x-0,y-i))); //Capture of enemy
break;
}
else
{
break; //Own color
}
}
return moves;
}
//---------------------------------------------------------------------------
const std::vector<Move> Board2d::GetAllValidMovesKing(
const int x, const int y) const
{
const Piece piece = GetPiece(x,y);
assert(piece.IsNull()==false);
assert(piece.GetType() == Piece::king);
std::vector<Move> moves;
//+0 -1
if (y > 0)
{
//Is it a capture
if (GetPiece(x+0,y-1).IsNull() == true)
{
moves.push_back(
Move(
Piece::king,
Square(x,y),
false,
Square(x+0,y-1))); //No capture
}
else if (GetPiece(x+0,y-1).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::king,
Square(x,y),
true,
Square(x+0,y-1))); //Capture of enemy
}
}
//-1 -1
if (y > 0 && x > 0)
{
//Is it a capture
if (GetPiece(x-1,y-1).IsNull() == true)
{
moves.push_back(
Move(
Piece::king,
Square(x,y),
false,
Square(x-1,y-1))); //No capture
}
else if (GetPiece(x-1,y-1).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::king,
Square(x,y),
true,
Square(x-1,y-1))); //Capture of enemy
}
}
//+1 -1
if (y > 0 && x < 7)
{
//Is it a capture
if (GetPiece(x+1,y-1).IsNull() == true)
{
moves.push_back(
Move(
Piece::king,
Square(x,y),
false,
Square(x+1,y-1))); //No capture
}
else if (GetPiece(x+1,y-1).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::king,
Square(x,y),
true,
Square(x+1,y-1))); //Capture of enemy
}
}
//+0 +1
if (y < 7)
{
//Is it a capture
if (GetPiece(x+0,y+1).IsNull() == true)
{
moves.push_back(
Move(
Piece::king,
Square(x,y),
false,
Square(x+0,y+1))); //No capture
}
else if (GetPiece(x+0,y+1).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::king,
Square(x,y),
true,
Square(x+0,y+1))); //Capture of enemy
}
}
//-1 +1
if (y < 7 && x > 0)
{
//Is it a capture
if (GetPiece(x-1,y+1).IsNull() == true)
{
moves.push_back(
Move(
Piece::king,
Square(x,y),
false,
Square(x-1,y+1))); //No capture
}
else if (GetPiece(x-1,y+1).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::king,
Square(x,y),
true,
Square(x-1,y+1))); //Capture of enemy
}
}
//+1 +1
if (y < 7 && x < 7)
{
//Is it a capture
if (GetPiece(x+1,y+1).IsNull() == true)
{
moves.push_back(
Move(
Piece::king,
Square(x,y),
false,
Square(x+1,y+1))); //No capture
}
else if (GetPiece(x+1,y+1).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::king,
Square(x,y),
true,
Square(x+1,y+1))); //Capture of enemy
}
}
//-1 +0
if (x > 0)
{
//Is it a capture
if (GetPiece(x-1,y+0).IsNull() == true)
{
moves.push_back(
Move(
Piece::king,
Square(x,y),
false,
Square(x-1,y+0))); //No capture
}
else if (GetPiece(x-1,y+0).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::king,
Square(x,y),
true,
Square(x-1,y+0))); //Capture of enemy
}
}
//+1 +1
if (x < 7)
{
//Is it a capture
if (GetPiece(x+1,y+0).IsNull() == true)
{
moves.push_back(
Move(
Piece::king,
Square(x,y),
false,
Square(x+1,y+0))); //No capture
}
else if (GetPiece(x+1,y+0).GetColor() != piece.GetColor())
{ //Is it an enemy?
moves.push_back(
Move(
Piece::king,
Square(x,y),
true,
Square(x+1,y+0))); //Capture of enemy
}
}
//Can do castling?
if (this->CanDoCastlingLong(piece.GetColor()))
moves.push_back(
Move(
Piece::king,
Square(x,y),
false,
Square(x-2,y)));
if (this->CanDoCastlingShort(piece.GetColor()))
moves.push_back(
Move(
Piece::king,
Square(x,y),
false,
Square(x+2,y)));
return moves;
}
//---------------------------------------------------------------------------
*/
//---------------------------------------------------------------------------
} //~ namespace Chess
//---------------------------------------------------------------------------
|