int get_car_with_mouse(int x, int y, game tmpGame) { int miny, minx, maxx, maxy; for (int i = 0; i < game_nb_pieces(tmpGame); i++) { cpiece tmp = game_piece(tmpGame, i); minx = get_x(tmp) * RATIO; miny = (game_height(tmpGame) - get_y(tmp) - get_height(tmp)) * RATIO; maxx = (get_x(tmp) + get_width(tmp)) * RATIO; maxy = (game_height(tmpGame) - get_y(tmp)) * RATIO; if (x >= minx && x <= maxx && y >= miny && y <= maxy) { return i; } } return -1; }
bool play_move(game g, int piece_num, dir d, int distance){ if ((!can_move_y(g->pieces[piece_num]) && (d == 0 || d == 2)) || ((!can_move_x(g->pieces[piece_num])) && (d == 1 || d == 3))) return false; bool move_isAllowed = true; piece tmp_piece = new_piece(0,0,0,0,true,true); // Initialisation d'une pièce temporaire (mallocs) copy_piece(g->pieces[piece_num],tmp_piece); for (int i = 0; i < distance; i++) { // On decompose le mouvement en déplacement de une case move_piece(g->pieces[piece_num], d, 1); if ((get_x(g->pieces[piece_num])+get_width(g->pieces[piece_num])-1 >= game_width(g) || get_x(g->pieces[piece_num]) < 0) || (get_y(g->pieces[piece_num])+get_height(g->pieces[piece_num])-1 >= game_height(g) || get_y(g->pieces[piece_num]) < 0)) move_isAllowed = false; for(int p = 0; p < game_nb_pieces(g);++p) { // On verifie si le mouvement est valide (intersect+depassement grille) if (piece_num != p && intersect(g->pieces[piece_num], g->pieces[p])) move_isAllowed = false; } } if (move_isAllowed) { for(int p = 0; p < game_nb_pieces(g);++p) { if (piece_num != p && intersect(g->pieces[piece_num], g->pieces[p])) printf("Erreur\n"); } g->nb_mouv += distance; delete_piece(tmp_piece); return true; } // si le mouvement n'est pas valide on remets la piece a sa place initiale copy_piece(tmp_piece, g->pieces[piece_num]); delete_piece(tmp_piece); return false; }
bool game_equals_not_mov(cgame G1, cgame G2){ bool res = true; res = res && game_width(G1) == game_width(G2); res = res && game_height(G1) == game_height(G2); res = res && game_nb_pieces(G1) == game_nb_pieces(G2); if(res){ int pieces = 0; for(int i = 0 ; i<game_nb_pieces(G1) ; i++){ for(int j = 0 ; j<game_nb_pieces(G2) ;j++){ if(piece_equals(game_piece(G1, i), game_piece(G2, j))){ pieces ++; break; } } if(i+1 != pieces) return false; } if(pieces == game_nb_pieces(G1)) return true; } return false; }
game copy_game_for_solver(cgame src){ int nb_pieces = game_nb_pieces(src); int w = game_width(src); int h = game_height(src); piece *tab = malloc(sizeof(piece)*nb_pieces); for (int i=0;i<nb_pieces;i++){ tab[i] = copy_piece_for_solver(game_piece(src, i)); } game dst = new_game (w, h, nb_pieces, tab); delete_pieces_array(tab, nb_pieces); return dst; }
void play_events(game newGame, int *click, bool *gameOver) { MLV_Keyboard_button touche; MLV_Button_state state; MLV_Event event; int mouseX, mouseY; if (!click || !newGame) { fprintf(stderr, "play_events parameters error"); exit(EXIT_FAILURE); } do { // // Récupère un évènement dans la file des évènements // non traités. // event = MLV_get_event( &touche, NULL, NULL, NULL, NULL, &mouseX, &mouseY, NULL, &state ); // // Traite l'évènement s'il s'agit d'un évènement clavier // if (event == MLV_KEY || MLV_MOUSE_BUTTON) { if (event == MLV_MOUSE_BUTTON && state == MLV_PRESSED) { *click = get_car_with_mouse(mouseX, mouseY, newGame); } if (event == MLV_MOUSE_BUTTON && state == MLV_RELEASED) { *click = -1; } if (event == MLV_MOUSE_MOTION && *click != -1) { cpiece tmp = game_piece(newGame, *click); int x = get_x(tmp); int y = game_height(newGame) - get_y(tmp) - get_height(tmp); if (mouseY > (y + get_height(tmp)) * RATIO) play_move(newGame, *click, DOWN, 1); else if (mouseY < y * RATIO) play_move(newGame, *click, UP, 1); else if (mouseX > (x + get_width(tmp)) * RATIO) play_move(newGame, *click, RIGHT, 1); else if (mouseX < x * RATIO) play_move(newGame, *click, LEFT, 1); } if(event == MLV_KEY && touche == 'q') { *gameOver = true; } } } while (event != MLV_NONE); }
void show_grid(game g){ printf("\n"); for (int ord=game_height(g)-1;ord>=0;ord--){ for (int abs=0;abs<game_width(g);abs++){ if (game_square_piece(g, abs, ord)== -1) printf(" · "); else printf("%2d ", game_square_piece(g, abs, ord)); } printf("\n\n\n"); } printf("\nMoves : %d\n----------\n\n", game_nb_moves(g)); }
void tableau_1D(int *t, game g){ int taille_tab = game_height(g)*game_width(g); for (int i = 0; i<taille_tab; ++i){ t[i] = -1; } for (int num_piece = 0; num_piece<game_nb_pieces(g); ++num_piece){ cpiece p=game_piece(g, num_piece); t[get_x(p)+(get_y(p)*6)] = num_piece; if (get_width(p)>1){ for (int i = 1; i<get_width(p); ++i){ t[get_x(p)+(get_y(p)*6)+i] = num_piece; } } if (get_height(p)>1){ for (int j = 1; j<get_height(p); ++j){ t[get_x(p)+((get_y(p)*6)+(j*6))] = num_piece; } } } }
int game_square_piece (game g, int x, int y){ /*for (int p = 0; p < game_nb_pieces(g); ++p) { for(int i = 0; i < get_height(g->pieces[p]); ++i) { for(int j = 0; j < get_width(g->pieces[p]); ++j) { if (get_x(g->pieces[p])+i == x && get_y(g->pieces[p])+j == y) return p; } } } return -1;*/ int size_x = game_width(g); int size_y = game_height(g); int nb_pieces = game_nb_pieces(g); int **grid = malloc(sizeof(int*)*size_y); int output; for (int i = 0; i < size_y; ++i){ grid[i] = malloc(sizeof(int)*size_x); } for(int x = 0; x < size_x; ++x){ for(int y = 0; y < size_y; ++y){ grid[y][x] = -1; } } for (int i = 0; i < nb_pieces; i++) { for (int x = 0; x < get_width(game_piece(g, i)); x++) { for (int y = 0; y < get_height(game_piece(g, i)); y++) { grid[get_y(game_piece(g, i))+y][get_x(game_piece(g, i))+x] = i; } } } output = grid[y][x]; for (int i = 0; i < size_y; ++i){ free(grid[i]); } free(grid); return output; }
void SDL_Display(game g, SDL_Renderer* rdr, TTF_Font* font, int popup){ SDL_Rect rect; SDL_Color fontColor = {255, 255, 255}; rect.w = (SCREEN_Y/game_height(g)); rect.h = (SCREEN_Y/game_height(g)); SDL_SetRenderDrawColor(rdr, 192,192,192, 255); SDL_RenderClear(rdr); SDL_SetRenderDrawColor(rdr, 0,255,127, 255); if(rules==0){//pour la Sortie des piece de Rush hour rect.y = (SCREEN_Y/game_height(g))*2; rect.x = (SCREEN_Y/game_height(g))*game_width(g); rect.h = (SCREEN_Y/game_height(g)); rect.w = 10; SDL_RenderFillRect(rdr, &rect); SDL_SetRenderDrawColor(rdr, 105,105,105, 255); rect.y = 0; rect.x = (SCREEN_Y/game_height(g))*game_width(g); rect.w = 10; rect.h = ((SCREEN_Y/game_height(g))*2); SDL_RenderFillRect(rdr, &rect); rect.y = ((SCREEN_Y/game_height(g))*3); rect.x = (SCREEN_Y/game_height(g))*game_width(g); rect.w = 10; rect.h = ((SCREEN_Y/game_height(g))*3); SDL_RenderFillRect(rdr, &rect); rect.y = (SCREEN_Y); rect.x = 0; rect.w = SCREEN_X ; rect.h = 10; SDL_RenderFillRect(rdr, &rect); } else if(rules==1){ //pour la Sortie des piece de Ane rouge rect.y = SCREEN_Y; rect.x = (SCREEN_Y/game_height(g)); rect.h = 10; rect.w = (SCREEN_Y/game_height(g))*2; SDL_RenderFillRect(rdr, &rect); SDL_SetRenderDrawColor(rdr, 105,105,105, 255); rect.y = 0; rect.x = (SCREEN_Y/game_height(g))*game_width(g); rect.w = 10; rect.h = SCREEN_Y; SDL_RenderFillRect(rdr, &rect); rect.y = SCREEN_Y; rect.x = 0; rect.w = (SCREEN_Y/game_height(g)); rect.h = 10; SDL_RenderFillRect(rdr, &rect); rect.y = SCREEN_Y; rect.x = ((SCREEN_Y/game_height(g))*3); rect.w = ((SCREEN_Y/game_height(g))*6); rect.h = 10; SDL_RenderFillRect(rdr, &rect); } //Affichage des pièces for(int i = 0; i < game_nb_pieces(g); ++i){ SDL_SetRenderDrawColor(rdr, color[i][0],color[i][1],color[i][2], 255); rect.x = get_x(game_piece(g,i))*(SCREEN_Y/game_height(g)); rect.y = (SCREEN_Y - (get_y(game_piece(g,i))*(SCREEN_Y/game_height(g)))); rect.w = get_width(game_piece(g,i))*(SCREEN_Y/game_height(g)); rect.h = get_height(game_piece(g,i))*(SCREEN_Y/game_height(g)); rect.y -= rect.h; SDL_RenderFillRect(rdr, &rect); } //Affichage du nombre de mouvements char disp_moves[20]; //contiendra l'affichage du nombre de mouvements char end_msg[30]; //contiendra le message de fin de partie sprintf(disp_moves," Mouvements : %d ",game_nb_moves(g));// Convertie le nb_mouv en caractère drawText(rdr, font, fontColor,SCREEN_X-250 ,SCREEN_Y/2-SCREEN_Y/6 -200 ,disp_moves); //affichage nombre de mouvements //Affichage des règles drawText(rdr, font, fontColor,(SCREEN_Y/game_height(g))*game_width(g)+120 ,SCREEN_Y-40 ,"R : Relancer"); drawText(rdr, font, fontColor,SCREEN_X-120 ,SCREEN_Y-40 ,"Q : Quitter"); if (popup != 0){ SDL_SetRenderDrawColor(rdr, 50, 50, 50, 170); rect.x = 0; rect.y = SCREEN_Y/4; rect.w = SCREEN_X; rect.h = SCREEN_Y/2; SDL_RenderFillRect(rdr, &rect); if (popup == 1){ drawText(rdr, font, fontColor,SCREEN_X/2 ,SCREEN_Y/2-SCREEN_Y/8 ,"Voulez-vous lancer une nouvelle partie ?"); } else if (popup == 2){ drawText(rdr, font, fontColor,SCREEN_X/2 ,SCREEN_Y/2-SCREEN_Y/8 ,"Voulez-vous quitter le jeu en cours ?"); } else if (popup == 3){ sprintf(end_msg,"Partie finie en %d mouvements",game_nb_moves(g)); drawText(rdr, font, fontColor,SCREEN_X/2, SCREEN_Y/2-SCREEN_Y/8, end_msg); drawText(rdr, font, fontColor,SCREEN_X/2, SCREEN_Y/2-SCREEN_Y/17, "Voulez vous rejouer ?"); } drawText(rdr, font, fontColor,SCREEN_X/6 ,SCREEN_Y/2+SCREEN_Y/8 ,"Echap : Non"); drawText(rdr, font, fontColor,SCREEN_X-SCREEN_X/6 ,SCREEN_Y/2+SCREEN_Y/8 ,"Entree : Oui"); } SDL_RenderPresent(rdr); SDL_Delay(50); }
// @brief Check if the piece p is out of the grid of the game g. bool out_of_grid(cpiece p, cgame g) { //used only once but enhances readibility return (get_x(p)<0||get_x(p)+get_width(p)>game_width(g)||(get_y(p)<0||get_y(p)+get_height(p)>game_height(g))); }
/* * @brief Show different game and wait for user to choose * @return game The new game created */ static game select_game() { int row, col; int pos = 0; int ch = 0; game newGame = NULL; while (ch != '\n') { clear(); getmaxyx(stdscr, row, col); mvprintw(row / 2, col / 2 - 20, "Use arrow key to select your game"); if (pos == 0) { mvprintw(row / 2 + 1, col / 2 - 20, "-> Rush Hour"); mvprintw(row / 2 + 2, col / 2 - 20, " Ane rouge"); } else { mvprintw(row / 2 + 1, col / 2 - 20, " Rush Hour"); mvprintw(row / 2 + 2, col / 2 - 20, "-> Ane rouge"); } ch = getch(); if (ch == KEY_UP) { if (pos > 0) pos--; } else if (ch == KEY_DOWN) { if (pos < 1) pos++; } refresh(); } if (pos == 0) { //Rush hour piece pieces[4]; pieces[0] = new_piece_rh(3, 3, true, true); pieces[1] = new_piece_rh(3, 0, true, false); pieces[2] = new_piece_rh(4, 1, true, true); pieces[3] = new_piece_rh(5, 3, false, false); newGame = new_game(6, 6, 4, pieces); MAXCOL = game_width(newGame); MAXROW = game_height(newGame); MINH = MAXROW * SIZE + 2; MINW = MAXCOL * SIZE; game_over = game_over_hr; gameOverRh = true; for (int i = 0; i < game_nb_pieces(newGame); i++) { delete_piece(pieces[i]); } clear(); refresh(); return newGame; } else { //Ane rouge piece pieces[10]; pieces[0] = new_piece(1, 3, 2, 2, true, true); //Rouge pieces[1] = new_piece(3, 3, 1, 2, true, true); // 2 pieces[2] = new_piece(3, 1, 1, 2, true, true); // 3 pieces[3] = new_piece(3, 0, 1, 1, true, true); // 4 pieces[4] = new_piece(1, 2, 2, 1, true, true); // 5 pieces[5] = new_piece(2, 1, 1, 1, true, true); // 6 pieces[6] = new_piece(1, 1, 1, 1, true, true); // 7 pieces[7] = new_piece(0, 0, 1, 1, true, true); // 8 pieces[8] = new_piece(0, 1, 1, 2, true, true); // 9 pieces[9] = new_piece(0, 3, 1, 2, true, true); // 10 newGame = new_game(4, 5, 10, pieces); MAXCOL = game_width(newGame); MAXROW = game_height(newGame); MINH = MAXROW * SIZE + 2; MINW = MAXCOL * SIZE; game_over = game_over_an; gameOverRh = false; for (int i = 0; i < game_nb_pieces(newGame); i++) { delete_piece(pieces[i]); } clear(); refresh(); return newGame; } }
int main(int argc, char *argv[]) { WINDOW *my_win, *score; WINDOW **car; game newGame, tmpGame; MEVENT event; int ch = 0, choosenCar = -1, soluce_move = 0; char message[1024]; bool quit = false; bool show_solution = false; gameStruct *resultSolv = NULL; //INIT setup(); //END INIT //Wait for good size wait_for_size(MINH, MINW); //Instruction show_instruction(MINH, MINW); while (!quit) { quit = false; show_solution = false; soluce_move = 0; strcpy(message, "Playing"); //Select game newGame = select_game(); //Check for level file if (handle_level(&tmpGame)) { delete_game(newGame); newGame = tmpGame; MAXCOL = game_width(newGame); MAXROW = game_height(newGame); MINH = MAXROW * SIZE + 2; MINW = MAXCOL * SIZE; } car = malloc(sizeof (WINDOW*) * game_nb_pieces(newGame)); //First draw draw_game(newGame, 0, 0, MAXROW, MAXCOL, &my_win, car, &score, choosenCar, message, gameOverRh); //Loop while the game is not finished while (!game_over(newGame)) { //Print on bottom of grid mvprintw(MAXROW * SIZE + 1, 0, "Please choose car :"); ch = getch(); if (ch == 's' && !show_solution) { show_solution = true; strcpy(message, "Solution"); resultSolv = solv(newGame, gameOverRh,true); if(!resultSolv){ strcpy(message, "No solution"); show_solution=false; } } if (show_solution) { newGame = play_solution(newGame, resultSolv, soluce_move++); } else { if (KEY_MOUSE == ch) { /* Mouse event. */ if (OK == getmouse(&event)) { choosenCar = get_car_with_mouse(event.y, event.x, car, game_nb_pieces(newGame)); } } else { if (ch == 'q') { quit = true; break; } play_input(newGame, ch, &choosenCar); } } wait_for_size(MINH, MINW); erase_game(newGame, my_win, car, score); draw_game(newGame, 0, 0, MAXROW, MAXCOL, &my_win, car, &score, choosenCar, message, gameOverRh); } if (!quit) { display_score(newGame); } for (int i = 0; i < game_nb_pieces(newGame); i++) { destroy_win(car[i]); } destroy_win(my_win); destroy_win(score); free(car); delete_game(newGame); if (resultSolv != NULL) { delete_game(resultSolv->current); free(resultSolv->move); free(resultSolv); resultSolv = NULL; } } endwin(); /* End curses mode */ return 0; }