Blame 2048.c

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