bool test_intersect() { bool result = true; //the first one (set_up_1()) is with new_piece_rh (int x, int y, bool small, bool horizontal) set_up_1(); for (int i = 0; i < NB_PIECES; i++) for (int j = 0; j < NB_PIECES; j++) { result = result && test_equality_bool(i == j, intersect(pieces[i], pieces[j]), "intersect"); } piece pb_piece1 = new_piece_rh(3, 3, false, false); piece pb_piece2 = new_piece_rh(3, 1, false, false); result = result && test_equality_bool(true, intersect(pieces[0], pb_piece1), "set up 1 intersect pb1"); result = result && test_equality_bool(true, intersect(pb_piece2, pb_piece1), "set up 1 intersect pb2"); tear_down(); delete_piece(pb_piece1); delete_piece(pb_piece2); //the second one (set_up_2()) is with new_piece(int x, int y, int width, int height, bool move_x, bool move_y) set_up_2(); for (int i = 0; i < NB_PIECES; i++) for (int j = 0; j < NB_PIECES; j++) { result = result && test_equality_bool(i == j, intersect(pieces[i], pieces[j]), "intersect"); } piece pb_piece3 = new_piece(3, 3, 1, 3, false, true); piece pb_piece4 = new_piece(3, 1, 1, 3, false, true); result = result && test_equality_bool(true, intersect(pieces[0], pb_piece3), "set up 2 intersect pb1"); result = result && test_equality_bool(true, intersect(pb_piece4, pb_piece3), "set up 2 intersect pb2"); tear_down(); delete_piece(pb_piece3); delete_piece(pb_piece4); return result; }
void set_up_2() { pieces[0] = new_piece(3, 3, 2, 1, true, false); pieces[1] = new_piece(3, 0, 1, 2, false, true); pieces[2] = new_piece(4, 1, 2, 1, true, false); pieces[3] = new_piece(5, 3, 1, 3, false, true); }
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; }
piece copy_piece_for_solver(cpiece src){ int x = get_x(src); int y = get_y(src); int width = get_width(src); int height = get_height(src); bool move_x = can_move_x(src); bool move_y = can_move_y(src); piece dst = new_piece (x, y, width, height, move_x, move_y); return dst; }
bool test_move() { bool result = true; piece p = new_piece(0, 0, 2, 1, true, false); //move_x-> TRUE, move_y->FALSE set_up(); for (int dist = 1; dist < NB_PIECES; dist++) for (int i=0; i < NB_PIECES; i++) { // Test move LEFT copy_piece(pieces[i],p); move_piece(p, LEFT, dist); if (can_move_x(pieces[i])) result = result && test_equality_int(get_x(pieces[i])-dist,get_x(p),"move LEFT"); else result = result && test_equality_int(get_x(pieces[i]),get_x(p),"move LEFT"); // Test move RIGHT copy_piece(pieces[i],p); move_piece(p, RIGHT, dist); if (can_move_x(pieces[i])) result = result && test_equality_int(get_x(pieces[i])+dist,get_x(p),"move RIGHT"); else result = result && test_equality_int(get_x(pieces[i]),get_x(p),"move RIGHT"); // Test move UP copy_piece(pieces[i],p); move_piece(p, UP, dist); if (can_move_y(pieces[i])) result = result && test_equality_int(get_y(pieces[i])+dist,get_y(p),"move UP"); else result = result && test_equality_int(get_y(pieces[i]),get_y(p),"move UP"); // Test move DOWN copy_piece(pieces[i],p); move_piece(p, DOWN, dist); if (can_move_y(pieces[i])) result = result && test_equality_int(get_y(pieces[i])-dist,get_y(p),"move DOWN"); else result = result && test_equality_int(get_y(pieces[i]),get_y(p),"move DOWN"); } tear_down(); delete_piece(p); return result; }
bool test_intersect() { bool result = true; set_up(); for (int i = 0; i < NB_PIECES; i++) for (int j = 0; j < NB_PIECES; j++) { result = result && test_equality_bool(i==j, intersect(pieces[i], pieces[j]),"intersect"); } piece pb_piece1 = new_piece(3, 3, 2, 1, true, false); piece pb_piece2 = new_piece(5, 3, 1, 3, false, true); result = result && test_equality_bool(true, intersect(pieces[0], pb_piece1),"intersect pb1"); result = result && test_equality_bool(false, intersect(pb_piece2, pb_piece1),"intersect pb2"); delete_piece(pb_piece1); delete_piece(pb_piece2); tear_down(); return result; }
game new_game (int width, int height, int nb_pieces, piece *pieces){ game g = malloc(sizeof(struct game_s)); g->pieces = malloc(nb_pieces*sizeof(struct piece_s*)); for(int i=0;i<nb_pieces;i++) g->pieces[i]= new_piece(get_x(pieces[i]),get_y(pieces[i]),get_width(pieces[i]),get_height(pieces[i]),can_move_x(pieces[i]), can_move_y(pieces[i])); g->nb_mouv = 0; g->nb_pieces = nb_pieces; g->w = width; g->h = height; return g; }
piece new_piece_rh(int x, int y, bool small, bool horizontal) { piece newp = NULL; if (small) { if (horizontal) { newp = new_piece(x, y, smallSize, thickness, horizontal, !horizontal); } else { newp = new_piece(x, y, thickness, smallSize, horizontal, !horizontal); } } else { if (horizontal) { newp = new_piece(x, y, bigSize, thickness, horizontal, !horizontal); } else { newp = new_piece(x, y, thickness, bigSize, horizontal, !horizontal); } } if (!newp) { failure("new_piece_rh alloc newp"); return NULL; } return newp; }
piece new_piece_rh (int x, int y, bool small, bool horizontal){ int width; int height; if(horizontal) { height = 1; width = small ? 2 : 3; } else { height = small ? 2 : 3; width = 1; } piece newPiece = new_piece(x, y, width, height, horizontal, !horizontal); return newPiece; }
bool test_copy() { bool result = true; piece p = new_piece(0, 0, 2, 1, true, false); set_up(); for (int i = 0 ; i < NB_PIECES; i++) { copy_piece(pieces[i],p); result = result && test_equality_int(get_height(pieces[i]), get_height(p), "copy get_height"); result = result && test_equality_int(get_width(pieces[i]), get_width(p), "copy get_width"); result = result && test_equality_int(get_x(pieces[i]), get_x(p), "copy get_x"); result = result && test_equality_int(get_y(pieces[i]), get_y(p), "copy get_y"); result = result && test_equality_bool(can_move_x(pieces[i]), can_move_x(p), "copy can_move_x"); result = result && test_equality_bool(can_move_y(pieces[i]), can_move_y(p), "copy can_move_y"); } tear_down(); delete_piece(p); return result; }
bool test_new_piece() { bool result = true; for(int y = 0; y < 5; y++){ for(int x = 0; x < 5; x++){ for(bool move_y = false; !move_y; move_y = !move_y){ for(bool move_x = false; !move_x; move_x = !move_x){ int sizeX = 5 - x; int sizeY = 5 - y; piece p = new_piece(x, y, sizeX, sizeY, move_x, move_y); // Test coordonnées de p result = result && test_equality_int(x, get_x(p), "get_x"); result = result && test_equality_int(y, get_y(p), "get_y"); // Test hauteur/largeur de p result = result && test_equality_int(sizeY, get_height(p), "get_height"); result = result && test_equality_int(sizeX, get_width(p), "get_width"); // Test mouvement sur x result = result && test_equality_bool(move_x, can_move_x(p), "move_x"); // Test mouvement sur y result = result && test_equality_bool(move_y, can_move_y(p), "move_y"); delete_piece(p); } } } } return result; }
/** This is a very ugly function that draws blocks on the * info window for statistical purposes. * It uses several position hacks that i need to fix later. * The problem is that pieces always start relative to the * middle of the board, independent of the screen. * So im repositioning them according to it, on the info screen. */ void engine_draw_statistics(game_s* g) { window_s w = engine.screen.info; int k; int x_offset = 3; wattrset(w.win, engine_get_color(COLOR_WHITE, COLOR_BLACK, false)); mvwprintw(w.win, 3, 1, "%10d x", g->I_count); piece_s p = new_piece(PIECE_I); p.x = x_offset; p.y = 4; for (k = 0; k < 4; k++) { p.block[k].x += p.x; p.block[k].y += p.y; } engine_draw_piece(&p, w.win); wattrset(w.win, engine_get_color(COLOR_WHITE, COLOR_BLACK, false)); mvwprintw(w.win, 5, 1, "%10d x", g->T_count); p = new_piece(PIECE_T); p.x = x_offset; p.y = 6; for (k = 0; k < 4; k++) { p.block[k].x += p.x; p.block[k].y += p.y; } engine_draw_piece(&p, w.win); wattrset(w.win, engine_get_color(COLOR_WHITE, COLOR_BLACK, false)); mvwprintw(w.win, 7, 1, "%10d x", g->L_count); p = new_piece(PIECE_L); p.x = x_offset; p.y = 8; for (k = 0; k < 4; k++) { p.block[k].x += p.x; p.block[k].y += p.y; } engine_draw_piece(&p, w.win); wattrset(w.win, engine_get_color(COLOR_WHITE, COLOR_BLACK, false)); mvwprintw(w.win, 9, 1, "%10d x", g->J_count); p = new_piece(PIECE_J); p.x = x_offset; p.y = 10; for (k = 0; k < 4; k++) { p.block[k].x += p.x; p.block[k].y += p.y; } engine_draw_piece(&p, w.win); wattrset(w.win, engine_get_color(COLOR_WHITE, COLOR_BLACK, false)); mvwprintw(w.win, 11, 1, "%10d x", g->S_count); p = new_piece(PIECE_S); p.x = x_offset; p.y = 12; for (k = 0; k < 4; k++) { p.block[k].x += p.x; p.block[k].y += p.y; } engine_draw_piece(&p, w.win); wattrset(w.win, engine_get_color(COLOR_WHITE, COLOR_BLACK, false)); mvwprintw(w.win, 13, 1, "%10d x", g->Z_count); p = new_piece(PIECE_Z); p.x = x_offset; p.y = 14; for (k = 0; k < 4; k++) { p.block[k].x += p.x; p.block[k].y += p.y; } engine_draw_piece(&p, w.win); wattrset(w.win, engine_get_color(COLOR_WHITE, COLOR_BLACK, false)); mvwprintw(w.win, 15, 1, "%10d x", g->O_count); p = new_piece(PIECE_O); p.x = x_offset - 1; p.y = 16; for (k = 0; k < 4; k++) { p.block[k].x += p.x; p.block[k].y += p.y; } engine_draw_piece(&p, w.win); wattrset(w.win, engine_get_color(COLOR_WHITE, COLOR_BLACK, false)); mvwprintw(w.win, 16, 1, "%10d Total", g->piece_count); }
/** * Main game cycle, handles user interaction and checks if game is over */ void Game::play() { // run indefinitely while (1) { auto b1 = new Board(); auto b2 = new Board(); srand(time(NULL)); //random seed set as current time int game_over = 0; int winner; while (!game_over) { display_help(); display_score(b1, b2); // if any board needs a piece, add it if (b1->needs_piece) { int next = rand() % 7; Piece new_piece(next); if (b1->is_collision(new_piece)) { game_over = 1; winner = 2; } b1->set_curr_piece(new_piece); } if (b2->needs_piece) { int next = rand() % 7; Piece new_piece(next); if (b2->is_collision(new_piece)) { game_over = 1; winner = 1; } b2->set_curr_piece(new_piece); } Piece current1 = b1->get_curr_piece(), potential1; Piece current2 = b2->get_curr_piece(), potential2; char move; // draw boards b1->draw(b2); move = wait_for_char(WAIT_TIME); // wait for input // quit immediatly if (move == 'q') { winner = 1; break; } if (move == 'w') { current1.move(UP); if (!b1->is_collision(current1)) b1->set_curr_piece(current1); continue; } else if (move == 's') { current1.move(DOWN); if (!b1->is_collision(current1)) b1->set_curr_piece(current1); continue; } else if (move == 'a') { current1.rotate(); if (!b1->is_collision(current1)) b1->set_curr_piece(current1); continue; } else if (move == 'i') { current2.move(UP); if (!b2->is_collision(current2)) b2->set_curr_piece(current2); continue; } else if (move == 'k') { current2.move(DOWN); if (!b2->is_collision(current2)) b2->set_curr_piece(current2); continue; } else if (move == 'l') { current2.rotate(); if (!b2->is_collision(current2)) b2->set_curr_piece(current2); continue; } // check if current piece of the boards has completely fallen potential1 = current1; potential2 = current2; potential1.move(RIGHT); if (!b1->is_collision(potential1)) b1->set_curr_piece(potential1); else { b1->add_piece(current1); b1->needs_piece = true; } potential2.move(RIGHT); if (!b2->is_collision(potential2)) b2->set_curr_piece(potential2); else { b2->add_piece(current2); b2->needs_piece = true; } int adjust1 = b1->delete_needed_lines(); int adjust2 = b2->delete_needed_lines(); // for each deleted line adjust the base of the boards accordingly for (int i = 0; i < adjust1; i++) { b1->adjust_middle(DOWN); b2->adjust_middle(UP); } for (int i = 0; i < adjust2; i++) { b2->adjust_middle(DOWN); b1->adjust_middle(UP); } } // ask for input, if input is 'y' start another game cout << "\nPlayer " << winner << " WINS!\n\n"; cout << "Play again? (Y or N)\n"; char resume = getch(); if (resume == 'n') break; } }
bool test_new_piece() { bool result = true; for (int x = 0; x < 5; x++) { for (int y = 0; y < 5; y++) { for (int compt_small = 0; compt_small < 2; ++compt_small) { for (int compt_horizontal = 0; compt_horizontal < 2; ++compt_horizontal) { int size; bool small; bool horizontal; if (compt_small == 0) { small = true; size = 2; } else { small = false; size = 3; } if (compt_horizontal == 0) horizontal = true; else horizontal = false; piece p = new_piece_rh(x, y, small, horizontal); result = result && test_equality_int(x, get_x(p), "get_x"); result = result && test_equality_int(y, get_y(p), "get_y"); if (horizontal) { result = result && test_equality_int(1, get_height(p), "get_height"); result = result && test_equality_int(size, get_width(p), "get_width"); result = result && test_equality_bool(true, can_move_x(p), "can_move_x"); result = result && test_equality_bool(false, can_move_y(p), "can_move_y"); } else { result = result && test_equality_int(size, get_height(p), "get_height"); result = result && test_equality_int(1, get_width(p), "get_width"); result = result && test_equality_bool(false, can_move_x(p), "can_move_x"); result = result && test_equality_bool(true, can_move_y(p), "can_move_y"); } delete_piece(p); } } for (int width = 1; width < 4; width++) { for (int height = 1; height < 4; height++) { for (int compt_move_x = 0; compt_move_x < 2; ++compt_move_x) { for (int compt_move_y = 0; compt_move_y < 2; ++compt_move_y) { bool move_x; bool move_y; if (compt_move_x == 0) move_x = true; else move_x = false; if (compt_move_y == 0) move_y = true; else move_y = false; piece p = new_piece(x, y, width, height, move_x, move_y); result = result && test_equality_int(x, get_x(p), "get_x"); result = result && test_equality_int(y, get_y(p), "get_y"); result = result && test_equality_int(height, get_height(p), "get_height"); result = result && test_equality_int(width, get_width(p), "get_width"); if (move_x) result = result && test_equality_bool(true, can_move_x(p), "can_move_x"); else result = result && test_equality_bool(false, can_move_x(p), "not can_move_x"); if (move_y) result = result && test_equality_bool(true, can_move_y(p), "can_move_y"); else result = result && test_equality_bool(false, can_move_y(p), "not can_move_y"); delete_piece(p); } } } } } } return result; }
void main_loop() { struct colour *board[WIDTH_CELLS][HEIGHT_CELLS]; SDL_Event e = {0}; bool running = false; bool game_over = false; int i = 0; int x = 0; int y = 0; int score = 0; int last_x = 0; int last_y = 1; struct piece held; new_piece(&held); TTF_Font *font = TTF_OpenFont(FONT_FILE, FONT_SIZE); if (!font) { printf("TTF_OpenFont: %s\n", TTF_GetError()); return; } for (y = 0; y < HEIGHT_CELLS; y++) for (x = 0; x < WIDTH_CELLS; x++) board[x][y] = &(palette[0]); running = true; last_x = last_y = x = y = 0; SDL_AddTimer(INTERVAL_NORMAL, &gravity_callback, NULL); char lockout; while (running) { lockout = 0; score += clear_rows(&board); if (hit_side(x, y, &held, &board)) x = last_x; if (hit_floor(x, y, &held, &board)) lockout = 1; draw_board(&board); if (!game_over) draw_piece(x, y, held.colour, held.bitmap); char score_string[16]; snprintf(score_string, sizeof(score_string), "Score: %d", score); score_string[sizeof(score_string) - 1] = '\0'; plot_text(score_string, font, ((SDL_Color){255,255,255,255}), 10, 10); if (game_over) plot_text("Game over", font, ((SDL_Color){255,255,255,255}), 90, 50); plot_update(); SDL_WaitEvent(&e); if (pause_mode) { if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_p) { pause_mode = 0; } continue; } switch (e.type) { case SDL_USEREVENT: if (lockout && !game_over) { drop_piece(x, y, &held, &board); last_x = last_y = x = y = 0; new_piece(&held); if (piece_overlaps(&held, &board, x, y)) { game_over = true; } lockout = 0; } else { last_y = y++; /* gravity */ last_x = x; } break; case SDL_QUIT: fprintf(stderr, "quit\n"); running = false; break; case SDL_KEYDOWN: switch (e.key.keysym.sym) { case SDLK_p: pause_mode = 1; break; case SDLK_a: last_x = x--; break; case SDLK_d: last_x = x++; break; case SDLK_w: i = 0; do { rotate(&held, 1); } while(hit_side(x, y, &held, &board) && i++ < 4); break; case SDLK_s: speed_mode = 1; break; case SDLK_q: running = false; break; default: break; } break; case SDL_KEYUP: switch (e.key.keysym.sym) { case SDLK_s: speed_mode = 0; break; default: break; } default: break; } } }
/* * @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; } }