Multiplayer available, EndGameMenu better than ever

merge-requests/2/merge
marouault 3 years ago
parent 2741bf875c
commit 9473c0c2b4

@ -10,10 +10,9 @@
#include "model/Player.h" #include "model/Player.h"
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
GeneralState generalState; SDL_Rect windowSize = {10, 10, 900, 900};
SDL_Window* window = NULL; SDL_Window* window = NULL;
SDL_Rect windowSize = {10, 10, 900, 900};
SDL_Renderer* renderer = NULL; SDL_Renderer* renderer = NULL;
int statut = EXIT_FAILURE; int statut = EXIT_FAILURE;
@ -44,7 +43,7 @@ int main(int argc, char *argv[]) {
FontHandler fontHandler = loadFonts(); FontHandler fontHandler = loadFonts();
AudioHandler audioHandler = newAudioHandler(128, 128, 128); AudioHandler audioHandler = newAudioHandler(128, 128, 128);
generalState = GS_MainMenu; GeneralState generalState = GS_MainMenu;
while(generalState != GS_Quit){ while(generalState != GS_Quit){
switch (generalState) { switch (generalState) {
case GS_MainMenu: case GS_MainMenu:
@ -56,11 +55,12 @@ int main(int argc, char *argv[]) {
SDL_GetWindowSize(window, &windowW, &windowH); SDL_GetWindowSize(window, &windowW, &windowH);
size_t nbPlayers = 2; size_t nbPlayers = 3;
Player players[] = { Player players[] = {
newPlayer("Bépo", PlayerViolet), newPlayer("Bépo", PlayerViolet),
newPlayer("Azeryty", PlayerYellow), newPlayer("Azeryty", PlayerBlue),
//newPlayer("Adcsg", PlayerRed) newPlayer("Adcsg", PlayerRed),
//newPlayer("qsdfqsdfq", PlayerYellow)
}; };
//players[2] = ; //players[2] = ;
@ -74,6 +74,15 @@ int main(int argc, char *argv[]) {
gameView(&generalState, window, renderer, players, nbPlayers, &fontHandler); gameView(&generalState, window, renderer, players, nbPlayers, &fontHandler);
//Pour tester le endGameMenu directement
/*generalState = GS_EndOfGameMenu;
players[0].eliminationTurn = 10;
players[0].rank = 3;
players[1].eliminationTurn = 15;
players[1].rank = 2;
players[2].eliminationTurn = 0;
players[2].rank = 1;*/
endGameMenu(&generalState, window, renderer, &fontHandler, players, nbPlayers); endGameMenu(&generalState, window, renderer, &fontHandler, players, nbPlayers);
break; break;
} }

@ -63,8 +63,10 @@ bool isButtonEntry(P_Button * button,const int x,const int y){
coord.y = y; coord.y = y;
if(isHover(button)){ if(isHover(button)){
button->hover = SDL_PointInRect(&coord,&(button->rect)); button->hover = SDL_PointInRect(&coord,&(button->rect));
button->drawn = button->hover;
return false; return false;
} }
button->hover = SDL_PointInRect(&coord,&(button->rect)); button->hover = SDL_PointInRect(&coord,&(button->rect));
button->drawn = !button->hover;
return button->hover; return button->hover;
} }

@ -65,6 +65,25 @@ void eliminatePlayer(Game* game, const size_t playerId) {
void endGame(Game* game) { void endGame(Game* game) {
game->phase = GAME_ENDED; game->phase = GAME_ENDED;
for (size_t i=0; i<game->nbPlayers; ++i) {
if (game->arrPlayers[i].rank==1) {
game->arrPlayers[i].eliminationTurn = game->nb_rounds;
return;
}
}
}
Piece* getNonPlacedPieceFromPlayer(Piece arrPieces[], const size_t nbPieces, const size_t currentPlayerID) {
for (size_t i = 0; i < nbPieces; ++i)
{
if (arrPieces[i].idJ == currentPlayerID && islandEqual(arrPieces[i].island, newIsland(-1,-1)))
{
return &arrPieces[i];
}
}
return NULL;
} }
void changePhaseOrPlayerTurn(Game* game) void changePhaseOrPlayerTurn(Game* game)
@ -72,29 +91,32 @@ void changePhaseOrPlayerTurn(Game* game)
switch (game->phase) switch (game->phase)
{ {
case PLACEMENT: case PLACEMENT:
if (game->currentPlayerID == 0) //Joueur suivant
{ if (game->currentPlayerID == 0) {
game->phase = MOVE_PIECE; game->currentPlayerID = game->nbPlayers-1;
} }
else else {
{
game->currentPlayerID--; game->currentPlayerID--;
} }
if (getNonPlacedPieceFromPlayer(game->board.arrPieces, game->board.nbPieces, game->currentPlayerID) == NULL) {
game->phase = MOVE_PIECE;
}
break; break;
case MOVE_PIECE: case MOVE_PIECE:
game->phase = RM_BRIDGE; game->phase = RM_BRIDGE;
break; break;
case RM_BRIDGE: case RM_BRIDGE:
{ {
const size_t lastPlayerId = game->currentPlayerID; // check if all players are eliminated
if (areAllPlayerPiecesStucked(lastPlayerId, game->board.arrPieces, game->board.nbPieces)) { if (game->lastRank == 2) {
eliminatePlayer(game, lastPlayerId); endGame(game);
if (game->lastRank == 2) { return;
endGame(game);
return;
}
} }
do do
{ {
game->currentPlayerID++; game->currentPlayerID++;
@ -102,19 +124,6 @@ void changePhaseOrPlayerTurn(Game* game)
{ {
game->currentPlayerID = 0; game->currentPlayerID = 0;
} }
/*if (lastPlayerId == game->currentPlayerID) {
game->phase = GAME_ENDED;
return;
}*/
if (game->arrPlayers[game->currentPlayerID].eliminationTurn != 0 && areAllPlayerPiecesStucked(game->currentPlayerID, game->board.arrPieces, game->board.nbPieces)) {
eliminatePlayer(game, game->currentPlayerID);
if (game->lastRank == 2) {
endGame(game);
return;
}
}
} while (game->arrPlayers[game->currentPlayerID].eliminationTurn != 0); } while (game->arrPlayers[game->currentPlayerID].eliminationTurn != 0);
@ -286,11 +295,16 @@ void updatePieceIsolated(Game* game, const Island* island)
{ {
Piece* piecePotentialyIsolated = getPieceFromIsland(game->board.arrPieces, game->board.nbPieces, *island); Piece* piecePotentialyIsolated = getPieceFromIsland(game->board.arrPieces, game->board.nbPieces, *island);
if (piecePotentialyIsolated != NULL && isPieceIsolated(piecePotentialyIsolated, &game->board)) if (piecePotentialyIsolated != NULL && isPieceIsolated(piecePotentialyIsolated, &game->board))
{ // Check is a piece is isolated //and then if the player is eliminated { // Check is a piece is isolated and then if the player is eliminated
piecePotentialyIsolated->stuck = true; piecePotentialyIsolated->stuck = true;
if (areAllPlayerPiecesStucked(piecePotentialyIsolated->idJ, game->board.arrPieces, game->board.nbPieces)) {
eliminatePlayer(game, piecePotentialyIsolated->idJ);
}
} }
} }
GameAction clickOnBoard(const Coord coord, Game* game) GameAction clickOnBoard(const Coord coord, Game* game)
{ {
const IslandOrBridge islandOrBridge = coordToEntity(coord); const IslandOrBridge islandOrBridge = coordToEntity(coord);
@ -301,7 +315,9 @@ GameAction clickOnBoard(const Coord coord, Game* game)
if (islandOrBridge.type == ISLAND) if (islandOrBridge.type == ISLAND)
{ {
Piece* piece = getPieceFromIsland(game->board.arrPieces, game->board.nbPieces, islandOrBridge.data.island); Piece* piece = getPieceFromIsland(game->board.arrPieces, game->board.nbPieces, islandOrBridge.data.island);
if (piece != NULL) { if (piece == NULL) { // No piece here
piece = getNonPlacedPieceFromPlayer(game->board.arrPieces, game->board.nbPieces, game->currentPlayerID);
if (placePiece(piece, islandOrBridge.data.island, &game->board)) { if (placePiece(piece, islandOrBridge.data.island, &game->board)) {
changePhaseOrPlayerTurn(game); changePhaseOrPlayerTurn(game);
return GameAction_PlacePiece; return GameAction_PlacePiece;
@ -362,8 +378,8 @@ GameAction moveOnBoard(const Coord start, const Coord end, Game* game)
if (pieceMoved) if (pieceMoved)
{ {
changePhaseOrPlayerTurn(game); changePhaseOrPlayerTurn(game);
return GameAction_MovePiece;
} }
return pieceMoved ? GameAction_MovePiece : GameAction_None;
} }
} }
break; break;

@ -106,7 +106,7 @@ void gameView(GeneralState* generalState, SDL_Window* window, SDL_Renderer* rend
switch (actionRealized) switch (actionRealized)
{ {
case GameAction_PlacePiece: case GameAction_PlacePiece:
drawPlacePiece(renderer, &boardRect, &textureHandler, game.arrPlayers[(game.currentPlayerID-1>0) ? game.currentPlayerID-1 : game.nbPlayers-1].color, &inputElement.data.coord); drawPlacePiece(renderer, &boardRect, &textureHandler, game.arrPlayers[(game.currentPlayerID<game.nbPlayers-1) ? game.currentPlayerID+1 : 0].color, &inputElement.data.coord);
SDL_RenderPresent(renderer); SDL_RenderPresent(renderer);
break; break;
case GameAction_RemoveBridge: case GameAction_RemoveBridge:

@ -23,6 +23,20 @@ void setStateToMainMenu(P_Button* caller) {
*((GeneralState*)caller->arg) = GS_MainMenu; *((GeneralState*)caller->arg) = GS_MainMenu;
} }
SDL_Rect getEndGameMenuRect(SDL_Window* window) {
int windowW;
int windowH;
SDL_GetWindowSize(window, &windowW, &windowH);
SDL_Rect rect = {
.x=windowW/10,
.y=0,
.w=windowW*80/100,
.h=windowH
};
return rect;
}
/** /**
* @brief Create button For EndGameMenu * @brief Create button For EndGameMenu
* *
@ -55,96 +69,71 @@ P_Button createButtonForEndGameMenu(SDL_Renderer* renderer, TTF_Font* font, cons
return buttonMenuEndGame; return buttonMenuEndGame;
} }
/** TextLabel createTitleLabel(SDL_Renderer* renderer, TTF_Font* font) {
* @brief Draw Pseudo and rank for end game menu SDL_Color color = {0,0,0,0};
*
* @param renderer The renderer where pseudo and rank will be drawn
* @param rect Rect in which the endGameMenu is drawn
* @param height Height of line in score table
* @param font Font used for pseudo and rank
* @param color Color used for pseudo and rank
* @param rank
* @param pseudo
*/
void drawPseudoAndRank(SDL_Renderer* renderer, const SDL_Rect* rect, const int height, TTF_Font* font, const SDL_Color* color, const size_t rank, const char *const pseudo) {
const SDL_Point posRangPseudo = {
.x = rect->x+rect->w*0.05,
.y = height
};
char *const text = (char*) malloc(sizeof(char)*(4+strlen(pseudo)));// potentialy one character wider than necesarry
if (text == NULL) {
fprintf(stderr,"allocation error\n");
fflush(stderr);
return;
}
sprintf(text, "%lld. %s", rank, pseudo);
TextLabel joueur = createTextLabel(text, &posRangPseudo, 1, color, font, renderer, POSX_LEFT, POSY_TOP);
free(text);
drawTextLabel(renderer, &joueur);
freeTextLabel(&joueur); return createUnsizedTextLabel("Scores", &color, font, renderer);
} }
void drawEliminationTurn(SDL_Renderer* renderer, const SDL_Rect* rect, const int height, TTF_Font* font, const SDL_Color* color, const int eliminationTurn) { TextLabel createEliminationTurnLabel(SDL_Renderer* renderer, TTF_Font* font, const SDL_Color* color, const int eliminationTurn) {
SDL_Point posTourElimination = {
.x = rect->x+rect->w*0.95,
.y = height
};
char *const text = (char*) malloc(sizeof(char*) * 10); char *const text = (char*) malloc(sizeof(char*) * 10);
if (text == NULL) { if (text == NULL) {
fprintf(stderr,"allocation error\n"); fprintf(stderr,"allocation error\n");
fflush(stderr); fflush(stderr);
return; return createUnsizedTextLabel("Error allocation", color, font, renderer);
} }
sprintf(text, "Tour: %d", eliminationTurn); sprintf(text, "Tour: %d", eliminationTurn);
TextLabel label = createTextLabel(text, &posTourElimination, 1, color, font, renderer, POSX_RIGHT, POSY_TOP); TextLabel label = createUnsizedTextLabel(text, color, font, renderer);
free(text); free(text);
drawTextLabel(renderer, &label);
freeTextLabel(&label);
return label;
} }
void drawPlayersScores(SDL_Renderer* renderer, const Player players[], const size_t nbPlayers, const SDL_Rect* rect, TTF_Font* font) { TextLabel createPseudoAndRankLabel(SDL_Renderer* renderer, TTF_Font* font, const SDL_Color* color, const int rank, const char *const pseudo) {
SDL_Color black = {0,0,0,0}; char *const text = (char*) malloc(sizeof(char)*(4+strlen(pseudo)));// potentialy one character wider than necesarry
for (size_t i=0; i<nbPlayers; ++i) { if (text == NULL) {
const int height = rect->y+(players[i].rank+1)*rect->h/10+rect->y+rect->h/100; fprintf(stderr,"allocation error\n");
fflush(stderr);
drawPseudoAndRank(renderer, rect, height, font, &black, i, players[i].pseudo); return createUnsizedTextLabel("Error allocation", color, font, renderer);
drawEliminationTurn(renderer, rect, height, font, &black, players[i].eliminationTurn);
} }
} sprintf(text, "%d. %s", rank, pseudo);
void drawEndGameMenu(SDL_Renderer* renderer, const Player players[], const size_t nbPlayers, const SDL_Rect* rect, FontHandler* fontHandler) { TextLabel pseudoRankLbl = createUnsizedTextLabel(text, color, font, renderer);
free(text);
SDL_SetRenderDrawColor(renderer, 220,220,220,255);
SDL_RenderFillRect(renderer, rect);
drawPlayersScores(renderer, players, nbPlayers, rect, fontHandler->fonts[FONT_retro]); return pseudoRankLbl;
} }
TextLabel createTitleLabel(SDL_Renderer* renderer, TTF_Font* font) { PositionSpecifier getPseudoAndRankPositionSpecifier(const SDL_Rect* labelSize, const int rank) {
SDL_Color color = {0,0,0,0}; SDL_Rect base100 = {
.x=2,
.y=20+8*(rank-1),
.w = 5*labelSize->w/labelSize->h,
.h = 5
};
return newPositionSpecifier(&base100, POSX_LEFT, POSY_TOP, ASPECT_KEEP_FIT);
}
return createUnsizedTextLabel("Scores", &color, font, renderer); PositionSpecifier getEliminationTurnPositionSpecifier(const SDL_Rect* labelSize, const int rank) {
SDL_Rect base100 = {
.x=98,
.y=20+8*(rank-1),
.w = 5*labelSize->w/labelSize->h,
.h = 5
};
return newPositionSpecifier(&base100, POSX_RIGHT, POSY_TOP, ASPECT_KEEP_FIT);
} }
PositionSpecifier getTitleRect100(SDL_Rect* labelSize) { PositionSpecifier getTitlePositionClassifier(const SDL_Rect* labelSize) {
SDL_Rect base100 = { SDL_Rect base100 = {
.x=50, .x=50,
.y=1, .y=1,
.w = 30, .w = 15*labelSize->w/labelSize->h,
.h = 30*labelSize->h/labelSize->w .h = 15
}; };
return newPositionSpecifier(&base100, POSX_CENTER, POSY_TOP, ASPECT_KEEP_W); return newPositionSpecifier(&base100, POSX_CENTER, POSY_TOP, ASPECT_KEEP_FIT);
} }
struct endGameMenuTextLabel createLabels(SDL_Renderer* renderer, const Player players[], const size_t nbPlayers, FontHandler* fontHandler) { struct endGameMenuTextLabel createLabels(SDL_Renderer* renderer, const Player players[], const size_t nbPlayers, FontHandler* fontHandler) {
@ -155,43 +144,51 @@ struct endGameMenuTextLabel createLabels(SDL_Renderer* renderer, const Player pl
// Titre // Titre
array_TextLabel_AddElement(&labels.textLabels, createTitleLabel(renderer, fontHandler->fonts[FONT_retro])); array_TextLabel_AddElement(&labels.textLabels, createTitleLabel(renderer, fontHandler->fonts[FONT_retro]));
array_PositionSpecifier_AddElement(&labels.positionSpecifiers, getTitleRect100(&array_TextLabel_Last(&labels.textLabels)->textZone)); array_PositionSpecifier_AddElement(&labels.positionSpecifiers, getTitlePositionClassifier(&array_TextLabel_Last(&labels.textLabels)->textZone));
// Lignes de score // Lignes de score
for (size_t i=0; i<nbPlayers; ++i) {
array_TextLabel_AddElement(&labels.textLabels, createPseudoAndRankLabel(renderer, fontHandler->fonts[FONT_retro], &PLAYER_SDL_COLORS[players[i].color], players[i].rank, players[i].pseudo));
array_PositionSpecifier_AddElement(&labels.positionSpecifiers, getPseudoAndRankPositionSpecifier(&array_TextLabel_Last(&labels.textLabels)->textZone, players[i].rank));
array_TextLabel_AddElement(&labels.textLabels, createEliminationTurnLabel(renderer, fontHandler->fonts[FONT_retro], &PLAYER_SDL_COLORS[players[i].color], players[i].eliminationTurn));
array_PositionSpecifier_AddElement(&labels.positionSpecifiers, getEliminationTurnPositionSpecifier(&array_TextLabel_Last(&labels.textLabels)->textZone, players[i].rank));
}
return labels; return labels;
} }
void endGameMenu(GeneralState* generalState, SDL_Window* window, SDL_Renderer* renderer, FontHandler* fontHandler, const Player players[], const size_t nbPlayers) {
int windowW;
int windowH;
SDL_GetWindowSize(window, &windowW, &windowH); void drawEndGameMenu(SDL_Renderer* renderer, const SDL_Rect rectMenuEndGame, struct endGameMenuTextLabel* labels) {
SDL_Rect rectMenuEndGame = { SDL_SetRenderDrawColor(renderer, 220,220,220,255);
.x=windowW/10, SDL_RenderFillRect(renderer, &rectMenuEndGame);
.y=0,
.w=windowW*80/100, for (size_t i=0; i<labels->textLabels.size; ++i) {
.h=windowH labels->textLabels.elems[i].textZone = adaptPosToRect(&labels->positionSpecifiers.elems[i], &rectMenuEndGame);
}; drawTextLabel(renderer, &labels->textLabels.elems[i]);
}
SDL_RenderPresent(renderer);
}
void endGameMenu(GeneralState* generalState, SDL_Window* window, SDL_Renderer* renderer, FontHandler* fontHandler, const Player players[], const size_t nbPlayers) {
InputProcessor inputProcessor = createInputProcessor(); InputProcessor inputProcessor = createInputProcessor();
array_P_Button_AddElement(&inputProcessor.tabButton, createButtonForEndGameMenu(renderer, fontHandler->fonts[FONT_retro], &rectMenuEndGame, generalState)); const SDL_Rect endGameMenuRect = getEndGameMenuRect(window);
array_P_Button_AddElement(&inputProcessor.tabButton, createButtonForEndGameMenu(renderer, fontHandler->fonts[FONT_retro], &endGameMenuRect, generalState));
P_Button* buttonMenuEndGame = array_P_Button_Last(&inputProcessor.tabButton); P_Button* buttonMenuEndGame = array_P_Button_Last(&inputProcessor.tabButton);
SDL_Rect base100 = { SDL_Rect base100 = {
.x = 50, .x = 50,
.y = 99, .y = 99,
.w = 30, .w = 90,
.h = 30*buttonMenuEndGame->rect.h/buttonMenuEndGame->rect.w .h = 90*buttonMenuEndGame->rect.h/buttonMenuEndGame->rect.w
}; };
PositionSpecifier positionSpecifierButtonRetour = newPositionSpecifier(&base100, POSX_CENTER, POSY_BOTTOM, ASPECT_KEEP_H); PositionSpecifier positionSpecifierButtonRetour = newPositionSpecifier(&base100, POSX_CENTER, POSY_BOTTOM, ASPECT_KEEP_FIT);
drawEndGameMenu(renderer, players, nbPlayers, &rectMenuEndGame, fontHandler); buttonMenuEndGame->rect = adaptPosToRect(&positionSpecifierButtonRetour, &endGameMenuRect);
buttonMenuEndGame->drawn = false;
struct endGameMenuTextLabel labels = createLabels(renderer, players, nbPlayers, fontHandler); struct endGameMenuTextLabel labels = createLabels(renderer, players, nbPlayers, fontHandler);
for (size_t i=0; i<labels.textLabels.size; ++i) {
labels.textLabels.elems[i].textZone = adaptPosToRect(&labels.positionSpecifiers.elems[i], &rectMenuEndGame); drawEndGameMenu(renderer, endGameMenuRect, &labels);
drawTextLabel(renderer, &labels.textLabels.elems[i]);
}
while(*generalState == GS_EndOfGameMenu) while(*generalState == GS_EndOfGameMenu)
{ {
@ -217,21 +214,16 @@ void endGameMenu(GeneralState* generalState, SDL_Window* window, SDL_Renderer* r
break; break;
case InputType_Window_Resize: { case InputType_Window_Resize: {
SDL_Rect rectM = { const SDL_Rect rectM = {
.x=inputElement.data.windowSize.w/10, .x=inputElement.data.windowSize.w/10,
.y=0, .y=0,
.w=inputElement.data.windowSize.w*80/100, .w=inputElement.data.windowSize.w*80/100,
.h=inputElement.data.windowSize.h .h=inputElement.data.windowSize.h
}; };
drawEndGameMenu(renderer, players, nbPlayers, &rectM, fontHandler); drawEndGameMenu(renderer, rectM, &labels);
for (size_t i=0; i<labels.textLabels.size; ++i) {
labels.textLabels.elems[i].textZone = adaptPosToRect(&labels.positionSpecifiers.elems[i], &rectM);
drawTextLabel(renderer, &labels.textLabels.elems[i]);
}
buttonMenuEndGame->rect = adaptPosToRect(&positionSpecifierButtonRetour, &rectM); buttonMenuEndGame->rect = adaptPosToRect(&positionSpecifierButtonRetour, &rectM);
drawButtonOnRenderer(renderer, buttonMenuEndGame); buttonMenuEndGame->drawn = false;
fprintf(stderr, "Resize\n"); fflush(stderr); fprintf(stderr, "Resize\n"); fflush(stderr);
} }
@ -241,12 +233,22 @@ void endGameMenu(GeneralState* generalState, SDL_Window* window, SDL_Renderer* r
} }
} }
drawButtonOnRenderer(renderer, buttonMenuEndGame); if (!buttonMenuEndGame->drawn) {
drawButtonOnRenderer(renderer, buttonMenuEndGame);
SDL_RenderPresent(renderer);
}
SDL_RenderPresent(renderer);
SDL_Delay(50); SDL_Delay(50);
} }
freeInputProcessor(&inputProcessor); freeInputProcessor(&inputProcessor);
for (size_t i=0; i<labels.textLabels.size; ++i) {
freeTextLabel(&labels.textLabels.elems[i]);
}
array_TextLabel_Free(&labels.textLabels);
array_PositionSpecifier_Free(&labels.positionSpecifiers);
freeButton(buttonMenuEndGame);
} }

Loading…
Cancel
Save