Blekinge Institude of Technology

Kmom01Kursmoment01: Gör ett menyprogram

Create a Menu Program

In this assignment, you will create a menu-driven program in C#, structuring your code into functions. The app, named Menu, will include various tasks like temperature conversion, string manipulation, acronyms, sum and average calculations, and validating personal numbers using the Luhn algorithm. All outputs are displayed through menu options.

Program.cs ⌄

                    
using System; // DEN HÄR RADEN IMPORTERAR GRUNDLÄGGANDE FUNKTIONER SOM CONSOLE
// FÖR ATT TESTERNA SKA KUNNA KÖRAS BEHÖVER MAN LÄGGA DESSA TVÅ RADER ÖVERST I DIN PROGRAM.CS.
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Menu.Tests")]

// NAMESPACE ANVÄNDS FÖR ATT ORDNA KODEN UNDER NAMNET 'MENU'.
namespace Menu
{
    internal class Program // HUVUDKLASSEN FÖR PROGRAMMET
    {
        static void Main(string[] args) // HÄR KOMMER MAIN-METODEN SOM STARTAR PROGRAMMET
        {
            int val; // skapar variabel för att lagra user's menyval
            do // en do while loop, så länge användarens val inte är 0
            {
                ShowMenu(); // anropar metoden som visar meny
                Console.Write("Välj ett alternativ:  ");
                // läser in users text konverterar den till ett heltal
                int.TryParse(Console.ReadLine(), out val);
                --------------------------------------------------------------------------------
                // SWITCH-SATS FÖR ATT BÖRJA KÖRA MENYVAL
                switch (val)
                {
                    case 1:
                        // anropar funktionen för att skriva ut c# info
                        PrintInfoAboutCsharp();
                        break;

                    case 2:
                        // ber om att ange temperatur
                        Console.Write("Ange temperaturen i Celsius: ");
                        // läser om users inmatning och gör den till ett decimal tal
                        double temperatur = double.Parse(Console.ReadLine()!);
                        // anropar metoden som räknar celcius till ahrenheit
                        double resultat = ConvertCelsiusToFahrenheit(temperatur);
                        // skriver ut resultat
                        Console.WriteLine($"{temperatur} Celsius blir {resultat} Fahrenheit");
                        break; // avslutar det menyvalet

                    case 3:
                        // denna val kör funktionen som upprepar varje bokstav i en text
                        Console.WriteLine(RepeatLetters());
                        break;

                    case 4:
                        // denna val kör funktionen som skapar en akronym tex Kaffe
                        Console.WriteLine(CreateAcronym());
                        break;

                    case 5:
                        // denna val kör funktionen
                        // som räknar ut summan och medelvärdet av flera tal
                        Console.WriteLine(CountSumAndAverage());
                        break;

                    case 6:
                        // anropar funk som kontrollerar personnummer om det är giltig
                        bool validation = ValidateSsn();
                        // skriver ut resultat, gäller det om det är okej eller ej
                        Console.WriteLine(validation ? "Valid" : "Not valid");
                        break;

                    case 0:
                        // skriver ut ett meddelande programmet avslutas
                        Console.WriteLine("Programmet avslutas...");
                        break;

                    default: // skriver user nåt som inte finns med i meny, visa den
                        Console.WriteLine("Ogiltigt val, försök gärna igen!");
                        break;
                }

            } while (val != 0); // försök köra än sålänge user inte skriver 0
        }
        --------------------------------------------------------------------------------

        // DEN HÄR METODEN VISAR EN MENY MED OLIKA VAL I KONSOLEN
        // VISAR EN TITEL FÖR MENYN
        // 1: VISA INFORMATION OM C#
        static void ShowMenu()
        {
            Console.WriteLine("\n========= Menu ========");
            Console.WriteLine("1. Visa Information om C#");
            Console.WriteLine("2. Celsius till Fahrenheit");
            Console.WriteLine("3. Upprepa tecken");
            Console.WriteLine("4. Skapa akronym");
            Console.WriteLine("5. Summa och medelvärde");
            Console.WriteLine("6. Validera personnummer");
            Console.WriteLine("0. Avsluta");
        }
        --------------------------------------------------------------------------------

        // DEN HÄR METODEN SKRIVER UT INFORMATION OM PROGRAMMERINGSSPRÅKET C# I OUTPUT
        internal static void PrintInfoAboutCsharp()
        {
            Console.WriteLine("C# är ett modernt, objektorienterat programmeringsspråk som skapades av Microsoft.");
            Console.WriteLine("Det används för att bygga appar, webbplatser och spel på .NET-plattformen.");
            Console.WriteLine("Språket kombinerar enkelhet, kraft och säkerhet, och används över hela världen.");
        }
        --------------------------------------------------------------------------------

