Castle Lords Reign – A Medieval Tinder Game

(1*) var io = new ConsoleInputOutput(); This constitutes the declaration of a variable and the creation of a new instance (object) in a single step. var io (Declaration): Here, a new variable named `io` is declared. Thanks to the `var` keyword, the compiler automatically infers the type (implicit typing) based on the expression on the right-hand side. = new ConsoleInputOutput(); (New Instance): The `new` operator creates a new object (instance) of the `ConsoleInputOutput` class and invokes its constructor. Summary: You declare the variable io, initialize it with an instance of the ConsoleInputOutput class, and assign that instance to it. Note: This applies specifically to C#, where `var` is used for implicitly typed local variables.
An example in C#:
// Castle Lords Reign Game in C#

using System;
using System.Collections.Generic;
using System.Linq;

namespace Castle Lords Reign
{

    /// <summary>Program Entry Point with Menu Control</summary>
    class Program
    {
        static void Main()
        {
            var io = new ConsoleInputOutput(); // (1*)

            // Register all available events (easily extensible)
            var events = new List<GameEvent>
            {
                new PlagueEvent(),
                new MedicineEvent(),
                new GoldEvent(),
                new WeaponEvent()
            };
            var eventManager = new EventManager(events);
            var game = new Game(io, io, eventManager);

            while (true)
            {
                ShowMainMenu(io);
                var choice = io.ReadKey();
                if (choice == "1")
                {
                    game.Run();
                    AskForRestart(io);
                }
                else if (choice == "9")
                    break;
                else
                    io.WriteLine("Invalid input. Please press 1 or 9.");
            }
        }

        /// <summary> Concrete Implementation of Console Input/Output</summary>
        public class ConsoleInputOutput : IUserInput, IOutput
        {
            public string ReadKey() => Console.ReadKey().KeyChar.ToString();
            public void WriteLine(string line) => Console.WriteLine(line);
            public void Clear() => Console.Clear();
        }

        private static void ShowMainMenu(IOutput output)
        {
            output.Clear();
            output.WriteLine("*******Castle Lords Reign******");
            output.WriteLine("*******Dominions français******");
            output.WriteLine("*******************************\n");
            output.WriteLine("Click 1 to run the game");
            output.WriteLine("Click 9 to quit the game\n");
            output.WriteLine("*******************************");
        }

        private static void AskForRestart(IOutput output)
        {
            output.WriteLine("Do you want to restart? 1 = Yes, 9 = Exit");
            while (true)
            {
                var input = Console.ReadKey().KeyChar.ToString();
                if (input == "1") return;      // Restart, main menu reappears
                if (input == "9") Environment.Exit(0);
                output.WriteLine("\nInvalid input.");
            }
        }
    }


    /// <summary>
    /// Game state (the four power indicators).
    /// </summary>
    public class GameState
    {
        public int Gold { get; private set; }
        public int Church { get; private set; }
        public int Military { get; private set; }
        public int People { get; private set; }

        public GameState(int gold, int church, int military, int people)
        {
            Gold = gold;
            Church = church;
            Military = military;
            People = people;
        }

        /// <summary>Changes the values by the specified deltas.</summary>
        public void Modify(int deltaGold, int deltaChurch, int deltaMilitary, int deltaPeople)
        {
            Gold += deltaGold;
            Church += deltaChurch;
            Military += deltaMilitary;
            People += deltaPeople;
        }

        /// <summary>Checks whether the king is still alive (all values between 1 and 99).</summary>
        public bool IsAlive => Gold is > 0 and < 100 &&
                                Church is > 0 and < 100 &&
                                Military is > 0 and < 100 &&
                                People is > 0 and < 100;
    }

    /// <summary>Abstract base class for all game events.</summary>
    public abstract class GameEvent
    {
        public string Name { get; }
        public string Description { get; }

        protected GameEvent(string name, string description)
        {
            Name = name;
            Description = description;
        }

        /// <summary>Executes the event (asks the player and modifies the state).</summary>
        public abstract void Execute(GameState state, IUserInput input, IOutput output);
    }

    /// <summary>Event: Plague</summary>
    public class PlagueEvent : GameEvent
    {
        private const int PeopleLossArmy = 8;
        private const int MilitaryLossArmy = 15;
        private const int ChurchLossArmy = 5;

        private const int PeopleLossNoArmy = 11;
        private const int MilitaryLossNoArmy = 9;
        private const int ChurchLossNoArmy = 7;

        public PlagueEvent() : base("Plague", "Should it primarily affect the military?") { }

        public override void Execute(GameState state, IUserInput input, IOutput output)
        {
            output.WriteLine($"\n{Description}\n1 = YES\n9 = NO");
            var choice = input.ReadKey();
            if (choice == "1")
                state.Modify(0, -ChurchLossArmy, -MilitaryLossArmy, -PeopleLossArmy);
            else
                state.Modify(0, -ChurchLossNoArmy, -MilitaryLossNoArmy, -PeopleLossNoArmy);
        }
    }

