Skip to content

Commit

Permalink
Merge pull request thecardkid#32 from thecardkid/db/refactor
Browse files Browse the repository at this point in the history
block movement refactored into utility functions
  • Loading branch information
Hieu Nguyen authored Apr 24, 2017
2 parents 0dcc555 + 1533d2f commit b025117
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 55 deletions.
60 changes: 5 additions & 55 deletions src/controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,6 @@ int move_block(State* s) {
Movement* m = s->net_move;
int applied_move = 1;
int can_move_vert = 1;
int can_move_horiz = 1;
int can_rotate = 1;

if (m->drop) {
s->block->y = s->block->ghosty;
Expand All @@ -226,70 +224,22 @@ int move_block(State* s) {

// Try to move vertically
if (m->y != 0) {
can_move_vert = 1;
for (int i = 0; i < 4; i++) {
int x = s->block->cells[i][0] + s->block->x;
int y = s->block->cells[i][1] + s->block->y;

// Conditions where move is invalid
if (!in_grid(x, y + m->y) || ((s->grid[x][y + m->y] != EMPTY) && (s->grid[x][y + m->y] != GHOST))) {
can_move_vert = 0;
break;
}
}
can_move_vert = move_block_vertically(s);
if (can_move_vert) {
s->block->y += m->y;
m->y = 0; // signal that we have performed this operation
applied_move = 1; // signal that A operation was performed
}
applied_move = 1;
}
}

// Try to move horizontally
if (m->x != 0) {
can_move_horiz = 1;
for (int i = 0; i < 4; i++) {
int x = s->block->cells[i][0] + s->block->x;
int y = s->block->cells[i][1] + s->block->y;

// Conditions where move is invalid
if (!in_grid(x + m->x, y) || s->grid[x + m->x][y] != EMPTY) {
can_move_horiz = 0;
break;
}
}
if (can_move_horiz) {
s->block->x += m->x;
m->x = 0;
if (move_block_horizontally(s)) {
applied_move = 1;
}
}

// Try to rotate
int old_cells[4][2];
if (m->r) {
can_rotate = 1;
// Make copy of current cells
memcpy(old_cells, s->block->cells, sizeof(I_Block));
rotate(s->block);

for (int i = 0; i < 4; i++) {
int x = s->block->cells[i][0] + s->block->x;
int y = s->block->cells[i][1] + s->block->y;

// Conditions where move is invalid
if (!in_grid(x, y) || s->grid[x][y] != EMPTY) {
can_rotate = 0;
break;
}
}

if (!can_rotate) {
// Undo rotation
if (m->r) {
memcpy(s->block->cells, old_cells, sizeof(I_Block));
}
} else {
m->r = 0;
if (rotate_block(s)) {
applied_move = 1;
}
}
Expand Down
123 changes: 123 additions & 0 deletions src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,129 @@ int in_grid(int x, int y) {
return 1;
}

int can_move_vertically(int x, int y, State* s) {
int delta_y = s->net_move->y;
int dy;
if (delta_y < 0) {
dy = -1;
} else {
dy = 1;
}

while (dy*dy <= delta_y*delta_y) {
if (!in_grid(x, y + dy) || s->grid[x][y + dy] != EMPTY) {
return 0;
}

if (delta_y < 0) {
dy--;
} else {
dy++;
}
}

return 1;
}

int can_move_horizontally(int x, int y, State* s) {
int delta_x = s->net_move->x;
int dx;
if (delta_x < 0) {
dx = -1;
} else {
dx = 1;
}

while (dx*dx <= delta_x*delta_x) {
if (!in_grid(x + dx, y) || s->grid[x + dx][y] != EMPTY) {
return 0;
}

if (delta_x < 0) {
dx--;
} else {
dx++;
}
}

return 1;
}

int move_block_vertically(State* s) {
Movement* m = s->net_move;
int can_move_vert = 1;
for (int i = 0; i < 4; i++) {
int x = s->block->cells[i][0] + s->block->x;
int y = s->block->cells[i][1] + s->block->y;

// Conditions where move is invalid
if (!can_move_vertically(x, y, s)) {
can_move_vert = 0;
break;
}
}
if (can_move_vert) {
s->block->y += m->y;
m->y = 0; // signal that we have performed this operation
return 1; // signal that A operation was performed
} else {
return 0;
}
}

int move_block_horizontally(State* s) {
Movement* m = s->net_move;
int can_move_horiz = 1;
for (int i = 0; i < 4; i++) {
int x = s->block->cells[i][0] + s->block->x;
int y = s->block->cells[i][1] + s->block->y;

// Conditions where move is invalid
if (!can_move_horizontally(x, y, s)) {
can_move_horiz = 0;
break;
}
}
if (can_move_horiz) {
s->block->x += m->x;
m->x = 0;
return 1;
} else {
return 0;
}
}

int rotate_block(State* s) {
Movement* m = s->net_move;
int old_cells[4][2];
int can_rotate = 1;
// Make copy of current cells
memcpy(old_cells, s->block->cells, sizeof(I_Block));
rotate(s->block);

for (int i = 0; i < 4; i++) {
int x = s->block->cells[i][0] + s->block->x;
int y = s->block->cells[i][1] + s->block->y;

// Conditions where move is invalid
if (!in_grid(x, y) || s->grid[x][y] != EMPTY) {
can_rotate = 0;
break;
}
}

if (!can_rotate) {
// Undo rotation
if (m->r) {
memcpy(s->block->cells, old_cells, sizeof(I_Block));
}
return 0;
} else {
m->r = 0;
return 1;
}
}

void clear_block(State* s) {
for (int i = 0; i < 4; i++) {
int x = s->block->cells[i][0] + s->block->x;
Expand Down
25 changes: 25 additions & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,31 @@ typedef struct {
*/
int in_grid(int x, int y);

/*
* Checks whether the spaces below or above a cell are empty
*/
int can_move_vertically(int x, int y, State* s);

/*
* Checks whether the spaces to the sides of a cell are empty
*/
int can_move_horizontally(int x, int y, State* s);

/*
* Attempt to move a block a vertical distance defined by the movement struct
*/
int move_block_vertically(State* s);

/*
* Attempt to move a block a horizontal distance
*/
int move_block_horizontally(State* s);

/*
* Attempt to rotate a block
*/
int rotate_block(State* s);

/*
* Set all cells occupied by playable block to EMPTY
*/
Expand Down

0 comments on commit b025117

Please sign in to comment.