Skip to main content

2.6 - Fundamentals Exercise: Simple Calculator & Mad Libs Game

It's time to put your C# knowledge into practice! In this mini-project, we'll build two console applications that demonstrate the concepts we've learned in Module 2:

  1. Simple Calculator: A program that performs basic arithmetic operations
  2. Mad Libs Game: A word game that prompts the user for words and creates a funny story

These projects will reinforce your understanding of variables, operators, type conversion, console I/O, and nullable types.

Project 1: Simple Calculator

Let's build a calculator that can perform addition, subtraction, multiplication, and division.

Requirements

  1. Display a welcome message and menu of operations
  2. Prompt the user for two numbers
  3. Perform the selected operation
  4. Display the result
  5. Ask if the user wants to perform another calculation
  6. Handle invalid input and division by zero

Implementation

using System;

namespace SimpleCalculator
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("=== Simple Calculator ===");
Console.WriteLine("A C# console application for basic arithmetic");

bool continueCalculating = true;

while (continueCalculating)
{
// Display menu
Console.WriteLine("\nAvailable operations:");
Console.WriteLine("1. Addition (+)");
Console.WriteLine("2. Subtraction (-)");
Console.WriteLine("3. Multiplication (*)");
Console.WriteLine("4. Division (/)");
Console.WriteLine("5. Exit");

// Get operation choice
Console.Write("\nEnter your choice (1-5): ");
string? choiceInput = Console.ReadLine();

// Exit if user chooses option 5
if (choiceInput == "5")
{
continueCalculating = false;
Console.WriteLine("Thank you for using Simple Calculator!");
break;
}

// Validate operation choice
if (string.IsNullOrEmpty(choiceInput) ||
!int.TryParse(choiceInput, out int choice) ||
choice < 1 || choice > 5)
{
Console.WriteLine("Invalid choice. Please enter a number between 1 and 5.");
continue;
}

// Get first number
Console.Write("Enter the first number: ");
string? firstInput = Console.ReadLine();

if (string.IsNullOrEmpty(firstInput) ||
!double.TryParse(firstInput, out double firstNumber))
{
Console.WriteLine("Invalid input. Please enter a valid number.");
continue;
}

// Get second number
Console.Write("Enter the second number: ");
string? secondInput = Console.ReadLine();

if (string.IsNullOrEmpty(secondInput) ||
!double.TryParse(secondInput, out double secondNumber))
{
Console.WriteLine("Invalid input. Please enter a valid number.");
continue;
}

// Perform the selected operation
double result = 0;
string operationSymbol = "";

switch (choice)
{
case 1: // Addition
result = firstNumber + secondNumber;
operationSymbol = "+";
break;

case 2: // Subtraction
result = firstNumber - secondNumber;
operationSymbol = "-";
break;

case 3: // Multiplication
result = firstNumber * secondNumber;
operationSymbol = "*";
break;

case 4: // Division
if (secondNumber == 0)
{
Console.WriteLine("Error: Division by zero is not allowed.");
continue;
}
result = firstNumber / secondNumber;
operationSymbol = "/";
break;
}

// Display the result
Console.WriteLine($"\nResult: {firstNumber} {operationSymbol} {secondNumber} = {result}");

// Ask if the user wants to continue
Console.Write("\nDo you want to perform another calculation? (y/n): ");
string? continueInput = Console.ReadLine()?.ToLower();

continueCalculating = continueInput == "y" || continueInput == "yes";
}

Console.WriteLine("\nPress any key to exit...");
Console.ReadKey();
}
}
}

Key Concepts Demonstrated

  1. Variables: Using various data types (int, double, bool, string)
  2. Operators: Arithmetic operators (+, -, *, /) and comparison operators
  3. Type Conversion: Using TryParse to convert string input to numeric types
  4. Console I/O: Reading user input and displaying formatted output
  5. Nullable Types: Using nullable reference types with string?
  6. Control Flow: Using if, switch, and while statements (preview of Module 3)

