Tp* merge_down(Tp* a, size_t sa, Tp* b, size_t sb) { bool afree = false, bfree = false; std::thread at; std::thread bt; if(sa > 1) { at = std::thread([&]() { a = merge_down(a, sa/2, a+sa/2, (sa+1)/2); }); afree = true; } if(sb > 1) { bt = std::thread([&]() { b = merge_down(b, sb/2, b+sb/2, (sb+1)/2); }); bfree = true; } if(afree) at.join(); if(bfree) bt.join(); Tp* out = new Tp[sa+sb]; size_t i = 0, j = 0, o = 0; while(i < sa || j < sb) { if(i < sa && j < sb) { if(a[i] < b[j]) out[o] = a[i++]; else out[o] = b[j++]; } else if(i < sa) out[o] = a[i++]; else if(j < sb) out[o] = b[j++]; o++; } if(afree) delete[] a; if(bfree) delete[] b; return out; }
int can_move_down(board *b) { board *tmp; tmp = dup_board(b); shift_down(tmp); merge_down(tmp); shift_down(tmp); if (cmp_board(b, tmp)) { free(tmp); return 0; } else { free(tmp); return 1; } }
void merge_sort(Tp* vals, size_t sz) { Tp* out = merge_down(vals, sz/2, vals+sz/2, (sz+1)/2); std::copy(out,out+sz,vals); delete[] out; }
void play_game() { board *b = &grid; do { switch (os_wait_for_key()) { case ESC_KEY: return; case UP_KEY: if (can_move_up(b)) { shift_up(b); merge_up(b); shift_up(b); add_big_int(&score, &merge_score); break; } else { continue; } case DOWN_KEY: if (can_move_down(b)) { shift_down(b); merge_down(b); shift_down(b); add_big_int(&score, &merge_score); break; } else { continue; } case LEFT_KEY: if (can_move_left(b)) { shift_left(b); merge_left(b); shift_left(b); add_big_int(&score, &merge_score); break; } else { continue; } case RIGHT_KEY: if (can_move_right(b)) { shift_right(b); merge_right(b); shift_right(b); add_big_int(&score, &merge_score); break; } else { continue; } default: continue; } add_tile(b); display_board(b); } while (!game_is_lost()); }