bool test_equality_game(cgame expected, cgame value, char * msg) { bool result = true; for (int i = 0; i < NB_PIECES; i++) { result = result && test_equality_piece(game_piece(expected, i), game_piece(value, i), msg); } if (!result) fprintf(stderr, "%s expected game is not equal to value game\n", msg); return result; }
MLV_Image* init_car(game newGame, int indice_piece) { char size[6]; char orientation[2]; char color[30]; char path[50]; cpiece tmp = game_piece(newGame, indice_piece); int width = get_width(tmp) * RATIO; int height = get_height(tmp) * RATIO; if (get_width(tmp) >= 3 || get_height(tmp) >= 3) sprintf(size, "truck"); else sprintf(size, "car"); is_horizontal(tmp) ? sprintf(orientation, "h") : sprintf(orientation, "v"); sprintf(color, "%s", carColor[indice_piece % NB_OF_COLOR]); sprintf(path, "../../assets/%s_%s_%s.png", size, color, orientation); if (indice_piece == 0) sprintf(path, "../../assets/car_red_h.png"); MLV_Image *tmp_img = MLV_load_image(path); if (!tmp_img) { return NULL; } MLV_resize_image(tmp_img, width, height); return tmp_img; }
bool play_move(game g, int piece_num, dir d, int distance) { piece p=g->piece_list[piece_num]; int travel=0; while (distance!=0) { move_piece(p, d, 1); g->nb_moves+=1; distance--; travel++; for (int i=0; i<game_nb_pieces(g); ++i) { if (p==g->piece_list[i]) { i++; if (i>=game_nb_pieces(g)) break; } if (intersect(p, game_piece(g, i))) { fprintf(stderr, "Unauthorized move: Piece %d is preventing %d from moving.\n\n", i, piece_num); move_piece(p, d, travel*-1); g->nb_moves-=travel; return false; } if (out_of_grid(p, g)) { fprintf(stderr, "Unauthorized move: %d would be out of bounds.\n\n", piece_num); move_piece(p, d, travel*-1); g->nb_moves-=travel; return false; } if (((d==LEFT||d==RIGHT)&&(!can_move_x(p)))||((d==UP||d==DOWN)&&(!can_move_y(p)))) { fprintf(stderr, "Unauthorized move: Piece orientation doesn't match move direction.\n\n"); return false; } } } return true; }
bool compareMap(map m1, map m2) { //char* s1 = (char*) malloc(256*sizeof(char)); //char* s2 = (char*) malloc(256*sizeof(char)); //getIdFromGame(m1->g, s1); //getIdFromGame(m2->g, s2); //int r = strcmp(s1, s2); //free(s1); //free(s2); for (int i = 0; i < game_nb_pieces(m1->g); i++) { if ((get_x(game_piece(m1->g, i)) != get_x(game_piece(m2->g, i))) || (get_y(game_piece(m1->g, i)) != get_y(game_piece(m2->g, i)))) return false; } return true; //return (r == 0); //retourne true si les chaines sont identiques }
void draw_game(game newGame, int starty, int startx, int MAXROW, int MAXCOL, WINDOW **grid, WINDOW **car, WINDOW **score, int choosenCar, char *message, bool gameOverRh) { *grid = create_newgrid(starty, startx, MAXROW, MAXCOL, SIZE, gameOverRh); // Create new grid wmove(*grid, 0, 0); //Create each car and highlight the selected one for (int i = 0; i < game_nb_pieces(newGame); i++) { if (choosenCar == i) { car[i] = create_newcar(game_piece(newGame, i), i, true, SIZE, MAXROW); // Create new car and highlight it continue; } car[i] = create_newcar(game_piece(newGame, i), i, false, SIZE, MAXROW); // Create new car } wmove(*grid, 0, 0); //Create score on right of the grid *score = create_newscore(SIZE * MAXROW + 1, SIZE*MAXCOL, starty, startx + SIZE * MAXCOL * 2 + 1, game_nb_moves(newGame), message); wmove(*grid, 0, 0); }
bool good_direction(game g, int piece_num, dir d){ cpiece p = game_piece(g, piece_num); if(is_horizontal(p)){ if(d == UP || d == DOWN) return false; }else{ if(d == RIGHT || d == LEFT) return false; } return true; }
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); }
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; }
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 good_direction(game g, int piece_num, dir d){ //Verify if you can move to the direction d cpiece p = game_piece(g, piece_num); int x_piece = get_x(p); int y_piece = get_y(p); if(is_horizontal(p)){ if(d == UP || d == DOWN){ printf("The piece %d cannot move vertycaly\n", piece_num); return false; } if(d == RIGHT){ //Verify if the piece is not nears the limit board and if there is not an other piece sticks to hir if(x_piece+get_width(p) >= SIZE_ARRAY || is_piece(g, x_piece+get_width(p),y_piece) != -1){ printf("The piece %d cannot move to right\n", piece_num); return false; } } if(d == LEFT){ if(x_piece-1 < 0 || is_piece(g, x_piece-1, y_piece) != -1){ printf("The piece %d cannot move to left\n", piece_num); return false; } } }else{ if(d == RIGHT || d == LEFT){ printf("The piece %d cannot move horizontaly\n", piece_num); return false; } if(d == UP){ if(y_piece+get_height(p) >= SIZE_ARRAY || is_piece(g, x_piece, y_piece+get_height(p)) != -1){ printf("The piece %d cannot move to up\n", piece_num); return false; } } if(d == DOWN){ if(y_piece-1 < 0 || is_piece(g, x_piece, y_piece-1) != -1){ printf("The piece %d cannot move to down\n", piece_num); return false; } } } return true; }
// return the number of the piece in (,y) or -1 int is_piece(game g, int x, int y){ for(int i=0; i<game_nb_pieces(g); ++i){ cpiece p = game_piece(g, i); int x_piece = get_x(p); int y_piece = get_y(p); if(x_piece == x && !is_horizontal(p)){ if(y_piece == y || y_piece == y-1) return i; if(get_height(p) == 3 && y_piece == y-2) return i; } if(y_piece == y && is_horizontal(p)){ if(x_piece == x || x_piece == x-1) return i; if(get_width(p) == 3 && x_piece == x-2) return i; } } return -1; }
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; } } } }
bool can_move(game g, int piece_num){ cpiece p = game_piece(g, piece_num); int x_piece = get_x(p); int y_piece = get_y(p); if(is_horizontal(p)){ //Check if the piece is not nears the limit board and if there is not an other piece sticks to hir if(x_piece-1 >= 0 && x_piece+get_width(p) < SIZE_ARRAY) return is_piece(g, x_piece-1, y_piece) == -1 || is_piece(g, x_piece+get_width(p), y_piece) == -1; if(x_piece+get_width(p) < SIZE_ARRAY) return is_piece(g, x_piece+get_width(p), y_piece) == -1; if(x_piece-1 >= 0) return is_piece(g, x_piece-1, y_piece) == -1; }else{ if(y_piece-1 >= 0 && y_piece+get_height(p) < SIZE_ARRAY) return is_piece(g, x_piece, y_piece-1) == -1 || is_piece(g, x_piece, y_piece+get_height(p)) == -1; if(y_piece+get_height(p) < SIZE_ARRAY) return is_piece(g, x_piece, y_piece+get_height(p)) == -1; if(y_piece-1 >= 0) return is_piece(g, x_piece, y_piece-1) == -1; } return false; }
char* convertGame(game newGame) { int n = game_nb_pieces(newGame); cpiece *arrPieces; arrPieces = malloc(sizeof (piece) * n); for (int i = 0; i < n; i++) { arrPieces[i] = game_piece(newGame, i); } //Sort for (int i = 0; i < (n - 1); i++) { for (int j = 0; j < n - i - 1; j++) { if (sup(arrPieces[j], arrPieces[j + 1])) { cpiece swap = arrPieces[j]; arrPieces[j] = arrPieces[j + 1]; arrPieces[j + 1] = swap; } } } char *parsed = serialize(arrPieces, n); free(arrPieces); return parsed; }
void set_up_board(game g){ for(int x=0; x<SIZE_ARRAY; ++x){ for(int y=0; y<SIZE_ARRAY; ++y) board[x][y] = 100; } for(int y=0; y<SIZE_ARRAY; ++y){ for(int x=0; x<SIZE_ARRAY; ++x){ for(char piece_num=0; piece_num<NB_PIECES; ++piece_num){ cpiece p = game_piece(g, piece_num); if(get_x(p) == x && get_y(p) == y){ if(is_horizontal(p)){ for(int i=0; i<get_width(p); ++i) board[x+i][y] = piece_num; break; }else{ for(int i=0; i<get_height(p); ++i) board[x][y+i] = piece_num; break; } } } } } }
bool game_over_an(cgame newGame) { return get_x(game_piece(newGame, 0)) == 1 && get_y(game_piece(newGame, 0)) == 0; }
bool game_over_ar(cgame g){ return get_x(game_piece(g, 0))==0 && get_y(game_piece(g, 0))==0; }
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); }
bool test_game_piece(cgame gtest) { bool result = true; for (int i = 0; i < NB_PIECES; i++) result = result && test_equality_piece(pieces[i], game_piece(gtest, i), "game_piece"); return result; }
int main(int argc, char *argv[]){ set_up_pieces(); game g = new_game_hr(NB_PIECES, pieces); char buf[3][100]; int piece_num; dir d; int distance; while(!game_over_hr(g)){ bool good = false; while(!good){ while(!good){ set_up_board(g); print_game(g); printf("Move the pieces for free the piece 0 to the exit:\n"); printf("Total move: %d\n",game_nb_moves(g)); while(!good){ printf("What piece do you want to move?\n"); read(0, buf[0], sizeof(char)*100); if(strcmp(buf[0], "cancel") == 10) break; if(strcmp(buf[0], "exit") == 10) return EXIT_SUCCESS; if(buf[0][0]<48 || buf[0][0]>=48+NB_PIECES || buf[0][1] != 10) printf("Write a number between 0 and %d\tor write cancel or exit.\n",NB_PIECES-1); else{ piece_num = atoi(buf[0]); good = true; } } if(!good) break; good = false; while(!good){ printf("In what direction?\n"); read(0, buf[1], sizeof(char)*100); if(strcmp(buf[1], "cancel") == 10) break; if(strcmp(buf[1], "exit") == 10) return EXIT_SUCCESS; if(!is_dir_option(buf[1])) printf("Write one of those direction: up, down, right, left\tor write cancel or exit.\n"); else{ for(int i=0; i<4; ++i){ if(strcmp(buf[1], direction[i].dir_name) == 10) d = direction[i].dir_option; } if(!good_direction(g, piece_num, d)){ if(is_horizontal(game_piece(g, piece_num))) printf("The piece %d cannot move vertycaly\n", piece_num); else printf("The piece %d cannot move horizontaly\n", piece_num); }else good = true; } } if(!good) break; good = false; while(!good){ printf("How many case?\n"); read(0, buf[2], sizeof(char)*100); if(strcmp(buf[2], "cancel") == 10) break; if(strcmp(buf[2], "exit") == 10) return EXIT_SUCCESS; if(buf[2][0]<48 || buf[2][0]>=48+SIZE_ARRAY || buf[2][1] != 10) printf("Write a number between 0 and %d\tor write cancel or exit.\n",SIZE_ARRAY-1); else{ distance = atoi(buf[2]); good = play_move(g, piece_num, d, distance); if(!good) printf("The piece %d cannot move to that case.\n", piece_num); } } } } } set_up_board(g); print_game(g); printf("CONGRETULATION\nYou won in %d moves\n", game_nb_moves(g)); return EXIT_SUCCESS; }