        // DENNA METOD ANVÄNDS I MENYN FÖR ATT RÄKNA CELSIUS till FAHRENHEIT
        internal static double ConvertCelsiusToFahrenheit(double tempCelsius)
        {
            // den räknar om en temperatur från Celsius till Fahrenheit
            double fahrenheit = tempCelsius * 9 / 5 + 32;
            // returnerar > avrundar värdet till 2 decimaler.
            return Math.Round(fahrenheit, 2);
        }
        --------------------------------------------------------------------------------

        // DENNA METODEN ANVÄNDS AV TESTERNA SOM LÄSER FRÅN CONSOLE OCH SKRIVER UT RESULTATET
        internal static void ConvertCelsiusToFahrenheit()
        {
            // läser in text som user skriver i console
            string? input = Console.ReadLine();
            // hanterar om användaren inte skrev något eller bara mellanslag
            if (string.IsNullOrWhiteSpace(input))
                return;  // slutar metoden om ingen giltig text finns

            // den delar upp texten vid mellanslag
            // gör att tomma delar ignoreras
            // resultat sparas i en array av strängar som heter parts
            string[] parts = input.Split(' ', StringSplitOptions.RemoveEmptyEntries);

            // om inget skriv angav, avsluta
            if (parts.Length == 0)
                return;
            // omvandlar första delen t ett decimal
            if (double.TryParse(parts[0], out double celsius))
            {
                // sen räknar om cel till fah med gällande formeln
                double fahrenheit = Math.Round((celsius * 9 / 5) + 32, 2);
                Console.WriteLine(fahrenheit);
            }
        }
        --------------------------------------------------------------------------------

        // SKAPAR EN METOD SOM UPPREPAR VARJE BOKSTAV I EN TEXT FLERA GÅNGER
        // BEROENDE PÅ DESS POSITION 0=1, 1=2 GÅNGER OSV..
        internal static string RepeatLetters()
        {
            Console.Write("Give a string: ");
            // läser in text LR tom sträng om null
            string input = Console.ReadLine() ?? "";
            string result = ""; // skapar en varaibel där string result sparas

            // i yttre loop går vi igenom varje tecken i texten
            for (int i = 0; i < input.Length; i++)
            {
                // hämta bokstav på posi i
                char letter = input[i];
                // i den innre loop upprepar bokstav
                // ex: abc a=0 1, b=1 01=2gånger, c=2 012=3gånger.
                for (int s = 0; s <= i; s++)
                {
                    // lägger till bokstav i resultat
                    result = result + letter;
                }
                /*
                om det inte är sista bokstaven,
                lägger jag till ett bindestreck (-) efteråt
                */
                if (i < input.Length - 1)
                {
                    result = result + "-";
                }
            }
            return result; // return den färdiga texten
        }
        --------------------------------------------------------------------------------

        // DEN HÄR METODEN SKAPAR EN AKRONYM KORTNING FRÅN ETT NAMN SOM ANVÄNDAREN SKRIVER IN
        internal static string CreateAcronym()
        {
            // ber om att ange en input
            Console.Write("Ange ett namn: ");
            // läser in string eller tom om null
            string input = Console.ReadLine() ?? "";
            string acronym = ""; // sparas resultat här

            // delar upp texten i ord
            string[] words = input.Split(' ', StringSplitOptions.RemoveEmptyEntries);

            bool hasUpper = false; // kollar om texten innehåller minst en stor bokstav
            bool allUpper = true; // kollar om alla bokstäver är stora

            // går igenom varje tecken i texten
            foreach (char c in input)
            {
                // bara bokstäver räknas
                if (char.IsLetter(c))
                {
                    if (char.IsUpper(c))
                        // hittar minst en s bokstav
                        hasUpper = true;
                    else
                        // hittar en liten bokstav
                        allUpper = false;
                }
            }
            // om hela text består av stora bokstäver
            if (allUpper)
            {
                // här tar bort mellanslag och använder hela texten som akronym
                acronym = input.Replace(" ", "");
            }
            // kontrollerar om texten blandade bokstäver några små å stor bokstäver
            else if (hasUpper)
            {
                 // tar bara de stora bokstäverna som akronym
                foreach (char c in input)
                {
                    if (char.IsUpper(c))
                        acronym = acronym + c;
                }
            }
            // om texten inte innehåller några versaler alls
            else
            {
                // return en tom sträng
                return "";
            }
            // return den färdiga akronymen
            return acronym;
        }
        --------------------------------------------------------------------------------

