Skip to main content

4.7 - Methods Exercise: Utility Methods

In this exercise, you'll practice creating and using methods by building a collection of utility methods that could be useful in game development. These methods will cover string manipulation, mathematical operations, and game-related functionality.

Exercise Overview

You'll create a GameUtilities class with various utility methods. This exercise will help you practice:

  • Defining methods with different parameter types
  • Implementing return values
  • Using method overloading
  • Applying recursion
  • Managing variable scope

Part 1: Setting Up the Project

  1. Create a new C# Console Application project
  2. Add a new class file named GameUtilities.cs
  3. Set up the basic structure:
using System;
using System.Collections.Generic;
using System.Text;

namespace UtilityMethodsExercise
{
public static class GameUtilities
{
// You'll add your utility methods here
}

class Program
{
static void Main(string[] args)
{
// You'll test your utility methods here
Console.WriteLine("Game Utilities Exercise");

// Keep console window open
Console.WriteLine("\nPress any key to exit...");
Console.ReadKey();
}
}
}

Part 2: String Manipulation Methods

Add the following string manipulation methods to your GameUtilities class:

1. Format Player Name

Create a method that formats a player name according to specific rules:

  • Convert to title case (first letter of each word capitalized)
  • Remove any numbers
  • Limit to a maximum length
// Method signature to implement:
public static string FormatPlayerName(string name, int maxLength = 15)
{
// Your implementation here
}

// Example usage:
// GameUtilities.FormatPlayerName("john_doe123") should return "John_doe"
// GameUtilities.FormatPlayerName("MASTER_BLASTER99", 10) should return "Master_blas"

2. Generate Random Username

Create a method that generates a random username by combining words from predefined lists:

// Method signature to implement:
public static string GenerateRandomUsername(Random random)
{
// Your implementation here
// Use arrays of adjectives and nouns to create combinations like "BraveWolf" or "MightyDragon"
}

// Example usage:
// Random rng = new Random();
// string username = GameUtilities.GenerateRandomUsername(rng);

3. Censor Inappropriate Words

Create a method that replaces inappropriate words with asterisks:

// Method signature to implement:
public static string CensorText(string text, string[] inappropriateWords)
{
// Your implementation here
}

// Example usage:
// string[] badWords = { "noob", "cheat", "hack" };
// GameUtilities.CensorText("You're such a noob!", badWords) should return "You're such a ****!"

Part 3: Mathematical Utility Methods

Add the following mathematical utility methods:

1. Calculate Distance

Create overloaded methods to calculate distance between points:

// Method signatures to implement:
public static double CalculateDistance(int x1, int y1, int x2, int y2)
{
// Your implementation here - 2D distance formula
}

public static double CalculateDistance(int x1, int y1, int z1, int x2, int y2, int z2)
{
// Your implementation here - 3D distance formula
}

// Example usage:
// double dist2D = GameUtilities.CalculateDistance(0, 0, 3, 4); // Should return 5
// double dist3D = GameUtilities.CalculateDistance(0, 0, 0, 3, 4, 12); // Should return 13

2. Calculate Damage

Create methods to calculate damage with different formulas:

// Method signatures to implement:
public static int CalculateDamage(int baseDamage, int characterLevel)
{
// Your implementation here - Simple scaling with level
}

public static int CalculateDamage(int baseDamage, int characterLevel, float criticalMultiplier, bool isCritical)
{
// Your implementation here - Include critical hit calculation
}

// Example usage:
// int damage = GameUtilities.CalculateDamage(10, 5); // Basic damage scaled by level
// int critDamage = GameUtilities.CalculateDamage(10, 5, 2.5f, true); // With critical hit

3. Recursive Factorial

Implement a recursive method to calculate factorial:

// Method signature to implement:
public static int Factorial(int n)
{
// Your implementation here using recursion
}

// Example usage:
// int result = GameUtilities.Factorial(5); // Should return 120

Add the following game-related utility methods:

1. Generate Random Loot

Create a method that generates random loot based on rarity:

// Define an enum for item rarity
public enum ItemRarity
{
Common,
Uncommon,
Rare,
Epic,
Legendary
}

// Method signature to implement:
public static string[] GenerateLoot(Random random, int numberOfItems, ItemRarity minimumRarity = ItemRarity.Common)
{
// Your implementation here
// Generate an array of item names with appropriate rarities
}

// Example usage:
// Random rng = new Random();
// string[] loot = GameUtilities.GenerateLoot(rng, 3, ItemRarity.Uncommon);

2. Calculate Experience Points

Create methods to calculate experience points for different scenarios:

// Method signatures to implement:
public static int CalculateExperience(int enemyLevel, int playerLevel)
{
// Your implementation here - Basic XP calculation
}

public static int CalculateExperience(int enemyLevel, int playerLevel, bool isElite, bool questReward)
{
// Your implementation here - Advanced XP calculation with bonuses
}

// Example usage:
// int xp = GameUtilities.CalculateExperience(10, 8); // Basic XP
// int bonusXp = GameUtilities.CalculateExperience(10, 8, true, false); // Elite enemy bonus

3. Check If Point Is In Range

Create a method to check if a point is within a certain range of another point:

// Method signature to implement:
public static bool IsInRange(int x1, int y1, int x2, int y2, double range)
{
// Your implementation here
// Use your CalculateDistance method!
}

// Example usage:
// bool inRange = GameUtilities.IsInRange(0, 0, 3, 4, 6); // Should return true
// bool notInRange = GameUtilities.IsInRange(0, 0, 10, 10, 5); // Should return false

Part 5: Testing Your Methods

In your Main method, add code to test each of your utility methods:

static void Main(string[] args)
{
Console.WriteLine("Game Utilities Exercise\n");

// Test string manipulation methods
Console.WriteLine("=== String Manipulation Tests ===");
Console.WriteLine($"Formatted name: {GameUtilities.FormatPlayerName("john_doe123")}");

Random rng = new Random();
Console.WriteLine($"Random username: {GameUtilities.GenerateRandomUsername(rng)}");

string[] badWords = { "noob", "cheat", "hack" };
Console.WriteLine($"Censored text: {GameUtilities.CensorText("You're such a noob!", badWords)}");

// Test mathematical methods
Console.WriteLine("\n=== Mathematical Utility Tests ===");
Console.WriteLine($"2D Distance: {GameUtilities.CalculateDistance(0, 0, 3, 4)}");
Console.WriteLine($"3D Distance: {GameUtilities.CalculateDistance(0, 0, 0, 3, 4, 12)}");

Console.WriteLine($"Basic damage: {GameUtilities.CalculateDamage(10, 5)}");
Console.WriteLine($"Critical damage: {GameUtilities.CalculateDamage(10, 5, 2.5f, true)}");

Console.WriteLine($"Factorial of 5: {GameUtilities.Factorial(5)}");

// Test game-related methods
Console.WriteLine("\n=== Game Utility Tests ===");
string[] loot = GameUtilities.GenerateLoot(rng, 3, ItemRarity.Uncommon);
Console.WriteLine("Generated loot:");
foreach (string item in loot)
{
Console.WriteLine($"- {item}");
}

Console.WriteLine($"Basic XP: {GameUtilities.CalculateExperience(10, 8)}");
Console.WriteLine($"Elite XP: {GameUtilities.CalculateExperience(10, 8, true, false)}");

Console.WriteLine($"Point in range: {GameUtilities.IsInRange(0, 0, 3, 4, 6)}");
Console.WriteLine($"Point not in range: {GameUtilities.IsInRange(0, 0, 10, 10, 5)}");

// Keep console window open
Console.WriteLine("\nPress any key to exit...");
Console.ReadKey();
}

Challenge Extensions

If you want to challenge yourself further, try implementing these additional methods:

Create a method that recursively searches for files with a specific extension:

public static List<string> FindFiles(string directory, string extension)
{
// Your implementation here using recursion and System.IO
}

2. Shuffle Array

Create a method that shuffles an array using the Fisher-Yates algorithm:

public static void Shuffle<T>(T[] array, Random random)
{
// Your implementation here
}

3. Parse Command

Create a method that parses a command string into a command and parameters:

public static (string command, string[] parameters) ParseCommand(string input)
{
// Your implementation here
// Example: "/give sword 1" -> command: "give", parameters: ["sword", "1"]
}

Solution Guidelines

Here are some guidelines for implementing your solutions:

FormatPlayerName

  • Use ToLower() and then capitalize the first letter of each word
  • Use a loop or LINQ to remove numbers
  • Use Substring() to limit the length

GenerateRandomUsername

  • Create arrays of adjectives and nouns
  • Use random.Next() to select random elements
  • Combine them to form a username

CensorText

  • Use string.Replace() or a loop to check for and replace inappropriate words
  • Replace each inappropriate word with asterisks of the same length

CalculateDistance

  • Use the Pythagorean formula: sqrt((x2-x1)² + (y2-y1)²) for 2D
  • Extend to 3D with sqrt((x2-x1)² + (y2-y1)² + (z2-z1)²)

CalculateDamage

  • For basic damage: baseDamage * (1 + characterLevel / 10.0)
  • For critical: multiply by the critical multiplier if isCritical is true

Factorial

  • Base case: if n <= 1, return 1
  • Recursive step: return n * Factorial(n-1)

GenerateLoot

  • Create arrays of item prefixes and item types for each rarity
  • Use random to select items based on rarity
  • Ensure the rarity is at least the minimum specified

CalculateExperience

  • Basic: baseXP * (enemyLevel / playerLevel)
  • Advanced: add bonuses for elite enemies and quest rewards

IsInRange

  • Use your CalculateDistance method to check if the distance is less than or equal to the range

Submission

When you've completed the exercise, your solution should include:

  1. A fully implemented GameUtilities class with all the required methods
  2. A Main method that tests all your utility methods
  3. Proper documentation (comments) explaining what each method does

Unity Relevance

While this exercise uses a console application for simplicity, the utility methods you're creating are directly applicable to Unity game development. In a Unity project, you might place these methods in a static utility class that can be accessed from any script.

For example, the distance calculation methods could be used for:

  • Determining if an enemy is within attack range
  • Checking if a player is close enough to interact with an object
  • Calculating damage falloff based on distance from an explosion

The string manipulation methods could be used for:

  • Formatting player names in a multiplayer game
  • Filtering chat messages
  • Generating random NPC names

By practicing these utility methods now, you're building skills that will directly transfer to your Unity projects!