Fun With Classes (Hero & Monster Fight)

Here is a quick D&D style game that demonstrates the creation of classes and properties. Then using those properties to pass around to methods and perform different functions on them. Since this was a very simple program with a loop I put the Character and Dice classes into the Default.aspx.cs file. I didn’t see the need to split them out for something so small along with demonstration purposes. I’ll upload anotherĀ  program later with them split out to show how the OOP nature further. If you goto the live example of this one just keep refreshing the webpage. There isn’t anything intuitive that goes on here. Or just download the source code for yourself.

Keep tabs on next weeks submission. Doing some simple work with class libraries and how you share code across a winform and windows application.

HeroMonster

You can see from the main html page there is only a result label that’s used to add text to the screen.

Default.aspx Code File Contents

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="HeroMonster.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

        <asp:Label ID="resultLabel" runat="server"></asp:Label>

    </div>
    </form>
</body>
</html>

Here in the code behind file you will how the Character class and Dice class are used. Pay attention to how I’m passing the objects around to
the different methods. The damage amount is based on using random numbers from the property set for the character. I’ve been trying to keep
my methods as specific as possible. And trying to keep them at least a maximum of 10 lines of code. If they get any more than that I’ll split
function off to another helper method. I’m also making more use of the StringBuilder method. You can see I’ve created a helper method passing
the Character objects to pull data from and display the text on the screen.

Default.aspx Code Behind Contents

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace HeroMonster
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // Quick text to display the start of the battle.
            resultLabel.Text += "<p><strong>The Battle Begins!!!</strong></p>";

            //Defining the properties of our hero.
            Character hero = new Character();
            hero.Name = "Hero";
            hero.Health = 100;
            hero.DamageMaximum = 10;
            hero.AttackBonus = 2;

            //Defining the properties of our monster.
            Character monster = new Character();
            monster.Name = "Monster";
            monster.Health = 100;
            monster.DamageMaximum = 8;
            monster.AttackBonus = 1;

            // Starting the battle.
            Dice dice = new Dice();
            performAttack(hero, monster, dice);
        }

        private void performAttack(Character hero, Character monster, Dice dice)
        {
            // Perform the battle loop to the death.
            while(hero.Health > 0 && monster.Health > 0)
            {
                int heroDamage = hero.Attack(dice);             // Getting the random damage amount the hero can inflict.
                int monsterDamage = monster.Attack(dice);       // Getting the random damage amount the monster can inflict.
                hero.Health = hero.Defend(monsterDamage);       // Adjusting the hero's health.
                monster.Health = monster.Defend(heroDamage);    // Adjusting the monsters health.

                // Printing the results to the screen.
                printStats(hero, monster);
            }
        }

        // Method used to print the character statuses to the screen.
        private void printStats(Character hero, Character monster)
        {
            // Checking to see if anyone has won. If not then display stats and move to the next round.
            if (hero.Health <= 0)
                resultLabel.Text += displayHealth(hero, monster) + "</br>Monster Wins!!!";

            else if (monster.Health <= 0)
                resultLabel.Text += displayHealth(hero, monster) + "</br>Hero Wins!!!";

            else if (hero.Health <= 0 && monster.Health <= 0)
                resultLabel.Text += displayHealth(hero, monster) + "</br>Hero And Monster Are Both Dead!!!";

            else
                resultLabel.Text += displayHealth(hero, monster);
        }

        // Method used to to return the character status amounts.
        private StringBuilder displayHealth(Character hero, Character monster)
        {
            StringBuilder resultBuilder = new StringBuilder();
            return resultBuilder.Append(String.Format("Hero Health: {0} - Monster Health: {1}</br>",
                    hero.Health, monster.Health));
        }
    }

    class Character
    {
        // Character properties.
        public string Name { get; set; }
        public int Health { get; set; }
        public int DamageMaximum { get; set; }
        public int AttackBonus { get; set; }

        // Random declaration to be used for the bonus attack.
        Random bonusAttack = new Random();

        public int Attack(Dice dice)
        {
            dice.Sides = DamageMaximum;     // Setting the Sides property to the maximum amount of damage.
            int damageAmount = dice.Roll(); // Getting the damage amount based on a random number. 1 - damage max.
            return damageAmount;
        }

        public int Defend(int damage)
        {
            // Getting a number for a percentage to decide if a surprise attack will happen.
            int surpriseAttack = bonusAttack.Next(0, 20);

            // Based on the percentage deciding if a surprised attack will happen.
            if (surpriseAttack > 15)
                return this.Health - (damage + AttackBonus);
            else
                return this.Health - damage;
        }
    }

    class Dice
    {
        // Dice properties.
        public int Sides { get; set; }

        Random random = new Random();

        public int Roll()
        {
            return random.Next(1, this.Sides);     // Returning a random damage amount. Range based on max damage.
        }
    }
}
Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s