        // DEN HÄR METODEN LÅTER ANVÄNDAREN SKRIVA IN FLERA TAL,
        // RÄKNAR UT SUMMAN OCH MEDELVÄRDET, OCH VISAR RESULTATET.
        internal static string CountSumAndAverage()
        {
            // skapar en variabel där jag kan spara summan av alla inmatade tal
            double sum = 0;
            // räknar hur många tal användaren har skrivit
            int count = 0;
            // en while loop som fortsätter tills användaren skriver "klar"
            while (true)
            {
                Console.Write("Ange ett tal (eller 'klar' för att avsluta): ");
                // läser in texten gör den till små bokstäver
                string input = Console.ReadLine()?.ToLower() ?? "";

                // om skriv klar , bryt loopen
                if (input == "klar") break;
                // här omvandlar jag texten till ett decimaltal
                if (double.TryParse(input, out double number))
                {
                    // lägger t talet i decimal
                    sum = sum + number;
                    count++; // öka räknaren med 1
                }
                else
                {
                    Console.WriteLine("Ogiltig inmatning, försök igen.");
                }
            }
            // om inga tal har matats in, returnera en tom sträng
            if (count == 0)
                return "";
            // räknar ut medelvärdet och avrundar till 2 decimaler
            double average = Math.Round(sum / count, 2);
            return $"Summan={sum} och medelvärdet={average}";
        }
        --------------------------------------------------------------------------------

        // DEN HÄR METODEN KONTROLLERAR OM ETT PERSONNUMMER ÄR GILTIGT
        // ENLIGT LUHN-ALGORITMEN
        internal static bool ValidateSsn()
        {
            Console.Write("Ange personnummer (yymmdd-xxxx eller utan -): ");
            // läser in användarens text och tar bort eventuellt bindestreck
            string ssnInput = Console.ReadLine()?.Replace("-", "") ?? "";
            // kontroll att personnumret har exakt 10 siffror och består av bara siffror
            if (ssnInput.Length != 10 || !long.TryParse(ssnInput, out _))
            {
                return false;
            }
            // skapar variabel för att beräkna kontroll summa
            int sum = 0;
            // går igenom varje siffra i personnumret
            for (int i = 0; i < ssnInput.Length; i++)
            {
                // gör om tecknet till en siffra ex '5' > 5
                int digit = ssnInput[i] - '0';
                // varannan siffra jämn position, multipliceras med 2
                if (i % 2 == 0)
                {
                    digit = digit * 2;
                    // om resultat bli tvåsiffrigt ex 12 addera siffrorna (1 + 2 = 3)
                    if (digit > 9)
                        digit = digit / 10 + digit % 10;
                }
                // här lägger jag till resultat i summan
                sum = sum + digit;
            }
            // som summan är jämnt delbar med 10 → giltigt personnummer
            return sum % 10 == 0;
        }
    }
}
                    
                

Kmom02Kursmoment02:The Dice Game Dice100

The Dice Game Dice100

Dice100 is a simple yet fun dice game. The goal is to reach 100 points first by rolling five dice. On each turn, a player rolls the dice until they choose to stop and save their points, or roll a 1, which causes them to lose all points collected that round. Rounds are counted whether the player saves their score or rolls a 1.

In this assignment, you will create classes to represent a die, a game round, and the game itself. You will also build a class to manage the menu.

Die.cs ⌄

                    
using System;

namespace Dice100 // ett program som handlar om en tärning
{
    public class Die
    {
        private const int MIN_VALUE = 1; // det minsta värde en tärning kan få, alltid ett
        private const int MAX_VALUE = 6; // det högsta värde en tärning kan få, alltid sex
        private int _value; // lagrar den nuvarande värdet på tärningen
        private static Random _dieRandom = new Random(); // en slumpgenerator som alla tarningar delar
        --------------------------------------------------------------------------------

        public Die() // konstruktor som skapar en tärning med slumpat värde
        {
            this._value = _dieRandom.Next(MIN_VALUE, MAX_VALUE + 1);
        }
        --------------------------------------------------------------------------------

        public Die(int value) // konstruktor som skapar en tärning med ett givet värde
        {
            if (value < MIN_VALUE)
                this._value = MIN_VALUE; // använd this._value
            else if (value > MAX_VALUE)
                this._value = MAX_VALUE; // använd this._value
            else
                this._value = value; // använd this._value
        }
        --------------------------------------------------------------------------------

        public int GetValue() // skapar metod som hämtar tärningens värde
        {
            return this._value; // använd this._value
        }
        --------------------------------------------------------------------------------

        public string GetString() // metod som ger värdet som text
        {
            return this._value.ToString(); // använd this._value
        }
        --------------------------------------------------------------------------------

        public void Roll() // metod som slår tärningen och ger den ett nytt slumpt värde
        {
            this._value = _dieRandom.Next(MIN_VALUE, MAX_VALUE + 1); // använd this._value
        }
        --------------------------------------------------------------------------------
    }
}
                    
                

Game.cs ⌄

                    
using System;

namespace Dice100
{
    public class Game // klassen game håller ordning på hela spelet, round, poäng och regler
    {
        private int _totalPoints; // sparar totalpoängen som spelaren fått ihop
        private int _roundCount; // räknar hur många round spelaren har spelat
        private Round _currentRound = new Round();

        private const int TARGET_SCORE = 100; // målet för att vinna spelet, 100 poäng
        --------------------------------------------------------------------------------

