diff --git a/game.c b/game.c index a34aafc..cf6a394 100644 --- a/game.c +++ b/game.c @@ -23,6 +23,9 @@ size_t hand_count = 0; struct brick active = {0}; int has_active = 0; +struct brick preview[256] = {0}; +size_t preview_count = 0; + struct eye direction[4] = { {.x = 0, .y = -1}, {.x = -2, .y = 0}, @@ -30,6 +33,39 @@ struct eye direction[4] = { {.x = 0, .y = 1}, }; +void get_prewiews() { + preview_count = 0; + for (size_t i = 0; i < bricks.count * 2; i++) { + struct eye e = bricks.items.eye[i]; + if (e.val != active.front.val) continue; + + struct brick p = active; + p.front.x = e.x; + p.front.y = e.y; + p.back.x = e.x + 1; + p.back.y = e.y; + struct brick previews[4] = {p, p, p, p}; + for (size_t ii = 0; ii < 4; ii++) { + previews[ii].front.x += direction[ii].x; + previews[ii].front.y += direction[ii].y; + previews[ii].front.val = 0; + + previews[ii].back.x += direction[ii].x; + previews[ii].back.y += direction[ii].y; + + for (size_t iii = 0; iii < bricks.count * 2; iii++) { + previews[ii].front.val |= ((bricks.items.eye[iii].x == previews[ii].back.x && bricks.items.eye[iii].y == previews[ii].back.y) || + (bricks.items.eye[iii].x == previews[ii].front.x && bricks.items.eye[iii].y == previews[ii].front.y)); + } + } + + for (size_t ii = 0; ii < 4; ii++) { + if (!previews[ii].front.val) + preview[preview_count++] = previews[ii]; + } + } +} + void key_callback(int key, int scancode, int action, int mods) { if (action != GLFW_PRESS) return; switch (key) { @@ -47,6 +83,7 @@ void cursor_position_callback(int xpos, int ypos) { void mouse_button_callback(int button, int action, int mods) { if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) { + // pick up brick from hand for (size_t i = 0; i < hand_count; i++) { struct brick *b = &hand[i]; if (!has_active) { @@ -62,14 +99,36 @@ void mouse_button_callback(int button, int action, int mods) { hand[i - 1] = hand[i]; } } - if (has_active) hand_count--; + if (has_active) { + hand_count--; + get_prewiews(); + } } printf("click!\n"); if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_RELEASE) { if (has_active) { has_active = 0; - hand[hand_count++] = active; + + size_t min_dist = -1; + for (size_t i = 0; i < preview_count; i++) { + int active_x = active.front.x + mouse_x + DOMINO_WIDTH / 2; + int active_y = active.front.y + mouse_y + DOMINO_HEIGHT / 2; + int preview_x = preview[i].front.x * EYE_SIZE + DOMINO_WIDTH / 2; + int preview_y = preview[i].front.y * EYE_SIZE + DOMINO_HEIGHT / 2; + preview[i].front.val = (active_x - preview_x) * (active_x - preview_x) + (active_y - preview_y) * (active_y - preview_y); + if (min_dist == (size_t)-1) min_dist = 1; + if (preview[i].front.val < preview[min_dist].front.val) min_dist = i; + } + + if (preview[min_dist].front.val < EYE_SIZE * EYE_SIZE && preview_count) { + preview[min_dist].front.val = active.front.val; + preview[min_dist].back.val = active.back.val; + bricks_append(&bricks, preview[min_dist]); + } else { + hand[hand_count++] = active; + } + preview_count = 0; } } @@ -160,36 +219,8 @@ void render(struct image canvas) { draw(canvas, red_and_peach_dominoes[b->back.val][b->front.val], b->front.x * EYE_SIZE, b->front.y * EYE_SIZE); } - if (has_active) { - for (size_t i = 0; i < bricks.count * 2; i++) { - struct eye e = bricks.items.eye[i]; - if (e.val != active.front.val) continue; - - struct brick p = active; - p.front.x = e.x; - p.front.y = e.y; - p.back.x = e.x + 1; - p.back.y = e.y; - struct brick previews[4] = {p, p, p, p}; - for (size_t ii = 0; ii < 4; ii++) { - previews[ii].front.x += direction[ii].x; - previews[ii].front.y += direction[ii].y; - previews[ii].front.val = 0; - - previews[ii].back.x += direction[ii].x; - previews[ii].back.y += direction[ii].y; - - for (size_t iii = 0; iii < bricks.count * 2; iii++) { - previews[ii].front.val |= ((bricks.items.eye[iii].x == previews[ii].back.x && bricks.items.eye[iii].y == previews[ii].back.y) || - (bricks.items.eye[iii].x == previews[ii].front.x && bricks.items.eye[iii].y == previews[ii].front.y)); - } - } - - for (size_t ii = 0; ii < 4; ii++) { - if (!previews[ii].front.val) - draw(canvas, white_and_blue_dominoes[active.back.val][active.front.val], previews[ii].front.x * EYE_SIZE, previews[ii].front.y * EYE_SIZE); - } - } + for (size_t i = 0; i < preview_count; i++) { + draw(canvas, white_and_blue_dominoes[active.back.val][active.front.val], preview[i].front.x * EYE_SIZE, preview[i].front.y * EYE_SIZE); } // hand