Compare commits
10 Commits
7958cea858
...
2024d53e48
Author | SHA1 | Date | |
---|---|---|---|
2024d53e48 | |||
17cfae9c54 | |||
|
9c7212cae0 | ||
|
e989b69340 | ||
|
ef83b74a3c | ||
|
525a00e6e2 | ||
|
22ec7de16c | ||
|
7f459aa5b8 | ||
|
ea1b78b9b2 | ||
|
14cd5e61bb |
2
Makefile
2
Makefile
@ -2,7 +2,7 @@ VERSION = 1.3.1
|
|||||||
|
|
||||||
CC ?= gcc
|
CC ?= gcc
|
||||||
CFLAGS ?= -g
|
CFLAGS ?= -g
|
||||||
CFLAGS += -W -Wall -pedantic -ansi -std=c99 -DVERSION=\"$(VERSION)\" -fcommon
|
CFLAGS += -W -Wall -pedantic -ansi -std=c99 -DVERSION=\"$(VERSION)\"
|
||||||
|
|
||||||
# The Ncurses library with wide character support is available as "lncurses"
|
# The Ncurses library with wide character support is available as "lncurses"
|
||||||
# under macOS.
|
# under macOS.
|
||||||
|
14
src/cursor.c
14
src/cursor.c
@ -50,25 +50,25 @@ void cursor_move(struct cursor *cursor, enum movement movement) {
|
|||||||
if (cursor->y == CURSOR_BEGIN_Y) {
|
if (cursor->y == CURSOR_BEGIN_Y) {
|
||||||
switch (cursor->x - 3) {
|
switch (cursor->x - 3) {
|
||||||
case MANEUVRE_0_BEGIN_X:
|
case MANEUVRE_0_BEGIN_X:
|
||||||
cursor->y = cursor->y + 7 + stack_length(deck->maneuvre[0]);
|
cursor->y = 6 + deck->maneuvre[0]->card->frame->begin_y;
|
||||||
break;
|
break;
|
||||||
case MANEUVRE_1_BEGIN_X:
|
case MANEUVRE_1_BEGIN_X:
|
||||||
cursor->y = cursor->y + 7 + stack_length(deck->maneuvre[1]);
|
cursor->y = 6 + deck->maneuvre[1]->card->frame->begin_y;
|
||||||
break;
|
break;
|
||||||
case MANEUVRE_2_BEGIN_X:
|
case MANEUVRE_2_BEGIN_X:
|
||||||
cursor->y = cursor->y + 7 + stack_length(deck->maneuvre[2]);
|
cursor->y = 6 + deck->maneuvre[2]->card->frame->begin_y;
|
||||||
break;
|
break;
|
||||||
case MANEUVRE_3_BEGIN_X:
|
case MANEUVRE_3_BEGIN_X:
|
||||||
cursor->y = cursor->y + 7 + stack_length(deck->maneuvre[3]);
|
cursor->y = 6 + deck->maneuvre[3]->card->frame->begin_y;
|
||||||
break;
|
break;
|
||||||
case MANEUVRE_4_BEGIN_X:
|
case MANEUVRE_4_BEGIN_X:
|
||||||
cursor->y = cursor->y + 7 + stack_length(deck->maneuvre[4]);
|
cursor->y = 6 + deck->maneuvre[4]->card->frame->begin_y;
|
||||||
break;
|
break;
|
||||||
case MANEUVRE_5_BEGIN_X:
|
case MANEUVRE_5_BEGIN_X:
|
||||||
cursor->y = cursor->y + 7 + stack_length(deck->maneuvre[5]);
|
cursor->y = 6 + deck->maneuvre[5]->card->frame->begin_y;
|
||||||
break;
|
break;
|
||||||
case MANEUVRE_6_BEGIN_X:
|
case MANEUVRE_6_BEGIN_X:
|
||||||
cursor->y = cursor->y + 7 + stack_length(deck->maneuvre[6]);
|
cursor->y = 6 + deck->maneuvre[6]->card->frame->begin_y;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
23
src/game.c
23
src/game.c
@ -141,7 +141,16 @@ void move_block(struct stack **origin, struct stack **destination,
|
|||||||
if (stack_length(*destination) > 1) {
|
if (stack_length(*destination) > 1) {
|
||||||
cursor->y += block_size;
|
cursor->y += block_size;
|
||||||
}
|
}
|
||||||
stack_free(tmp);
|
}
|
||||||
|
|
||||||
|
void expose_top(struct stack **origin)
|
||||||
|
{
|
||||||
|
struct card *top;
|
||||||
|
if((top = stack_pop(origin)))
|
||||||
|
{
|
||||||
|
card_expose(top);
|
||||||
|
stack_push(origin, top);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fill_deck(struct deck *deck) {
|
static void fill_deck(struct deck *deck) {
|
||||||
@ -191,7 +200,7 @@ static void deal_cards(struct deck *deck) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void game_init(struct game *game, int passes_through_deck,
|
void game_init(struct game *game, int passes_through_deck,
|
||||||
int four_color_deck) {
|
int four_color_deck, int auto_win_disable) {
|
||||||
cursor_malloc(&cursor);
|
cursor_malloc(&cursor);
|
||||||
cursor_init(cursor);
|
cursor_init(cursor);
|
||||||
deck_malloc(&deck);
|
deck_malloc(&deck);
|
||||||
@ -211,6 +220,7 @@ void game_init(struct game *game, int passes_through_deck,
|
|||||||
}
|
}
|
||||||
|
|
||||||
game->four_color_deck = four_color_deck;
|
game->four_color_deck = four_color_deck;
|
||||||
|
game->auto_win_disable = auto_win_disable;
|
||||||
|
|
||||||
fill_deck(deck);
|
fill_deck(deck);
|
||||||
shuffle_deck(deck);
|
shuffle_deck(deck);
|
||||||
@ -227,7 +237,13 @@ void game_end() {
|
|||||||
deck_free(deck);
|
deck_free(deck);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool game_won() {
|
bool game_won(int auto_win_disable) {
|
||||||
|
if (auto_win_disable) {
|
||||||
|
return(stack_length(deck->foundation[0]) == 13 &&
|
||||||
|
stack_length(deck->foundation[1]) == 13 &&
|
||||||
|
stack_length(deck->foundation[2]) == 13 &&
|
||||||
|
stack_length(deck->foundation[3]) == 13);
|
||||||
|
} else {
|
||||||
// If any card in the maneuvre stacks is covered, game is not won.
|
// If any card in the maneuvre stacks is covered, game is not won.
|
||||||
for (int i = 0; i < MANEUVRE_STACKS_NUMBER; i++) {
|
for (int i = 0; i < MANEUVRE_STACKS_NUMBER; i++) {
|
||||||
for (struct stack *j = deck->maneuvre[i]; j != NULL; j = j->next) {
|
for (struct stack *j = deck->maneuvre[i]; j != NULL; j = j->next) {
|
||||||
@ -243,4 +259,5 @@ bool game_won() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (true);
|
return (true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
struct game {
|
struct game {
|
||||||
int passes_through_deck_left;
|
int passes_through_deck_left;
|
||||||
int four_color_deck;
|
int four_color_deck;
|
||||||
|
int auto_win_disable;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct deck *deck;
|
extern struct deck *deck;
|
||||||
@ -43,7 +44,8 @@ bool stock_stack(struct stack *);
|
|||||||
bool valid_move(struct stack *, struct stack *);
|
bool valid_move(struct stack *, struct stack *);
|
||||||
void move_card(struct stack **, struct stack **);
|
void move_card(struct stack **, struct stack **);
|
||||||
void move_block(struct stack **, struct stack **, int);
|
void move_block(struct stack **, struct stack **, int);
|
||||||
void game_init(struct game *, int, int);
|
void expose_top(struct stack **);
|
||||||
|
void game_init(struct game *, int, int, int);
|
||||||
bool game_won();
|
bool game_won();
|
||||||
void game_end();
|
void game_end();
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@ static void handle_card_movement(struct cursor *cursor) {
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
if ((key = getch()) == 'q' || key == 'Q') {
|
if ((key = getch()) == 'q' || key == 'Q') {
|
||||||
endwin();
|
endwin();
|
||||||
|
game_end();
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
if (term_size_ok()) {
|
if (term_size_ok()) {
|
||||||
@ -157,6 +158,7 @@ static void handle_card_movement(struct cursor *cursor) {
|
|||||||
;
|
;
|
||||||
if (valid_move(block, *destination)) {
|
if (valid_move(block, *destination)) {
|
||||||
move_block(origin, destination, _marked_cards_count);
|
move_block(origin, destination, _marked_cards_count);
|
||||||
|
expose_top(origin);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (valid_move(*origin, *destination)) {
|
if (valid_move(*origin, *destination)) {
|
||||||
@ -164,6 +166,7 @@ static void handle_card_movement(struct cursor *cursor) {
|
|||||||
cursor->y++;
|
cursor->y++;
|
||||||
}
|
}
|
||||||
move_card(origin, destination);
|
move_card(origin, destination);
|
||||||
|
expose_top(origin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
draw_stack(*origin);
|
draw_stack(*origin);
|
||||||
|
@ -26,12 +26,14 @@ int main(int argc, char *argv[]) {
|
|||||||
int passes_through_deck = 3;
|
int passes_through_deck = 3;
|
||||||
static int four_color_deck;
|
static int four_color_deck;
|
||||||
static int no_background_color;
|
static int no_background_color;
|
||||||
|
static int auto_win_disable;
|
||||||
static const struct option options[] = {
|
static const struct option options[] = {
|
||||||
{"help", no_argument, NULL, 'h'},
|
{"help", no_argument, NULL, 'h'},
|
||||||
{"version", no_argument, NULL, 'v'},
|
{"version", no_argument, NULL, 'v'},
|
||||||
{"passes", required_argument, NULL, 'p'},
|
{"passes", required_argument, NULL, 'p'},
|
||||||
{"four-color-deck", no_argument, &four_color_deck, 1},
|
{"four-color-deck", no_argument, &four_color_deck, 1},
|
||||||
{"no-background-color", no_argument, &no_background_color, 1},
|
{"no-background-color", no_argument, &no_background_color, 1},
|
||||||
|
{"auto-win-disable", no_argument, &auto_win_disable, 1},
|
||||||
{0, 0, 0, 0}};
|
{0, 0, 0, 0}};
|
||||||
|
|
||||||
program_name = basename(argv[0]);
|
program_name = basename(argv[0]);
|
||||||
@ -108,7 +110,7 @@ int main(int argc, char *argv[]) {
|
|||||||
if (key == KEY_SPACEBAR) {
|
if (key == KEY_SPACEBAR) {
|
||||||
clear();
|
clear();
|
||||||
refresh();
|
refresh();
|
||||||
game_init(&game, passes_through_deck, four_color_deck);
|
game_init(&game, passes_through_deck, four_color_deck, auto_win_disable);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (key == KEY_RESIZE) {
|
} else if (key == KEY_RESIZE) {
|
||||||
@ -120,7 +122,7 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
keyboard_event(getch());
|
keyboard_event(getch());
|
||||||
} while (!game_won());
|
} while (!game_won(game.auto_win_disable));
|
||||||
|
|
||||||
endwin();
|
endwin();
|
||||||
game_end();
|
game_end();
|
||||||
@ -132,10 +134,10 @@ int main(int argc, char *argv[]) {
|
|||||||
void draw_greeting() {
|
void draw_greeting() {
|
||||||
mvprintw(8, 26, "Welcome to tty-solitaire.");
|
mvprintw(8, 26, "Welcome to tty-solitaire.");
|
||||||
mvprintw(10, 21, "Move with the arrow keys or <hjkl>.");
|
mvprintw(10, 21, "Move with the arrow keys or <hjkl>.");
|
||||||
mvprintw(11, 18, "Use the space bar to select and place cards.");
|
mvprintw(12, 18, "Use the space bar to select and place cards.");
|
||||||
mvprintw(12, 13, "After selecting a card you can use <m> to select more");
|
mvprintw(14, 13, "After selecting a card you can use <m> to select more");
|
||||||
mvprintw(13, 13, "and <n> to select less. Press <Shift+M> to select all.");
|
mvprintw(15, 12, "and <n> to select fewer. Press <Shift+M> to select all.");
|
||||||
mvprintw(15, 19, "Press the space bar to play or q to quit.");
|
mvprintw(17, 19, "Press the space bar to play or q to quit.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void usage(const char *program_name) {
|
void usage(const char *program_name) {
|
||||||
@ -148,6 +150,8 @@ void usage(const char *program_name) {
|
|||||||
"(default: false)\n");
|
"(default: false)\n");
|
||||||
printf(" --no-background-color Don't draw background color "
|
printf(" --no-background-color Don't draw background color "
|
||||||
"(default: false)\n");
|
"(default: false)\n");
|
||||||
|
printf(" --auto-win-disable Disable auto-winning the game "
|
||||||
|
"(default: false)\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void version() { printf("%s\n", VERSION); }
|
void version() { printf("%s\n", VERSION); }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user