    /// <summary>Event: Medicine</summary>
    public class MedicineEvent : GameEvent
    {
        private const int GoldCostYes = 7;
        private const int PeopleGainYes = 12;
        private const int MilitaryGainYes = 1;
        private const int ChurchGainYes = 3;

        private const int PeopleLossNo = 4;
        private const int MilitaryGainNo = 5;
        private const int ChurchGainNo = 7;

        public MedicineEvent() : base("Medicine", "As king, do you want to buy enough medicine for your people?") { }

        public override void Execute(GameState state, IUserInput input, IOutput output)
        {
            output.WriteLine($"\n{Description}\n1 = YES\n9 = NO");
            var choice = input.ReadKey();
            if (choice == "1")
                state.Modify(-GoldCostYes, ChurchGainYes, MilitaryGainYes, PeopleGainYes);
            else
                state.Modify(0, ChurchGainNo, MilitaryGainNo, -PeopleLossNo);
        }
    }

    /// <summary>Event: Gold</summary>
    public class GoldEvent : GameEvent
    {
        private const int GoldGainYes = 12;
        private const int PeopleLossYes = 5;
        private const int MilitaryLossYes = 10;
        private const int ChurchLossYes = 8;

        private const int PeopleGainNo = 8;
        private const int MilitaryGainNo = 5;
        private const int ChurchGainNo = 7;

        public GoldEvent() : base("Gold", "Should the new gold delivery belong entirely to you?") { }

        public override void Execute(GameState state, IUserInput input, IOutput output)
        {
            output.WriteLine($"\n{Description}\n1 = YES\n9 = NO");
            var choice = input.ReadKey();
            if (choice == "1")
                state.Modify(GoldGainYes, -ChurchLossYes, -MilitaryLossYes, -PeopleLossYes);
            else
                state.Modify(0, ChurchGainNo, MilitaryGainNo, PeopleGainNo);
        }
    }

    /// <summary>Event: Weapons</summary>
    public class WeaponEvent : GameEvent
    {
        private const int GoldCostYes = 5;
        private const int PeopleGainYes = 12;
        private const int MilitaryLossYes = 10;
        private const int ChurchGainYes = 3;

        private const int PeopleLossNo = 10;
        private const int MilitaryGainNo = 15;
        private const int ChurchLossNo = 10;

        public WeaponEvent() : base("Weapons", "Give weapons to your people against the military?") { }

        public override void Execute(GameState state, IUserInput input, IOutput output)
        {
            output.WriteLine($"\n{Description}\n1 = YES\n9 = NO");
            var choice = input.ReadKey();
            if (choice == "1")
                state.Modify(-GoldCostYes, ChurchGainYes, -MilitaryLossYes, PeopleGainYes);
            else
                state.Modify(0, -ChurchLossNo, MilitaryGainNo, -PeopleLossNo);
        }
    }

    /// <summary>Interface for user input (enables future extensions, e.g., mouse).</summary>
    public interface IUserInput
    {
        string ReadKey();   // Reads a single key (as a string)
    }

    /// <summary>Interface for output (enables GUI later, e.g.).</summary>
    public interface IOutput
    {
        void WriteLine(string line);
        void Clear();
    }

   

    /// <summary>Manages all events (central list).</summary>
    public class EventManager
    {
        private readonly List<GameEvent> _events;
        private readonly Random _random = Random.Shared; // Thread-safe and efficient

        public EventManager(IEnumerable<GameEvent> events)
        {
            _events = events.ToList();
        }

        /// <summary>Returns a random event.</summary>
        public GameEvent GetRandomEvent() => _events[_random.Next(_events.Count)];
    }

    /// <summary>Main game logic.</summary>
    public class Game
    {
        private readonly IUserInput _input;
        private readonly IOutput _output;
        private readonly EventManager _eventManager;

        public Game(IUserInput input, IOutput output, EventManager eventManager)
        {
            _input = input;
            _output = output;
            _eventManager = eventManager;
        }

        /// <summary>Starts a new round of the game.</summary>
        public void Run()
        {
            // Random starting values (1-100)
            var rnd = Random.Shared;
            var state = new GameState(
                gold: rnd.Next(1, 101),
                church: rnd.Next(1, 101),
                military: rnd.Next(1, 101),
                people: rnd.Next(1, 101)
            );

            _output.Clear();
            _output.WriteLine("Always keep your four powers in balance. Otherwise, death awaits!\n");
            DisplayStats(state);

            // Main game loop: as long as the king is alive
            while (state.IsAlive)
            {
                var gameEvent = _eventManager.GetRandomEvent();
                _output.WriteLine(gameEvent.Name);
                gameEvent.Execute(state, _input, _output);
                DisplayStats(state);
            }

            _output.WriteLine("\nThe king is dead!\n");
        }

        private void DisplayStats(GameState state)
        {
            _output.WriteLine($"Gold: {state.Gold}  Church: {state.Church}  Military: {state.Military}  People: {state.People}\n");
        }
    }
}
error: Content is protected
Scroll to Top