Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.

 

 

 

 

 

(C++) SearchAndDestroyChess source code (version 2.1)

 

SearchAndDestroyChess version 2.1 source code.

 

Operating system: Windows XP

IDE: C++ Builder 6.0 Enterprise Edition

Project type: GUI application

Compiler: supplied with C++ Builder 6.0 Enterprise Edition

Libraries used:

 

 

 

 

 

ProjectSearchAndDestroyChess2Vcl.cpp

 

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
USEFORM("UnitFormSearchAndDestroyChess2.cpp", FormSearchAndDestroyChess2);
USEFORM("UnitFormPressKey.cpp", FormPressKey);
USEFORM("UnitFormAbout.cpp", FormAbout);
USEFORM("UnitFormSearchAndDestroyChess2Menu.cpp", FormSearchAndDestroyChessMenu);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
        try
        {
                 Application->Initialize();
                 Application->Title = "Search And Destroy Chess 2";
                 Application->CreateForm(__classid(TFormSearchAndDestroyChessMenu), &FormSearchAndDestroyChessMenu);
     Application->Run();
        }
        catch (Exception &exception)
        {
                 Application->ShowException(&exception);
        }
        catch (...)
        {
                 try
                 {
                         throw Exception("");
                 }
                 catch (Exception &exception)
                 {
                         Application->ShowException(&exception);
                 }
        }
        return 0;
}
//---------------------------------------------------------------------------

 

 

 

 

 

ProjectSearchAndDestroyChessVcl.cpp

 

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
USEFORM("UnitFormSearchAndDestroyChess.cpp", FormSearchAndDestroyChess);
USEFORM("UnitFormPressKey.cpp", FormPressKey);
USEFORM("UnitFormAbout.cpp", FormAbout);
USEFORM("UnitFormSearchAndDestroyChessMenu.cpp", FormSearchAndDestroyChessMenu);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
        try
        {
                 Application->Initialize();
                 Application->Title = "Search And Destroy Chess";
                 Application->CreateForm(__classid(TFormSearchAndDestroyChessMenu), &FormSearchAndDestroyChessMenu);
                 Application->Run();
        }
        catch (Exception &exception)
        {
                 Application->ShowException(&exception);
        }
        catch (...)
        {
                 try
                 {
                         throw Exception("");
                 }
                 catch (Exception &exception)
                 {
                         Application->ShowException(&exception);
                 }
        }
        return 0;
}
//---------------------------------------------------------------------------

 

 

 

 

 

UnitChessBoard.cpp

 

