2015-02-21 02:36:15 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdbool.h>
|
2015-02-25 01:51:48 +00:00
|
|
|
#include "ai.h"
|
2015-02-21 02:36:15 +00:00
|
|
|
#include "engine.h"
|
|
|
|
#include "gfx.h"
|
2018-05-29 22:56:28 +00:00
|
|
|
#include <libintl.h>
|
|
|
|
#include <locale.h>
|
2015-02-21 02:36:15 +00:00
|
|
|
|
|
|
|
void draw_then_sleep(struct gfx_state *s, struct gamestate *g)
|
|
|
|
{
|
|
|
|
gfx_draw(s, g);
|
2015-02-25 02:14:15 +00:00
|
|
|
/* Have a fixed time for each turn to animate (160 default) */
|
|
|
|
gfx_sleep(160 / g->opts->grid_width);
|
2015-02-21 02:36:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
2018-05-29 22:56:28 +00:00
|
|
|
setlocale (LC_ALL, "");
|
|
|
|
bindtextdomain ("gfx_terminal", "/usr/share/locale/");
|
|
|
|
textdomain ("gfx_terminal");
|
|
|
|
|
2015-02-25 10:54:13 +00:00
|
|
|
struct gamestate *g = gamestate_init(argc, argv);
|
2017-08-11 23:09:07 +00:00
|
|
|
if (!g) {
|
|
|
|
fatal("failed to allocate gamestate");
|
|
|
|
}
|
|
|
|
|
2015-12-29 22:49:04 +00:00
|
|
|
struct gfx_state *s = NULL;
|
2015-02-25 01:51:48 +00:00
|
|
|
|
2017-08-11 23:09:07 +00:00
|
|
|
if (g->opts->interactive) {
|
2015-02-25 01:51:48 +00:00
|
|
|
s = gfx_init(g);
|
2017-08-11 23:09:07 +00:00
|
|
|
if (!s) {
|
|
|
|
fatal("failed to allocate gfx state");
|
|
|
|
}
|
|
|
|
}
|
2015-02-21 02:36:15 +00:00
|
|
|
|
|
|
|
int game_running = true;
|
|
|
|
while (game_running) {
|
2015-02-25 01:51:48 +00:00
|
|
|
|
|
|
|
if (g->opts->interactive)
|
|
|
|
gfx_draw(s, g);
|
2015-02-21 02:36:15 +00:00
|
|
|
|
|
|
|
get_new_key:;
|
|
|
|
int direction = dir_invalid;
|
2015-02-25 01:51:48 +00:00
|
|
|
int value = !g->opts->ai ? gfx_getch(s) : ai_move(g);
|
|
|
|
switch (value) {
|
2015-02-21 02:36:15 +00:00
|
|
|
case 'h':
|
|
|
|
case 'a':
|
|
|
|
direction = dir_left;
|
|
|
|
break;
|
|
|
|
case 'l':
|
|
|
|
case 'd':
|
|
|
|
direction = dir_right;
|
|
|
|
break;
|
|
|
|
case 'j':
|
|
|
|
case 's':
|
|
|
|
direction = dir_down;
|
|
|
|
break;
|
|
|
|
case 'k':
|
|
|
|
case 'w':
|
|
|
|
direction = dir_up;
|
|
|
|
break;
|
|
|
|
case 'q':
|
|
|
|
game_running = false;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
goto get_new_key;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Game will only end if 0 moves available */
|
|
|
|
if (game_running) {
|
2015-02-25 01:51:48 +00:00
|
|
|
gamestate_tick(s, g, direction, g->opts->animate && g->opts->interactive
|
|
|
|
? draw_then_sleep : NULL);
|
2015-02-22 21:12:01 +00:00
|
|
|
|
2015-12-29 22:35:35 +00:00
|
|
|
if (g->moved == 0)
|
|
|
|
goto get_new_key;
|
|
|
|
|
2015-02-22 21:12:01 +00:00
|
|
|
int spawned;
|
|
|
|
for (spawned = 0; spawned < g->opts->spawn_rate; spawned++)
|
2015-02-21 02:36:15 +00:00
|
|
|
gamestate_new_block(g);
|
|
|
|
|
|
|
|
if (gamestate_end_condition(g)) {
|
|
|
|
game_running = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-25 01:51:48 +00:00
|
|
|
if (g->opts->interactive) {
|
|
|
|
// gfx_getch(s); // getch here would be good,
|
|
|
|
// need an exit message for each graphical output
|
|
|
|
gfx_destroy(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("%ld\n", g->score);
|
2015-02-21 02:36:15 +00:00
|
|
|
gamestate_clear(g);
|
|
|
|
return 0;
|
|
|
|
}
|