HOW TO CREATE TEXT GAMES USING C! : PART 4 (Rock, Paper, & Scissors game)



This is the fourth part of the series of how to create text games using C. If you haven't seen the previous posts check them out by clicking the links below:
Coming to part 4, here we are going to create the classic Rock, Paper, & Scissors game using the knowledge from the previous three posts. If you haven't gone through the previous posts, I'd recommend you to go through them as they're very easy to understand and take hardly any time for you to complete reading them.

So till now we have learned how to use the rand() function, prompting for and scanning the user's actions and also how to construct a menu for a game. Now is the time that we bring together all these small elements together and create a fun game of Rock, Paper, and Scissors(from now on I'll be calling it as RPS for simplicity).

So before talking about the code, it's good to think about what are the different options we would like to have in our simple RPS game.

  1. Play: To make the player play the game
  2. Help: To let the player know how to play the game
  3. Exit: To exit the game

So our main() function would have a menu which displays the above three options. When the user selects, any one of them, the corresponding function or the subroutine is called. We can put this selection in a loop so that the menu gets displayed every time user returns to the main function.
Here's the first part of the code which has the main() function along with a definition of clear() function which is used to clear the console screen and also other function prototypes.

Note that I'm using scanf_s() function instead of scanf(). scanf_s function has an additional argument specifying the size of the number of characters to be scanned while scanning characters or strings. You can replace all the scanf_s() functions with scanf() and don't forget to remove the additional argument when replacing a scanf_s() which scan a character. For example:
char ch; //character to be scanned
int n;   //integer to be scanned

//scanf_s() usage:
scanf_s(" %c", &ch, 1);
scanf_s("%d", &n);

//scanf() replacement:
scanf(" %c", &ch); //notice that the additional argument is removed
scanf("%d", &n);

Now coming back to the RPS:

#include "stdio.h"
#include "stdlib.h"
#include "time.h"

//the clear() function: used to clear the screen on the console
void clear(void) {
 system("cls");
}

//function prototypes
void play(void); //function which is used for running the game
void help(void); //function to display the instructions of the game

int main(void)
{
 //adding the sing srand() function to seed the values of rand() function
 srand((unsigned int) time(NULL)); //casting return value of time to unsigned int

 //constructing the menu in a loop
 while (true) { 
  
  //'true' is given in order to iterate loop till user selects exit option

  clear(); //clearing the screen before redrawing the menu

  char selection; //to store the user's selection
  char wait; //used to pause game till user enters character

  //printing the menu
  printf("ROCK-PAPER-SCISSORS!\n\n");
  printf("1.Play\n");
  printf("2.Help\n");
  printf("3.Exit\n\n");

  printf("enter your selection(1 - 3): ");
  
  //scanning the user's selection
  scanf_s(" %c", &selection, 1);

  switch (selection) {
  case '1':
   play();
   break;
  case '2':
   help();
   break;
  case '3':
   exit(0);    //predefined function used to exit
  default:
   printf("invalid entry! enter any key to continue: ");
   //wait for users entry to continue
   scanf_s(" %c", &wait, 1);
  }
 }

    return 0;
}

Now with the menu having been constructed, all that is left to do is write the functions play() and help(). Let's write the help function first. Constructing the help function can be done in two ways:

  1. Using only printf() statements to write about how to play the game or
  2. Reading and displaying the contents a file in which the details are already written.
I've selected later approach as I feel it's quite easier. I have written a file "help.txt" with the following contents:

You beat another player if your choice "beats" theirs in the following way:-

Rock beats Scissors
Scissors beat Paper
Paper beats Rock
Each round you score 1 for every other player you beat.

The first player to score 5 or more points wins the game.

Now here's the help() function which is pretty basic. All it does is reads the above contents from the file and displays them.

