/* Improvements: - ask user how many players - group player data together into one unit [- restrict who shoots what, add more weapons - just an idea] */ #include #include #include #include #include #include "game.h" #include "Player.h" //Global variables struct Player *players; int NUM_PLAYERS; //Enums are integers //PLAYER1 == 0, PLAYER2 == 1 enum { PLAYER1, PLAYER2 }; //Don't forget the semi-colon! int main(int argc, char *argv[]) { char name[21]; int np; //Make sure two values are specified if (argc != 2) { printf("Usage: game numPlayers\n"); return 0; } NUM_PLAYERS = atoi(argv[1]); np = NUM_PLAYERS; players = calloc(NUM_PLAYERS, sizeof(struct Player)); printf("enter the players names\n"); for (int i = 0; i < NUM_PLAYERS; i++) { players[i].health = 100; scanf("%s", name); players[i].name = (char *) malloc(sizeof(char) * (strlen(name) + 1)); strcpy(players[i].name, name); } int turn = -1; while (!gameOver()) { turn = (turn + 1) % NUM_PLAYERS; // roll over to 0 printTurn(turn); //Attack and target tokens longer than 9 characters //will not work char attack[10], target[10]; scanf("%s %s", attack, target); int playerIndex = getPlayerIndex(target); if (strcmp(attack, "fireball") == 0) fireball(turn, playerIndex); else if (strcmp(attack, "arrow") == 0) arrow(turn, playerIndex); else printf("Invalid spell!\n"); if (!isAlive(playerIndex) && turn >= playerIndex) turn--; } printf("winner is %s!\n", players->name); // shorthand for players[0].name for (int i = 0; i < NUM_PLAYERS; i++) free(players[i].name); free(players); return 0; } int getPlayerIndex(const char *name) { for (int i = 0; i < NUM_PLAYERS; i++) if (strcmp(name, players[i].name) == 0) return i; //We haven't found the name! printf("Invalid target! Type a new player name:\n"); char newName[10]; scanf("%s", newName); return getPlayerIndex(newName); } bool gameOver() { int count = 0; struct Player temp; for (int i = 0; i < NUM_PLAYERS; i++) { if (isAlive(i)) count++; else { printf("%s is DEAD\n", players[i].name); temp = players[i]; for (int j = i + 1; j < NUM_PLAYERS; j++) players[j - 1] = players[j]; players[--NUM_PLAYERS] = temp; i--; // backup a player } } return count == 1; } bool isAlive(int player) { checkValidPlayer(player); return players[player].health > 0; } void printTurn(int player) { for (int i = 0; i < NUM_PLAYERS; i++) { printf("%s now has %d health, ", players[i].name, players[i].health); } printf("\n%s's turn\n", getPlayerName(player)); } void fireball(int source, int target) { checkValidPlayer(source); checkValidPlayer(target); //Decrease target's health players[target].health -= FIREBALL_DAMAGE; printf("%s cast fireball at %s, dealing %d damage\n", getPlayerName(source), getPlayerName(target), FIREBALL_DAMAGE); } void arrow(int source, int target) { checkValidPlayer(source); checkValidPlayer(target); //Decrease target's health players[target].health -= ARROW_DAMAGE; printf("%s shot an arrow at %s, dealing %d damage\n", getPlayerName(source), getPlayerName(target), ARROW_DAMAGE); } /** Returns the player's name from the array of names base on his or her index. */ char *getPlayerName(int player) { checkValidPlayer(player); return players[player].name; } /** Checks if the player (integer) is valid. Exits the program on failure. */ void checkValidPlayer(int player) { assert(player >= 0); assert(player < NUM_PLAYERS); }