        public Game() // konstruktor som startar spelet genom att nollställa allt
        {
            ResetGame();
        }
        --------------------------------------------------------------------------------

        public void PrintRules() // skriver ut reglerna för hur spelet fungerar
        {
            Console.WriteLine("Regler:");
            Console.WriteLine("● Du kastar 5 tärningar.");
            Console.WriteLine("● Summan ger rundans poäng.");
            Console.WriteLine("● Om någon tärning visar 1 blir rundans poäng 0.");
            Console.WriteLine("● Först till 100 poäng vinner.");
        }
        --------------------------------------------------------------------------------

        public void RollDice()// slår tärningar i den aktuella round
        // och ökar antalet round med 1
        {
            _currentRound.Roll();
            _roundCount++;
        }
        --------------------------------------------------------------------------------

        public void SaveRound()// sparar round poäng till totalpoängen
        // och startar en ny round
        {
            _totalPoints += _currentRound.GetPoints();
            _currentRound = new Round();

            Console.WriteLine("Totala poäng: " + _totalPoints);
        }
        --------------------------------------------------------------------------------

        public bool HasWon() // kontrollerar om spelaren har nått 100 poäng eller mer
        {
            return _totalPoints >= TARGET_SCORE;
        }
        --------------------------------------------------------------------------------

        public void ResetGame() // nollställer spelet och börjar om från round 1 med 0 poäng
        {
            _totalPoints = 0;
            _roundCount = 0;
            _currentRound = new Round();
        }
        --------------------------------------------------------------------------------

        public void PrintStatus() // skriver ut information om spelets nuvarande läge
        {
            Console.WriteLine("========================");
            Console.WriteLine("Round: " + _roundCount);
            Console.WriteLine("Totalpoäng: " + _totalPoints);
            _currentRound.PrintRound(); // visar tärningar värden
            Console.WriteLine("========================");
        }
        --------------------------------------------------------------------------------

    }
}
                    
                

Menu.cs ⌄

                    
using System;

namespace Dice100
{
    public class Menu
    {
        private Game _game; // skapar ett objekt av spelet så att menyn kan styra spelet

        public Menu()
        {
            _game = new Game(); // när menyn startar skapas ett nytt spel
        }
        --------------------------------------------------------------------------------

        public void Start()
        {
            bool running = true; // håller koll på om menyn ska fortsätta köras

            while (running) // loopen kör tills spelaren väljer att avsluta
            {
                Console.WriteLine("\n== Välkommen till Dice 100 ==\n");
                Console.WriteLine("Dagens datum: " + DateTime.Now.ToString("yyyy-MM-dd"));
                Console.WriteLine("Tiden:   " + DateTime.Now.ToString("HH:mm:ss\n"));

                Console.WriteLine("1. Slå och summera");
                Console.WriteLine("2. Spara poäng och avsluta rundan");
                Console.WriteLine("3. Nollställ och börja om");
                Console.WriteLine("4. Skriv ut reglerna");
                Console.WriteLine("5. Avsluta");
                Console.Write("\nDitt val: ");

                string input = Console.ReadLine(); // läser spelarens val
                Console.Clear(); // rensar skärmen efter varje val
                --------------------------------------------------------------------------------

                if (input == "1")
                {
                    // slår tärningar och uppdaterar round
                    _game.RollDice();
                    _game.PrintStatus(); // skriver ut tärningar och poäng

                    if (_game.HasWon()) // kontrollerar om spelaren vann
                    {
                        Console.WriteLine("\nGRATTIS! Du vann!");
                        running = false; // avslutar spelet
                    }
                }
                --------------------------------------------------------------------------------
                else if (input == "2")
                {
                    // sparar rundans poäng och skapar ny runda
                    _game.SaveRound();
                    _game.PrintStatus(); // visar status efter sparat

                    if (_game.HasWon())
                    {
                        Console.WriteLine("\nGRATTIS! Du vann!");
                        running = false;
                    }
                }
                --------------------------------------------------------------------------------
                else if (input == "3")
                {
                    _game.ResetGame(); // startar om spelet
                    Console.WriteLine("Spelet är nollställt.");
                }
                --------------------------------------------------------------------------------
                else if (input == "4")
                {
                    _game.PrintRules(); // visar reglerna
                }
                --------------------------------------------------------------------------------
                else if (input == "5")
                {
                    running = false; // avsluta spelet
                }
                --------------------------------------------------------------------------------
                else
                {
                    // felaktigt menyval
                    Console.WriteLine("Fel val, försök igen.");
                }
                --------------------------------------------------------------------------------
            }
        }
    }
}
                    
                

Round.cs ⌄

                    
using System;
using System.Collections.Generic;

