From ddb214c5fb9d51d4454fcf66235d3f9353e3b75f Mon Sep 17 00:00:00 2001 From: John Zaitseff Date: Sat, 16 Jul 2011 10:30:58 +1000 Subject: [PATCH] Move the selection and processing of game moves to move.c --- src/Makefile.am | 1 + src/README | 1 + src/game.c | 305 ------------------------------------------ src/game.h | 4 - src/move.c | 346 ++++++++++++++++++++++++++++++++++++++++++++++++ src/move.h | 46 +++++++ src/trader.h | 1 + 7 files changed, 395 insertions(+), 309 deletions(-) create mode 100644 src/move.c create mode 100644 src/move.h diff --git a/src/Makefile.am b/src/Makefile.am index 33b978f..1fa4ee9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -33,6 +33,7 @@ trader_SOURCES = \ trader.c trader.h \ globals.c globals.h \ game.c game.h \ + move.c move.h \ fileio.c fileio.h \ help.c help.h \ intf.c intf.h \ diff --git a/src/README b/src/README index 8b4ad5c..bc63448 100644 --- a/src/README +++ b/src/README @@ -11,6 +11,7 @@ source code is split up among the following files: trader.c trader.h - Main program, command-line interface globals.c globals.h - Global game constants and variables game.c game.h - Game start and end routines + move.c move.h - Routines for making and processing a move fileio.c fileio.h - Load and save game file routines help.c help.h - Help text routines: how to play Star Traders intf.c intf.h - Basic text input/output routines diff --git a/src/game.c b/src/game.c index 715e97c..828f5d9 100644 --- a/src/game.c +++ b/src/game.c @@ -35,7 +35,6 @@ * Internal function declarations * ************************************************************************/ -int cmp_game_move (const void *a, const void *b); int cmp_player (const void *a, const void *b); @@ -488,284 +487,12 @@ void end_game (void) free(buf); } - -/*----------------------------------------------------------------------- - Function: select_moves - Select NUMBER_MOVES random moves - Arguments: (none) - Returns: (nothing) - - This function selects NUMBER_MOVES random moves and stores them in the - game_move[] array. If there are less than NUMBER_MOVES empty spaces in - the galaxy map, the game is automatically finished by setting - quit_selected to true. -*/ - -void select_moves (void) -{ - int count; - int x, y, i, j; - int tx, ty; - bool unique; - - - // How many empty spaces are there in the galaxy map? - count = 0; - for (x = 0; x < MAX_X; x++) { - for (y = 0; y < MAX_Y; y++) { - if (galaxy_map[x][y] == MAP_EMPTY) { - count++; - } - } - } - - if (count < NUMBER_MOVES) { - quit_selected = true; - return; - } - - // Generate unique random moves - for (i = 0; i < NUMBER_MOVES; i++) { - do { - do { - tx = randi(MAX_X); - ty = randi(MAX_Y); - } while (galaxy_map[tx][ty] != MAP_EMPTY); - - unique = true; - for (j = i - 1; j >= 0; j--) { - if (tx == game_move[j].x && ty == game_move[j].y) { - unique = false; - break; - } - } - } while (! unique); - - game_move[i].x = tx; - game_move[i].y = ty; - } - - // Sort moves from left to right - qsort(game_move, NUMBER_MOVES, sizeof(move_rec_t), cmp_game_move); - - quit_selected = false; -} - - -/*----------------------------------------------------------------------- - Function: get_move - Wait for the player to enter their move - Arguments: (none) - Returns: (nothing) - - This function displays the galaxy map and the current moves, then waits - for the player to select one of the moves. On entry, current_player - points to the current player; quit_selected and/or abort_game may be - true (if so, get_move() justs returns without waiting for the player to - select a move). On exit, selection contains the choice made by the - player. Note that two windows (the "Select move" window and the galaxy - map window) are left on the screen: they are closed in process_move(). -*/ - -void get_move (void) -{ - int i, x, y; - - - if (quit_selected || abort_game) { - selection = SEL_QUIT; - return; - } else { - selection = SEL_NONE; - } - - // Display map without closing window - show_map(false); - - // Display current move choices on the galaxy map - for (i = 0; i < NUMBER_MOVES; i++) { - mvwaddch(curwin, game_move[i].y + 3, game_move[i].x * 2 + 2, - MOVE_TO_KEY(i) | ATTR_MAP_CHOICE); - } - wrefresh(curwin); - - // Show menu of choices for the player - newtxwin(5, 80, LINE_OFFSET + 19, COL_CENTER(80)); - while (selection == SEL_NONE) { - wbkgd(curwin, ATTR_NORMAL_WINDOW); - werase(curwin); - box(curwin, 0, 0); - - wmove(curwin, 2, 2); - attrpr(curwin, ATTR_KEYCODE_STR, "<1>"); - waddstr(curwin, " Display stock portfolio"); - - wmove(curwin, 3, 2); - attrpr(curwin, ATTR_KEYCODE_STR, "<2>"); - waddstr(curwin, " Declare bankruptcy"); - - wmove(curwin, 2, 41); - attrpr(curwin, ATTR_KEYCODE_STR, "<3>"); - waddstr(curwin, " Save and end the game"); - - wmove(curwin, 3, 40); - attrpr(curwin, ATTR_KEYCODE_STR, ""); - waddstr(curwin, " Quit the game"); - - mvwaddstr(curwin, 1, 2, " Select move "); - waddstr(curwin, "["); - attrpr(curwin, ATTR_MAP_CHOICE, "%c", MOVE_TO_KEY(0)); - waddstr(curwin, "-"); - attrpr(curwin, ATTR_MAP_CHOICE, "%c", MOVE_TO_KEY(NUMBER_MOVES - 1)); - waddstr(curwin, "/"); - attrpr(curwin, ATTR_KEYCODE_STR, "1"); - waddstr(curwin, "-"); - attrpr(curwin, ATTR_KEYCODE_STR, "3"); - waddstr(curwin, "/"); - attrpr(curwin, ATTR_KEYCODE_STR, ""); - waddstr(curwin, "]: "); - - curs_set(CURS_ON); - wrefresh(curwin); - - // Get the actual selection made by the player - while (selection == SEL_NONE) { - int key = tolower(gettxchar(curwin)); - - if (IS_MOVE_KEY(key)) { - selection = KEY_TO_MOVE(key); - - curs_set(CURS_OFF); - waddstr(curwin, "Move "); - attrpr(curwin, ATTR_MAP_CHOICE, "%c", key); - } else { - switch (key) { - case '1': - curs_set(CURS_OFF); - show_status(current_player); - curs_set(CURS_ON); - break; - - case '2': - selection = SEL_BANKRUPT; - - curs_set(CURS_OFF); - wattron(curwin, A_BOLD); - waddstr(curwin, "<2>"); - wattroff(curwin, A_BOLD); - waddstr(curwin, " (Declare bankruptcy)"); - break; - - case '3': - selection = SEL_SAVE; - - curs_set(CURS_OFF); - wattron(curwin, A_BOLD); - waddstr(curwin, "<3>"); - wattroff(curwin, A_BOLD); - waddstr(curwin, " (Save and end the game)"); - break; - - case KEY_ESC: - case KEY_CANCEL: - case KEY_CTRL('C'): - case KEY_CTRL('G'): - case KEY_CTRL('\\'): - selection = SEL_QUIT; - - curs_set(CURS_OFF); - wattron(curwin, A_BOLD); - waddstr(curwin, ""); - wattroff(curwin, A_BOLD); - waddstr(curwin, " (Quit the game)"); - break; - - default: - beep(); - } - } - } - - // Clear the menu choices - wattrset(curwin, ATTR_NORMAL_WINDOW); - for (y = 2; y < 4; y++) { - wmove(curwin, y, 2); - for (x = 2; x < getmaxx(curwin) - 2; x++) { - waddch(curwin, ' ' | ATTR_NORMAL_WINDOW); - } - } - wrefresh(curwin); - - // Ask the player to confirm their choice - mvwaddstr(curwin, 2, 2, " Are you sure? "); - waddstr(curwin, "["); - attrpr(curwin, ATTR_KEYCODE_STR, "Y"); - waddstr(curwin, "/"); - attrpr(curwin, ATTR_KEYCODE_STR, "N"); - waddstr(curwin, "] "); - - if (! answer_yesno(curwin)) { - selection = SEL_NONE; - } - } -} - -void process_move (void) -{ - // @@@ To be written - if (selection == SEL_QUIT) { - quit_selected = true; - } - - deltxwin(); // "Select move" window - deltxwin(); // Galaxy map window - txrefresh(); -} - void exchange_stock (void) { // @@@ To be written } -/*----------------------------------------------------------------------- - Function: next_player - Get the next player - Arguments: (none) - Returns: (nothing) - - This function sets the global variable current_player to the next - eligible player. If no player is still in the game, quit_selected is - set to true. The variable turn_number is also incremented if required. -*/ - -void next_player (void) -{ - int i; - bool all_out; - - - all_out = true; - for (i = 0; i < number_players; i++) { - if (player[i].in_game) { - all_out = false; - break; - } - } - - if (all_out) { - quit_selected = true; - } else { - do { - current_player++; - if (current_player == number_players) { - current_player = 0; - } - if (current_player == first_player) { - turn_number++; - } - } while (! player[current_player].in_game); - } -} - - /*----------------------------------------------------------------------- Function: show_map - Display the galaxy map on the screen Arguments: closewin - Wait for user, then close window if true @@ -1011,38 +738,6 @@ double total_value (int num) } -/*----------------------------------------------------------------------- - Function: cmp_game_move - Compare two game_move[] elements - Arguments: a, b - Elements to compare - Returns: int - Comparison of a and b - - This function compares two game_move[] elements (of type move_rec_t) - and returns -1 if a < b, 0 if a == b and 1 if a > b. It is used for - sorting game moves into ascending order. -*/ - -int cmp_game_move (const void *a, const void *b) -{ - const move_rec_t *aa = (const move_rec_t *) a; - const move_rec_t *bb = (const move_rec_t *) b; - - - if (aa->x < bb->x) { - return -1; - } else if (aa->x > bb->x) { - return 1; - } else { - if (aa->y < bb->y) { - return -1; - } else if (aa->y > bb->y) { - return 1; - } else { - return 0; - } - } -} - - /*----------------------------------------------------------------------- Function: cmp_player - Compare two player[] elements Arguments: a, b - Elements to compare diff --git a/src/game.h b/src/game.h index fbe5b84..1a6a4b2 100644 --- a/src/game.h +++ b/src/game.h @@ -42,11 +42,7 @@ extern void init_game (void); extern void end_game (void); -extern void select_moves (void); -extern void get_move (void); -extern void process_move (void); extern void exchange_stock (void); -extern void next_player (void); extern void show_map (bool show_moves); extern void show_status (int num); diff --git a/src/move.c b/src/move.c new file mode 100644 index 0000000..37b3bf1 --- /dev/null +++ b/src/move.c @@ -0,0 +1,346 @@ +/************************************************************************ +* * +* Star Traders: A Game of Interstellar Trading * +* Copyright (C) 1990-2011, John Zaitseff * +* * +************************************************************************/ + +/* + Author: John Zaitseff + $Id$ + + This file, move.c, contains the implementation of functions that make + and process a game move in Star Traders. + + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see http://www.gnu.org/licenses/. +*/ + + +#include "trader.h" + + +/************************************************************************ +* Internal function declarations * +************************************************************************/ + +int cmp_game_move (const void *a, const void *b); + + +/************************************************************************ +* Game move function definitions * +************************************************************************/ + +/*----------------------------------------------------------------------- + Function: select_moves - Select NUMBER_MOVES random moves + Arguments: (none) + Returns: (nothing) + + This function selects NUMBER_MOVES random moves and stores them in the + game_move[] array. If there are less than NUMBER_MOVES empty spaces in + the galaxy map, the game is automatically finished by setting + quit_selected to true. +*/ + +void select_moves (void) +{ + int count; + int x, y, i, j; + int tx, ty; + bool unique; + + + // How many empty spaces are there in the galaxy map? + count = 0; + for (x = 0; x < MAX_X; x++) { + for (y = 0; y < MAX_Y; y++) { + if (galaxy_map[x][y] == MAP_EMPTY) { + count++; + } + } + } + + if (count < NUMBER_MOVES) { + quit_selected = true; + return; + } + + // Generate unique random moves + for (i = 0; i < NUMBER_MOVES; i++) { + do { + do { + tx = randi(MAX_X); + ty = randi(MAX_Y); + } while (galaxy_map[tx][ty] != MAP_EMPTY); + + unique = true; + for (j = i - 1; j >= 0; j--) { + if (tx == game_move[j].x && ty == game_move[j].y) { + unique = false; + break; + } + } + } while (! unique); + + game_move[i].x = tx; + game_move[i].y = ty; + } + + // Sort moves from left to right + qsort(game_move, NUMBER_MOVES, sizeof(move_rec_t), cmp_game_move); + + quit_selected = false; +} + + +/*----------------------------------------------------------------------- + Function: get_move - Wait for the player to enter their move + Arguments: (none) + Returns: (nothing) + + This function displays the galaxy map and the current moves, then waits + for the player to select one of the moves. On entry, current_player + points to the current player; quit_selected and/or abort_game may be + true (if so, get_move() justs returns without waiting for the player to + select a move). On exit, selection contains the choice made by the + player. Note that two windows (the "Select move" window and the galaxy + map window) are left on the screen: they are closed in process_move(). +*/ + +void get_move (void) +{ + int i, x, y; + + + if (quit_selected || abort_game) { + selection = SEL_QUIT; + return; + } else { + selection = SEL_NONE; + } + + // Display map without closing window + show_map(false); + + // Display current move choices on the galaxy map + for (i = 0; i < NUMBER_MOVES; i++) { + mvwaddch(curwin, game_move[i].y + 3, game_move[i].x * 2 + 2, + MOVE_TO_KEY(i) | ATTR_MAP_CHOICE); + } + wrefresh(curwin); + + // Show menu of choices for the player + newtxwin(5, 80, LINE_OFFSET + 19, COL_CENTER(80)); + while (selection == SEL_NONE) { + wbkgd(curwin, ATTR_NORMAL_WINDOW); + werase(curwin); + box(curwin, 0, 0); + + wmove(curwin, 2, 2); + attrpr(curwin, ATTR_KEYCODE_STR, "<1>"); + waddstr(curwin, " Display stock portfolio"); + + wmove(curwin, 3, 2); + attrpr(curwin, ATTR_KEYCODE_STR, "<2>"); + waddstr(curwin, " Declare bankruptcy"); + + wmove(curwin, 2, 41); + attrpr(curwin, ATTR_KEYCODE_STR, "<3>"); + waddstr(curwin, " Save and end the game"); + + wmove(curwin, 3, 40); + attrpr(curwin, ATTR_KEYCODE_STR, ""); + waddstr(curwin, " Quit the game"); + + mvwaddstr(curwin, 1, 2, " Select move "); + waddstr(curwin, "["); + attrpr(curwin, ATTR_MAP_CHOICE, "%c", MOVE_TO_KEY(0)); + waddstr(curwin, "-"); + attrpr(curwin, ATTR_MAP_CHOICE, "%c", MOVE_TO_KEY(NUMBER_MOVES - 1)); + waddstr(curwin, "/"); + attrpr(curwin, ATTR_KEYCODE_STR, "1"); + waddstr(curwin, "-"); + attrpr(curwin, ATTR_KEYCODE_STR, "3"); + waddstr(curwin, "/"); + attrpr(curwin, ATTR_KEYCODE_STR, ""); + waddstr(curwin, "]: "); + + curs_set(CURS_ON); + wrefresh(curwin); + + // Get the actual selection made by the player + while (selection == SEL_NONE) { + int key = tolower(gettxchar(curwin)); + + if (IS_MOVE_KEY(key)) { + selection = KEY_TO_MOVE(key); + + curs_set(CURS_OFF); + waddstr(curwin, "Move "); + attrpr(curwin, ATTR_MAP_CHOICE, "%c", key); + } else { + switch (key) { + case '1': + curs_set(CURS_OFF); + show_status(current_player); + curs_set(CURS_ON); + break; + + case '2': + selection = SEL_BANKRUPT; + + curs_set(CURS_OFF); + wattron(curwin, A_BOLD); + waddstr(curwin, "<2>"); + wattroff(curwin, A_BOLD); + waddstr(curwin, " (Declare bankruptcy)"); + break; + + case '3': + selection = SEL_SAVE; + + curs_set(CURS_OFF); + wattron(curwin, A_BOLD); + waddstr(curwin, "<3>"); + wattroff(curwin, A_BOLD); + waddstr(curwin, " (Save and end the game)"); + break; + + case KEY_ESC: + case KEY_CANCEL: + case KEY_CTRL('C'): + case KEY_CTRL('G'): + case KEY_CTRL('\\'): + selection = SEL_QUIT; + + curs_set(CURS_OFF); + wattron(curwin, A_BOLD); + waddstr(curwin, ""); + wattroff(curwin, A_BOLD); + waddstr(curwin, " (Quit the game)"); + break; + + default: + beep(); + } + } + } + + // Clear the menu choices + wattrset(curwin, ATTR_NORMAL_WINDOW); + for (y = 2; y < 4; y++) { + wmove(curwin, y, 2); + for (x = 2; x < getmaxx(curwin) - 2; x++) { + waddch(curwin, ' ' | ATTR_NORMAL_WINDOW); + } + } + wrefresh(curwin); + + // Ask the player to confirm their choice + mvwaddstr(curwin, 2, 2, " Are you sure? "); + waddstr(curwin, "["); + attrpr(curwin, ATTR_KEYCODE_STR, "Y"); + waddstr(curwin, "/"); + attrpr(curwin, ATTR_KEYCODE_STR, "N"); + waddstr(curwin, "] "); + + if (! answer_yesno(curwin)) { + selection = SEL_NONE; + } + } +} + +void process_move (void) +{ + // @@@ To be written + if (selection == SEL_QUIT) { + quit_selected = true; + } + + deltxwin(); // "Select move" window + deltxwin(); // Galaxy map window + txrefresh(); +} + + +/*----------------------------------------------------------------------- + Function: next_player - Get the next player + Arguments: (none) + Returns: (nothing) + + This function sets the global variable current_player to the next + eligible player. If no player is still in the game, quit_selected is + set to true. The variable turn_number is also incremented if required. +*/ + +void next_player (void) +{ + int i; + bool all_out; + + + all_out = true; + for (i = 0; i < number_players; i++) { + if (player[i].in_game) { + all_out = false; + break; + } + } + + if (all_out) { + quit_selected = true; + } else { + do { + current_player++; + if (current_player == number_players) { + current_player = 0; + } + if (current_player == first_player) { + turn_number++; + } + } while (! player[current_player].in_game); + } +} + + +/*----------------------------------------------------------------------- + Function: cmp_game_move - Compare two game_move[] elements + Arguments: a, b - Elements to compare + Returns: int - Comparison of a and b + + This function compares two game_move[] elements (of type move_rec_t) + and returns -1 if a < b, 0 if a == b and 1 if a > b. It is used for + sorting game moves into ascending order. +*/ + +int cmp_game_move (const void *a, const void *b) +{ + const move_rec_t *aa = (const move_rec_t *) a; + const move_rec_t *bb = (const move_rec_t *) b; + + + if (aa->x < bb->x) { + return -1; + } else if (aa->x > bb->x) { + return 1; + } else { + if (aa->y < bb->y) { + return -1; + } else if (aa->y > bb->y) { + return 1; + } else { + return 0; + } + } +} diff --git a/src/move.h b/src/move.h new file mode 100644 index 0000000..be95a18 --- /dev/null +++ b/src/move.h @@ -0,0 +1,46 @@ +/************************************************************************ +* * +* Star Traders: A Game of Interstellar Trading * +* Copyright (C) 1990-2011, John Zaitseff * +* * +************************************************************************/ + +/* + Author: John Zaitseff + $Id$ + + This file, move.h, contains declarations for functions that make and + process a game move in Star Traders. + + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see http://www.gnu.org/licenses/. +*/ + + +#ifndef included_MOVE_H +#define included_MOVE_H 1 + + +/************************************************************************ +* Game move function declarations * +************************************************************************/ + +extern void select_moves (void); +extern void get_move (void); +extern void process_move (void); + +extern void next_player (void); + + +#endif /* included_MOVE_H */ diff --git a/src/trader.h b/src/trader.h index b935f83..2a6debc 100644 --- a/src/trader.h +++ b/src/trader.h @@ -50,6 +50,7 @@ #include "globals.h" #include "game.h" +#include "move.h" #include "fileio.h" #include "help.h" #include "intf.h"