Overview
The project is to create a card-based battle game between two (computer) players in which they battle each other with action cards.
Game Play
In each turn, there is a battle in which the outcome is determined by the card types and values. After each turn, the current cards are discarded into the abyss. In some outcomes, one player may gain one card from the other or both may lose their cards into the abyss. The game continues until one player has lost all their cards. The player with any remaining cards wins.
Cards
Each player has a deck of cards, implemented with a linked list. Each card is a node in a linked list. There are three types of cards: ATTACK, DEFEND, and RUN. Here are the scenarios for each battle showdown between the two players.
| ATTACK | DEFEND | RUN | |
| ATTACK | If both players ATTACK, the player with the higher value wins. The winning player gets a new card, which will be added to their card list in the descending order of the card value. The losing player will lose their next card into the abyss. In a tie, nothing happens. | If one player ATTACKs and the other player DEFENDs, the player with the higher value wins. If the ATTACKing player wins, they get a new card added to their card list in the descending order of the card value and nothing happens to the DEFENDing player. If the DEFENDing player wins or ties, then the ATTACKing player loses their next card into the abyss. | If one player ATTACKs and the other player RUNs, the RUNning player loses their next card into the abyss. |
| DEFEND | If both players DEFEND, nothing happens. | If one player DEFENDs and the other player RUNs, the DEFENDING player gets a new card added to their card list in the descending order of the card value. The RUNning player loses their next card into the abyss | |
| RUN | If both players RUN, they both lose their next card and those cards disappear into the abyss. |
Task 1 – cards.h
- Declare a struct that will represent a Card, which will also be a node in a linked list. It will contain a CardType (see enum below) and an integer value.
- Declare all prototypes for the required functions (see Task 2)
- Include header guards
- Include this enum for the CardType.
typedef enum CardType { ATTACK, DEFEND, RUN } CardType;
Task 2 – cards.c
Write the following functions. These functions are typical linked list functions, but adapted for the game play.
- Card* createCard() – This function dynamically allocates a new Card struct object and returns a pointer to that struct object which will later be used to insert into a linked list. There are three types of cards ATTACK, DEFEND, and RUN. ATTACK and DEFEND cards also have a value. You will assign a card type based on these random chances:
- 40% – ATTACK: the value is a random number between 1 and 5 inclusive.
- 50% – DEFEND: the value is a random number between 3 and 8 inclusive.
- 10% – RUN: the value is a random number between 1 and 8 inclusive. The value of a RUN card is only used for sorting purposes.
- Card* removeCard( Card* head ) – This function removes and deallocates the first node in the linked list that head is pointing at. It returns the new head of the linked list.
- Card* addCard( Card* head, Card* c ) – This function adds a new Card struct object to the the linked list that head is pointing at. It is assumed that a new Card struct object, that is being passed into this function as parameter c. This function will add the new node in descending order of its value regardless of the action. This essentially puts the “stronger” cards in front of the deck.
- int getLength( Card* head ) – This function returns the length of the linked list that head is pointing at.
- void printCard( Card* head ) – This function prints a single card with abbreviations: A for ATTACK, D for DEFEND, and R for RUN and their corresponding values. Example: A5 means an ATTACK worth 5 points.
- void printCards( Card* head ) – This function traverses the linked list that head is pointing at. It will call printCard(). It should print out from front to back. Example: R6 D5 D4 A4 D3
- Card* buildDeck( int n ) – This function builds a deck of cards using a linked list. The parameter n determines how many cards are created. It will use createCard() and addCard(). It returns the head of the new linked list.
- Card* destroyCards( Card* head ) – This function is the destructor for a linked list that head is pointing at. It should return NULL.
Task 3 – project3-main.c
Write the main() to do the following.
- Print the game header
- Ask the user how many cards they want in the deck. If it is not a valid number or it is zero, print an error and end the program.
- If the user enters a valid number greater than zero, you can start the game:
- Build each player’s Card linked list based on the size that the user inputted. Print out each player’s cards using printCards().
- Start the game loop. The game continues so long as both players have cards to play with. In each turn (iteration of the loop):
- Print the player name and the number of cards currently remaining in brackets. Also print each player’s first card that is being played currently, along with its value. For example, Player 1 (12): D7 & Player-2 (12): R8.
- Implement the outcomes for each permutations of player actions. There are 9 permutations of ATTACK, DEFEND, and RUN (AA, AD, AR, DA, DD, DR, RA, RD, RR). You can have an if-statement for each of these permutations. Print out descriptive information about what is happening, who wins, and assess the reward/punishment on both players as determined by the rules above. This involves creating/adding a new card to a player’s linked list if they win and/or removing another card from a player’s linked list. There are also cases when there are no rewards nor punishment. You will use your functions to assess these outcomes.
- At the end of each turn, remove the front of the linked list from each player. This discards the cards that the players used in this round. Remember to do remove this current card before applying the reward/punishment for each of the above cases. i.e. the current card should be discarded first before removing the next card as penalty or adding a new card as reward.
- Determine the winner and print out the outcomes. There is also the case in which both players lose.
Task 4: Create a makefile
Create a makefile to compile .


0 comments