namespace Dice100
{
    public class Round // här börjar klassen round
    // den representerar en spelrunda med 5 tärningar
    {
        // en konstant (ett fast värde) som säger hur många tärningar rundan ska ha
        private const int NBR_OF_DICE = 5;

        private List _hand; // en lista som håller alla tärningar i rundan
        private int _points; // poäng för round
        --------------------------------------------------------------------------------

        public Round() // detta är första konstruktorn
        // den skapar en tom runda och fyller den med fem slumpade tärningar
        {
            this._hand = new List();

            // skapar 5 nya tärningar
            for (int i = 0; i < NBR_OF_DICE; i++)
            {
                this._hand.Add(new Die());
            }
            UpdatePoints(); // räknar poängen direkt
        }
        --------------------------------------------------------------------------------

        public Round(List values) // detta är andra konstruktorn
        // den används om man vill skapa en runda med bestämda värden
        {
            this._hand = new List();

            for (int i = 0; i < values.Count; i++)
            {
                this._hand.Add(new Die(values[i])); // skapar tärning med bestämt värde
            }
            UpdatePoints();
        }
        --------------------------------------------------------------------------------

        public int GetPoints() // en publik metod som returnerar rundans poäng
        {
            return this._points;
        }
        --------------------------------------------------------------------------------

        public void ClearPoints() // en publik metod som nollställer poängen
        {
            this._points = 0;
        }
        --------------------------------------------------------------------------------

        private void UpdatePoints() // en privat metod som räknar ut poängen för rundan
        // om någon tärning visar 1 blir poängen 0
        {
            int sum = 0;
            bool hasOne = false;

            // går igenom alla tärningar
            for (int i = 0; i < this._hand.Count; i++)
            {
                int value = this._hand[i].GetValue();
                if (value == 1) // om någon tärning är 1 blir poängen 0
                {
                    hasOne = true; // tärning visade 1
                }
                sum += value; // lägg till värdet
            }

            if (hasOne)
            {
                this._points = 0; // får ingen poäng om en etta finns
            }
            else
            {
                this._points = sum; // annars sätt summan som poäng
            }
        }
        --------------------------------------------------------------------------------

        public void Roll() // metod som slår alla tärningar på nytt
        {
            for (int i = 0; i < this._hand.Count; i++)
            {
                this._hand[i].Roll(); // slå tärningen
            }
            UpdatePoints(); // räkna nya poängen
        }
        --------------------------------------------------------------------------------

        public void Roll(List indexes) // metod som bara slår vissa tärningar baserat på index
        {
            for (int i = 0; i < indexes.Count; i++)
            {
                int idx = indexes[i];
                if (idx >= 0 && idx < this._hand.Count) // kontrollerar att index finns i listen
                {
                    this._hand[idx].Roll();
                }
            }
            UpdatePoints();
        }
        --------------------------------------------------------------------------------

        public List HandToList() // metod som gör om tärningarna till en lista med endast värden
        {
            List values = new List();

            for (int i = 0; i < this._hand.Count; i++)
            {
                values.Add(this._hand[i].GetValue());
            }

            return values;
        }
        --------------------------------------------------------------------------------

        public void PrintRound() // metod som skriver ut tärningarnas värden
        {
            Console.Write("Tärningar: ");
            for (int i = 0; i < this._hand.Count; i++)
            {
                Console.Write("[" + this._hand[i].GetValue() + "], ");
            }
            Console.WriteLine();
            Console.WriteLine("Poäng för denna rund är: " + this._points);
        }
        --------------------------------------------------------------------------------
    }
}
                    
                

Program.cs ⌄

                    
using Dice100;

Menu menu = new Menu();
menu.Start();
                    
                

Kmom03Kursmoment03:The Dice Game Dice100 Part 2

The Dice Game Dice100 Part 2

Dice100 is a simple yet fun dice game. The goal is to reach 100 points first by rolling dice. On each turn, a player rolls the dice until they choose to stop and save their points, or roll a 1, which causes them to lose all points collected that round. Rounds are counted whether the player saves their score or rolls a 1.

In this assignment, you will use a static class AsciiArt to display the dice as simple terminal images in ASCII. You will also create a custom exception and save a high-score list to a file. Naturally, you will add a menu option to display the high-score list in the terminal.

AsciiArt.cs ⌄

                    
using System;
using System.Collections.Generic;

