diff --git a/Chess/dep/ChessContext.cpp b/Chess/dep/ChessContext.cpp index 5b60fd0..a525a00 100644 --- a/Chess/dep/ChessContext.cpp +++ b/Chess/dep/ChessContext.cpp @@ -24,18 +24,176 @@ void ChessContext::init(){ /* [2] Renvoie le pion qui est en case (x, y) =========================================================*/ -Player* ChessContext::at(const int x, const int 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 _p1; + return p; // On verifie que c'est pas le Player 2 qui l'a p = _p2->at(x, y); if( p != NULL ) - return _p2; + return p; return NULL; -} \ No newline at end of file +} + + +/* [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; +} diff --git a/Chess/dep/ChessContext.h b/Chess/dep/ChessContext.h index aeeb6fd..b504d35 100644 --- a/Chess/dep/ChessContext.h +++ b/Chess/dep/ChessContext.h @@ -8,6 +8,7 @@ #include #include #include + #include /* (2) Externes */ #include "term.h" @@ -23,12 +24,27 @@ public: ChessContext(); void init(); - Player* at(const int x, const int y); + Piece* at(const int x, const int y); + bool checkMove(Piece& p, int x, int y); + + // GETTERS + Player* getCurrent(); + Player* getEnemy(); // ATTRIBUTS char _turn; Player *_p1; Player *_p2; + + private: + // FONCTIONS UTILITAIRES + bool checkPion(Piece& p, int x, int y); + bool checkFou(Piece& p, int x, int y); + bool checkTour(Piece& p, int x, int y); + bool checkCavalier(Piece& p, int x, int y); + bool checkRoi(Piece& p, int x, int y); + bool checkReine(Piece& p, int x, int y); + }; /* [n] Inclusion du corps diff --git a/Chess/dep/Pieces/Cavalier.cpp b/Chess/dep/Pieces/Cavalier.cpp index da0cf95..a90deae 100644 --- a/Chess/dep/Pieces/Cavalier.cpp +++ b/Chess/dep/Pieces/Cavalier.cpp @@ -5,10 +5,6 @@ Cavalier::Cavalier(int x, int y) : Piece(CAVALIER, x, y) { } // ABSTRACT -bool Cavalier::can(int x, int y){ - return true; -} - char Cavalier::getchar(){ return 'C'; } diff --git a/Chess/dep/Pieces/Cavalier.h b/Chess/dep/Pieces/Cavalier.h index 59b511a..38a4db4 100644 --- a/Chess/dep/Pieces/Cavalier.h +++ b/Chess/dep/Pieces/Cavalier.h @@ -19,7 +19,6 @@ Cavalier(int x, int y); // ABSTRACT - bool can(int x, int y); char getchar(); }; diff --git a/Chess/dep/Pieces/Fou.cpp b/Chess/dep/Pieces/Fou.cpp index 3655447..2cc3774 100644 --- a/Chess/dep/Pieces/Fou.cpp +++ b/Chess/dep/Pieces/Fou.cpp @@ -5,37 +5,6 @@ Fou::Fou(int x, int y) : Piece(FOU, x, y) { } // ABSTRACT -bool Fou::can(int x, int y){ - bool inDiag = abs( _x-x ) == abs( _y-y ); - - // Si deplacement pas en diagonale, on retourne faux - if( !inDiag ) return false; - - // On verifie que la diagonale est degagee - int xstep = ( x-_x ) / abs( x-_x ); - int ystep = ( y-_y ) / abs( y-_y ); - - return true; -} - - -/*bool Fou::can(ChessContext *c, int x, int y){ - bool inDiag = abs( _x-x ) == abs( _y-y ); - - // Si deplacement pas en diagonale, on retourne faux - if( !inDiag ) return false; - - // On verifie que la diagonale est degagee - int xstep = ( x-_x ) / abs( x-_x ); - int ystep = ( y-_y ) / abs( y-_y ); - - for( int i = _x+xstep, j = _y+ystep ; i != x && j != y ; i+=xstep, j+=ystep ) - if( c->_p1->at(i, j) != NULL ) return false; - - - return true; -}*/ - char Fou::getchar(){ return 'F'; } diff --git a/Chess/dep/Pieces/Fou.h b/Chess/dep/Pieces/Fou.h index 54322b0..698cabd 100644 --- a/Chess/dep/Pieces/Fou.h +++ b/Chess/dep/Pieces/Fou.h @@ -8,7 +8,6 @@ /* (2) Externes */ #include "Piece.h" - class ChessContext; /* (3) Namespace */ using namespace std; @@ -20,8 +19,6 @@ Fou(int x, int y); // ABSTRACT - bool can(int x, int y); - //bool can(ChessContext *c, int x, int y); char getchar(); }; diff --git a/Chess/dep/Pieces/Piece.cpp b/Chess/dep/Pieces/Piece.cpp index 9b93df5..b405305 100644 --- a/Chess/dep/Pieces/Piece.cpp +++ b/Chess/dep/Pieces/Piece.cpp @@ -27,6 +27,4 @@ ostream& operator<<(ostream& o, const Piece& p){ } // ABTRACT -bool Piece::can(int x, int y){ return false; } -bool Piece::can(ChessContext *c, int x, int y){ return false; } char Piece::getchar(){ return '?'; } \ No newline at end of file diff --git a/Chess/dep/Pieces/Piece.h b/Chess/dep/Pieces/Piece.h index dc3a6d5..9f1c1ba 100644 --- a/Chess/dep/Pieces/Piece.h +++ b/Chess/dep/Pieces/Piece.h @@ -59,8 +59,6 @@ friend ostream& operator<<(ostream& o, const Piece& p); // ABSTRACT - virtual bool can(int x, int y); - virtual bool can(ChessContext *c, int x, int y); virtual char getchar(); diff --git a/Chess/dep/Pieces/Pion.cpp b/Chess/dep/Pieces/Pion.cpp index dca32c5..3be8128 100644 --- a/Chess/dep/Pieces/Pion.cpp +++ b/Chess/dep/Pieces/Pion.cpp @@ -5,10 +5,6 @@ Pion::Pion(int x, int y) : Piece(PION, x, y) { } // ABSTRACT -bool Pion::can(int x, int y){ - return true; -} - char Pion::getchar(){ return 'P'; } diff --git a/Chess/dep/Pieces/Pion.h b/Chess/dep/Pieces/Pion.h index 8d6f3a1..cbfe4f4 100644 --- a/Chess/dep/Pieces/Pion.h +++ b/Chess/dep/Pieces/Pion.h @@ -19,7 +19,6 @@ Pion(int x, int y); // ABSTRACT - bool can(int x, int y); char getchar(); }; diff --git a/Chess/dep/Pieces/Reine.cpp b/Chess/dep/Pieces/Reine.cpp index a002362..613efba 100644 --- a/Chess/dep/Pieces/Reine.cpp +++ b/Chess/dep/Pieces/Reine.cpp @@ -5,10 +5,6 @@ Reine::Reine(int x, int y) : Piece(REINE, x, y) { } // ABSTRACT -bool Reine::can(int x, int y){ - return true; -} - char Reine::getchar(){ return 'Q'; } diff --git a/Chess/dep/Pieces/Reine.h b/Chess/dep/Pieces/Reine.h index 2fbafd6..3944209 100644 --- a/Chess/dep/Pieces/Reine.h +++ b/Chess/dep/Pieces/Reine.h @@ -19,7 +19,6 @@ Reine(int x, int y); // ABSTRACT - bool can(int x, int y); char getchar(); }; diff --git a/Chess/dep/Pieces/Roi.cpp b/Chess/dep/Pieces/Roi.cpp index f228334..c887778 100644 --- a/Chess/dep/Pieces/Roi.cpp +++ b/Chess/dep/Pieces/Roi.cpp @@ -5,10 +5,6 @@ Roi::Roi(int x, int y) : Piece(ROI, x, y) { } // ABSTRACT -bool Roi::can(int x, int y){ - return true; -} - char Roi::getchar(){ return 'K'; } diff --git a/Chess/dep/Pieces/Roi.h b/Chess/dep/Pieces/Roi.h index a542c1b..3dfc81a 100644 --- a/Chess/dep/Pieces/Roi.h +++ b/Chess/dep/Pieces/Roi.h @@ -19,7 +19,6 @@ Roi(int x, int y); // ABSTRACT - bool can(int x, int y); char getchar(); }; diff --git a/Chess/dep/Pieces/Tour.cpp b/Chess/dep/Pieces/Tour.cpp index b5f2407..79dfed2 100644 --- a/Chess/dep/Pieces/Tour.cpp +++ b/Chess/dep/Pieces/Tour.cpp @@ -5,10 +5,6 @@ Tour::Tour(int x, int y) : Piece(TOUR, x, y) { } // ABSTRACT -bool Tour::can(int x, int y){ - return true; -} - char Tour::getchar(){ return 'T'; } diff --git a/Chess/dep/Pieces/Tour.h b/Chess/dep/Pieces/Tour.h index 5553cb0..ab9f588 100644 --- a/Chess/dep/Pieces/Tour.h +++ b/Chess/dep/Pieces/Tour.h @@ -19,7 +19,6 @@ Tour(int x, int y); // ABSTRACT - bool can(int x, int y); char getchar(); }; diff --git a/Chess/dep/Player.cpp b/Chess/dep/Player.cpp index d58c5f6..46ef7a6 100644 --- a/Chess/dep/Player.cpp +++ b/Chess/dep/Player.cpp @@ -56,7 +56,7 @@ void Player::remPiece(Piece& p){ /* DEBUG */ setfont(BLUE, ITALIC); - cout << "\t\t[-] " << p << " to cimetery of Player " << (_first?1:2); + cout << " [-] " << p << " to cimetery of Player " << (_first?1:2); setfont(); cout << endl; @@ -64,8 +64,8 @@ void Player::remPiece(Piece& p){ // INITIALISATION DES PIECES DE BASE void Player::initPieces(){ - int y1 = _first ? 0 : 7; // ligne forte - int y2 = _first ? 1 : 6; // ligne de pions + int y1 = _first ? 7 : 0; // ligne forte + int y2 = _first ? 6 : 1; // ligne de pions // Premier ligne diff --git a/Chess/dep/term.cpp b/Chess/dep/term.cpp index 23604c6..3c8f288 100644 --- a/Chess/dep/term.cpp +++ b/Chess/dep/term.cpp @@ -8,4 +8,18 @@ void clear(){ // efface l'ecran void setfont(const TERM_COLOR c, const TERM_STYLE s){ cout << "\033[" << s << ";" << c << "m"; +} + +void err(string msg){ + // On affiche le WARNING + setfont(RED, BOLD); + cout << "/!\\ "; + + // On affiche le message d'erreur + setfont(RED); + cout << msg << endl; + + // On attends l'appui sur une touche + setfont(); + sleep(1); } \ No newline at end of file diff --git a/Chess/dep/term.h b/Chess/dep/term.h index c146219..ded27ad 100644 --- a/Chess/dep/term.h +++ b/Chess/dep/term.h @@ -39,7 +39,8 @@ =========================================================*/ void clear(); void setfont(const TERM_COLOR c=DEFAULT, const TERM_STYLE s=NORMAL); - + void err(string msg); + /* [n] Inclusion du corps =========================================================*/ #include "term.cpp" diff --git a/Chess/exe b/Chess/exe index ec04027..660cd8c 100755 Binary files a/Chess/exe and b/Chess/exe differ diff --git a/Chess/main.cpp b/Chess/main.cpp index 4b5eaa2..de1f13b 100644 --- a/Chess/main.cpp +++ b/Chess/main.cpp @@ -4,11 +4,12 @@ =========================================================*/ int main(){ ChessContext ctx; - // On initialise la partie ctx.init(); + // On continue d'attendre que les joueurs jouent + // tant que la partie n'est pas finie do{ display_board(ctx); game_routine(ctx); @@ -96,11 +97,11 @@ void display_board(ChessContext& ctx){ cout << endl << endl; if( ctx._turn == '1' ) - cout << "TOUR DU JOUEUR 1" << endl; + cout << "> TOUR DU JOUEUR 1 <" << endl << "--------------------" << endl; else if( ctx._turn == '2' ) - cout << "TOUR DU JOUEUR 2" << endl; + cout << "> TOUR DU JOUEUR 2 <" << endl << "--------------------" << endl; else - cout << "PARTIE FINIE" << endl; + cout << "> PARTIE FINIE <" << endl << "-----------------" << endl; } @@ -112,9 +113,9 @@ void game_routine(ChessContext& ctx){ int dest[2]; // contiendra la position souhaitee // Contient le joueur courant - Player *curnt = (ctx._turn=='1') ? ctx._p1 : ctx._p2; + Player *curnt = ctx.getCurrent(); // Contient l'ennemi - Player *enemy = (ctx._turn=='1') ? ctx._p2 : ctx._p1; + Player *enemy = ctx.getEnemy(); @@ -122,8 +123,6 @@ void game_routine(ChessContext& ctx){ =========================================================*/ chess_input(origin, dest); - cout << "(" << origin[0] << "," << origin[1] << ")" << endl; - /* [3] On verifie qu'un pion est a cette case =========================================================*/ Piece *toMove = ctx._p1->at(origin[0], origin[1]); @@ -134,30 +133,33 @@ void game_routine(ChessContext& ctx){ if( toMove != NULL ) cout << *toMove << endl; - else{ - cout << "Aucune piece sur cette case" << endl; - return; - } + else + err("Aucune piece sur cette case"); /* [4] On verifie qu'il peut atteindre la destination =========================================================*/ - cout << "Can move to dest : " << toMove->can(dest[0], dest[1]) << endl; + bool canMove = ctx.checkMove(*toMove, dest[0], dest[1]); + + if( canMove ){ + + /* [5] On gere le deplacement + =========================================================*/ + /* (1) Gestion de si on mange l'ennemi */ + Piece *eaten = enemy->at(dest[0], dest[1]); + + if( eaten != NULL ) // si piece mangee + enemy->remPiece( *eaten ); // on mange l'ennemi + + toMove->move(dest[0], dest[1]); // on deplace la piece - /* [5] On gere le deplacement - =========================================================*/ - /* (1) Gestion de si on mange l'ennemi */ - Piece *eaten = enemy->at(dest[0], dest[1]); - if( eaten != NULL ) // si piece mangee - enemy->remPiece( *eaten ); // on mange l'ennemi + /* [n] Gestion du tour ou partie finie + =========================================================*/ + ctx._turn = (ctx._turn=='1') ? '2' : '1'; - toMove->move(dest[0], dest[1]); // on deplace la piece - - - /* [n] Gestion du tour ou partie finie - =========================================================*/ - ctx._turn = (ctx._turn=='1') ? '2' : '1'; + }else + err("Mouvement interdit"); } /* [3] Gestion de la saisie du tour @@ -165,12 +167,12 @@ void game_routine(ChessContext& ctx){ void chess_input(int* origin, int* dest){ char coord[2] = {'\0'}; - cout << "Piece to move (XN) : "; + cout << "Piece a deplacer (XN) : "; cin >> coord; Piece::decode(coord, origin); cout << endl; - cout << "Move to (XN) : "; + cout << "Deplacer vers (XN) : "; cin >> coord; Piece::decode(coord, dest); cout << endl; diff --git a/Chess/main.h b/Chess/main.h index f3d246b..aaa3b6c 100644 --- a/Chess/main.h +++ b/Chess/main.h @@ -9,6 +9,7 @@ #include #include #include + #include /* (2) Externes */ #include "dep/term.h" diff --git a/Chess/main.o b/Chess/main.o index e5d33af..e33d928 100644 Binary files a/Chess/main.o and b/Chess/main.o differ