Added ai modes. Altered output of highscores to allow possible parsing with tools easier

master
Tiehuis 9 years ago
parent 2d9f89f339
commit cf1a147078
  1. 2
      README.md
  2. 6
      man/2048.1
  3. 11
      src/highscore.c
  4. 2
      src/highscore.h
  5. 26
      src/main.c
  6. 30
      src/options.c
  7. 13
      src/options.h

@ -32,6 +32,8 @@ enabled.
-c Enable color support if supported.
-a Enable animations (default).
-A Disable animations.
-i Enable ai without displaying game.
-I Enable ai and display game.
-r Reset highscore. Will prompt user.
-s SIZE Set the size of the playing field.
-b RATE Set the rate at which blocks spawn per turn.

@ -40,6 +40,12 @@ Enable animations (default).
.BR \-A
Disable animations.
.TP
.BR \-i
Enable ai without displaying game.
.TP
.BR \-I
Enable ai and display game.
.TP
.BR \-r
Reset highscore. Will prompt user.
.TP

@ -78,23 +78,28 @@ reset_scores:;
fclose(fd);
}
void highscore_load(struct gamestate *g)
long highscore_load(struct gamestate *g)
{
const char *hsfile = highscore_retrieve_file();
long result = 0;
FILE *fd = fopen(hsfile, "r");
if (fd == NULL)
fd = fopen(hsfile, "w+");
fscanf(fd, "%ld", &g->score_high);
fscanf(fd, "%ld", &result);
fclose(fd);
if (g) g->score_high = result;
return result;
}
void highscore_save(struct gamestate *g)
{
/* Someone could make their own merge rules for highscores and this could be meaningless,
* howeverhighscores are in plaintext, so that isn't that much of a concern */
if (g->score < g->score_high || g->opts->grid_width != 4 || g->opts->grid_height != 4)
if (g->score < g->score_high || g->opts->grid_width != 4 ||
g->opts->grid_height != 4 || g->opts->ai == true)
return;
const char *hsfile = highscore_retrieve_file();

@ -2,7 +2,7 @@
#define HIGHSCORE_H
void highscore_reset(void);
void highscore_load(struct gamestate *g);
long highscore_load(struct gamestate *g);
void highscore_save(struct gamestate *g);
#endif

@ -1,5 +1,6 @@
#include <stdio.h>
#include <stdbool.h>
#include "ai.h"
#include "engine.h"
#include "gfx.h"
@ -12,15 +13,21 @@ void draw_then_sleep(struct gfx_state *s, struct gamestate *g)
int main(int argc, char **argv)
{
struct gamestate *g = gamestate_init(argc, argv);
struct gfx_state *s = gfx_init(g);
struct gfx_state *s;
if (g->opts->interactive)
s = gfx_init(g);
int game_running = true;
while (game_running) {
gfx_draw(s, g);
if (g->opts->interactive)
gfx_draw(s, g);
get_new_key:;
int direction = dir_invalid;
switch (gfx_getch(s)) {
int value = !g->opts->ai ? gfx_getch(s) : ai_move(g);
switch (value) {
case 'h':
case 'a':
direction = dir_left;
@ -46,7 +53,8 @@ get_new_key:;
/* Game will only end if 0 moves available */
if (game_running) {
gamestate_tick(s, g, direction, g->opts->animate ? draw_then_sleep : NULL);
gamestate_tick(s, g, direction, g->opts->animate && g->opts->interactive
? draw_then_sleep : NULL);
int spawned;
for (spawned = 0; spawned < g->opts->spawn_rate; spawned++)
@ -58,9 +66,13 @@ get_new_key:;
}
}
gfx_destroy(s);
printf("Highscore: %ld\n", g->score_high);
printf(" Score: %ld\n", g->score);
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);
gamestate_clear(g);
return 0;
}

@ -1,11 +1,12 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "highscore.h"
#include "options.h"
void print_usage(void)
{
printf("usage: 2048 [-cCaArh] [-s SIZE] [-b RATE]\n");
printf("usage: 2048 [-cCaAiIrh] [-s SIZE] [-b RATE]\n");
}
@ -19,8 +20,10 @@ struct gameoptions* gameoptions_default(void)
opt->grid_width = DEFAULT_GRID_WIDTH;
opt->spawn_value = DEFAULT_SPAWN_VALUE;
opt->spawn_rate = DEFAULT_SPAWN_RATE;
opt->enable_color = DEFAULT_COLOR_TOGGLE;
opt->animate = DEFAULT_ANIMATE_TOGGLE;
opt->enable_color = DEFAULT_COLOR_FLAG;
opt->animate = DEFAULT_ANIMATE_FLAG;
opt->ai = DEFAULT_AI_FLAG;
opt->interactive = DEFAULT_INTERACTIVE_FLAG;
return opt;
}
@ -33,19 +36,27 @@ void gameoptions_destroy(struct gameoptions *opt)
struct gameoptions* parse_options(struct gameoptions *opt, int argc, char **argv)
{
int c;
while ((c = getopt(argc, argv, "aArcCh:s:b:")) != -1) {
while ((c = getopt(argc, argv, "aArcCiIhHs:b:")) != -1) {
switch (c) {
case 'a':
opt->animate = 1;
opt->animate = true;
break;
case 'A':
opt->animate = 0;
opt->animate = false;
break;
case 'c':
opt->enable_color = 1;
opt->enable_color = true;
break;
case 'C':
opt->enable_color = 0;
opt->enable_color = false;
break;
case 'i':
opt->ai = true;
opt->interactive = false;
break;
case 'I':
opt->ai = true;
opt->interactive = true;
break;
case 's':;
/* Stick with square for now */
@ -64,6 +75,9 @@ struct gameoptions* parse_options(struct gameoptions *opt, int argc, char **argv
case 'h':
print_usage();
exit(0);
case 'H':
printf("%ld\n", highscore_load(NULL));
exit(0);
}
}

@ -1,6 +1,7 @@
#ifndef OPTIONS_H
#define OPTIONS_H
#include <stdbool.h>
#include <getopt.h>
#define CONSTRAINT_GRID_MIN 4
@ -9,16 +10,20 @@
#define DEFAULT_GRID_WIDTH 4
#define DEFAULT_SPAWN_VALUE 2
#define DEFAULT_SPAWN_RATE 1
#define DEFAULT_COLOR_TOGGLE 0
#define DEFAULT_ANIMATE_TOGGLE 1
#define DEFAULT_COLOR_FLAG false
#define DEFAULT_ANIMATE_FLAG true
#define DEFAULT_AI_FLAG false
#define DEFAULT_INTERACTIVE_FLAG true
struct gameoptions {
int grid_height;
int grid_width;
long spawn_value;
int spawn_rate;
int enable_color;
int animate;
bool enable_color;
bool animate;
bool ai;
bool interactive;
};
void print_usage(void);

Loading…
Cancel
Save