namespace Dice100.src
{
    public static class AsciiArt
    {
        public static string BuildDiceFaces(List values)
        {
            var tarningBilder = new Dictionary
            {
                { 0, new string[] {
                    "-----",
                    "| ? |",
                    "| ? |",
                    "| ? |",
                    "-----" } },
                { 1, new string[] {
                    "-----",
                    "|   |",
                    "| o |",
                    "|   |",
                    "-----" } },
                { 2, new string[] {
                    "-----",
                    "|o  |",
                    "|   |",
                    "|  o|",
                    "-----" } },
                { 3, new string[] {
                    "-----",
                    "|o  |",
                    "| o |",
                    "|  o|",
                    "-----" } },
                { 4, new string[] {
                    "-----",
                    "|o o|",
                    "|   |",
                    "|o o|",
                    "-----" } },
                { 5, new string[] {
                    "-----",
                    "|o o|",
                    "| o |",
                    "|o o|",
                    "-----" } },
                { 6, new string[] {
                    "-----",
                    "|o o|",
                    "|o o|",
                    "|o o|",
                    "-----" } }
            };
            --------------------------------------------------------------------------------

            string result = "";
            int maxDicePerLine = 3;
            int antalRader = (values.Count + maxDicePerLine - 1) / maxDicePerLine;
            --------------------------------------------------------------------------------

            for (int line = 0; line < 5; line++)
            {
                for (int rad = 0; rad < antalRader; rad++)
                {
                    for (int i = rad * maxDicePerLine; i < (rad + 1) * maxDicePerLine && i < values.Count; i++)
                    {
                        int value = values[i];
                        int safeValue = (value < 0 || value > 6) ? 0 : value;
                        result += tarningBilder[safeValue][line] + "  ";
                    }
                    if (rad < antalRader - 1) result += "   ";
                }
                result += "\n";
            }
            --------------------------------------------------------------------------------

            Console.Write(result);
            return result;
        }
    }
}
                    
                

Die.cs ⌄

                    
namespace Dice100.src
{
    public class Die
    {
        private int _value;
        private Random _random = new Random();
        public int Value => _value;

        public Die()
        {
            _value = 1;
        }
        --------------------------------------------------------------------------------

        public Die(int value)
        {
            if (value < 1) _value = 1;
            else if (value > 6) _value = 6;
            else _value = value;
        }
        --------------------------------------------------------------------------------

        public void Roll()
        {
            _value = _random.Next(1, 7);
        }
        --------------------------------------------------------------------------------

        public int GetValue() => _value;
        public string GetString() => _value.ToString();
    }
}
                    
                

FileHandler.cs ⌄

                    
using System;
using System.Collections.Generic;
using System.IO;

namespace Dice100.src
{
    public static class FileHandler
    {
        private const string FILE_NAME = "toplist.txt";

        // Skriver EN rad (overwrite) till standardfilen
        public static void SaveToFile(int noOfDice, string name, int points, int rounds)
        {
            string line = $"{noOfDice}, {name}, {points}, {rounds}";
            File.WriteAllText(FILE_NAME, line + Environment.NewLine);
        }
        --------------------------------------------------------------------------------

        // Skriver FLERA rader (overwrite) till standardfilen
        public static void SaveToFile(List lines)
        {
            File.WriteAllLines(FILE_NAME, lines);
        }
        --------------------------------------------------------------------------------

        // Läser standardfilen – returnerar List
        public static List ReadFromFile()
        {
            if (!File.Exists(FILE_NAME))
                return new List();

            return new List(File.ReadAllLines(FILE_NAME));
        }
        --------------------------------------------------------------------------------

        // **KORRIGERAD:** Läser den fil som testerna anger (via fileName)
        public static string[] ReadFromFile(string fileName)
        {
            if (!File.Exists(fileName))
                return Array.Empty();

            return File.ReadAllLines(fileName);
        }
        --------------------------------------------------------------------------------

        // Om testerna skickar SaveToFile med endast antal och namn
        public static void SaveToFile(int noOfDice, string name)
        {
            SaveToFile(noOfDice, name, 0, 0); // points = 0, rounds = 0
        }
        --------------------------------------------------------------------------------

        // **NY:** Överlagring för testerna som skickar filnamn och innehåll (string[])
        public static void SaveToFile(string fileName, string[] lines)
        {
            File.WriteAllLines(fileName, lines);
        }
        --------------------------------------------------------------------------------

        // ===========================
        // Hjälpmetoder för Menu.cs
        // ===========================

        public static void WriteResult(int noOfDice, string name, int points, int rounds)
        {
            // Här behöver du antingen skriva till FILE_NAME eller lägga till till filen
            // Jag antar att du vill OVERWRITE när du sparar ett resultat, baserat på tidigare kod.
            SaveToFile(noOfDice, name, points, rounds);
        }
        --------------------------------------------------------------------------------

        public static List ReadResults()
        {
            return ReadFromFile();
        }
        --------------------------------------------------------------------------------
    }
}
                    
                

Game.cs ⌄

                    

using System;

namespace Dice100.src
{
    public class Game
    {
        private int _totalPoints;
        private int _roundCount;
        private Round _currentRound;
        private string _playerName;
        private int _numberOfDice;
        private const int TARGET_SCORE = 100;
        --------------------------------------------------------------------------------

        public Game()
        {
            _playerName = "Spelare";
            _numberOfDice = 5;
            _currentRound = new Round(_numberOfDice);
            _totalPoints = 0;
            _roundCount = 0;
        }
        --------------------------------------------------------------------------------

        public bool SetGameValues(int noOfDice, string name)
        {
            if (noOfDice < 2)
                throw new NumberOfDieException(
                    "antalet tärningar måste vara 2 eller fler.");
            if (noOfDice > 10)
                throw new NumberOfDieException(
                    "antalet tärningar måste vara 10 eller färre.");

            if (string.IsNullOrWhiteSpace(name))
                name = "Spelare";

            _numberOfDice = noOfDice;
            _playerName = name;
            _currentRound = new Round(_numberOfDice);

            return true;
        }
        --------------------------------------------------------------------------------

        public string GetPlayerName() => _playerName;
        public int GetNoOfDice() => _numberOfDice;
        public int GetRounds() => _roundCount;
        public int GetTotalPoints() => _totalPoints;

        public void RollDice()
        {
            _currentRound.Roll();
            _roundCount++;
        }
        --------------------------------------------------------------------------------

        public void SaveRound()
        {
            _totalPoints += _currentRound.GetPoints();
            _currentRound = new Round(_numberOfDice);
        }
        --------------------------------------------------------------------------------

        public bool HasWon() => _totalPoints >= TARGET_SCORE;
        public void ResetGame()
        {
            _totalPoints = 0;
            _roundCount = 0;
            _playerName = "Spelare";
            _numberOfDice = 5;
            _currentRound = new Round(_numberOfDice);
        }
        --------------------------------------------------------------------------------
        public Round GetCurrentRound() => _currentRound;
    }
}

                    
                

Menu.cs ⌄

                    
using System;
using System.Collections.Generic;
using Dice100.src;

namespace Dice100.src
{
    public class Menu
    {
        private Game _game;
        public Menu()
        {
            _game = new Game();
        }
        --------------------------------------------------------------------------------

        public void InitGame()
        {
            Console.WriteLine("Välkommen till dice100!");

            Console.Write("Ange ditt namn: ");
            string name = Console.ReadLine() ?? "";

            int noOfDice = 0;
            bool valid = false;

            while (!valid)
            {
                Console.Write("Hur många tärningar (2-10)? ");
                string input = Console.ReadLine() ?? "";

                if (int.TryParse(input, out noOfDice))
                {
                    try
                    {
                        valid = _game.SetGameValues(noOfDice, name);
                    }
                    catch (NumberOfDieException ex)
                    {
                        Console.WriteLine("Fel: " + ex.Message);
                    }
                }
                else
                {
                    Console.WriteLine("Fel: ange ett giltigt nummer.");
                }
            }
            Console.WriteLine($"\nVälkommen {name}! Spelet spelas nu med {noOfDice} tärningar.\n");
        }
        --------------------------------------------------------------------------------

        public void Start()
        {
            InitGame();
            bool running = true;

            while (running)
            {
                Console.WriteLine("\n1. Slå och summera");
                Console.WriteLine("2. Spara poäng och avsluta rundan");
                Console.WriteLine("3. Nollställ och börja om");
                Console.WriteLine("4. Skriv ut reglerna");
                Console.WriteLine("5. Visa topplista");
                Console.WriteLine("6. Avsluta");
                Console.Write("\nDitt val: ");

                switch (Console.ReadLine())
                {
                    case "1":
                        _game.RollDice();
                        PrintStatus();
                        if (_game.HasWon()) EndGame(ref running);
                        break;
                    case "2":
                        _game.SaveRound();
                        PrintStatus();
                        if (_game.HasWon()) EndGame(ref running);
                        break;
                    case "3":
                        _game.ResetGame();
                        Console.WriteLine("\nSpelet har nollställts och startas om!");
                        PrintStatus();
                        break;
                    case "4":
                        PrintRules();
                        break;
                    case "5":
                        ShowToplist();
                        break;
                    case "6":
                        running = false;
                        break;
                    default:
                        Console.WriteLine("Felaktigt val.");
                        break;
                }
            }
        }
        --------------------------------------------------------------------------------

        private void EndGame(ref bool running)
        {
            Console.WriteLine("\nGrattis! du har vunnit dice100!");
            Console.WriteLine($"Totalpoäng: {_game.GetTotalPoints()}");
            Console.WriteLine($"Antal rundor: {_game.GetRounds()}");

            // I EndGame()
            FileHandler.WriteResult(
                _game.GetNoOfDice(),
                _game.GetPlayerName(),
                _game.GetTotalPoints(),
                _game.GetRounds()
            );

            Console.WriteLine("\nTryck på valfri tangent för att avsluta...");
            Console.ReadKey();
            running = false;
        }
        --------------------------------------------------------------------------------

        private void PrintStatus()
        {
            var values = _game.GetCurrentRound().HandToList();

            Console.WriteLine("\nTärningar:");
            string diceArt = AsciiArt.BuildDiceFaces(values);
            Console.WriteLine(diceArt);

            Console.WriteLine("Värden: " + string.Join(", ", values));
            Console.WriteLine("Rundpoäng: " + _game.GetCurrentRound().GetPoints());
            Console.WriteLine("Totalpoäng: " + _game.GetTotalPoints());
            Console.WriteLine("Antal rundor: " + _game.GetRounds());
        }
        --------------------------------------------------------------------------------