//---------------------------------------------------------------------------
/*
  SearchAndDestroyChess 2, Kriegspiel/Dark Chess game
  Copyright (C) 2008  Richel Bilderbeek

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl
//---------------------------------------------------------------------------
#include <stdexcept>
#include <cassert>
#include <iostream>
#include "UnitChessPiece.h"
#pragma hdrstop

#include "UnitChessBoard.h"
//---------------------------------------------------------------------------
ChessBoard::ChessBoard()
  : mPieces(GetInitialSetup())
{

}
//---------------------------------------------------------------------------
const ChessPiece ChessBoard::GetPiece(const int x, const int y) const
{
  return mPieces[y][x];
}
//---------------------------------------------------------------------------
void ChessBoard::SetPiece(const ChessPiece& piece, const int x, const int y)
{
  mPieces[y][x] = piece;
  assert(this->GetPiece(x,y) == piece);
}
//---------------------------------------------------------------------------
const bool ChessBoard::IsGameOver() const
{
  bool whiteHasKing = false;
  bool blackHasKing = false;

  for (int y=0; y!=8; ++y)
  {
    for (int x=0; x!=8; ++x)
    {
      const ChessPiece piece = mPieces[y][x];
      if (piece.IsNull()==false && piece.GetType()==king)
      {
        if (piece.GetColor() == white)
          whiteHasKing = true;
        else
          blackHasKing = true;
      }
    }
  }
  return (whiteHasKing == false || blackHasKing == false);
}
//---------------------------------------------------------------------------
const EnumChessPieceColor ChessBoard::GetWinner() const
{
  assert(this->IsGameOver()==true);
  for (int y=0; y!=8; ++y)
  {
    for (int x=0; x!=8; ++x)
    {
      const ChessPiece piece = mPieces[y][x];
      if (piece.GetType()==king)
      {
        if (piece.GetColor() == white)
          return white;
        else
          return black;
      }
    }
  }
  assert(!"Should not get here");
  throw std::logic_error("Cannot find winner");
}
//---------------------------------------------------------------------------
const bool ChessBoard::CanDoMove(const ChessMove& move) const
{
  const ChessPiece piece = this->GetPiece(move.x1,move.y1);
  //Is there a chesspiece?
  if (piece.IsNull()==true) return false;
  //Is it of the right type?
  if (piece.GetType()!=move.type) return false;
  //Is it of the right color? ->Checked by ChessGame
  //Is the destination free or is there an enemy?
  const ChessPiece destination = this->GetPiece(move.x2,move.y2);
  if ( destination.IsNull()==true
    && move.capture == true) return false; //Free space && capture
  if ( destination.IsNull()==false)
  {
    //Cannot capture own pieces
    if (destination.GetColor()==piece.GetColor())
      return false;
    if (destination.GetColor()!=piece.GetColor()
      && move.capture == false) return false; //An enemy && no capture
  }
  return this->IsValidMove(move);
}
//---------------------------------------------------------------------------
void ChessBoard::DoMove(const ChessMove& move)
{
  assert(this->CanDoMove(move)==true);
  const ChessPiece piece = this->GetPiece(move.x1,move.y1);

  if (piece.GetType()==king
    && move.x1 == 4
    && (move.x2 == 2 || move.x2 == 6) )
  {
    const EnumChessPieceColor color = piece.GetColor();
    assert( (color == white && move.y1 == 0 && move.y2 == 0)
      ||    (color == black && move.y1 == 7 && move.y2 == 7) );
    const int y = move.y2;
    //Castling
    if (move.x2 == 2)
    {
      //Castling long
      this->SetPiece(ChessPiece(color,king),2,y); //Move King
      this->SetPiece(ChessPiece(color,rook),3,y); //Move rook
      this->SetPiece(ChessPiece(),4,y);           //Erase old king
      this->SetPiece(ChessPiece(),0,y);           //Erase old rook
    }
    else
    {
      //Castling short
      this->SetPiece(ChessPiece(color,king),6,y); //Move King
      this->SetPiece(ChessPiece(color,rook),5,y); //Move rook
      this->SetPiece(ChessPiece(),4,y);           //Erase old king
      this->SetPiece(ChessPiece(),7,y);           //Erase old rook
    }
  }
  else if (piece.GetType()==pawn
    && this->GetPiece(move.x2,move.y2).IsNull()==true
    && move.x1 != move.x2
    && move.y1 != move.y2)
  {
    //En passant
    this->SetPiece(ChessPiece(piece.GetColor(),pawn),move.x2,move.y2); //Move pawn
    this->SetPiece(ChessPiece(),move.x1,move.y1); //Erase old pawn
    this->SetPiece(ChessPiece(),move.x2,move.y1); //Capture pawn
  }
  else if (piece.GetType()==pawn
    && (move.y2 == 0 || move.y2 == 7) )
  {
    //Promotion to queen
    this->SetPiece(ChessPiece(),move.x1,move.y1); //Overwrite old piece by NullType
    this->SetPiece(ChessPiece(piece.GetColor(),queen),move.x2,move.y2);
  }
  else
  {
    //Regular move (i.e. non-castling)
    this->SetPiece(ChessPiece(),move.x1,move.y1); //Overwrite old piece by NullType
    this->SetPiece(piece,move.x2,move.y2);
  }
  mMoves.push_back(move);
}
//---------------------------------------------------------------------------
const bool ChessBoard::CanDoCastlingShort(const EnumChessPieceColor color) const
{
  //Determine the y
  const int y = (color == white ? 0 : 7);
  //King must be in place
  if(this->GetPiece(4,y).GetType() != king) return false;
  //Is the rook in place?
  if(this->GetPiece(7,y).GetType() != 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<ChessMove>::const_iterator Iter;
  const Iter j = mMoves.end();
  for (Iter i = mMoves.begin(); i!=j; ++i)
  {
    //Check if king has moved
    if ( (*i).type == king && (*i).y1 == y) return false;
    //Check if kingside rook has moved
    if ( (*i).type == rook && (*i).y1 == y && (*i).x1 == 7) return false;
  }
  return true;
}
//---------------------------------------------------------------------------
const bool ChessBoard::CanDoCastlingLong(const EnumChessPieceColor color) const
{
  //Determine the y
  const int y = (color == white ? 0 : 7);
  //King must be in place
  if(this->GetPiece(4,y).GetType() != king) return false;
  //Is the rook in place?
  if(this->GetPiece(0,y).GetType() != 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<ChessMove>::const_iterator Iter;
  const Iter j = mMoves.end();
  for (Iter i = mMoves.begin(); i!=j; ++i)
  {
    //Check if king has moved
    if ( (*i).type == king && (*i).y1 == y) return false;
    //Check if kingside rook has moved
    if ( (*i).type == rook && (*i).y1 == y && (*i).x1 == 0) return false;
  }
  return true;
}
//---------------------------------------------------------------------------
const std::vector<std::vector<ChessPiece> > ChessBoard::GetInitialSetup()
{
  std::vector<std::vector<ChessPiece> > v(8,std::vector<ChessPiece>(8));
  //v has [y][x] index
  v[0][0] = ChessPiece(white,rook  );
  v[0][1] = ChessPiece(white,knight);
  v[0][2] = ChessPiece(white,bishop);
  v[0][3] = ChessPiece(white,queen );
  v[0][4] = ChessPiece(white,king  );
  v[0][5] = ChessPiece(white,bishop);
  v[0][6] = ChessPiece(white,knight);
  v[0][7] = ChessPiece(white,rook  );
  v[1][0] = ChessPiece(white,pawn  );
  v[1][1] = ChessPiece(white,pawn  );
  v[1][2] = ChessPiece(white,pawn  );
  v[1][3] = ChessPiece(white,pawn  );
  v[1][4] = ChessPiece(white,pawn  );
  v[1][5] = ChessPiece(white,pawn  );
  v[1][6] = ChessPiece(white,pawn  );
  v[1][7] = ChessPiece(white,pawn  );
  v[7][0] = ChessPiece(black,rook  );
  v[7][1] = ChessPiece(black,knight);
  v[7][2] = ChessPiece(black,bishop);
  v[7][3] = ChessPiece(black,queen );
  v[7][4] = ChessPiece(black,king  );
  v[7][5] = ChessPiece(black,bishop);
  v[7][6] = ChessPiece(black,knight);
  v[7][7] = ChessPiece(black,rook  );
  v[6][0] = ChessPiece(black,pawn  );
  v[6][1] = ChessPiece(black,pawn  );
  v[6][2] = ChessPiece(black,pawn  );
  v[6][3] = ChessPiece(black,pawn  );
  v[6][4] = ChessPiece(black,pawn  );
  v[6][5] = ChessPiece(black,pawn  );
  v[6][6] = ChessPiece(black,pawn  );
  v[6][7] = ChessPiece(black,pawn  );
  return v;
}
//---------------------------------------------------------------------------
//Color denotes the player who's turn it is, i.e. the player looking at the board
void ChessBoard::CoutPieces(
  const EnumChessPieceColor color) const
{
  const int yBegin = (color == black ? 0 : 7);
  const int yEnd   = (color == black ? 8 : -1);
  const int yStep  = (color == black ? 1 : -1);
  const int xBegin = (color == white ? 0 : 7);
  const int xEnd   = (color == white ? 8 : -1);
  const int xStep  = (color == white ? 1 : -1);

  if (color == 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 << "|" << mPieces[y][x];
    }
    std::cout << "| " << (y+1) << std::endl;

  }
  std::cout << "  -------------------------" << std::endl;
  if (color == 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 ChessBoard::CoutSight(
  const EnumChessPieceColor color) const
{
  //
  const std::vector<std::vector<bool> > inSight = this->GetInSight(color);

  const int yBegin = (color == black ? 0 : 7);
  const int yEnd   = (color == black ? 8 : -1);
  const int yStep  = (color == black ? 1 : -1);
  const int xBegin = (color == white ? 0 : 7);
  const int xEnd   = (color == white ? 8 : -1);
  const int xStep  = (color == white ? 1 : -1);

  if (color == 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[y][x]==true ? mPieces[y][x] : ChessPiece() );
    }
    std::cout << "| " << (y+1) << std::endl;

  }
  std::cout << "  -------------------------" << std::endl;
  if (color == 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 std::vector<std::vector<bool> > ChessBoard::GetInSight(const EnumChessPieceColor color) const
{
  std::vector<std::vector<bool> > inSight(8, std::vector<bool>(8,false));

  for (int y=0; y!=8; ++y)
  {
    for (int x=0; x!=8; ++x)
    {
      //Get the piece there
      const ChessPiece 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[y][x] = true;
      //Then get all its valid moves
      const std::vector<ChessMove> moves = this->GetAllValidMoves(x,y);
      const std::vector<ChessMove>::const_iterator j = moves.end();
      for (std::vector<ChessMove>::const_iterator i = moves.begin(); i!=j; ++i)
      {
        inSight[(*i).y2][(*i).x2] = true;
      }
      //Special treatment of pawns
      if (piece.GetType() == pawn)
      {
        if (piece.GetColor()==white)
        {
          //Always look a single square forward
          inSight[y+1][x] = true;
          //Look two squares forward, if the first is not occupied
          if (y==1 && GetPiece(x,y+1).IsNull()==true)
          {
            inSight[y+2][x] = true;
          }
          //Look sideways left
          if (x > 0 && GetPiece(x-1,y+1).IsNull()==true)
          {
            inSight[y+1][x-1] = true;
          }
          //Look sideways right
          if (x < 7 && GetPiece(x+1,y+1).IsNull()==true)
          {
            inSight[y+1][x+1] = true;
          }
          //Look sideways if en passant is possible
          if (y == 4                            //4th row
            && this->mMoves.back().type == pawn //Black moved a pawn
            && this->mMoves.back().y1 == 6      //Black moved two places
            && this->mMoves.back().y2 == 4)     //Black moved two places
          {
            if (this->mMoves.back().x1 == x-1)
              inSight[y][x-1] = true;
            else if (this->mMoves.back().x1 == x+1)
              inSight[y][x+1] = true;
          }
        }
        else
        {
          //Always look a single square forward
          inSight[y-1][x] = true;
          //Look two squares forward, if the first is not occupied
          if (y==6 && GetPiece(x,y-1).IsNull()==true)
          {
            inSight[y-2][x] = true;
          }
          //Look sideways left
          if (x > 0 && GetPiece(x-1,y-1).IsNull()==true)
          {
            inSight[y-1][x-1] = true;
          }
          //Look sideways right
          if (x < 7 && GetPiece(x+1,y-1).IsNull()==true)
          {
            inSight[y-1][x+1] = true;
          }
          //Look sideways if en passant is possible
          if (y == 3                            //3rd row
            && this->mMoves.back().type == pawn //White moved a pawn
            && this->mMoves.back().y1 == 1      //White moved two places
            && this->mMoves.back().y2 == 3)     //White moved two places
          {
            if (this->mMoves.back().x1 == x-1)
              inSight[y][x-1] = true;
            else if (this->mMoves.back().x1 == x+1)
              inSight[y][x+1] = true;
          }
        }
      }
    }
  }
  return inSight;
}
//---------------------------------------------------------------------------
const bool ChessBoard::IsValidMove(const ChessMove& move) const
{
  const std::vector<ChessMove> moves = this->GetAllValidMoves(move.x1, move.y1);
  if (std::find(moves.begin(),moves.end(),move)!=moves.end())
    return true;
  else
    return false;

}
//---------------------------------------------------------------------------
const std::vector<ChessMove> ChessBoard::GetAllPossibleMoves(
  const EnumChessPieceColor whoseTurn) const
{
  std::vector<ChessMove> 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<ChessMove> thisPieceMoves = GetAllValidMoves(x,y);
        //Append it to allMoves
        std::copy(
          thisPieceMoves.begin(),thisPieceMoves.end(),
          std::back_inserter(allMoves));
      }
    }
  }
  return allMoves;
}
//---------------------------------------------------------------------------
const std::vector<ChessMove> ChessBoard::GetAllValidMoves(
  const int x, const int y) const
{
  const ChessPiece piece = GetPiece(x,y);
  assert(piece.IsNull()==false);
  switch (piece.GetType())
  {
    case pawn  : return GetAllValidMovesPawn(x,y);
    case knight: return GetAllValidMovesKnight(x,y);
    case bishop: return GetAllValidMovesBishop(x,y);
    case rook  : return GetAllValidMovesRook(x,y);
    case queen : return GetAllValidMovesQueen(x,y);
    case king  : return GetAllValidMovesKing(x,y);
  }
  assert(!"Should not get here");
  throw std::logic_error("Unknown EnumChessPieceType");
}
//---------------------------------------------------------------------------
const std::vector<ChessMove> ChessBoard::GetAllValidMovesPawn(
  const int x, const int y) const
{
  const ChessPiece piece = GetPiece(x,y);
  assert(piece.IsNull()==false);
  assert(piece.GetType() == pawn);

  std::vector<ChessMove> moves;

  if (piece.GetColor()==white)
  {
    //Move single square forward
    if (GetPiece(x,y+1).IsNull()==true)
    {
      moves.push_back(ChessMove(pawn,x,y,false,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(ChessMove(pawn,x,y,false,x,y+2));
    }
    //Capture left
    if (x > 0
      && GetPiece(x-1,y+1).IsNull()==false
      && GetPiece(x-1,y+1).GetColor()==black)
    {
      moves.push_back(ChessMove(pawn,x,y,true,x-1,y+1));
    }
    //Capture right
    if (x < 7
      && GetPiece(x+1,y+1).IsNull()==false
      && GetPiece(x+1,y+1).GetColor()==black)
    {
      moves.push_back(ChessMove(pawn,x,y,true,x+1,y+1));
    }
    //En passant
    if (y == 4
      && mMoves.back().y1 == 6 //Black had moved two squares
      && mMoves.back().y2 == 4)
    {
      if (mMoves.back().x1 == x - 1) //To the left
      {
        //Note: En passant is not regarded as a capture, as the spot moved to is empty
        moves.push_back(ChessMove(pawn,x,y, false /* note */ ,x-1,y+1));
      }
      else if (mMoves.back().x1 == x + 1) //To the right
      {
        //Note: En passant is not regarded as a capture, as the spot moved to is empty
        moves.push_back(ChessMove(pawn,x,y,false /* note */,x+1,y+1));
      }
    }
  }
  else
  {
    //Move single square forward
    if (GetPiece(x,y-1).IsNull()==true)
    {
      moves.push_back(ChessMove(pawn,x,y,false,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(ChessMove(pawn,x,y,false,x,y-2));
    }
    //Capture left
    if (x > 0
      && GetPiece(x-1,y-1).IsNull()==false
      && GetPiece(x-1,y-1).GetColor()==white)
    {
      moves.push_back(ChessMove(pawn,x,y,true,x-1,y-1));
    }
    //Capture right
    if (x < 7
      && GetPiece(x+1,y-1).IsNull()==false
      && GetPiece(x+1,y-1).GetColor()==white)
    {
      moves.push_back(ChessMove(pawn,x,y,true,x+1,y-1));
    }
    //En passant
    if (y == 3
      && mMoves.back().y1 == 1  //White had moved two squares
      && mMoves.back().y2 == 3)
    {
      if (mMoves.back().x1 == x - 1) //To the left
      {
        //Note: En passant is not regarded as a capture, as the spot moved to is empty
        moves.push_back(ChessMove(pawn,x,y, false /* note */ ,x-1,y-1));
      }
      else if (mMoves.back().x1 == x + 1) //To the right
      {
        //Note: En passant is not regarded as a capture, as the spot moved to is empty
        moves.push_back(ChessMove(pawn,x,y,false /* note */,x+1,y-1));
      }
    }
  }
  return moves;
}
//---------------------------------------------------------------------------
const std::vector<ChessMove> ChessBoard::GetAllValidMovesKnight(
  const int x, const int y) const
{
  const ChessPiece piece = GetPiece(x,y);
  assert(piece.IsNull()==false);
  assert(piece.GetType() == knight);

  std::vector<ChessMove> moves;

  //-2 -1
  if (x > 1 && y > 0)
  {
    //Is it a capture?
    if (GetPiece(x-2,y-1).IsNull() == true)
    {
      moves.push_back(ChessMove(knight,x,y,false,x-2,y-1)); //No capture
    }
    else if (GetPiece(x-2,y-1).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(knight,x,y,true,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(ChessMove(knight,x,y,false,x-1,y-2)); //No capture
    }
    else if (GetPiece(x-1,y-2).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(knight,x,y,true,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(ChessMove(knight,x,y,false,x+2,y-1)); //No capture
    }
    else if (GetPiece(x+2,y-1).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(knight,x,y,true,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(ChessMove(knight,x,y,false,x-1,y+2)); //No capture
    }
    else if (GetPiece(x-1,y+2).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(knight,x,y,true,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(ChessMove(knight,x,y,false,x-2,y+1)); //No capture
    }
    else if (GetPiece(x-2,y+1).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(knight,x,y,true,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(ChessMove(knight,x,y,false,x+1,y-2)); //No capture
    }
    else if (GetPiece(x+1,y-2).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(knight,x,y,true,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(ChessMove(knight,x,y,false,x+2,y+1)); //No capture
    }
    else if (GetPiece(x+2,y+1).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(knight,x,y,true,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(ChessMove(knight,x,y,false,x+1,y+2)); //No capture
    }
    else if (GetPiece(x+1,y+2).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(knight,x,y,true,x+1,y+2)); //Capture of enemy
    }
  }

  return moves;
}
//---------------------------------------------------------------------------
const std::vector<ChessMove> ChessBoard::GetAllValidMovesBishop(
  const int x, const int y) const
{
  const ChessPiece piece = GetPiece(x,y);
  assert(piece.IsNull()==false);
  assert(piece.GetType() == bishop);

  std::vector<ChessMove> 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(ChessMove(bishop,x,y,false,x+i,y+i)); //No capture
    }
    else if (GetPiece(x+i,y+i).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(bishop,x,y,true,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(ChessMove(bishop,x,y,false,x-i,y+i)); //No capture
    }
    else if (GetPiece(x-i,y+i).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(bishop,x,y,true,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(ChessMove(bishop,x,y,false,x+i,y-i)); //No capture
    }
    else if (GetPiece(x+i,y-i).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(bishop,x,y,true,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(ChessMove(bishop,x,y,false,x-i,y-i)); //No capture
    }
    else if (GetPiece(x-i,y-i).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(bishop,x,y,true,x-i,y-i)); //Capture of enemy
      break;
    }
    else
    {
      break; //Own color
    }
  }

  return moves;
}
//---------------------------------------------------------------------------
const std::vector<ChessMove> ChessBoard::GetAllValidMovesRook(
  const int x, const int y) const
{
  const ChessPiece piece = GetPiece(x,y);
  assert(piece.IsNull()==false);
  assert(piece.GetType() == rook);

  std::vector<ChessMove> 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(ChessMove(rook,x,y,false,x+i,y+0)); //No capture
    }
    else if (GetPiece(x+i,y+0).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(rook,x,y,true,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(ChessMove(rook,x,y,false,x-i,y+0)); //No capture
    }
    else if (GetPiece(x-i,y+0).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(rook,x,y,true,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(ChessMove(rook,x,y,false,x+0,y+i)); //No capture
    }
    else if (GetPiece(x+0,y+i).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(rook,x,y,true,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(ChessMove(rook,x,y,false,x-0,y-i)); //No capture
    }
    else if (GetPiece(x-0,y-i).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(rook,x,y,true,x-0,y-i)); //Capture of enemy
      break;
    }
    else
    {
      break; //Own color
    }
  }

  return moves;
}
//---------------------------------------------------------------------------
const std::vector<ChessMove> ChessBoard::GetAllValidMovesQueen(
  const int x, const int y) const
{
  const ChessPiece piece = GetPiece(x,y);
  assert(piece.IsNull()==false);
  assert(piece.GetType() == queen);

  std::vector<ChessMove> 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(ChessMove(queen,x,y,false,x+i,y+i)); //No capture
    }
    else if (GetPiece(x+i,y+i).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(queen,x,y,true,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(ChessMove(queen,x,y,false,x-i,y+i)); //No capture
    }
    else if (GetPiece(x-i,y+i).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(queen,x,y,true,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(ChessMove(queen,x,y,false,x+i,y-i)); //No capture
    }
    else if (GetPiece(x+i,y-i).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(queen,x,y,true,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(ChessMove(queen,x,y,false,x-i,y-i)); //No capture
    }
    else if (GetPiece(x-i,y-i).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(queen,x,y,true,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(ChessMove(queen,x,y,false,x+i,y+0)); //No capture
    }
    else if (GetPiece(x+i,y+0).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(queen,x,y,true,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(ChessMove(queen,x,y,false,x-i,y+0)); //No capture
    }
    else if (GetPiece(x-i,y+0).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(queen,x,y,true,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(ChessMove(queen,x,y,false,x+0,y+i)); //No capture
    }
    else if (GetPiece(x+0,y+i).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(queen,x,y,true,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(ChessMove(queen,x,y,false,x-0,y-i)); //No capture
    }
    else if (GetPiece(x-0,y-i).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(queen,x,y,true,x-0,y-i)); //Capture of enemy
      break;
    }
    else
    {
      break; //Own color
    }
  }

  return moves;
}
//---------------------------------------------------------------------------
const std::vector<ChessMove> ChessBoard::GetAllValidMovesKing(
  const int x, const int y) const
{
  const ChessPiece piece = GetPiece(x,y);
  assert(piece.IsNull()==false);
  assert(piece.GetType() == king);

  std::vector<ChessMove> moves;

  //+0 -1
  if (y > 0)
  {
    //Is it a capture
    if (GetPiece(x+0,y-1).IsNull() == true)
    {
      moves.push_back(ChessMove(king,x,y,false,x+0,y-1)); //No capture
    }
    else if (GetPiece(x+0,y-1).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(king,x,y,true,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(ChessMove(king,x,y,false,x-1,y-1)); //No capture
    }
    else if (GetPiece(x-1,y-1).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(king,x,y,true,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(ChessMove(king,x,y,false,x+1,y-1)); //No capture
    }
    else if (GetPiece(x+1,y-1).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(king,x,y,true,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(ChessMove(king,x,y,false,x+0,y+1)); //No capture
    }
    else if (GetPiece(x+0,y+1).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(king,x,y,true,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(ChessMove(king,x,y,false,x-1,y+1)); //No capture
    }
    else if (GetPiece(x-1,y+1).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(king,x,y,true,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(ChessMove(king,x,y,false,x+1,y+1)); //No capture
    }
    else if (GetPiece(x+1,y+1).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(king,x,y,true,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(ChessMove(king,x,y,false,x-1,y+0)); //No capture
    }
    else if (GetPiece(x-1,y+0).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(king,x,y,true,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(ChessMove(king,x,y,false,x+1,y+0)); //No capture
    }
    else if (GetPiece(x+1,y+0).GetColor() != piece.GetColor())
    { //Is it an enemy?
      moves.push_back(ChessMove(king,x,y,true,x+1,y+0)); //Capture of enemy
    }
  }

  //Can do castling?
  if (this->CanDoCastlingLong(piece.GetColor()))
    moves.push_back(ChessMove(king,x,y,false,x-2,y));
  if (this->CanDoCastlingShort(piece.GetColor()))
    moves.push_back(ChessMove(king,x,y,false,x+2,y));

  return moves;
}
//---------------------------------------------------------------------------



#pragma package(smart_init)



 

 

 

 

 

UnitChessBoard.h

 

//---------------------------------------------------------------------------
/*
  SearchAndDestroyChess 2, Kriegspiel/Dark Chess game
  Copyright (C) 2008  Richel Bilderbeek

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl
//---------------------------------------------------------------------------
#ifndef UnitChessBoardH
#define UnitChessBoardH
//---------------------------------------------------------------------------
#include <iosfwd>
#include <vector>
#include "UnitEnumChessPieceColor.h"
#include "UnitChessMove.h"
struct ChessPiece;
//---------------------------------------------------------------------------
//ChessBoard manages the position of the pieces
//It does not know whose turn it is (ChessGame does)
struct ChessBoard
{
  typedef std::vector<std::vector<ChessPiece> > Board;

  ChessBoard();

  const Board& GetPieces() const { return mPieces; }

  const bool CanDoMove(const ChessMove& move) const;
  void DoMove(const ChessMove& move);
  const ChessPiece GetPiece(const int x, const int y) const;

  const std::vector<std::vector<bool> > GetInSight(const EnumChessPieceColor color) const;

  const std::vector<ChessMove> GetAllValidMoves(const int x, const int y) const;
  const std::vector<ChessMove> GetAllPossibleMoves(const EnumChessPieceColor whoseTurn) const;

  void CoutPieces(const EnumChessPieceColor color) const;
  void CoutSight(const EnumChessPieceColor color) const;

  const bool IsGameOver() const;
  const EnumChessPieceColor GetWinner() const;

  private:

  Board mPieces;
  void SetPiece(const ChessPiece& piece, const int x, const int y);

  std::vector<ChessMove> mMoves;

  const std::vector<std::vector<ChessPiece> > GetInitialSetup();

  const bool IsValidMove(const ChessMove& move) const;

  const std::vector<ChessMove> GetAllValidMovesPawn(const int x, const int y) const;
  const std::vector<ChessMove> GetAllValidMovesKnight(const int x, const int y) const;
  const std::vector<ChessMove> GetAllValidMovesBishop(const int x, const int y) const;
  const std::vector<ChessMove> GetAllValidMovesRook(const int x, const int y) const;
  const std::vector<ChessMove> GetAllValidMovesQueen(const int x, const int y) const;
  const std::vector<ChessMove> GetAllValidMovesKing(const int x, const int y) const;

  const bool CanDoCastlingShort(const EnumChessPieceColor color) const;
  const bool CanDoCastlingLong(const EnumChessPieceColor color) const;
};
//---------------------------------------------------------------------------
#endif

 

 

 

 

 

UnitChessGame.cpp

 

//---------------------------------------------------------------------------
/*
  SearchAndDestroyChess 2, Kriegspiel/Dark Chess game
  Copyright (C) 2008  Richel Bilderbeek

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl
//---------------------------------------------------------------------------
#include <algorithm>
#include <iostream>
#include <string>
#include <cassert>
#include "UnitChessBoard.h"
#include "UnitChessPiece.h"
#pragma hdrstop

#include "UnitChessGame.h"
//---------------------------------------------------------------------------
ChessGame::ChessGame()
  : mWhoseTurn(white)
{

}
//---------------------------------------------------------------------------
const bool ChessGame::CanDoMove(const ChessMove& move) const
{
  //Regular move
  const ChessPiece piece = mBoard.GetPiece(move.x1,move.y1);
  //Is it of the right color?
  if (piece.GetColor()!=mWhoseTurn) return false;
  //Is the captured piece of the other color?
  //->checked by ChessBoard
  //ChessBoard checks the rest
  return mBoard.CanDoMove(move);
}
//---------------------------------------------------------------------------
void ChessGame::DoMove(const ChessMove& move)
{
  assert(this->CanDoMove(move)==true);
  mBoard.DoMove(move);
  mWhoseTurn = (mWhoseTurn == white ? black : white);
}
//---------------------------------------------------------------------------
void ChessGame::CoutGame() const
{
  mBoard.CoutSight(mWhoseTurn);
  std::cout
    << std::endl
    << (mWhoseTurn == white ? "White" : "Black")
    << " player's turn"
    << std::endl;
}
//---------------------------------------------------------------------------
void ChessGame::CoutBoard() const
{
  mBoard.CoutPieces(mWhoseTurn);
  std::cout
    << std::endl
    << (mWhoseTurn == white ? "White" : "Black")
    << " player's turn"
    << std::endl;
}
//---------------------------------------------------------------------------
const bool ChessGame::IsGameOver() const
{
  return mBoard.IsGameOver();
}
//---------------------------------------------------------------------------
const EnumChessPieceColor ChessGame::GetWinner() const
{
  assert(this->IsGameOver()==true);
  return mBoard.GetWinner();
}
//---------------------------------------------------------------------------
const std::vector<std::vector<bool> > ChessGame::GetInSight() const
{
  return mBoard.GetInSight(mWhoseTurn);
}
//---------------------------------------------------------------------------
const ChessMove ChessGame::SuggestMove() const
{
  //Get all possible moves
  std::vector<ChessMove> moves = mBoard.GetAllPossibleMoves(mWhoseTurn);
  std::random_shuffle(moves.begin(), moves.end() );

  const int nMoves = moves.size();
  assert(nMoves>0);

  const std::vector<double> moveValues = AttributeValues(moves);

  const std::vector<double>::const_iterator pMove
    = std::max_element( moveValues.begin(),moveValues.end() );
  const int index = pMove - moveValues.begin();
  assert(index >= 0);
  assert(index < static_cast<int>(moves.size()));
  return moves[ index ];

}
//---------------------------------------------------------------------------
const std::vector<double> ChessGame::AttributeValues(
  const std::vector<ChessMove>& moves) const
{
  const int nMoves = moves.size();
  std::vector<double> v(nMoves,0.0);
  for (int i=0; i!=nMoves; ++i)
  {
    v[i] = AttributeValue(moves[i]);
  }
  return v;
}
//---------------------------------------------------------------------------
const double ChessGame::AttributeValue(
  const ChessMove& move) const
{
  double value = 0.0;
  const int y1 = move.y1;
  const int x1 = move.x1;
  const int y2 = move.y2;
  const int x2 = move.x2;
  const ChessPiece piece = mBoard.GetPiece(x1,y1);
  assert(piece.IsNull()==false);
  //const EnumChessPieceColor color = piece.GetColor();

  if (mBoard.GetPiece(x2,y2).IsNull()==false)
  {
    //An expensive piece should not take a cheaper piece
    //The more expensive the piece to move,
    //  the less motivated it will be to take a piece
    if (piece.GetType()==king  ) { value-=100.0; }
    if (piece.GetType()==queen ) { value-= 9.0; }
    if (piece.GetType()==rook  ) { value-= 4.0; }
    if (piece.GetType()==bishop) { value-= 2.0; }
    if (piece.GetType()==knight) { value-= 2.0; }
    if (piece.GetType()==pawn  ) { value-= 0.0; }
    //The more expensive the piece to take,
    //  the more motivated it will be to take it
    const ChessPiece victim = mBoard.GetPiece(x2,y2);
    if (victim.GetType()==king  ) { value+=100000.0; }
    if (victim.GetType()==queen ) { value+=10.0; }
    if (victim.GetType()==rook  ) { value+= 5.0; }
    if (victim.GetType()==bishop) { value+= 3.0; }
    if (victim.GetType()==knight) { value+= 3.0; }
    if (victim.GetType()==pawn  ) { value+= 1.0; }
  }
  return value;
}
//---------------------------------------------------------------------------
//Parse in the format:
//a2 a4
//a2xb3
//Na1 a8
//Pc1xd5
const bool ChessGame::ParseMove(
  const std::string& s,
  ChessMove& move) const
{
  if (s.empty()==true) return false;
  //Obtain chesstypes from the only upper case character at the first index
  //If there is no upper case, it is a pawn
  if (s=="o-o" || s=="O-O" || s == "0-0")
  {
    const int y = (this->GetWhoseTurn() == white ? 0 : 7);
    move = ChessMove(king,4,y,false,6,y);
    return true;
  }
  if (s=="o-o-o" || s=="O-O-O" || s == "0-0-0")
  {
    const int y = (this->GetWhoseTurn() == white ? 0 : 7);
    move = ChessMove(king,4,y,false,2,y);
    return true;
  }

  switch(s[0])
  {
    case 'N': move.type = knight; break;
    case 'B': move.type = bishop; break;
    case 'R': move.type = rook  ; break;
    case 'Q': move.type = queen ; break;
    case 'K': move.type = king  ; break;
    default: move.type = pawn;
  }

  const int minSize = (move.type == pawn ? 5 : 6);
  if (static_cast<int>(s.size()) < minSize) return false;

  if (move.type == pawn)
  {
     if (s[2]==' ') move.capture = false;
     else if (s[2]=='x') move.capture = true;
     else return false;
  }
  else
  {
     if (s[3]==' ') move.capture = false;
     else if (s[3]=='x') move.capture = true;
     else return false;
  }

  const std::string from = (move.type == pawn ? s.substr(0,2) : s.substr(1,2) );
  const std::string to   = (move.type == pawn ? s.substr(3,2) : s.substr(4,2) );

  switch(from[0])
  {
    case 'a': move.x1 = 0; break;
    case 'b': move.x1 = 1; break;
    case 'c': move.x1 = 2; break;
    case 'd': move.x1 = 3; break;
    case 'e': move.x1 = 4; break;
    case 'f': move.x1 = 5; break;
    case 'g': move.x1 = 6; break;
    case 'h': move.x1 = 7; break;
    default: return false;
  }

  switch(from[1])
  {
    case '1': move.y1 = 0; break;
    case '2': move.y1 = 1; break;
    case '3': move.y1 = 2; break;
    case '4': move.y1 = 3; break;
    case '5': move.y1 = 4; break;
    case '6': move.y1 = 5; break;
    case '7': move.y1 = 6; break;
    case '8': move.y1 = 7; break;
    default: return false;
  }

  switch(to[0])
  {
    case 'a': move.x2 = 0; break;
    case 'b': move.x2 = 1; break;
    case 'c': move.x2 = 2; break;
    case 'd': move.x2 = 3; break;
    case 'e': move.x2 = 4; break;
    case 'f': move.x2 = 5; break;
    case 'g': move.x2 = 6; break;
    case 'h': move.x2 = 7; break;
    default: return false;
  }

  switch(to[1])
  {
    case '1': move.y2 = 0; break;
    case '2': move.y2 = 1; break;
    case '3': move.y2 = 2; break;
    case '4': move.y2 = 3; break;
    case '5': move.y2 = 4; break;
    case '6': move.y2 = 5; break;
    case '7': move.y2 = 6; break;
    case '8': move.y2 = 7; break;
    default: return false;
  }

  //if it contains exactly one 'x' it is a capture
  return true;
}
//---------------------------------------------------------------------------
#pragma package(smart_init)

 

 

 

 

 

UnitChessGame.h

 

//---------------------------------------------------------------------------
/*
  SearchAndDestroyChess 2, Kriegspiel/Dark Chess game
  Copyright (C) 2008  Richel Bilderbeek

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl
//---------------------------------------------------------------------------
#ifndef UnitChessGameH
#define UnitChessGameH
//---------------------------------------------------------------------------
#include "UnitEnumChessPieceColor.h"
#include "UnitEnumChessPieceType.h"
#include "UnitChessBoard.h"
#include "UnitChessMove.h"
//---------------------------------------------------------------------------
//Manages the correct use of ChessBoard
struct ChessGame
{
  ChessGame();

  const bool CanDoMove(const ChessMove& move) const;
  void DoMove(const ChessMove& move);

  const ChessMove SuggestMove() const;

  void CoutGame() const;
  void CoutBoard() const;

  const ChessBoard& GetBoard() const { return mBoard; }
  const EnumChessPieceColor GetWhoseTurn() const { return mWhoseTurn; }

  const std::vector<std::vector<bool> > GetInSight() const;

  const bool IsGameOver() const;
  const EnumChessPieceColor GetWinner() const;

  const bool ParseMove(const std::string& s,ChessMove& move) const;

  private:
  ChessBoard mBoard;
  EnumChessPieceColor mWhoseTurn;

  const std::vector<double> AttributeValues(
    const std::vector<ChessMove>& moves) const;
  const double AttributeValue(
    const ChessMove& move) const;
};
//---------------------------------------------------------------------------


#endif
 

 

 

 

 

 

UnitChessMove.cpp

 

//---------------------------------------------------------------------------
/*
  SearchAndDestroyChess 2, Kriegspiel/Dark Chess game
  Copyright (C) 2008  Richel Bilderbeek

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl
//---------------------------------------------------------------------------
#pragma hdrstop

#include "UnitChessMove.h"
//---------------------------------------------------------------------------
const bool operator==(const ChessMove& lhs, const ChessMove& rhs)
{
  return (lhs.type == rhs.type
    && lhs.x1      == rhs.x1
    && lhs.y1      == rhs.y1
    && lhs.capture == rhs.capture
    && lhs.x2      == rhs.x2
    && lhs.y2      == rhs.y2);
}

#pragma package(smart_init)

 

 

 

 

 

UnitChessMove.h

 

//---------------------------------------------------------------------------
/*
  SearchAndDestroyChess 2, Kriegspiel/Dark Chess game
  Copyright (C) 2008  Richel Bilderbeek

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl
//---------------------------------------------------------------------------
#ifndef UnitChessMoveH
#define UnitChessMoveH
//---------------------------------------------------------------------------
#include "UnitEnumChessPieceType.h"
//---------------------------------------------------------------------------
struct ChessMove
{
  ChessMove(
    const EnumChessPieceType anyType = king,
    const int anyX1 = 0,
    const int anyY1 = 0,
    const bool anyCapture = true,
    const int anyX2 = 0,
    const int anyY2 = 0)
    : type(anyType),
      x1(anyX1),
      y1(anyY1),
      capture(anyCapture),
      x2(anyX2),
      y2(anyY2)
  {

  }
  EnumChessPieceType type;
  int x1;
  int y1;
  bool capture;
  int x2;
  int y2;
};
//---------------------------------------------------------------------------
const bool operator==(const ChessMove& lhs, const ChessMove& rhs);
#endif

 

 

 

 

 

UnitChessPiece.cpp

 

//---------------------------------------------------------------------------
/*
  SearchAndDestroyChess 2, Kriegspiel/Dark Chess game
  Copyright (C) 2008  Richel Bilderbeek

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl
//---------------------------------------------------------------------------
#include <iostream>
#pragma hdrstop

#include "UnitChessPiece.h"
//---------------------------------------------------------------------------
std::ostream& operator<<(std::ostream& os, const ChessPiece& piece)
{
  if (piece.IsNull()==true)
  {
    os << "  ";
  }
  else
  {
    os << piece.GetColor() << piece.GetType();
  }
  return os;
}
//---------------------------------------------------------------------------
const bool operator==(const ChessPiece& lhs, const ChessPiece& rhs)
{
  return (lhs.GetType() == rhs.GetType()
    && lhs.GetColor() == rhs.GetColor()
    && lhs.IsNull() == rhs.IsNull() );
}
//---------------------------------------------------------------------------

#pragma package(smart_init)

 

 

 

 

 

UnitChessPiece.h

 

//---------------------------------------------------------------------------
/*
  SearchAndDestroyChess 2, Kriegspiel/Dark Chess game
  Copyright (C) 2008  Richel Bilderbeek

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl
//---------------------------------------------------------------------------
#ifndef UnitChessPieceH
#define UnitChessPieceH
//---------------------------------------------------------------------------
#include <iosfwd>
#include "UnitEnumChessPieceType.h"
#include "UnitEnumChessPieceColor.h"
//---------------------------------------------------------------------------
//Read-only
struct ChessPiece
{
  ChessPiece()
    : mColor(white), mType(pawn), mIsNull(true) {}
  ChessPiece(
    const EnumChessPieceColor color,
    const EnumChessPieceType type)
    : mColor(color), mType(type), mIsNull(false) {}

  const EnumChessPieceColor GetColor() const { return mColor; }
  const EnumChessPieceType GetType() const { return mType; }
  const int IsNull() const { return mIsNull; }

  private:
    EnumChessPieceColor mColor;
    EnumChessPieceType mType;
    bool mIsNull;
};
//---------------------------------------------------------------------------
const bool operator==(const ChessPiece& lhs, const ChessPiece& rhs);
std::ostream& operator<<(std::ostream& os, const ChessPiece& piece);
//---------------------------------------------------------------------------
#endif

 

 

 

 

 

UnitCoordinatGetter.cpp

 

//---------------------------------------------------------------------------


#pragma hdrstop

#include "UnitCoordinatGetter.h"
//---------------------------------------------------------------------------
const int CoordinatGetter::GetX(const int x) const
{
  if (mColor == white)
  {
    return x;
  }
  else
  {
    return 7 - x;
  }
}
//---------------------------------------------------------------------------
const int CoordinatGetter::GetY(const int y) const
{
  if (mColor == white)
  {
    return 7 - y;
  }
  else
  {
    return y;
  }
}
//---------------------------------------------------------------------------
#pragma package(smart_init)

 

 

 

 

 

UnitCoordinatGetter.h

 

//---------------------------------------------------------------------------

#ifndef UnitCoordinatGetterH
#define UnitCoordinatGetterH
//---------------------------------------------------------------------------
#include "UnitEnumChessPieceColor.h"
//---------------------------------------------------------------------------
struct CoordinatGetter
{
  CoordinatGetter(const EnumChessPieceColor color)
    : mColor(color) {}
  const int GetX(const int x) const;
  const int GetY(const int y) const;
  const EnumChessPieceColor mColor;
};

#endif
 

 

 

 

 

 

UnitEnumChessPieceColor.cpp

 

//---------------------------------------------------------------------------
/*
  SearchAndDestroyChess 2, Kriegspiel/Dark Chess game
  Copyright (C) 2008  Richel Bilderbeek

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl
//---------------------------------------------------------------------------
#include <iostream>
#include <cassert>
#include <stdexcept>
#pragma hdrstop

#include "UnitEnumChessPieceColor.h"
//---------------------------------------------------------------------------
std::ostream& operator<<(std::ostream& os, const EnumChessPieceColor& color)
{
  switch (color)
  {
    case white: os << "W"; return os;
    case black: os << "B"; return os;
  }
  assert(!"Should not get here");
  throw std::logic_error("Unknown color");

}
//---------------------------------------------------------------------------
#pragma package(smart_init)

 

 

 

 

 

UnitEnumChessPieceColor.h

 

//---------------------------------------------------------------------------
/*
  SearchAndDestroyChess 2, Kriegspiel/Dark Chess game
  Copyright (C) 2008  Richel Bilderbeek

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl
//---------------------------------------------------------------------------
#ifndef UnitEnumChessPieceColorH
#define UnitEnumChessPieceColorH
//---------------------------------------------------------------------------
#include <iosfwd>
//---------------------------------------------------------------------------
enum EnumChessPieceColor
{
  black, white
};
//---------------------------------------------------------------------------
std::ostream& operator<<(std::ostream& os, const EnumChessPieceColor& color);
//---------------------------------------------------------------------------
#endif

 

 

 

 

 

UnitEnumChessPieceType.cpp

 

//---------------------------------------------------------------------------
/*
  SearchAndDestroyChess 2, Kriegspiel/Dark Chess game
  Copyright (C) 2008  Richel Bilderbeek

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl
//---------------------------------------------------------------------------
#include <iostream>
#include <cassert>
#include <stdexcept>
#pragma hdrstop

#include "UnitEnumChessPieceType.h"
//---------------------------------------------------------------------------
std::ostream& operator<<(std::ostream& os, const EnumChessPieceType& type)
{
  switch (type)
  {
    case pawn  : os << "P"; return os;
    case knight: os << "N"; return os;
    case bishop: os << "B"; return os;
    case rook  : os << "R"; return os;
    case queen : os << "Q"; return os;
    case king  : os << "K"; return os;
  }
  assert(!"Should not get here");
  throw std::logic_error("Unknown color");
}
//---------------------------------------------------------------------------
#pragma package(smart_init)

 

 

 

 

 

UnitEnumChessPieceType.h

 

//---------------------------------------------------------------------------
/*
  SearchAndDestroyChess 2, Kriegspiel/Dark Chess game
  Copyright (C) 2008  Richel Bilderbeek

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl
//---------------------------------------------------------------------------
#ifndef UnitEnumChessPieceTypeH
#define UnitEnumChessPieceTypeH
//---------------------------------------------------------------------------
#include <iosfwd>
//---------------------------------------------------------------------------
enum EnumChessPieceType
{
  pawn,
  knight,
  bishop,
  rook,
  queen,
  king
};
//---------------------------------------------------------------------------
std::ostream& operator<<(std::ostream& os, const EnumChessPieceType& type);
//---------------------------------------------------------------------------
#endif
 

 

 

 

 

 

UnitFormAbout.cpp

 

//---------------------------------------------------------------------------
/*
  SearchAndDestroyChess 2, Kriegspiel/Dark Chess game
  Copyright (C) 2008  Richel Bilderbeek

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "UnitFormAbout.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TFormAbout *FormAbout;
//---------------------------------------------------------------------------
__fastcall TFormAbout::TFormAbout(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------



 

 

 

 

 

UnitFormAbout.h

 

//---------------------------------------------------------------------------
/*
  SearchAndDestroyChess 2, Kriegspiel/Dark Chess game
  Copyright (C) 2008  Richel Bilderbeek

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl
//---------------------------------------------------------------------------
#ifndef UnitFormAboutH
#define UnitFormAboutH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ComCtrls.hpp>
#include <ExtCtrls.hpp>
#include <jpeg.hpp>
#include <Graphics.hpp>
//---------------------------------------------------------------------------
class TFormAbout : public TForm
{
__published: // IDE-managed Components
        TRichEdit *RichEdit1;
        TPanel *PanelTop;
        TImage *ImageRichel;
        TPanel *PanelTopRight;
        TPanel *Panel1;
        TPanel *PanelCopyright;
        TPanel *PanelTitle;
        TPanel *PanelWhen;
        TPanel *Panel6;
        TImage *ImageTitle;
  TPanel *Panel2;
private: // User declarations
public: // User declarations
        __fastcall TFormAbout(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TFormAbout *FormAbout;
//---------------------------------------------------------------------------
#endif

 

 

 

 

 

UnitFormPressKey.cpp

 

//---------------------------------------------------------------------------
/*
  SearchAndDestroyChess 2, Kriegspiel/Dark Chess game
  Copyright (C) 2008  Richel Bilderbeek

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "UnitFormPressKey.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TFormPressKey *FormPressKey;
//---------------------------------------------------------------------------
__fastcall TFormPressKey::TFormPressKey(TComponent* Owner,const String& s)
        : TForm(Owner)
{
  Panel1->Caption = s;
}
//---------------------------------------------------------------------------
void __fastcall TFormPressKey::FormKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
  Close();        
}
//---------------------------------------------------------------------------
void __fastcall TFormPressKey::Panel1Click(TObject *Sender)
{
  Close();        
}
//---------------------------------------------------------------------------


 

 

 

 

 

UnitFormPressKey.h

 

//---------------------------------------------------------------------------
/*
  SearchAndDestroyChess 2, Kriegspiel/Dark Chess game
  Copyright (C) 2008  Richel Bilderbeek

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl
//---------------------------------------------------------------------------
#ifndef UnitFormPressKeyH
#define UnitFormPressKeyH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TFormPressKey : public TForm
{
__published: // IDE-managed Components
        TPanel *Panel1;
        void __fastcall FormKeyDown(TObject *Sender, WORD &Key,
          TShiftState Shift);
        void __fastcall Panel1Click(TObject *Sender);
private: // User declarations
public: // User declarations
        __fastcall TFormPressKey(TComponent* Owner, const String& s);
};
//---------------------------------------------------------------------------
extern PACKAGE TFormPressKey *FormPressKey;
//---------------------------------------------------------------------------
#endif

 

 

 

 

 

UnitFormSearchAndDestroyChess2.cpp

 

//---------------------------------------------------------------------------
/*
  SearchAndDestroyChess 2, Kriegspiel/Dark Chess game
  Copyright (C) 2008  Richel Bilderbeek

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl
//---------------------------------------------------------------------------
#include <cstdlib>
#include <ctime>
#include <cassert>
#include <vector>
#include <stdexcept>
#include <boost/shared_ptr.hpp>
#include "UnitChessBoard.h"
#include "UnitChessPiece.h"
#include "UnitCoordinatGetter.h"
#include <vcl.h>
#pragma hdrstop

#include "UnitFormSearchAndDestroyChess2.h"
#include "UnitFormPressKey.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TFormSearchAndDestroyChess2 *FormSearchAndDestroyChess2;
//---------------------------------------------------------------------------
__fastcall TFormSearchAndDestroyChess2::TFormSearchAndDestroyChess2(
    TComponent* Owner,
    const bool isWhiteHuman,
    const bool isBlackHuman)
  : TForm(Owner),
    mIsWhiteHuman(isWhiteHuman),
    mIsBlackHuman(isBlackHuman),
    mCursorX(3),
    mCursorY(3),
    mSelectX(-1),
    mSelectY(-1)
{
  RandomizeTimer();

  this->Width  = Screen->Width  / 2;
  this->Height = Screen->Height / 2;
  this->Left   = Screen->Width  / 4;
  this->Top    = Screen->Height / 4;

  ImageSelected->Picture->Bitmap->TransparentColor = clLime;
  ImageSelected->Transparent = true;
  ImageCursor->Picture->Bitmap->TransparentColor = clLime;
  ImageCursor->Transparent = true;
  ImageCross->Picture->Bitmap->TransparentColor = clLime;
  ImageCross->Transparent = true;
  OnResize(0);

  if (mIsWhiteHuman)
  {
    const String s = "Player white, please press a key to start game.";
    boost::shared_ptr<TFormPressKey> form(new TFormPressKey(0,s));
    form->ShowModal();
  }

  Timer1->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TFormSearchAndDestroyChess2::FormResize(TObject *Sender)
{
  ImageBuffer->Picture->Bitmap->Width  = ClientWidth;
  ImageBuffer->Picture->Bitmap->Height = ClientHeight;

  DrawChessBoard();
}
//---------------------------------------------------------------------------
void TFormSearchAndDestroyChess2::DrawChessBoard()
{
  const std::vector<std::vector<bool> > inSight = mGame.GetInSight();
  const double squareWidth  = static_cast<double>(ClientWidth ) / 8.0;
  const double squareHeight = static_cast<double>(ClientHeight) / 8.0;
  //The CoordinatGetter transforms the coordinats of the board,
  //according to the player whose turn it is
  const CoordinatGetter coordinatGetter ( mGame.GetWhoseTurn());

  //Draw squares, question marks and pieces
  {
    const ChessBoard board = mGame.GetBoard();

    //Draw all squares on buffer (clearing it)
    for (int y=0; y!=8; ++y)
    {
      for (int x=0; x!=8; ++x)
      {
        const TImage * const image
          = ( (x + y) % 2 == 0 ? ImageWhiteSquare : ImageBlackSquare);
        //Draw it
        ImageBuffer->Canvas->StretchDraw(
          TRect( TPoint( ( coordinatGetter.GetX(x) + 0 ) * squareWidth ,
                         ( coordinatGetter.GetY(y) + 0 ) * squareHeight),
                 TPoint( ( coordinatGetter.GetX(x) + 1 ) * squareWidth ,
                         ( coordinatGetter.GetY(y) + 1 ) * squareHeight)
            ), image->Picture->Graphic);
      }
    }

    //Draw all question marks and pieces
    for (int y=0; y!=8; ++y)
    {
      for (int x=0; x!=8; ++x)
      {
        const TImage * const image = GetImage(inSight[y][x],board.GetPiece(x,y));
        if( image == 0) continue;
        //Draw it
        ImageBuffer->Canvas->StretchDraw(
          TRect( TPoint( ( coordinatGetter.GetX(x) + 0 ) * squareWidth ,
                         ( coordinatGetter.GetY(y) + 0 ) * squareHeight),
                 TPoint( ( coordinatGetter.GetX(x) + 1 ) * squareWidth ,
                         ( coordinatGetter.GetY(y) + 1 ) * squareHeight)
            ), image->Picture->Graphic);

      }
    }
  }

  //Draw selected
  if (mSelectX != -1)
  {
    //Draw selection cursor
    ImageBuffer->Canvas->StretchDraw(
      TRect( TPoint( ( coordinatGetter.GetX(mSelectX) + 0 ) * squareWidth ,
                     ( coordinatGetter.GetY(mSelectY) + 0 ) * squareHeight),
             TPoint( ( coordinatGetter.GetX(mSelectX) + 1 ) * squareWidth ,
                     ( coordinatGetter.GetY(mSelectY) + 1 ) * squareHeight)
        ), ImageSelected->Picture->Graphic);

    //If a chesspiece is selected, draw the crosses on the areas which
    //are valid moves
    if (mGame.GetBoard().GetPiece(mSelectX, mSelectY).IsNull() == false)
    {
      const std::vector<ChessMove> possibleMoves
        = mGame.GetBoard().GetAllValidMoves(mSelectX,mSelectY);
      typedef std::vector<ChessMove>::const_iterator Iterator;
      const Iterator lastMove = possibleMoves.end();
      for (Iterator possibleMove = possibleMoves.begin();
        possibleMove != lastMove;
        ++possibleMove)
      {
        ImageBuffer->Canvas->StretchDraw(
          TRect(
            TPoint( ( coordinatGetter.GetX(possibleMove->x2) + 0 ) * squareWidth ,
                    ( coordinatGetter.GetY(possibleMove->y2) + 0 ) * squareHeight),
            TPoint( ( coordinatGetter.GetX(possibleMove->x2) + 1 ) * squareWidth ,
                    ( coordinatGetter.GetY(possibleMove->y2) + 1 ) * squareHeight)
            ), ImageCross->Picture->Graphic);
      }
    }
  }

  //Draw cursor
  ImageBuffer->Canvas->StretchDraw(
    TRect( TPoint( ( coordinatGetter.GetX(mCursorX) + 0 ) * squareWidth ,
                   ( coordinatGetter.GetY(mCursorY) + 0 ) * squareHeight),
           TPoint( ( coordinatGetter.GetX(mCursorX) + 1 ) * squareWidth ,
                   ( coordinatGetter.GetY(mCursorY) + 1 ) * squareHeight)
      ), ImageCursor->Picture->Graphic);

  //Draw board and pieces to screen
  this->Canvas->Draw(0,0,ImageBuffer->Picture->Graphic);
  //ImageBuffer->Visible = true;
}
//---------------------------------------------------------------------------
const TImage * const TFormSearchAndDestroyChess2::GetImage(
  const bool inSight,
  const ChessPiece& piece) const
{
  //Visible?
  if (inSight== false) return ImageQuestionMark;
  //Piece located there?
  //No piece present? Then return null
  if (piece.IsNull()==true) { return 0; }
  //Piece present, draw a piece
  //Which color and type?
  const EnumChessPieceColor pieceColor = piece.GetColor();
  switch ( piece.GetType() )
  {
    case king  : return ( pieceColor == white ? ImageWhiteKing   : ImageBlackKing  );
    case queen : return ( pieceColor == white ? ImageWhiteQueen  : ImageBlackQueen );
    case rook  : return ( pieceColor == white ? ImageWhiteRook   : ImageBlackRook  );
    case bishop: return ( pieceColor == white ? ImageWhiteBishop : ImageBlackBishop);
    case knight: return ( pieceColor == white ? ImageWhiteKnight : ImageBlackKnight);
    case pawn  : return ( pieceColor == white ? ImageWhitePawn   : ImageBlackPawn  );
  }
  assert(!"Should not get here. Unknown piece type");
  throw std::logic_error("Unknown piece type");

}
//---------------------------------------------------------------------------
void __fastcall TFormSearchAndDestroyChess2::FormKeyDown(TObject *Sender,
      WORD &Key, TShiftState Shift)
{
  switch (Key)
  {
    case VK_LEFT: case 65: //A
      if (mGame.GetWhoseTurn()==white)
      {
        --mCursorX; if (mCursorX < 0) mCursorX = 0;
      }
      else
      {
        ++mCursorX; if (mCursorX > 7) mCursorX = 7;
      }
      break;
    case VK_RIGHT: case 68: //D
      if (mGame.GetWhoseTurn()==white)
      {
        ++mCursorX; if (mCursorX > 7) mCursorX = 7;
      }
      else
      {
        --mCursorX; if (mCursorX < 0) mCursorX = 0;
      }
      break;
    case VK_DOWN: case 83: //W
      if (mGame.GetWhoseTurn()==white)
      {
        --mCursorY; if (mCursorY < 0) mCursorY = 0;
      }
      else
      {
        ++mCursorY; if (mCursorY > 7) mCursorY = 7;
      }
      break;
    case VK_UP: case 87: //S
      if (mGame.GetWhoseTurn()==white)
      {
        ++mCursorY; if (mCursorY > 7) mCursorY = 7;
      }
      else
      {
        --mCursorY; if (mCursorY < 0) mCursorY = 0;
      }
      break;
    case VK_RETURN: case VK_SPACE:
      DoSelect(mCursorX, mCursorY);
    default: return;
  }
  this->DrawChessBoard();
}
//---------------------------------------------------------------------------
void TFormSearchAndDestroyChess2::DoMove()
{
  const int x1 = mSelectX;
  const int y1 = mSelectY;
  const int x2 = mCursorX;
  const int y2 = mCursorY;
  if (mSelectX == -1) return;
  if (mCursorX == -1) return;
  assert(x1 >=0);
  assert(x2 >=0);
  assert(x1 < 8);
  assert(x2 < 8);
  assert(y1 >=0);
  assert(y2 >=0);
  assert(y1 < 8);
  assert(y2 < 8);
  const ChessPiece piece = mGame.GetBoard().GetPiece(x1,y1);
  assert(piece.IsNull()==false
    && "User must not be able to select an empty square do do a move from");
  const EnumChessPieceType type = piece.GetType();
  const ChessPiece victim = mGame.GetBoard().GetPiece(x2,y2);
  const bool capture = (victim.IsNull()==true ? false : true);
  const ChessMove move(type,x1,y1,capture,x2,y2);
  this->DoMove(move);
  mSelectX = -1;
  mSelectY = -1;
}
//---------------------------------------------------------------------------
void TFormSearchAndDestroyChess2::DoMove(const ChessMove& move)
{
  if (mGame.CanDoMove(move)==false)
  {
    //Nothing happens anymore...
  }
  else
  {
    //A move takes place
    mGame.DoMove(move);
    //Change player

    //Turn off timer
    Timer1->Enabled = false;
    //Clear the buffer
    ImageBuffer->Canvas->StretchDraw(
      TRect(TPoint(0,0),TPoint(ClientWidth,ClientHeight)),
      ImageQuestionMark->Picture->Graphic );
    //Show the background
    this->Canvas->StretchDraw(
      TRect(TPoint(0,0),TPoint(ClientWidth,ClientHeight)),
      ImageQuestionMark->Picture->Graphic );

        //Game over?
    if (mGame.IsGameOver()==true)
    {
      const String s
        = "Player "
        + String(mGame.GetWinner() == white ? "white" : "black")
        + " has won the game!";
      boost::shared_ptr<TFormPressKey> form(new TFormPressKey(0,s));
      form->ShowModal();
      mGame = ChessGame();
    }
    else
    {
      if (IsCurrentPlayerHuman()==true)
      {
        //Ask for another player
        const String s
          = "Player "
          + String(mGame.GetWhoseTurn() == white ? "white" : "black")
          + ", please press a key to make your move.";
        boost::shared_ptr<TFormPressKey> form(new TFormPressKey(0,s));
        form->ShowModal();
      }
    }
    //Turn back timer on
    Timer1->Enabled = true;
    if (IsCurrentPlayerHuman()==true)
    {
      //On to the next player
      mCursorX = std::rand() % 8;
      mCursorY = std::rand() % 8;
      //Draw the chessboard
      DrawChessBoard();
    }
  }
}
//---------------------------------------------------------------------------
const bool TFormSearchAndDestroyChess2::IsCurrentPlayerHuman() const
{
  return ( (mGame.GetWhoseTurn() == white && mIsWhiteHuman == true)
    || (mGame.GetWhoseTurn() == black && mIsBlackHuman == true) );
}
//---------------------------------------------------------------------------
void __fastcall TFormSearchAndDestroyChess2::Timer1Timer(TObject *Sender)
{
  if (IsCurrentPlayerHuman()==false)
  {
    const ChessMove move = mGame.SuggestMove();
    this->DoMove(move);
  }
  else
  {
    DrawChessBoard();
  }
}
//---------------------------------------------------------------------------

void __fastcall TFormSearchAndDestroyChess2::FormMouseDown(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
  if (mGame.GetWhoseTurn()==white)
  {
    mCursorX = 0 + (X / (ClientWidth  / 8));
    mCursorY = 7 - (Y / (ClientHeight / 8));
  }
  else
  {
    mCursorX = 7 - (X / (ClientWidth  / 8));
    mCursorY = 0 + (Y / (ClientHeight / 8));
  }

  if (mCursorX < 0) mCursorX = 0;
  if (mCursorY < 0) mCursorY = 0;
  if (mCursorX > 7) mCursorX = 7;
  if (mCursorY > 7) mCursorY = 7;

  DoSelect(mCursorX, mCursorY);
}
//---------------------------------------------------------------------------
void TFormSearchAndDestroyChess2::DoSelect(const int cursorX, const int cursorY)
{
  if ( mSelectX == -1
    && mSelectY == -1
    && mGame.GetBoard().GetPiece(cursorX,cursorY).IsNull()==false)
  {
    //Nothing selected until now
    mSelectX = cursorX;
    mSelectY = cursorY;
  }
  else if (
       mSelectX != -1
    && mSelectY != -1
    && mGame.GetBoard().GetPiece(mSelectX,mSelectY).IsNull() == false
    && mGame.GetBoard().GetPiece(mSelectX,mSelectY).GetColor() == mGame.GetWhoseTurn()
    && mGame.GetBoard().GetPiece(cursorX,cursorY).IsNull() == false
    && mGame.GetBoard().GetPiece(cursorX,cursorY).GetColor() == mGame.GetWhoseTurn() )
  {
    //Selected a piece of own color and now selecting another piece
    //of own color
    mSelectX = cursorX;
    mSelectY = cursorY;
  }
  else
  {
    DoMove();
  }
}
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/CppRandomizeTimer.htm
void RandomizeTimer()
{
  std::srand(std::time(0));
}
//---------------------------------------------------------------------------


 

 

 

 

 

UnitFormSearchAndDestroyChess2.h

 

//---------------------------------------------------------------------------
/*
  SearchAndDestroyChess 2, Kriegspiel/Dark Chess game
  Copyright (C) 2008  Richel Bilderbeek

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl
//---------------------------------------------------------------------------
#ifndef UnitFormSearchAndDestroyChess2H
#define UnitFormSearchAndDestroyChess2H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include <Graphics.hpp>
//---------------------------------------------------------------------------
#include "UnitChessGame.h"
#include <ComCtrls.hpp>
//---------------------------------------------------------------------------
class TFormSearchAndDestroyChess2 : public TForm
{
__published: // IDE-managed Components
        TImage *ImageBuffer;
        TImage *ImageBlackBishop;
        TImage *ImageBlackKnight;
        TImage *ImageBlackKing;
        TImage *ImageBlackPawn;
        TImage *ImageBlackQueen;
        TImage *ImageBlackRook;
        TImage *ImageWhiteKing;
        TImage *ImageWhiteQueen;
        TImage *ImageWhiteRook;
        TImage *ImageWhiteBishop;
        TImage *ImageWhiteKnight;
        TImage *ImageWhitePawn;
        TImage *ImageSelected;
        TImage *ImageCursor;
        TTimer *Timer1;
        TImage *ImageQuestionMark;
        TImage *ImageWhiteSquare;
        TImage *ImageBlackSquare;
  TImage *ImageCross;
        void __fastcall FormResize(TObject *Sender);
        void __fastcall FormKeyDown(TObject *Sender, WORD &Key,
          TShiftState Shift);
        void __fastcall Timer1Timer(TObject *Sender);
        void __fastcall FormMouseDown(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y);

private: // User declarations
  ChessGame mGame;
  void DrawChessBoard();
  int mCursorX, mCursorY;
  int mSelectX, mSelectY;
  void DoMove();
  void DoMove(const ChessMove& move);
  const bool IsCurrentPlayerHuman() const;
  const TImage * const GetImage(
    const bool inSight,
    const ChessPiece& piece) const;
  void DoSelect(const int cursorX, const int cursorY);
public: // User declarations
  __fastcall TFormSearchAndDestroyChess2(
    TComponent* Owner,
    const bool isWhiteHuman,
    const bool isBlackHuman);
  const bool mIsWhiteHuman;
  const bool mIsBlackHuman;
};
//---------------------------------------------------------------------------
extern PACKAGE TFormSearchAndDestroyChess2 *FormSearchAndDestroyChess2;
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/CppRandomizeTimer.htm
void RandomizeTimer();
//---------------------------------------------------------------------------

#endif

 

 

 

 

 

UnitFormSearchAndDestroyChess2Menu.cpp

 

//---------------------------------------------------------------------------
/*
  SearchAndDestroyChess 2, Kriegspiel/Dark Chess game
  Copyright (C) 2008  Richel Bilderbeek

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl
//---------------------------------------------------------------------------
#include <boost/shared_ptr.hpp>
#include "UnitChessBoard.h"
#include "UnitChessPiece.h"
#include <vcl.h>
#pragma hdrstop

#include "UnitFormSearchAndDestroyChess2Menu.h"
#include "UnitFormAbout.h"
#include "UnitFormSearchAndDestroyChess2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TFormSearchAndDestroyChessMenu *FormSearchAndDestroyChessMenu;
//---------------------------------------------------------------------------
__fastcall TFormSearchAndDestroyChessMenu::TFormSearchAndDestroyChessMenu(TComponent* Owner)
        : TForm(Owner)
{
  /*
  this->Width  = Screen->Width  / 2;
  this->Height = Screen->Height / 2;
  this->Left   = Screen->Width  / 4;
  this->Top    = Screen->Height / 4;
  */
  this->Width  = 430;
  this->Height = 430;
  this->Left   = (Screen->Width  - 430) / 2;
  this->Top    = (Screen->Height - 430) / 2;

  OnResize(0);
}
//---------------------------------------------------------------------------
void __fastcall TFormSearchAndDestroyChessMenu::PanelQuitClick(
      TObject *Sender)
{
  Close();        
}
//---------------------------------------------------------------------------
void __fastcall TFormSearchAndDestroyChessMenu::PanelAboutClick(
      TObject *Sender)
{
  boost::shared_ptr<TFormAbout> form(new TFormAbout(0));
  form->ShowModal();

}
//---------------------------------------------------------------------------
void __fastcall TFormSearchAndDestroyChessMenu::PanelStartClick(
      TObject *Sender)
{
  const bool isWhiteHuman = ImageWhiteHuman->Visible;
  const bool isBlackHuman = ImageBlackHuman->Visible;
  boost::shared_ptr<TFormSearchAndDestroyChess2> form(
    new TFormSearchAndDestroyChess2(0, isWhiteHuman, isBlackHuman));
  form->ShowModal();

}
//---------------------------------------------------------------------------
void __fastcall TFormSearchAndDestroyChessMenu::FormKeyDown(
      TObject *Sender, WORD &Key, TShiftState Shift)
{
  if (Key == 's' || Key == 'S') PanelStartClick(0);
  if (Key == 'a' || Key == 'A') PanelAboutClick(0);
  if (Key == 'q' || Key == 'Q') PanelQuitClick(0);
}
//---------------------------------------------------------------------------
void __fastcall TFormSearchAndDestroyChessMenu::ImageWhiteClick(
      TObject *Sender)
{
  ImageWhiteHuman->Visible = !ImageWhiteHuman->Visible;
  ImageWhiteComputer->Visible = !ImageWhiteComputer->Visible;
}
//---------------------------------------------------------------------------
void __fastcall TFormSearchAndDestroyChessMenu::ImageBlackClick(
      TObject *Sender)
{
  ImageBlackHuman->Visible = !ImageBlackHuman->Visible;
  ImageBlackComputer->Visible = !ImageBlackComputer->Visible;
}
//---------------------------------------------------------------------------

void __fastcall TFormSearchAndDestroyChessMenu::FormResize(TObject *Sender)
{
  const int height = ClientHeight;
  const int panelHeight = height / 6;
  PanelTitle->Height = panelHeight * 2;
  PanelVersus->Height = panelHeight;
  PanelStart->Height = panelHeight;
  PanelAbout->Height = panelHeight;
  PanelQuit->Height = panelHeight;
  const int imageHeight = panelHeight - 2;
  const int imageWidth = panelHeight - 2;
  ImageBlackKing->Height = imageHeight;
  ImageWhiteKing->Height = imageHeight;
  ImageBlackQueen->Height = imageHeight;
  ImageWhiteQueen->Height = imageHeight;
  ImageBlackPawn->Height = imageHeight;
  ImageWhitePawn->Height = imageHeight;
  ImageWhiteHuman->Height = imageHeight;
  ImageBlackHuman->Height = imageHeight;
  ImageWhiteComputer->Height = imageHeight;
  ImageBlackComputer->Height = imageHeight;

  ImageBlackKing->Width = imageWidth;
  ImageWhiteKing->Width = imageWidth;
  ImageBlackQueen->Width = imageWidth;
  ImageWhiteQueen->Width = imageWidth;
  ImageBlackPawn->Width = imageWidth;
  ImageWhitePawn->Width = imageWidth;
  ImageWhiteHuman->Width = imageWidth;
  ImageBlackHuman->Width = imageWidth;
  ImageWhiteComputer->Width = imageWidth;
  ImageBlackComputer->Width = imageWidth;

}
//---------------------------------------------------------------------------


 

 

 

 

 

UnitFormSearchAndDestroyChess2Menu.h

 

//---------------------------------------------------------------------------
/*
  SearchAndDestroyChess 2, Kriegspiel/Dark Chess game
  Copyright (C) 2008  Richel Bilderbeek

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl
//---------------------------------------------------------------------------
#ifndef UnitFormSearchAndDestroyChessMenuH
#define UnitFormSearchAndDestroyChessMenuH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include <Graphics.hpp>
//---------------------------------------------------------------------------
class TFormSearchAndDestroyChessMenu : public TForm
{
__published: // IDE-managed Components
        TImage *ImageBlackKing;
        TImage *ImageWhiteKing;
        TPanel *PanelStart;
        TImage *ImageBlackQueen;
        TImage *ImageWhiteQueen;
        TImage *ImageBlackPawn;
        TImage *ImageWhitePawn;
        TPanel *PanelAbout;
        TPanel *PanelQuit;
        TPanel *PanelTitle;
        TImage *ImageTitle;
        TPanel *PanelVersus;
        TImage *ImageWhiteHuman;
        TImage *ImageBlackHuman;
        TImage *ImageWhiteComputer;
        TImage *ImageBlackComputer;
        void __fastcall PanelQuitClick(TObject *Sender);
        void __fastcall PanelAboutClick(TObject *Sender);
        void __fastcall PanelStartClick(TObject *Sender);
        void __fastcall FormKeyDown(TObject *Sender, WORD &Key,
          TShiftState Shift);
        void __fastcall ImageWhiteClick(TObject *Sender);
        void __fastcall ImageBlackClick(TObject *Sender);
        void __fastcall FormResize(TObject *Sender);
private: // User declarations
public: // User declarations
        __fastcall TFormSearchAndDestroyChessMenu(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TFormSearchAndDestroyChessMenu *FormSearchAndDestroyChessMenu;
//---------------------------------------------------------------------------
#endif

 

 

 

 

 

UnitSearchAndDestroyChess2Main.cpp

 

//---------------------------------------------------------------------------
/*
  SearchAndDestroyChess, a special kind of chess game
  Copyright (C) 2008  Richel Bilderbeek

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl
//---------------------------------------------------------------------------
#include <string>
#include <iostream>
#include "UnitChessGame.h"
#include "UnitEnumChessPieceColor.h"
#include "UnitEnumChessPieceType.h"
#include "UnitChessPiece.h"

#pragma hdrstop

//---------------------------------------------------------------------------
//From http://www.richelbilderbeek/CppAskUserForString.htm
const std::string AskUserForString()
{
  std::string s;
  std::getline(std::cin,s);
  return s;
}
//---------------------------------------------------------------------------
const bool AskUserForYesNo()
{
  while (1)
  {
    const std::string s = AskUserForString();
    if (s.empty()==true) continue;
    if (s[0] == 'y' || s[0] == 'Y' || s == "yes" || s == "Yes" || s == "YES") return true;
    if (s[0] == 'n' || s[0] == 'N' || s == "no" || s == "No" || s == "NO")    return false;
  }
}
//---------------------------------------------------------------------------
void ClearScreen()
{
  //'clear' the screen
  for (int i=0; i!=50; ++i) std::cout << std::endl;
}
//---------------------------------------------------------------------------
void ShowLicence()
{
  std::cout
    << std::string(79,'*') << std::endl
    << "LICENCE" << std::endl
    << std::endl
    << "SearchAndDestroyChess, a special kind of chess game" << std::endl
    << "Copyright (C) 2008  Richel Bilderbeek" << std::endl
    << std::endl
    << "This program is free software: you can redistribute it and/or modify" << std::endl
    << "it under the terms of the GNU General Public License as published by" << std::endl
    << "the Free Software Foundation, either version 3 of the License, or" << std::endl
    << "(at your option) any later version." << std::endl
    << std::endl
    << "This program is distributed in the hope that it will be useful," << std::endl
    << "but WITHOUT ANY WARRANTY; without even the implied warranty of" << std::endl
    << "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the" << std::endl
    << "GNU General Public License for more details." << std::endl
    << "You should have received a copy of the GNU General Public License" << std::endl
    << "along with this program.  If not, see <http://www.gnu.org/licenses/>." << std::endl
    << std::string(79,'*') << std::endl
    << "Programmed at the 4th, 5th and 6th July 2008" << std::endl
    << "by Richel Bilderbeek" << std::endl
    << "http://www.richelbilderbeek.nl"
    << std::endl;
}

#pragma argsused
int main()
{
  ShowLicence();

  std::cout
    << std::string(79,'*')
    << std::endl
    << "Welcome to Search And Destroy Chess."
    << std::endl
    << "White player, please"
    << std::endl
    << "press any key to start the game"
    << std::endl;
  AskUserForString();

  ClearScreen();

  std::cout << "Is player #1 (white) a human player (y/n) ?" << std::endl;
  const bool isPlayerOneHuman = AskUserForYesNo();
  std::cout << "Is player #2 (black) a human player (y/n) ?" << std::endl;
  const bool isPlayerTwoHuman = AskUserForYesNo();


  ChessGame game;
  while(1)
  {
    game.CoutGame();

    if ( (game.GetWhoseTurn() == white && isPlayerOneHuman == true)
      || (game.GetWhoseTurn() == black && isPlayerTwoHuman == true) )
    {
      //Human move
      const std::string input = AskUserForString();

      if (input == "q" || input == "Q" || input == "exit"    || input == "quit") break;
      if (input == "r" || input == "R" || input == "restart" || input == "new ")
      {
        game = ChessGame();
        continue;
      }

      ChessMove move;

      const bool validInput = game.ParseMove(input,move);
      if (validInput == false) continue;

      const bool validMove = game.CanDoMove(move);
      if (validMove == false) continue;

      game.DoMove(move);
    }
    else
    {
      //Computer move
      const ChessMove move = game.SuggestMove();
      game.DoMove(move);
    }

    if (game.IsGameOver()==true)
    {
      game.CoutGame();

      std::cout
        << "Game won by "
        << (game.GetWinner() == white ? "white" : "black")
        << " player." << std::endl
        << "Press any key to start a new game" << std::endl;
      const std::string input = AskUserForString();
      if (input == "q" || input == "Q" || input == "exit"    || input == "quit") break;
      game = ChessGame();
    }


    if ( (game.GetWhoseTurn() == white && isPlayerOneHuman == true)
      || (game.GetWhoseTurn() == black && isPlayerTwoHuman == true) )
    {
      //Human input
      ClearScreen();


      std::cout
        << (game.GetWhoseTurn() == white ? "white" : "black")
        << " player, please" << std::endl
        << "press any key to view the board" << std::endl;
      AskUserForString();
      ClearScreen();
    }
  }

  ShowLicence();
  std::cout
    << "press any key to quit"
    << std::endl;
  AskUserForString();

}
//---------------------------------------------------------------------------

 

 

 

 

 

 

 

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict