Merge pull request #2 from arbu/master
Some changes to the logic, so the game is closer to the original
This commit is contained in:
commit
73d328c3a0
|
@ -28,13 +28,11 @@
|
|||
free(ptr);\
|
||||
} while (0)
|
||||
|
||||
/* Define a sequence that should be executed each turn */
|
||||
/* should be executed each turn */
|
||||
#define TURN(x)\
|
||||
do {\
|
||||
gravitate(x);\
|
||||
merge(x);\
|
||||
gravitate(x);\
|
||||
} while (0)
|
||||
gravitate(x) +\
|
||||
merge(x) +\
|
||||
gravitate(x)
|
||||
|
||||
/* maximum length of any value in grid, for printing */
|
||||
int MAXVAL;
|
||||
|
@ -59,9 +57,10 @@ int hs;
|
|||
char *file;
|
||||
|
||||
/* Merges adjacent squares of the same value together in a certain direction */
|
||||
void merge(int d)
|
||||
int merge(int d)
|
||||
{
|
||||
if (d == DL || d == DR) {
|
||||
int moved = 0;
|
||||
if (d == DL) {
|
||||
int i, j;
|
||||
for (i = 0; i < SZ; i++) {
|
||||
for (j = 0; j < SZ; j++) {
|
||||
|
@ -70,11 +69,12 @@ void merge(int d)
|
|||
sl += g[i][j];
|
||||
s += g[i][j];
|
||||
g[i][j++ + 1] = 0;
|
||||
moved = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if (d == DU) {
|
||||
int i, j;
|
||||
for (i = 0; i < SZ; i++) {
|
||||
for (j = 0; j < SZ; j++) {
|
||||
|
@ -83,18 +83,49 @@ void merge(int d)
|
|||
sl += g[j][i];
|
||||
s += g[j][i];
|
||||
g[j++ + 1][i] = 0;
|
||||
moved = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (d == DR) {
|
||||
int i, j;
|
||||
for (i = SZ - 1; i >= 0; i--) {
|
||||
for (j = SZ - 1; j >= 0; j--) {
|
||||
if (j > 0 && g[i][j] && g[i][j] == g[i][j - 1]) {
|
||||
g[i][j] <<= 1;
|
||||
sl += g[i][j];
|
||||
s += g[i][j];
|
||||
g[i][j-- - 1] = 0;
|
||||
moved = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (d == DD) {
|
||||
int i, j;
|
||||
for (i = SZ - 1; i >= 0; i--) {
|
||||
for (j = SZ - 1; j >= 0; j--) {
|
||||
if (j > 0 && g[j][i] && g[j][i] == g[j - 1][i]) {
|
||||
g[j][i] <<= 1;
|
||||
sl += g[j][i];
|
||||
s += g[j][i];
|
||||
g[j-- - 1][i] = 0;
|
||||
moved = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return moved;
|
||||
}
|
||||
|
||||
|
||||
/* move all values in the grid to the edge given by the direction pressed */
|
||||
/* would be nice to generalize this code a little so didn't need four loops */
|
||||
/* if animations are wanted, then need to alter this so it moves each square one at a time */
|
||||
void gravitate(int d)
|
||||
int gravitate(int d)
|
||||
{
|
||||
int moved = 0;
|
||||
if (d == DL) {
|
||||
int i, j;
|
||||
for (i = 0; i < SZ; i++) {
|
||||
|
@ -105,6 +136,7 @@ void gravitate(int d)
|
|||
if (j + st < SZ) {
|
||||
g[i][j] = g[i][j + st];
|
||||
g[i][j + st] = 0;
|
||||
moved = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -119,6 +151,7 @@ void gravitate(int d)
|
|||
if (j + st < SZ) {
|
||||
g[j][i] = g[j + st][i];
|
||||
g[j + st][i] = 0;
|
||||
moved = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -133,6 +166,7 @@ void gravitate(int d)
|
|||
if (j - st >= 0) {
|
||||
g[i][j] = g[i][j - st];
|
||||
g[i][j - st] = 0;
|
||||
moved = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -147,10 +181,12 @@ void gravitate(int d)
|
|||
if (j - st >= 0) {
|
||||
g[j][i] = g[j - st][i];
|
||||
g[j - st][i] = 0;
|
||||
moved = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return moved;
|
||||
}
|
||||
|
||||
/* load hiscore */
|
||||
|
@ -171,13 +207,13 @@ void save_score() {
|
|||
}
|
||||
}
|
||||
|
||||
/* returns if there are any available spaces left on the grid */
|
||||
int space_left()
|
||||
/* returns if there are any possible moves */
|
||||
int moves_available()
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < SZ; i++)
|
||||
for (j = 0; j < SZ; j++)
|
||||
if (!g[i][j])
|
||||
if (!g[i][j] || ((i + 1 < SZ) && (g[i][j] == g[i + 1][j])) || ((j + 1 < SZ) && (g[i][j] == g[i][j + 1])))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -186,19 +222,10 @@ int space_left()
|
|||
/* could do this in a much smarter fashion by finding which spaces are free */
|
||||
void rand_block()
|
||||
{
|
||||
if (space_left()) {
|
||||
int x_p, y_p;
|
||||
while (g[x_p = rand() % SZ][y_p = rand() % SZ]);
|
||||
g[x_p][y_p] = (rand() & 3) ? 2 : 4;
|
||||
}
|
||||
else {
|
||||
endwin();
|
||||
printf("\n"
|
||||
"YOU LOSE! - Your score was %d\n", s);
|
||||
save_score();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
/* quick floor log2(n) */
|
||||
int flog2(int n)
|
||||
|
@ -329,10 +356,11 @@ int main(int argc, char **argv)
|
|||
ITER(2, rand_block());
|
||||
draw_grid(gamewin);
|
||||
|
||||
int key;
|
||||
int key, moved;
|
||||
while (1) {
|
||||
/* will goto this if we didn't get a valid keypress */
|
||||
retry:;
|
||||
moved = 0;
|
||||
key = wgetch(gamewin);
|
||||
sl = 0;
|
||||
|
||||
|
@ -341,22 +369,22 @@ int main(int argc, char **argv)
|
|||
case 'h':
|
||||
case 'a':
|
||||
case KEY_LEFT:
|
||||
TURN(DL);
|
||||
moved = TURN(DL);
|
||||
break;
|
||||
case 'l':
|
||||
case 'd':
|
||||
case KEY_RIGHT:
|
||||
TURN(DR);
|
||||
moved = TURN(DR);
|
||||
break;
|
||||
case 'j':
|
||||
case 's':
|
||||
case KEY_DOWN:
|
||||
TURN(DD);
|
||||
moved = TURN(DD);
|
||||
break;
|
||||
case 'k':
|
||||
case 'w':
|
||||
case KEY_UP:
|
||||
TURN(DU);
|
||||
moved = TURN(DU);
|
||||
break;
|
||||
case 'q':
|
||||
FREE2D(g, SZ);
|
||||
|
@ -369,7 +397,17 @@ int main(int argc, char **argv)
|
|||
goto retry;
|
||||
}
|
||||
|
||||
if (!moves_available()) {
|
||||
endwin();
|
||||
printf("\n"
|
||||
"YOU LOSE! - Your score was %d\n", s);
|
||||
save_score();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
if (moved) {
|
||||
ITER(n_blocks, rand_block());
|
||||
draw_grid(gamewin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,11 +33,9 @@
|
|||
|
||||
/* Define a sequence that should be executed each turn */
|
||||
#define TURN(x)\
|
||||
do {\
|
||||
gravitate(x);\
|
||||
merge(x);\
|
||||
gravitate(x);\
|
||||
} while (0)
|
||||
gravitate(x) +\
|
||||
merge(x) +\
|
||||
gravitate(x)
|
||||
|
||||
/* direction enumeration */
|
||||
enum {DR, DU, DL, DD};
|
||||
|
@ -59,9 +57,10 @@ int hs;
|
|||
char *file;
|
||||
|
||||
/* Merges adjacent squares of the same value together in a certain direction */
|
||||
void merge(int d)
|
||||
int merge(int d)
|
||||
{
|
||||
if (d == DL || d == DR) {
|
||||
int moved = 0;
|
||||
if (d == DL) {
|
||||
int i, j;
|
||||
for (i = 0; i < SZ; i++) {
|
||||
for (j = 0; j < SZ; j++) {
|
||||
|
@ -70,11 +69,12 @@ void merge(int d)
|
|||
sl += g[i][j];
|
||||
s += g[i][j];
|
||||
g[i][j++ + 1] = 0;
|
||||
moved = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if (d == DU) {
|
||||
int i, j;
|
||||
for (i = 0; i < SZ; i++) {
|
||||
for (j = 0; j < SZ; j++) {
|
||||
|
@ -83,17 +83,48 @@ void merge(int d)
|
|||
sl += g[j][i];
|
||||
s += g[j][i];
|
||||
g[j++ + 1][i] = 0;
|
||||
moved = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (d == DR) {
|
||||
int i, j;
|
||||
for (i = SZ - 1; i >= 0; i--) {
|
||||
for (j = SZ - 1; j >= 0; j--) {
|
||||
if (j > 0 && g[i][j] && g[i][j] == g[i][j - 1]) {
|
||||
g[i][j] <<= 1;
|
||||
sl += g[i][j];
|
||||
s += g[i][j];
|
||||
g[i][j-- - 1] = 0;
|
||||
moved = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (d == DD) {
|
||||
int i, j;
|
||||
for (i = SZ - 1; i >= 0; i--) {
|
||||
for (j = SZ - 1; j >= 0; j--) {
|
||||
if (j > 0 && g[j][i] && g[j][i] == g[j - 1][i]) {
|
||||
g[j][i] <<= 1;
|
||||
sl += g[j][i];
|
||||
s += g[j][i];
|
||||
g[j-- - 1][i] = 0;
|
||||
moved = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return moved;
|
||||
}
|
||||
|
||||
|
||||
/* move all values in the grid to the edge given by the direction pressed */
|
||||
/* would be nice to generalize this code a little so didn't need four loops */
|
||||
void gravitate(int d)
|
||||
int gravitate(int d)
|
||||
{
|
||||
int moved = 0;
|
||||
if (d == DL) {
|
||||
int i, j;
|
||||
for (i = 0; i < SZ; i++) {
|
||||
|
@ -104,6 +135,7 @@ void gravitate(int d)
|
|||
if (j + st < SZ) {
|
||||
g[i][j] = g[i][j + st];
|
||||
g[i][j + st] = 0;
|
||||
moved = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -118,6 +150,7 @@ void gravitate(int d)
|
|||
if (j + st < SZ) {
|
||||
g[j][i] = g[j + st][i];
|
||||
g[j + st][i] = 0;
|
||||
moved = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -132,6 +165,7 @@ void gravitate(int d)
|
|||
if (j - st >= 0) {
|
||||
g[i][j] = g[i][j - st];
|
||||
g[i][j - st] = 0;
|
||||
moved = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -146,10 +180,12 @@ void gravitate(int d)
|
|||
if (j - st >= 0) {
|
||||
g[j][i] = g[j - st][i];
|
||||
g[j - st][i] = 0;
|
||||
moved = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return moved;
|
||||
}
|
||||
|
||||
/* loads hiscore */
|
||||
|
@ -170,13 +206,13 @@ void save_score() {
|
|||
}
|
||||
}
|
||||
|
||||
/* returns if there are any available spaces left on the grid */
|
||||
int space_left()
|
||||
/* returns if there are any possible moves */
|
||||
int moves_available()
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < SZ; i++)
|
||||
for (j = 0; j < SZ; j++)
|
||||
if (!g[i][j])
|
||||
if (!g[i][j] || ((i + 1 < SZ) && (g[i][j] == g[i + 1][j])) || ((j + 1 < SZ) && (g[i][j] == g[i][j + 1])))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -185,19 +221,10 @@ int space_left()
|
|||
/* do this in a smarter fashion */
|
||||
void rand_block()
|
||||
{
|
||||
if (space_left()) {
|
||||
int x_p, y_p;
|
||||
while (g[x_p = rand() % SZ][y_p = rand() % SZ]);
|
||||
g[x_p][y_p] = (rand() & 3) ? 2 : 4;
|
||||
}
|
||||
else {
|
||||
printf("\n"
|
||||
"YOU LOSE\n"
|
||||
"Your score was %d\n", s);
|
||||
save_score();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
/* draws the grid and fills it with the current values */
|
||||
void draw_grid()
|
||||
|
@ -302,11 +329,11 @@ int main(int argc, char **argv)
|
|||
tattr.c_lflag &= ~(ICANON | ECHO);
|
||||
tcsetattr(STDOUT_FILENO, TCSANOW, &tattr);
|
||||
|
||||
int key;
|
||||
|
||||
int key, moved;
|
||||
while (1) {
|
||||
/* will goto this if we didn't get a valid keypress */
|
||||
retry:;
|
||||
moved = 0;
|
||||
key = getchar();
|
||||
sl = 0;
|
||||
|
||||
|
@ -314,19 +341,19 @@ int main(int argc, char **argv)
|
|||
switch (key) {
|
||||
case 'h':
|
||||
case 'a':
|
||||
TURN(DL);
|
||||
moved = TURN(DL);
|
||||
break;
|
||||
case 'l':
|
||||
case 'd':
|
||||
TURN(DR);
|
||||
moved = TURN(DR);
|
||||
break;
|
||||
case 'j':
|
||||
case 's':
|
||||
TURN(DD);
|
||||
moved = TURN(DD);
|
||||
break;
|
||||
case 'k':
|
||||
case 'w':
|
||||
TURN(DU);
|
||||
moved = TURN(DU);
|
||||
break;
|
||||
case 'q':
|
||||
save_score();
|
||||
|
@ -335,7 +362,16 @@ int main(int argc, char **argv)
|
|||
goto retry;
|
||||
}
|
||||
|
||||
if (!moves_available()) {
|
||||
printf("\n"
|
||||
"YOU LOSE! - Your score was %d\n", s);
|
||||
save_score();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
if (moved) {
|
||||
ITER(n_blocks, rand_block());
|
||||
draw_grid();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user