Enhancements You Can Try

  1. Add more operations (modulus, power, square root)
  2. Implement memory functions (store and recall results)
  3. Add support for more complex expressions with parentheses
  4. Implement a history feature to show previous calculations

Project 2: Mad Libs Game

Mad Libs is a word game where players fill in blanks with different types of words (nouns, verbs, adjectives, etc.) to create a funny story.

Requirements

  1. Display a welcome message and explain the game
  2. Prompt the user for various types of words (nouns, verbs, adjectives, etc.)
  3. Insert the user's words into a story template
  4. Display the completed story
  5. Ask if the user wants to play again with a different story

Implementation

using System;

namespace MadLibsGame
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("=== Mad Libs Game ===");
Console.WriteLine("A C# console application for creating funny stories");
Console.WriteLine("\nHow to play: I'll ask you for various words, and then use them to create a funny story!");

bool playAgain = true;
Random random = new Random();

while (playAgain)
{
// Select a random story template
int storyIndex = random.Next(0, 3);

switch (storyIndex)
{
case 0:
PlayAdventureStory();
break;
case 1:
PlaySpaceStory();
break;
case 2:
PlayGameDevStory();
break;
}

// Ask if the user wants to play again
Console.Write("\nDo you want to play again with a different story? (y/n): ");
string? playAgainInput = Console.ReadLine()?.ToLower();

playAgain = playAgainInput == "y" || playAgainInput == "yes";
}

Console.WriteLine("\nThanks for playing Mad Libs! Press any key to exit...");
Console.ReadKey();
}

static void PlayAdventureStory()
{
Console.WriteLine("\n=== Fantasy Adventure Story ===");

// Get words from the user
string? heroName = GetInput("Enter a name for the hero");
string? adjective1 = GetInput("Enter an adjective");
string? noun1 = GetInput("Enter a noun");
string? verb1 = GetInput("Enter a verb ending in 'ing'");
string? adjective2 = GetInput("Enter another adjective");
string? noun2 = GetInput("Enter another noun");
string? number = GetInput("Enter a number");
string? adjective3 = GetInput("Enter one more adjective");
string? bodyPart = GetInput("Enter a body part");
string? verb2 = GetInput("Enter a verb");

// Create the story
string story = $@"
Once upon a time, the {adjective1} hero named {heroName} embarked on a quest to find the legendary {noun1}.
After days of {verb1} through the {adjective2} forest, {heroName} discovered a hidden {noun2}.
Inside were {number} {adjective3} treasures that made {heroName}'s {bodyPart} tingle with excitement.
With newfound riches, {heroName} decided to {verb2} back to the village and live happily ever after.
";

// Display the completed story
Console.WriteLine("\n=== Your Completed Story ===");
Console.WriteLine(story);
}

static void PlaySpaceStory()
{
Console.WriteLine("\n=== Space Exploration Story ===");

// Get words from the user
string? shipName = GetInput("Enter a name for a spaceship");
string? adjective1 = GetInput("Enter an adjective");
string? planetName = GetInput("Enter a made-up planet name");
string? noun1 = GetInput("Enter a noun");
string? verb1 = GetInput("Enter a verb");
string? adjective2 = GetInput("Enter another adjective");
string? alienName = GetInput("Enter a funny alien name");
string? number = GetInput("Enter a number");
string? bodyPart = GetInput("Enter a body part (plural)");
string? food = GetInput("Enter a food item");

// Create the story
string story = $@"
Captain's Log, Stardate 42.7: The {adjective1} starship {shipName} has arrived at the planet {planetName}.
Our scanners have detected unusual {noun1} readings on the surface.
I've ordered the crew to {verb1} immediately to investigate.
Upon landing, we encountered a {adjective2} alien species called the {alienName}.
They had {number} {bodyPart} and offered us their local delicacy: {food} soup.
This could be the beginning of a beautiful intergalactic friendship... or a terrible digestive disaster.
";

// Display the completed story
Console.WriteLine("\n=== Your Completed Story ===");
Console.WriteLine(story);
}

