Welcome to your seventh lesson. In our last session, we navigated the complex world of C's implicit type conversions and integer promotions. We saw how these automatic, behind-the-scenes rules can lead to counter-intuitive behavior, especially when mixing signed and unsigned integer types.
This lesson transitions from theory to practice. As promised, we will now use our foundational knowledge of C's data types, control flow, and operators to build a complete, interactive program. Our goal is to write a simple number-based game, which serves as a warm-up exercise to solidify your understanding of loops, conditionals, and functions. This project is the first small, but crucial, step on your roadmap toward building more complex text-based games.
The Element of Chance: Random Numbers in C
Any game, from a simple dice roller to a complex RPG, needs an element of unpredictability. In programming, we achieve this using pseudo-random number generators. C provides a simple but effective set of tools for this in the <stdlib.h> library.
The core function is rand(), which generates an integer between 0 and a large system-specific value called RAND_MAX. However, by itself, rand() will produce the exact same sequence of "random" numbers every time you run your program. To make it truly feel random, we need to "seed" the generator—that is, give it a unique starting point for its calculations. The most common way to do this is by using the current time, which is different on every run. This is done with the srand() function, which takes the seed as its argument.
To see how this works in practice, this short video provides a very clear explanation.
The video "C random numbers" by Bro Code is a concise guide to the essentials.
Please watch the following segments: The setup: This covers the necessary headers (stdlib.h, time.h) and how to seed the generator using srand(time(0)). Generating numbers: This explains how rand() works and, critically, how to use the modulo operator (%) to constrain the output to a desired range, like the 1-6 needed for a dice roll. The D&D reference here is quite fitting for your goals!
The key formula to remember for generating a number in a specific range [min, max] is:int random_number = (rand() % (max - min + 1)) + min;
For example, to simulate a standard six-sided die (range 1 to 6):
max - min + 1is6 - 1 + 1 = 6.rand() % 6gives a number from 0 to 5.- Adding
min(which is 1) gives a final range of 1 to 6.
Practical Exercise: A Number Guessing Game
Now, let's put these concepts together. We will build a classic number guessing game. The program will:
- Generate a secret random number within a set range (e.g., 1 to 100).
- Repeatedly prompt the user to enter a guess.
- Tell the user if their guess is too high or too low.
- End the game when the user guesses the correct number.
This exercise is perfect for reinforcing your understanding of loops (do-while is a great choice here), conditionals (if-else if-else), and using functions from the standard library.
The following video provides a complete walkthrough of building this exact game.
Number Guessing Game | C Programming Example
The video "Number Guessing Game | C Programming Example" from Portfolio Courses is an excellent step-by-step guide.
Watch the entire video from start to finish to see how the game is constructed. As you watch, pay attention to: The use of srand(time(NULL)) at the beginning of main. How rand() % 100 + 1 generates a number between 1 and 100. The structure of the do-while loop, which guarantees the user gets to guess at least once. The if-else chain that provides feedback to the player. After watching, your task is to write the program yourself from scratch. Try not to simply copy the code; instead, use your understanding of the logic to build it. As a small challenge, try to add a feature: count how many guesses it takes the user to find the number and print this at the end.
From Guessing to Gaming: A Simple Combat Simulator
The number guessing game is a great start. Now, let's apply the same principles to a problem more aligned with your interest in RPGs. We'll outline a very simple, text-based combat loop.
Imagine a scenario like the one pictured below, where a player and an enemy trade blows until one is defeated.

Let's design a simplified version of this.
Game Rules:
- The Player starts with 20 Health Points (HP).
- The Enemy starts with 15 HP.
- On each turn, the Player attacks, dealing random damage between 3 and 8 (inclusive).
- The Enemy then retaliates, dealing random damage between 1 and 6 (inclusive).
- The battle continues until either the Player's or the Enemy's HP drops to 0 or below.
Your Task:
Write a C program that simulates this combat. Here is a structure you can follow:
-
Setup:
- Include the necessary headers (
stdio.h,stdlib.h,time.h). - Seed the random number generator once at the start of
main(). - Declare integer variables for
player_hpandenemy_hpand initialize them.
- Include the necessary headers (
-
The Game Loop:
- Use a
whileloop that continues as long as both player and enemy HP are greater than 0:while (player_hp > 0 && enemy_hp > 0).
- Use a
-
Inside the Loop (Turn Logic):
- Calculate player damage using the formula for a random range.
- Subtract the damage from
enemy_hp. - Print the result (e.g., "Player deals X damage. Enemy has Y HP remaining.").
- Check for win condition: If
enemy_hp <= 0, break out of the loop immediately. - Calculate enemy damage.
- Subtract the damage from
player_hp. - Print the result (e.g., "Enemy deals A damage. Player has B HP remaining.").
-
After the Loop (Determining the Winner):
- Use an
ifstatement to check who won. Ifplayer_hp > 0, the player won. Otherwise, the enemy won. Print a final victory or defeat message.
- Use an
This exercise combines everything from this lesson and directly applies it to a game development context. It also sets the stage for future lessons where we'll replace simple variables like player_hp with more complex data structures using structs. For inspiration on where these simple mechanics can lead, you can glance at the README of the "Liar's Dice Game" project on GitHub. It uses similar principles (dice rolling, game loops) but organizes them into a more advanced structure that we will be working towards.
Conclusion
In this lesson, you've bridged the gap between theoretical knowledge and practical application. You've learned how to introduce unpredictability into your programs using C's random number generation facilities and applied this, along with your existing knowledge of loops and conditionals, to build two small but complete game-oriented projects.
Key Takeaways:
- Randomness in C is achieved using
rand()to generate numbers andsrand()to seed the generator for unique sequences. - The
srand(time(NULL))pattern should be called only once at the start of your program. - The modulo operator (
%) is essential for constraining random numbers to a specific range (like a dice roll). - Game logic can be constructed by combining a game loop (
whileordo-while) with conditional statements that check the game's state (e.g., health points).
You've successfully completed the final warm-up in our fundamentals module. With this practical foundation in place, you are now ready to tackle one of C's most powerful and defining features. In the next lesson, we will begin our exploration of pointers, unlocking the ability to directly manipulate memory and write more efficient, capable programs.