        private void ShowToplist()
        {
            var list = FileHandler.ReadResults();

            if (list.Count == 0)
            {
                Console.WriteLine("\nTopplistan är tom.");
                return;
            }

            List entries = new List();

            foreach (string line in list)
            {
                string[] parts = line.Split(',');

                if (parts.Length >= 4)
                {
                    TopplisteRekord entry = new TopplisteRekord();
                    entry.Dice = int.Parse(parts[0].Trim());
                    entry.Name = parts[1].Trim();
                    entry.Points = int.Parse(parts[2].Trim());
                    entry.Rounds = int.Parse(parts[3].Trim());
                    entries.Add(entry);
                }
            }

            for (int i = 0; i < entries.Count - 1; i++)
            {
                for (int j = 0; j < entries.Count - i - 1; j++)
                {
                    if (entries[j].Rounds > entries[j + 1].Rounds)
                    {
                        TopplisteRekord temp = entries[j];
                        entries[j] = entries[j + 1];
                        entries[j + 1] = temp;
                    }
                }
            }

            Console.WriteLine("\nTopplistan för dice100");
            Console.WriteLine("===========================================");
            Console.WriteLine("Rundor  Namn              Tärningar   Poäng");

            foreach (TopplisteRekord entry in entries)
            {
                Console.WriteLine($"{entry.Rounds,-8}{entry.Name,-18}{entry.Dice,-12}{entry.Points}");
            }

            Console.WriteLine("===========================================");
        }
        --------------------------------------------------------------------------------

        private void PrintRules()
        {
            Console.WriteLine("\n=== Regler för Dice100 ===");
            Console.WriteLine("Spelet går ut på att samla 100 poäng eller mer");
            Console.WriteLine("Varje runda kastar du tärningar och får poäng");
            Console.WriteLine("Om du får en etta i ett kast blir rundans poäng 0");
            Console.WriteLine("Du kan välja att Spara poäng för att lägga till rundans poäng till totalen");
            Console.WriteLine("Väljer du att slå igen riskerar du att få noll poäng för rundan");
            Console.WriteLine("Spelet avslutas när du når 100 poäng eller väljer att avsluta");
            Console.WriteLine("===========================");
        }
        --------------------------------------------------------------------------------

        private class TopplisteRekord
        {
            public int Dice { get; set; }
            public string Name { get; set; } = "";
            public int Points { get; set; }
            public int Rounds { get; set; }
        }
        --------------------------------------------------------------------------------
    }
}
                    
                

NumberOfDieException.cs ⌄

                    
using System;

namespace Dice100
{
    public class NumberOfDieException : Exception
    {
        public NumberOfDieException(string message) : base(message) { }
    }
}
                    
                

Round.cs ⌄

                    

using System;
using System.Collections.Generic;
using Dice100.src;


namespace Dice100
{
    public class Round
    {
        private List _hand;
        private int _points;
        private bool _hasRolled;

        public Round(int nbrOfDice)
        {
            _hand = new List();
            _hasRolled = false;
            _points = 0;

            for (int i = 0; i < nbrOfDice; i++)
                _hand.Add(new Die());
        }
        --------------------------------------------------------------------------------

        public Round() : this(5) { }
        public Round(List values)
        {
            _hand = new List();
            foreach (var val in values)
                _hand.Add(new Die(val));
            _hasRolled = true;
            UpdatePoints();
        }
        --------------------------------------------------------------------------------

        public void ClearPoints()
        {
            _points = 0;
            _hasRolled = false;
        }
        --------------------------------------------------------------------------------

        public int GetPoints() => _points;
        private void UpdatePoints()
        {
            if (!_hasRolled)
            {
                _points = 0;
                return;
            }
            int sum = 0;
            bool hasOne = false;

            foreach (var die in _hand)
            {
                int v = die.Value;
                if (v == 1) hasOne = true;
                sum += v;
            }
            _points = hasOne ? 0 : sum;
        }
        --------------------------------------------------------------------------------

        public void Roll()
        {
            foreach (var die in _hand)
                die.Roll();
            _hasRolled = true;
            UpdatePoints();
        }
        --------------------------------------------------------------------------------

        public List HandToList()
        {
            List list = new List();

            foreach (var die in _hand)
                list.Add(die.Value);
            return list;
        }
        --------------------------------------------------------------------------------

    }
}

                    
                

Program.cs ⌄

                    
using Dice100.src;

Menu menu = new Menu();
menu.Start();
                    
                

Kmom04Kursmoment03:Kodintervju

Purpose

The purpose is for the student to demonstrate their knowledge of the content in kmom01–03.

Prerequisites

How does it work?

We teachers ask questions related to code and/or UML. Duration: about 10–15 minutes.
You join via Zoom or come to the classroom. You answer the questions without any aids.