void help(void) {
 FILE *fp; //file pointer
 char ch; //character to store the characters retrieved from file
 char wait; //used to pause the game till user enters a character
 clear(); //clearing the console screen

 fopen_s(&fp, "help.txt", "r"); //opening the file
        //or use fp = fopen("help.txt", "r");

 //displaying file contents
 while ((ch = fgetc(fp)) != EOF) {
  printf("%c", ch);
 }

 //closing the file
 fclose(fp);

 //wait for users entry to continue
 printf("Enter any key to go back: ");
 scanf_s(" %c", &wait, 1);
}

Let's talk about the final function play() which is the very game! I've created a simple implementation. Here's the implementation: (I've provided comments so that it's super understandable)
void play(void) {

    int player_points = 0; //to store the points of the player
    int opponent_points = 0; //to store the points of the opponent

    int player_selection; //to store the user's selection
    int opponent_selection; //to store the randomly generated opponent's selection

    char wait;          //used to pause the game till user enters a character

    //first person to reach 5 points is the winner
    while (player_points < 5 && opponent_points < 5) {
 clear(); //clear the screen before every entry

 //display points of both the player and the opponent
 printf("your points    : %d\n", player_points);
 printf("opponent points: %d\n\n", opponent_points);

 //display the player actions menu
 printf("enter 0 to select rock\n");
 printf("enter 1 to select paper\n");
 printf("enter 2 to select scissors\n\n");

 //prompting for and scanning the user's entry
 printf("enter your selection(0 - 2): ");
 scanf_s(" %d", &player_selection);

 //checking whether user's entry is valid or not 
 if (player_selection >= 0 && player_selection <= 2) {
  //valid entry

  //generating random selection for opponent
  opponent_selection = rand() % 3;

  //matching the values of user and opponent to decide the result
  if (player_selection == opponent_selection) {
   //when both player and opponent select the same option,
   //it's a draw.

   //notification
   printf("Both selected %d. it's a draw.", opponent_selection);
  }
  else {
   //all cases when user can win
   if ( (player_selection == 0 && opponent_selection == 2) ||
        (player_selection == 1 && opponent_selection == 0) ||
        (player_selection == 2 && opponent_selection == 1)) {
    //when player selects rock & opponent selects scissors
    //when player selects paper & opponent selects rock
    //when player selects scissors & opponent selects paper
    //player wins!

    //notification
    printf("Player gains a point.");
    printf("Opponent selected %d.", opponent_selection);

    //increasing the points of the player
    player_points++;
   }
   //in all other cases opponent gets points
   else {
    //notification
    printf("Opponent gains a point.");
    printf("Opponent selected %d.", opponent_selection);

    //increasing the points of the opponent
    opponent_points++;
   }
  }

                printf("Enter any key to continue: ");
  //wait for users entry to continue
  scanf_s(" %c", &wait, 1);  
 }

 else {
  //invalid entry

  printf("invalid entry! enter any key to continue: ");
  //wait for users entry to continue
  scanf_s(" %c", &wait, 1);
 }
    }

    //exits the loop whwn anyone of the player reaches 5 points
    clear(); //clear the screen

    if (player_points == 5) {
 //Notify the user that he won
 printf("YOU WIN!\n\n");  
    }
    else {
 printf("YOU LOSE :( better luck next time...\n\n");
    }

    //wait for users entry to continue
    printf("Enter any key to continue: ");
    scanf_s(" %c", &wait, 1);

    //return back to menu in the main function
}

I hope you can understand the above code. It's quite a simple mechanism. The user can either select 0 or 1 or 2 which refer to rock, paper, and scissors respectively. The computer generates a random number between 0 and 2(inclusive) for the opponent. The two values are then matched against each other using simple if-else statements. The game continues till anyone of the player reaches 5 points.

Here's a video of the game:


Hope you've learnt something new! 

Comments

Popular posts from this blog

Beginner's guide to Solving the N-Queens problem using backtracking method

PvP Chain reaction game using Python

Guide to Solving Maximal Subarray Problem using Kadane's Algorithm