200 lines
5.4 KiB
C++
200 lines
5.4 KiB
C++
// #include "ChessContext.h"
|
|
|
|
/* [0] Constructeur
|
|
=========================================================*/
|
|
ChessContext::ChessContext(){
|
|
setfont(GREEN, BOLD);
|
|
cout << "[+] ChessContext" << endl;
|
|
setfont();
|
|
}
|
|
|
|
|
|
/* [1] Initialisation de la partie
|
|
=========================================================*/
|
|
void ChessContext::init(){
|
|
_p1 = new Player(true);
|
|
_p2 = new Player(false);
|
|
|
|
_turn = '1';
|
|
|
|
_p1->initPieces();
|
|
_p2->initPieces();
|
|
}
|
|
|
|
|
|
/* [2] Renvoie le pion qui est en case (x, y)
|
|
=========================================================*/
|
|
Piece* ChessContext::at(const int x, const int y){
|
|
// On verifie que c'est pas le Player 1 qui l'a
|
|
Piece *p;
|
|
p = _p1->at(x, y);
|
|
if( p != NULL )
|
|
return p;
|
|
|
|
// On verifie que c'est pas le Player 2 qui l'a
|
|
p = _p2->at(x, y);
|
|
if( p != NULL )
|
|
return p;
|
|
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/* [3] Verifie si un deplacement est possible
|
|
=========================================================*/
|
|
bool ChessContext::checkMove(Piece& p, int x, int y){
|
|
/* (1) On verifie que c'est une piece du joueur courant */
|
|
Player *current = (_turn=='1') ? _p1 : _p2; // Player courant
|
|
Player *enemy = (_turn=='1') ? _p2 : _p1; // Player enemi
|
|
|
|
// Si c'est pas un pion du courant, on retourne FAUX
|
|
if( !current->owns(p) )
|
|
return false;
|
|
|
|
|
|
/* (2) On verifie qu'on va pas sur une de nos pieces */
|
|
Piece *pieceAtDest = this->at(x, y);
|
|
|
|
// Si on se deplace sur une de nos pieces
|
|
if( pieceAtDest != NULL && current->owns(*pieceAtDest) )
|
|
return false;
|
|
|
|
|
|
/* (3) Gestion en fonction du type de piece */
|
|
switch( p.gett() ){
|
|
case PION: return this->checkPion(p, x, y); break;
|
|
case FOU: return this->checkFou(p, x, y); break;
|
|
case TOUR: return this->checkTour(p, x, y); break;
|
|
case CAVALIER: return this->checkCavalier(p, x, y); break;
|
|
case ROI: return this->checkRoi(p, x, y); break;
|
|
case REINE: return this->checkReine(p, x, y); break;
|
|
}
|
|
|
|
|
|
// On retourne FAUX par defaut
|
|
return false;
|
|
}
|
|
|
|
|
|
/* [4] Renvoie le joueur courant / enemi
|
|
=========================================================*/
|
|
Player* ChessContext::getCurrent(){
|
|
return (_turn=='1') ? _p1 : _p2;
|
|
}
|
|
|
|
Player* ChessContext::getEnemy(){
|
|
return (_turn=='1') ? _p2 : _p1;
|
|
}
|
|
|
|
|
|
|
|
|
|
/* [5] Verifie le deplacement d'un PION
|
|
=========================================================*/
|
|
bool ChessContext::checkPion(Piece& p, int x, int y){
|
|
|
|
int way = _turn=='1' ? -1 : 1; // sens de marche
|
|
int baseline = _turn=='1' ? 6 : 1; // position initiale
|
|
|
|
// CAS 1 : Deplacement 1 vers avant
|
|
bool move1Front = p.getx()==x && p.gety()+way==y;
|
|
|
|
// CAS 2 : Deplacement 2 vers avant (si sur ligne depart)
|
|
bool move2Front = p.getx()==x && p.gety()+2*way==y && p.gety()==baseline;
|
|
|
|
// CAS 3 : Mange un pion adjacent (diagonale && 1 case && enemi)
|
|
int xDiff = abs(p.getx()-x);
|
|
int yDiff = abs(p.gety()-y);
|
|
bool eatEnemy = xDiff == yDiff && xDiff==1 && this->at(x, y) != NULL && this->getEnemy()->owns(*this->at(x, y));
|
|
|
|
return move1Front || move2Front || eatEnemy;
|
|
|
|
}
|
|
|
|
/* [6] Verifie le deplacement d'un FOU
|
|
=========================================================*/
|
|
bool ChessContext::checkFou(Piece& p, int x, int y){
|
|
|
|
// Deplacement diagonal
|
|
bool inDiag = abs(p.getx()-x) == abs(p.gety()-y);
|
|
|
|
// Si deplacement pas en diagonale, on retourne faux
|
|
if( !inDiag ) return false;
|
|
|
|
// On verifie que la diagonale est degagee
|
|
int xstep = (x-p.getx()) / abs(x-p.getx());
|
|
int ystep = (y-p.gety()) / abs(y-p.gety());
|
|
|
|
for( int i = p.getx()+xstep, j = p.gety()+ystep ; i != x && j != y ; i+=xstep, j+=ystep )
|
|
if( this->at(i, j) != NULL ) return false;
|
|
|
|
// Si on a pas retourne faux, on retourne VRAI
|
|
return true;
|
|
|
|
}
|
|
|
|
/* [7] Verifie le deplacement d'une TOUR
|
|
=========================================================*/
|
|
bool ChessContext::checkTour(Piece& p, int x, int y){
|
|
|
|
// Deplacement horizontal ou vertical
|
|
bool inLine = ( x==p.getx() || y==p.gety() );
|
|
|
|
// On verifie que le chemin est degage
|
|
bool moveY = p.getx() == x;
|
|
int originMovingAxis = (moveY) ? p.gety() : p.getx();
|
|
int destMovingAxis = (moveY) ? y : x;
|
|
|
|
int way = (destMovingAxis-originMovingAxis) / abs(destMovingAxis-originMovingAxis);
|
|
|
|
for( int i = originMovingAxis+way ; i != destMovingAxis ; i+=way ){
|
|
if( moveY ) // si on se deplace sur y
|
|
if( this->at(x, i) != NULL ) return false;
|
|
else // si on se deplace sur x
|
|
if( this->at(i, y) != NULL ) return false;
|
|
}
|
|
|
|
return inLine;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* [8] Verifie le deplacement d'un CAVALIER
|
|
=========================================================*/
|
|
bool ChessContext::checkCavalier(Piece& p, int x, int y){
|
|
|
|
bool horizontalL = abs(x-p.getx()) == 2 && abs(y-p.gety()) == 1;
|
|
bool verticalL = abs(x-p.getx()) == 1 && abs(y-p.gety()) == 2;
|
|
|
|
return horizontalL || verticalL;
|
|
|
|
}
|
|
|
|
|
|
/* [9] Verifie le deplacement d'un ROI
|
|
=========================================================*/
|
|
bool ChessContext::checkRoi(Piece& p, int x, int y){
|
|
|
|
bool fouMove = this->checkFou(p, x, y);
|
|
bool tourMove = this->checkTour(p, x, y);
|
|
|
|
bool oneCaseMove = abs(p.getx()-x) + abs(p.gety()-y) == 1;
|
|
bool twoCaseMove = abs(p.getx()-x) + abs(p.gety()-y) == 2;
|
|
|
|
return tourMove&&oneCaseMove || fouMove&&twoCaseMove;
|
|
|
|
}
|
|
|
|
|
|
/* [10] Verifie le deplacement d'une REINE
|
|
=========================================================*/
|
|
bool ChessContext::checkReine(Piece& p, int x, int y){
|
|
|
|
bool fouMove = this->checkFou(p, x, y);
|
|
bool tourMove = this->checkTour(p, x, y);
|
|
|
|
return fouMove || tourMove;
|
|
}
|