fixes and beggining of game logic
This commit is contained in:
parent
8a455adad7
commit
18b9d4064c
|
@ -9,7 +9,7 @@
|
|||
"request": "launch",
|
||||
"name": "Debug",
|
||||
"program": "${workspaceFolder}/builddir/src/2048",
|
||||
"args": ["--y", "5", "--x", "4"],
|
||||
"args": ["--x", "4", "--y", "5"],
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
]
|
||||
|
|
74
src/2048.c
74
src/2048.c
|
@ -8,7 +8,7 @@ void game_add_block(Game *game) {
|
|||
bool is_full = true;
|
||||
for (int i = 0; i < game->field_size_x; i++) {
|
||||
for (int j = 0; j < game->field_size_y; j++) {
|
||||
if (game->field[j][i] == 0) {
|
||||
if (game->field[i][j] == 0) {
|
||||
is_full = false;
|
||||
break;
|
||||
}
|
||||
|
@ -25,8 +25,8 @@ void game_add_block(Game *game) {
|
|||
x = rand() % game->field_size_x;
|
||||
y = rand() % game->field_size_y;
|
||||
value = (rand() % 2) + 1;
|
||||
} while (game->field[y][x] != 0);
|
||||
game->field[y][x] = value * 2;
|
||||
} while (game->field[x][y] != 0);
|
||||
game->field[x][y] = value * 2;
|
||||
}
|
||||
|
||||
Game game_init(size_t field_size_x, size_t field_size_y) {
|
||||
|
@ -36,7 +36,7 @@ Game game_init(size_t field_size_x, size_t field_size_y) {
|
|||
game.field_size_x = field_size_x;
|
||||
game.field_size_y = field_size_y;
|
||||
game.score = 0;
|
||||
game.field = malloc(sizeof(uint16_t *) * field_size_y);
|
||||
game.field = malloc(sizeof(uint16_t *) * field_size_x);
|
||||
for (size_t i = 0; i < field_size_x; i++) {
|
||||
game.field[i] = calloc(field_size_y, sizeof(uint16_t) * field_size_y);
|
||||
}
|
||||
|
@ -60,76 +60,32 @@ void game_move(Game *game, Direction direction) {
|
|||
if (game->game_over || game->won) {
|
||||
return;
|
||||
}
|
||||
// the fuck?
|
||||
// I have few chained for loops that do a lot of similar stuff so I call them in a for loop for better clarity and readability
|
||||
for (int u = 0; u < 3; u++) {
|
||||
for (int i = 0; i < game->field_size_x; i++) {
|
||||
uint16_t **field = game->field;
|
||||
// move everything on one side
|
||||
for (int j = 0; j < game->field_size_y - 1; j++) {
|
||||
// a, b is the same as i and j. It is just flipped when
|
||||
// it does not go horizontally so I can access stuff vertically
|
||||
int a = i;
|
||||
int b = j;
|
||||
if (direction == Up || direction == Down) {
|
||||
a = j;
|
||||
b = i;
|
||||
}
|
||||
|
||||
// make it so it can work with different directions
|
||||
int directionality = b;
|
||||
if (direction == Down) {
|
||||
directionality = a;
|
||||
}
|
||||
int movement = 1;
|
||||
if (direction == Left || direction == Up) {
|
||||
if (direction == Left) {
|
||||
directionality = game->field_size_x - b - 1;
|
||||
}
|
||||
else {
|
||||
directionality = game->field_size_y - a - 1;
|
||||
}
|
||||
movement = -1;
|
||||
}
|
||||
// the similar stuff
|
||||
switch (u) {
|
||||
case 0:
|
||||
case 2:
|
||||
if (direction == Left || direction == Right) {
|
||||
if (field[a][directionality + movement] == 0) {
|
||||
field[a][directionality + movement] = field[a][directionality];
|
||||
field[a][directionality] = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (field[directionality + movement][b] == 0) {
|
||||
field[directionality + movement][b] = field[directionality][b];
|
||||
field[directionality][b] = 0;
|
||||
}
|
||||
if (field[i][j + 1] == 0) {
|
||||
field[i][j + 1] = field[i][j];
|
||||
field[i][j] = 0;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
// TODO: fix 444 <- 48, should be 84
|
||||
if (direction == Left || direction == Right) {
|
||||
if (field[a][directionality + movement] == field[a][directionality]) {
|
||||
field[a][directionality + movement] = field[a][directionality] * 2;
|
||||
game->score += field[a][directionality + movement];
|
||||
if (field[a][directionality + movement] == 2048) {
|
||||
game->won = true;
|
||||
}
|
||||
field[a][directionality] = 0;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (field[directionality + movement][b] == field[directionality][b]) {
|
||||
field[directionality + movement][b] = field[directionality][b] * 2;
|
||||
game->score += field[directionality + movement][b];
|
||||
if (field[directionality + movement][b] == 2048) {
|
||||
game->won = true;
|
||||
}
|
||||
field[directionality][b] = 0;
|
||||
j++;
|
||||
if (field[i][j + 1] == field[i][j]) {
|
||||
field[i][j + 1] = field[i][j] * 2;
|
||||
game->score += field[i][j + 1];
|
||||
if (field[i][j + 1] == 2048) {
|
||||
game->won = true;
|
||||
}
|
||||
field[i][j] = 0;
|
||||
j++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
#ifndef HEADER_2048
|
||||
#define HEADER_2048
|
||||
|
||||
#define max(a,b) \
|
||||
({ __typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
_a > _b ? _a : _b; })
|
||||
|
||||
typedef enum Direction {
|
||||
NoDirection,
|
||||
Up,
|
||||
|
|
11
src/gui.c
11
src/gui.c
|
@ -144,6 +144,11 @@ void gui_loop(Game *game) {
|
|||
if (needs_redraw) {
|
||||
SDL_RenderClear(window_renderer);
|
||||
SDL_Rect tile_rect = tile_size;
|
||||
if (game->field_size_x > 5 || game->field_size_y > 5) {
|
||||
int size = 700 / max(game->field_size_y, game->field_size_x);
|
||||
tile_rect.w = size;
|
||||
tile_rect.h = size;
|
||||
}
|
||||
for (int i = 0; i < game->field_size_x; i++) {
|
||||
tile_rect.x = i * (700 / game->field_size_x) + 50;
|
||||
for (int j = 0; j < game->field_size_y; j++) {
|
||||
|
@ -151,7 +156,7 @@ void gui_loop(Game *game) {
|
|||
|
||||
// get texture index from value
|
||||
for (int k = 0; k < 13; k++) {
|
||||
if (!(game->field[j][i] >> k)) {
|
||||
if (!(game->field[i][j] >> k)) {
|
||||
SDL_RenderCopy(window_renderer, tile_textures[k], NULL, &tile_rect);
|
||||
break;
|
||||
}
|
||||
|
@ -160,9 +165,9 @@ void gui_loop(Game *game) {
|
|||
}
|
||||
|
||||
// score - I am too lazy to optimize this further
|
||||
char label_text[24] = "Score: 0x";
|
||||
char label_text[24] = "Score: ";
|
||||
char value[16];
|
||||
SDL_itoa(game->score, value, 16);
|
||||
SDL_itoa(game->score, value, 10);
|
||||
strncat(label_text, value, strlen(value));
|
||||
SDL_Surface *score_label = TTF_RenderText_Blended(Sans, label_text, Black);
|
||||
SDL_Texture *score_label_texture = SDL_CreateTextureFromSurface(window_renderer, score_label);
|
||||
|
|
16
src/main.c
16
src/main.c
|
@ -6,30 +6,36 @@ int main(int argc, char *argv[]) {
|
|||
bool tui = false;
|
||||
int size_x = 4;
|
||||
int size_y = 4;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (!strcmp(argv[i], "--help")) {
|
||||
printf("You can pass following arguments: \n--help, \n\--tui\ (not all ui elements are implemented, only for demonstration), \n--x (width, default 4), \n--y (height, default 4)\n");
|
||||
printf("You can pass following arguments: \n--help, \n--tui (not all ui elements are implemented, only for demonstration), \n--x (width, default 4), \n--y (height, default 4)\n");
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(argv[i], "--tui")) {
|
||||
else if (!strcmp(argv[i], "--tui")) {
|
||||
tui = true;
|
||||
}
|
||||
if (!strcmp(argv[i], "--x")) {
|
||||
else if (!strcmp(argv[i], "--x")) {
|
||||
if (argc >= i) {
|
||||
if(sscanf(argv[i+1], "%d", &size_x) != 1){
|
||||
printf("invalid input\n");
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (!strcmp(argv[i], "--y")) {
|
||||
else if (!strcmp(argv[i], "--y")) {
|
||||
if (argc >= i) {
|
||||
if(sscanf(argv[i+1], "%d", &size_y) != 1){
|
||||
printf("invalid input\n");
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("invalid input \"%s\"\n", argv[i]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Game game;
|
||||
game = game_init(size_x, size_y);
|
||||
|
|
Loading…
Reference in New Issue