solution_t* neighbor_into_solution(solution_t* s, neighbor_t* n, int write_mode) { solution_t* tmp=NULL; int r1,r2,c1,c2; if (write_mode==DUPLICATE) tmp=solution_cpy(tmp,s); else tmp=s; r1=n->move->pos1/tmp->n; r2=n->move->pos2/tmp->n; c1=n->move->pos1%tmp->n; c2=n->move->pos2%tmp->n; tmp->matches=n->matches; piece_free(tmp->mat[r1][c1]); tmp->mat[r1][c1]=NULL; tmp->mat[r1][c1]=piece_new(n->move->square_index1,n->move->rotation1); if(n->move->pos1!=n->move->pos2) { piece_free(tmp->mat[r2][c2]); tmp->mat[r2][c2]=NULL; tmp->mat[r2][c2]=piece_new(n->move->square_index2,n->move->rotation2); } return(s); }
/** Attempts to push the current piece down */ bool board_push_current_piece_down(Board * b) { // First test if the current piece is already touching something. // This can happen if you move sideways and are now touching another piece. bool is_on_bottom = !board_can_piece_move_down(b); bool result = false; if (!is_on_bottom) { piece_down(b->current_piece); is_on_bottom = !board_can_piece_move_down(b); result = true; } if (is_on_bottom){ // remove the rows board_place_piece(b, b->current_piece); bool * completed_rows = board_find_completed_rows(b); int total_complete_rows = count_true(completed_rows, b->height); for (int y=b->height-1; y>=0; y--) { if (completed_rows[y]) { board_remove_row(b, y); } } free(completed_rows); // score the points if (total_complete_rows == 1) { b->score += 10; } else if (total_complete_rows == 2) { b->score += 25; } else if (total_complete_rows == 3) { b->score += 40; } else if (total_complete_rows == 4) { b->score += 55; } if (total_complete_rows > 0){ printf("Score is %i\n", b->score); } // board_print(b); Piece * next_piece = piece_create_random((b->width / 2), 2); if (board_check_valid_placement(b, next_piece)){ piece_free(b->current_piece); b->current_piece = next_piece; } else { piece_free(next_piece); b->is_done = true; } } return result; }
solution_t* neighbor_into_solution(solution_t* s, neighbor_t* n, int write_mode) { solution_t* tmp=NULL; dir d; corner_dir cd; if (write_mode==DUPLICATE) tmp=solution_cpy(tmp,s); else tmp=s; tmp->matches=n->matches; piece_free(tmp->mat[n->move->pos/tmp->n][n->move->pos%tmp->n]); if (n->move->move_type==INNER) { tmp->mat[n->move->pos/tmp->n][n->move->pos%tmp->n]=tmp->mat[1][1]; tmp->mat[1][1]=piece_new(n->move->square_index,n->move->rotation); } else if (n->move->move_type==EDGE) { d=direction_edge(n->move->pos,s->n); tmp->mat[0][1]->rotation=square_rotate_edge(squares[tmp->mat[0][1]->square_index],d); tmp->mat[n->move->pos/tmp->n][n->move->pos%tmp->n]=tmp->mat[0][1]; tmp->mat[0][1]=piece_new(n->move->square_index,n->move->rotation); } else { cd=direction_edge(n->move->pos,s->n); tmp->mat[0][0]->rotation=square_rotate_corner(squares[tmp->mat[0][0]->square_index],cd); tmp->mat[n->move->pos/tmp->n][n->move->pos%tmp->n]=tmp->mat[0][0]; tmp->mat[0][0]=piece_new(n->move->square_index,n->move->rotation); } return(s); }
int move_matches_diff_corner(solution_t* s, move_t* move) { int tot; piece_t *p1, *p2; p1=piece_new(move->square_index1,move->rotation1); p2=piece_new(move->square_index2,move->rotation2); //always non adjacent swap //old pieces matches are subtracted tot=s->matches - solution_piece_matches_corner(s,NULL,move->pos1) - solution_piece_matches_corner(s,NULL,move->pos2); //new pieces matches are added tot+=solution_piece_matches_corner(s,p1,move->pos1) + solution_piece_matches_corner(s,p2,move->pos2); piece_free(p1); piece_free(p2); return(tot); }
/** * Is is possible for the given piece to move down? * Or is touching the bottom?. */ bool board_can_piece_move_down(Board * b) { Piece * copy = piece_copy(b->current_piece); piece_down(copy); bool result = board_check_valid_placement(b, copy); piece_free(copy); return result; }
int move_matches_diff_corner(solution_t* s, move_t* move) { int tot; piece_t *p1, *p2; corner_dir d; d=direction_corner(move->pos,s->n); p1=piece_new(s->mat[0][0]->square_index,square_rotate_corner(squares[s->mat[0][0]->square_index],d)); p2=piece_new(move->square_index,move->rotation); //always non adjacent swap //old pieces matches are subtracted tot=s->matches - solution_piece_matches_corner(s,NULL,move->pos) - solution_piece_matches_corner(s,NULL,0); //new pieces matches are added tot+=solution_piece_matches_corner(s,p2,0) + solution_piece_matches_corner(s,p1,move->pos); piece_free(p1); piece_free(p2); return(tot); }
int move_matches_diff_inner(solution_t* s, move_t* move) { int tot; piece_t *p1, *p2, *p1_old, *p2_old; dir d; p1=piece_new(move->square_index1,move->rotation1); p2=piece_new(move->square_index2,move->rotation2); //rotation of the same piece //p1==p2 if it is the same piece if (move->pos1==move->pos2) { tot=s->matches - solution_piece_matches_inner(s,NULL,move->pos1) + solution_piece_matches_inner(s, p1, move->pos1); } else { //non adjacent swap //old pieces matches are subtracted tot=s->matches - solution_piece_matches_inner(s,NULL,move->pos1) - solution_piece_matches_inner(s,NULL,move->pos2); //new pieces matches are added tot+=solution_piece_matches_inner(s, p1, move->pos1) + solution_piece_matches_inner(s,p2, move->pos2); d=is_adjacent(move->pos2,move->pos1,s->n); //swap_pos->other_pos //adjacent swap if (d!=NONE) { p1_old=s->mat[(move->pos2)/(s->n)][(move->pos2)%(s->n)]; p2_old=s->mat[(move->pos1)/(s->n)][(move->pos1)%(s->n)]; if ( PIECE_COLOUR(p1_old,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) ) //the match has been subtracted twice tot++; //to avoid counting matches with the previous version of themselves if ( PIECE_COLOUR(p2,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) ) tot--; if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p1_old,d) ) tot--; //to count the match between the new versions if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p2,d) ) tot++; } } piece_free(p1); piece_free(p2); return(tot); }
void solution_free(solution_t* s) { int i,j; for (i=0;i<s->n;i++) { for (j=0;j<s->n;j++) { piece_free(s->mat[i][j]); } free(s->mat[i]); } free(s->mat); free(s); }
int move_matches_diff_edge(solution_t* s, move_t* move) { int tot; piece_t *p1, *p2, *p1_old, *p2_old; dir d; d=direction_edge(move->pos,s->n); p1=piece_new(s->mat[0][1]->square_index,square_rotate_edge(squares[s->mat[0][1]->square_index],d)); p2=piece_new(move->square_index,move->rotation); //non adjacent swap //old pieces matches are subtracted tot=s->matches - solution_piece_matches_edge(s,NULL,move->pos) - solution_piece_matches_edge(s,NULL,1); //new pieces matches are added tot+=solution_piece_matches_edge(s,p2,1) + solution_piece_matches_edge(s,p1,move->pos); d=is_adjacent(1,move->pos,s->n); //adjacent swap if (d!=NONE) { p1_old=s->mat[0][1]; p2_old=s->mat[(move->pos)/(s->n)][(move->pos)%(s->n)]; if ( PIECE_COLOUR(p1_old,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) ) //the match has been subtracted twice tot++; //to avoid counting matches with the previous version of themselves if ( PIECE_COLOUR(p2,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) ) tot--; if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p1_old,d) ) tot--; //to count the match between the new versions if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p2,d) ) tot++; } piece_free(p1); piece_free(p2); return(tot); }
int move_matches_diff_inner(solution_t* s, move_t* move) { int tot; piece_t *p1, *p2, *p1_old, *p2_old; dir d; p1=s->mat[1][1]; p2=piece_new(move->square_index,move->rotation); //rotation of the first piece if (s->n+1==move->pos) { tot=s->matches - solution_piece_matches_inner(s,NULL,s->n+1) + solution_piece_matches_inner(s, p2, s->n+1); } else { //non adjacent swap //old pieces matches are subtracted tot=s->matches - solution_piece_matches_inner(s,NULL,move->pos) - solution_piece_matches_inner(s,NULL,s->n+1); //new pieces matches are added tot+=solution_piece_matches_inner(s, p2, s->n+1) + solution_piece_matches_inner(s,p1, move->pos); d=is_adjacent(s->n+1,move->pos,s->n); //adjacent swap if (d!=NONE) { p1_old=p1; p2_old=s->mat[(move->pos)/(s->n)][(move->pos)%(s->n)]; if ( PIECE_COLOUR(p1_old,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) ) //the match has been subtracted twice tot++; //to avoid counting matches with the previous version of themselves if ( PIECE_COLOUR(p2,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) ) tot--; if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p1_old,d) ) tot--; //to count the match between the new versions if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p2,d) ) tot++; } } //piece_free(p1); //placeholder for enhanced versions piece_free(p2); return(tot); }