|
|
d72a13 |
|
|
|
d72a13 |
#include <stdlib.h></stdlib.h>
|
|
|
d72a13 |
#include <stdio.h></stdio.h>
|
|
|
d72a13 |
#include <math.h></math.h>
|
|
|
d72a13 |
|
|
|
d72a13 |
#include <helianthus.h></helianthus.h>
|
|
|
d72a13 |
|
|
|
d72a13 |
|
|
|
d72a13 |
#define CELLSIZE 128
|
|
|
d72a13 |
#define MAPSIZE 4
|
|
|
d72a13 |
|
|
|
d72a13 |
|
|
|
d72a13 |
typedef struct {
|
|
|
d72a13 |
Group group;
|
|
|
d72a13 |
int value;
|
|
|
d72a13 |
} Cell;
|
|
|
d72a13 |
|
|
|
d72a13 |
|
|
|
d72a13 |
Animation grid;
|
|
|
d72a13 |
Animation numbers[11];
|
|
|
d72a13 |
Cell map[MAPSIZE][MAPSIZE];
|
|
|
d72a13 |
double speed = 8;
|
|
|
d72a13 |
|
|
|
d72a13 |
|
|
|
d72a13 |
void setSprite(Cell *cell, double x, double y) {
|
|
|
d72a13 |
if (cell->group)
|
|
|
d72a13 |
groupDestroyEach(cell->group);
|
|
|
d72a13 |
else
|
|
|
d72a13 |
cell->group = createGroup();
|
|
|
348218 |
Sprite sprite = createSpriteEx(x, y, 1, 1, numbers[cell->value]);
|
|
|
d72a13 |
groupAdd(cell->group, sprite);
|
|
|
d72a13 |
}
|
|
|
d72a13 |
|
|
|
d72a13 |
|
|
|
d72a13 |
int add(int dr, int dc) {
|
|
|
d72a13 |
int count = 0;
|
|
|
d72a13 |
for(int r = 0; r < MAPSIZE; ++r)
|
|
|
d72a13 |
for(int c = 0; c < MAPSIZE; ++c)
|
|
|
d72a13 |
if (map[r][c].value < 0)
|
|
|
d72a13 |
++count;
|
|
|
d72a13 |
if (count == 0) return 0;
|
|
|
d72a13 |
|
|
|
d72a13 |
int i = randomNumber(0, count-1);
|
|
|
d72a13 |
for(int r = 0; r < MAPSIZE; ++r)
|
|
|
d72a13 |
for(int c = 0; c < MAPSIZE; ++c)
|
|
|
d72a13 |
if (map[r][c].value < 0)
|
|
|
d72a13 |
if (i-- == 0) {
|
|
|
d72a13 |
map[r][c].value = 0;
|
|
|
d72a13 |
int cc = dc > 0 ? -1 : (dc < 0 ? MAPSIZE : c);
|
|
|
d72a13 |
int rr = dr > 0 ? -1 : (dr < 0 ? MAPSIZE : r);
|
|
|
d72a13 |
setSprite(&map[r][c], cc + 0.5, rr + 0.5);
|
|
|
d72a13 |
return 1;
|
|
|
d72a13 |
}
|
|
|
d72a13 |
|
|
|
d72a13 |
return 0;
|
|
|
d72a13 |
}
|
|
|
d72a13 |
|
|
|
d72a13 |
|
|
|
d72a13 |
void fallStep(int *moves, Cell **prev, int *skip, Cell *curr, Cell *empty) {
|
|
|
d72a13 |
if (curr->value < 0) {
|
|
|
d72a13 |
++(*skip);
|
|
|
d72a13 |
} else
|
|
|
d72a13 |
if (*prev && (*prev)->value == curr->value && curr->value < 10) {
|
|
|
d72a13 |
for(int i = 0; i < groupGetCount(curr->group); ++i)
|
|
|
d72a13 |
groupAdd((*prev)->group, groupGet(curr->group, i));
|
|
|
d72a13 |
groupDestroy(curr->group);
|
|
|
d72a13 |
curr->group = NULL;
|
|
|
d72a13 |
curr->value = -1;
|
|
|
d72a13 |
++((*prev)->value);
|
|
|
d72a13 |
++(*skip);
|
|
|
d72a13 |
++(*moves);
|
|
|
d72a13 |
*prev = NULL;
|
|
|
d72a13 |
} else {
|
|
|
d72a13 |
if (empty != curr) {
|
|
|
d72a13 |
empty->group = curr->group;
|
|
|
d72a13 |
empty->value = curr->value;
|
|
|
d72a13 |
curr->group = NULL;
|
|
|
d72a13 |
curr->value = -1;
|
|
|
d72a13 |
++(*moves);
|
|
|
d72a13 |
}
|
|
|
d72a13 |
*prev = empty;
|
|
|
d72a13 |
}
|
|
|
d72a13 |
}
|
|
|
d72a13 |
|
|
|
d72a13 |
|
|
|
d72a13 |
void fall(int dr, int dc) {
|
|
|
d72a13 |
Cell *prev;
|
|
|
d72a13 |
int skip;
|
|
|
d72a13 |
int moves = 0;
|
|
|
d72a13 |
|
|
|
d72a13 |
if (dr == 0) {
|
|
|
d72a13 |
for(int r = 0; r < MAPSIZE; ++r) {
|
|
|
d72a13 |
prev = NULL; skip = 0;
|
|
|
d72a13 |
if (dc < 0)
|
|
|
d72a13 |
for(int c = 0; c < MAPSIZE; ++c)
|
|
|
d72a13 |
fallStep(&moves, &prev, &skip, &map[r][c], &map[r][c-skip]);
|
|
|
d72a13 |
else
|
|
|
d72a13 |
if (dc > 0)
|
|
|
d72a13 |
for(int c = MAPSIZE-1; c >= 0; --c)
|
|
|
d72a13 |
fallStep(&moves, &prev, &skip, &map[r][c], &map[r][c+skip]);
|
|
|
d72a13 |
}
|
|
|
d72a13 |
} else
|
|
|
d72a13 |
if (dc == 0) {
|
|
|
d72a13 |
for(int c = 0; c < MAPSIZE; ++c) {
|
|
|
d72a13 |
prev = NULL; skip = 0;
|
|
|
d72a13 |
if (dr < 0)
|
|
|
d72a13 |
for(int r = 0; r < MAPSIZE; ++r)
|
|
|
d72a13 |
fallStep(&moves, &prev, &skip, &map[r][c], &map[r-skip][c]);
|
|
|
d72a13 |
else
|
|
|
d72a13 |
if (dr > 0)
|
|
|
d72a13 |
for(int r = MAPSIZE-1; r >= 0; --r)
|
|
|
d72a13 |
fallStep(&moves, &prev, &skip, &map[r][c], &map[r+skip][c]);
|
|
|
d72a13 |
}
|
|
|
d72a13 |
}
|
|
|
d72a13 |
|
|
|
d72a13 |
if (moves > 0) add(dr, dc);
|
|
|
d72a13 |
}
|
|
|
d72a13 |
|
|
|
d72a13 |
|
|
|
d72a13 |
void init() {
|
|
|
d72a13 |
for(int r = 0; r < MAPSIZE; ++r) {
|
|
|
d72a13 |
for(int c = 0; c < MAPSIZE; ++c) {
|
|
|
d72a13 |
map[r][c].group = NULL;
|
|
|
d72a13 |
map[r][c].value = -1;
|
|
|
d72a13 |
}
|
|
|
d72a13 |
}
|
|
|
d72a13 |
|
|
|
d72a13 |
grid = createAnimationEx("data/sprite/2048/frame.png", TRUE, TRUE, TRUE);
|
|
|
d72a13 |
numbers[ 0] = createAnimation("data/sprite/2048/2.png");
|
|
|
d72a13 |
numbers[ 1] = createAnimation("data/sprite/2048/4.png");
|
|
|
d72a13 |
numbers[ 2] = createAnimation("data/sprite/2048/8.png");
|
|
|
d72a13 |
numbers[ 3] = createAnimation("data/sprite/2048/16.png");
|
|
|
d72a13 |
numbers[ 4] = createAnimation("data/sprite/2048/32.png");
|
|
|
d72a13 |
numbers[ 5] = createAnimation("data/sprite/2048/64.png");
|
|
|
d72a13 |
numbers[ 6] = createAnimation("data/sprite/2048/128.png");
|
|
|
d72a13 |
numbers[ 7] = createAnimation("data/sprite/2048/256.png");
|
|
|
d72a13 |
numbers[ 8] = createAnimation("data/sprite/2048/512.png");
|
|
|
d72a13 |
numbers[ 9] = createAnimation("data/sprite/2048/1024.png");
|
|
|
d72a13 |
numbers[10] = createAnimation("data/sprite/2048/2048.png");
|
|
|
d72a13 |
|
|
|
d72a13 |
add(0, 0);
|
|
|
d72a13 |
add(0, 0);
|
|
|
d72a13 |
}
|
|
|
d72a13 |
|
|
|
d72a13 |
|
|
|
d72a13 |
void draw() {
|
|
|
d72a13 |
saveState();
|
|
|
d72a13 |
zoom(CELLSIZE);
|
|
|
d72a13 |
|
|
|
d72a13 |
saveState();
|
|
|
d72a13 |
noStroke();
|
|
|
d72a13 |
fillTexture(grid, 0, 0, 1, 1, FALSE);
|
|
|
d72a13 |
rect(0, 0, MAPSIZE, MAPSIZE);
|
|
|
d72a13 |
restoreState();
|
|
|
d72a13 |
|
|
|
d72a13 |
if (keyWentDown("left")) fall(0, -1);
|
|
|
d72a13 |
if (keyWentDown("right")) fall(0, 1);
|
|
|
d72a13 |
if (keyWentDown("up")) fall(-1, 0);
|
|
|
d72a13 |
if (keyWentDown("down")) fall( 1, 0);
|
|
|
d72a13 |
|
|
|
ef1455 |
double dp = speed * windowGetFrameTime();
|
|
|
d72a13 |
int score = 0;
|
|
|
d72a13 |
for(int r = 0; r < MAPSIZE; ++r) {
|
|
|
d72a13 |
for(int c = 0; c < MAPSIZE; ++c) {
|
|
|
d72a13 |
Cell *cell = &map[r][c];
|
|
|
d72a13 |
if (cell->group) {
|
|
|
d72a13 |
score += (1 << (cell->value + 1));
|
|
|
d72a13 |
int count = groupGetCount(cell->group);
|
|
|
d72a13 |
int ready = count > 1;
|
|
|
d72a13 |
double prevX = 0, prevY = 0;
|
|
|
d72a13 |
|
|
|
d72a13 |
double cx = c + 0.5;
|
|
|
d72a13 |
double cy = r + 0.5;
|
|
|
d72a13 |
for(int i = 0; i < count; ++i) {
|
|
|
d72a13 |
Sprite sprite = groupGet(cell->group, i);
|
|
|
d72a13 |
double x = spriteGetX(sprite);
|
|
|
d72a13 |
double y = spriteGetY(sprite);
|
|
|
d72a13 |
x = fabs(x - cx) <= dp ? cx : (x < cx ? x + dp : x - dp);
|
|
|
d72a13 |
y = fabs(y - cy) <= dp ? cy : (y < cy ? y + dp : y - dp);
|
|
|
d72a13 |
spriteSetXY(sprite, x, y);
|
|
|
d72a13 |
|
|
|
d72a13 |
if (i > 0 && (fabs(prevX - x) > 0.01 || fabs(prevY - y) > 0.01))
|
|
|
d72a13 |
ready = 0;
|
|
|
d72a13 |
prevX = x;
|
|
|
d72a13 |
prevY = y;
|
|
|
d72a13 |
}
|
|
|
d72a13 |
|
|
|
d72a13 |
if (ready)
|
|
|
d72a13 |
setSprite(cell, prevX, prevY);
|
|
|
d72a13 |
}
|
|
|
d72a13 |
}
|
|
|
d72a13 |
}
|
|
|
d72a13 |
|
|
|
d72a13 |
char buf[20];
|
|
|
d72a13 |
sprintf(buf, "%d", score);
|
|
|
ef1455 |
windowSetTitle(buf);
|
|
|
d72a13 |
|
|
|
d72a13 |
drawSprites();
|
|
|
d72a13 |
restoreState();
|
|
|
d72a13 |
}
|
|
|
d72a13 |
|
|
|
d72a13 |
|
|
|
d72a13 |
int main() {
|
|
|
b8d942 |
windowSetTitle("2048");
|
|
|
ef1455 |
windowSetSize(MAPSIZE*CELLSIZE, MAPSIZE*CELLSIZE);
|
|
|
ef1455 |
windowSetVariableFrameRate();
|
|
|
b8d942 |
windowSetInit(&init);
|
|
|
b8d942 |
windowSetDraw(&draw);
|
|
|
ef1455 |
windowRun();
|
|
|
d72a13 |
return 0;
|
|
|
d72a13 |
}
|
|
|
d72a13 |
|