static void PlayGameDevStory()
{
Console.WriteLine("\n=== Game Development Story ===");

// Get words from the user
string? gameName = GetInput("Enter a name for a video game");
string? adjective1 = GetInput("Enter an adjective");
string? noun1 = GetInput("Enter a noun");
string? verb1 = GetInput("Enter a verb");
string? adjective2 = GetInput("Enter another adjective");
string? number = GetInput("Enter a number");
string? bodyPart = GetInput("Enter a body part");
string? exclamation = GetInput("Enter an exclamation");
string? verb2 = GetInput("Enter a verb ending in 'ing'");

// Create the story
string story = $@"
After {number} months of development, the {adjective1} game studio finally released "{gameName}".
The game featured a revolutionary {noun1} mechanic that allowed players to {verb1} with unprecedented realism.
Critics called it "{adjective2} beyond belief" and "a feast for the {bodyPart}."
The lead developer was quoted saying, "{exclamation}! We never expected such success!"
The team is already {verb2} on the sequel, which promises to be even more groundbreaking.
";

// Display the completed story
Console.WriteLine("\n=== Your Completed Story ===");
Console.WriteLine(story);
}

static string? GetInput(string prompt)
{
Console.Write($"{prompt}: ");
string? input = Console.ReadLine();

// Provide a default value if input is empty
return string.IsNullOrWhiteSpace(input) ? "[missing word]" : input;
}
}
}

Key Concepts Demonstrated

  1. Variables: Using string variables to store user input
  2. String Interpolation: Creating story templates with $@"..." (verbatim string interpolation)
  3. Console I/O: Reading user input and displaying formatted output
  4. Nullable Types: Using nullable reference types with string?
  5. Methods: Creating and calling methods (preview of Module 4)
  6. Random Numbers: Using the Random class to select a story template
  7. Control Flow: Using switch and while statements (preview of Module 3)

Enhancements You Can Try

  1. Add more story templates
  2. Implement a scoring system based on how funny or creative the stories are
  3. Save completed stories to a file
  4. Add color to different parts of the story using Console.ForegroundColor
  5. Create a multiplayer version where different players provide words

Reflection and Learning Outcomes

After completing these mini-projects, you should have a better understanding of:

  1. Practical Application: How to apply C# concepts to solve real problems
  2. Program Structure: How to organize code in a logical way
  3. User Interaction: How to create an interactive console application
  4. Error Handling: How to validate input and handle potential errors
  5. Code Reusability: How to create methods for repeated tasks

Connecting to Unity Development

While these console applications might seem far removed from Unity game development, the core programming concepts are directly transferable:

  • Variables and Data Types: You'll use these to store game state, player stats, etc.
  • Operators: Essential for game mechanics, scoring, damage calculations, etc.
  • Type Conversion: Useful when working with different data formats in Unity
  • User Input: While the input method differs, the concept of processing user actions is fundamental
  • String Formatting: Useful for UI text, debug messages, and game dialogue

In Unity, instead of Console.WriteLine(), you'll use Debug.Log() or UI Text components, and instead of Console.ReadLine(), you'll use Unity's Input system, but the underlying programming principles remain the same.

Conclusion

Congratulations on completing the mini-projects for Module 2! You've now applied your knowledge of C# fundamentals to create functional programs. These projects demonstrate how the individual concepts you've learned can work together to create something useful and fun.

In Module 3, we'll explore control flow in more depth, learning about conditional statements and loops that will give you even more tools for creating sophisticated programs.

Challenge

Try combining elements from both projects to create a math quiz game that:

  1. Generates random math problems
  2. Asks the user to solve them
  3. Keeps track of the score
  4. Provides feedback on correct/incorrect answers
  5. Increases in difficulty as the user progresses

This challenge will further reinforce the concepts from Module 2 and prepare you for the control flow topics in Module 3.