From 4c01b5ae792bf907b81fe35e7a6bfc1f459ff96f Mon Sep 17 00:00:00 2001 From: KaseToatz1337 Date: Thu, 7 Nov 2024 10:18:20 +0100 Subject: [PATCH] Add comments --- Memory.Cmd/CmdGame.cs | 10 ++++++++++ Memory.Cmd/Program.cs | 2 ++ Memory.Data/ScoreHandler.cs | 25 +++++++++++++++---------- Memory.Gui/MainWindow.xaml.cs | 12 +++++++++++- Memory.Logic/Game.cs | 5 +++++ 5 files changed, 43 insertions(+), 11 deletions(-) diff --git a/Memory.Cmd/CmdGame.cs b/Memory.Cmd/CmdGame.cs index d6b86bd..4412e94 100644 --- a/Memory.Cmd/CmdGame.cs +++ b/Memory.Cmd/CmdGame.cs @@ -6,6 +6,7 @@ namespace Memory.Cmd { private readonly Game game = game; + // Add 0 padding to numbers so they have the same width private string FormatNumber(int number) { string num = ""; @@ -20,11 +21,14 @@ namespace Memory.Cmd private void DrawCard(Card card, int index, int column, int row) { + // Format both the card index and the card number string num = FormatNumber(card.ID); string cardNr = FormatNumber(index); int cardWidth = game.DeckSize.ToString().Length + 4; + // Double for loop for drawing characters both vertically and horizontally for (int i = 0; i < game.GridSize; i++) { + // Set the cursor position so cards don't overlap Console.CursorLeft += (cardWidth + 1) * column; Console.CursorTop = i + (game.GridSize + 1) * row; for (int j = 0; j < cardWidth; j++) @@ -50,6 +54,7 @@ namespace Memory.Cmd } else if (i == game.GridSize / 2 && j > 1 && j < cardWidth - 2) { + // Write the card number if it is selected otherwise hide it with star symbols if (card.Selected()) { Console.Write(num[j - 2]); @@ -71,11 +76,13 @@ namespace Memory.Cmd public void Redraw() { Console.Clear(); + // Loop over all cards to draw them individually for (int i = 0; i < game.Cards.Count; i++) { Card card = game.Cards[i]; if (!card.Completed) { + // Set the color of the card based on if it's selected or not if (card.Selected()) { Console.ForegroundColor = ConsoleColor.Green; @@ -92,6 +99,7 @@ namespace Memory.Cmd public void WriteScores() { + // Print the players score to the console then loop over highscores to print those aswell Console.WriteLine($"Your score: {game.Scoring.Points}\nTop 10 Highscores:"); List highscores = game.ScoreHandler.GetTopScores(); for (int i = 0; i < highscores.Count; i++) @@ -101,6 +109,7 @@ namespace Memory.Cmd } } + // Ask for the player's name with checks if the name is valid public static string GetPlayerName() { Console.Write("Enter your name: "); @@ -113,6 +122,7 @@ namespace Memory.Cmd return name!; } + // Ask if the player wants to play again public static bool ShouldReplay() { Console.Write("Game Finished. Do you want to play again? (Y/N): "); diff --git a/Memory.Cmd/Program.cs b/Memory.Cmd/Program.cs index 3b229c4..00f135a 100644 --- a/Memory.Cmd/Program.cs +++ b/Memory.Cmd/Program.cs @@ -12,6 +12,7 @@ namespace Memory.Cmd { Game game = new(new ScoreHandler(), name, 10); CmdGame cmdGame = new(game); + // While the game isn't finished ask for a card index then attempt to click the card while (!game.IsFinished()) { cmdGame.Redraw(); @@ -24,6 +25,7 @@ namespace Memory.Cmd } Console.Clear(); cmdGame.WriteScores(); + // Ask if the player wants to play again, if not break out of the loop and the program is finished if (!CmdGame.ShouldReplay()) { break; diff --git a/Memory.Data/ScoreHandler.cs b/Memory.Data/ScoreHandler.cs index b403184..0703a3a 100644 --- a/Memory.Data/ScoreHandler.cs +++ b/Memory.Data/ScoreHandler.cs @@ -7,12 +7,24 @@ namespace Memory.Data { public const string URI = "Data Source=Scores.db;Version=3;"; - private bool IsTop10(int points) + // Ensure the database and table exist upon ScoreHandler creation + public ScoreHandler() + { + using SQLiteConnection connection = new(URI); + connection.Open(); + using SQLiteCommand command = new("CREATE TABLE IF NOT EXISTS Scores(ID INTEGER PRIMARY KEY, Name TEXT, Points INTEGER)", connection); + command.ExecuteNonQuery(); + connection.Close(); + } + + // Check if the score is higher than 10th place + private static bool IsTop10(int points) { using SQLiteConnection connection = new(URI); connection.Open(); using SQLiteCommand command = new("SELECT Points FROM Scores ORDER BY Points DESC LIMIT 1 OFFSET 9", connection); using SQLiteDataReader reader = command.ExecuteReader(); + // If there aren't atleast 10 highscores, return true by default if (!reader.Read()) { connection.Close(); @@ -23,15 +35,7 @@ namespace Memory.Data return points > lowest; } - public ScoreHandler() - { - using SQLiteConnection connection = new(URI); - connection.Open(); - using SQLiteCommand command = new("CREATE TABLE IF NOT EXISTS Scores(ID INTEGER PRIMARY KEY, Name TEXT, Points INTEGER)", connection); - command.ExecuteNonQuery(); - connection.Close(); - } - + // Get the top 10 highscores public List GetTopScores() { List scores = []; @@ -47,6 +51,7 @@ namespace Memory.Data return scores; } + // Write the new score to the database public bool WriteScore(Score score) { if (IsTop10(score.Points)) diff --git a/Memory.Gui/MainWindow.xaml.cs b/Memory.Gui/MainWindow.xaml.cs index 9b0323b..787e924 100644 --- a/Memory.Gui/MainWindow.xaml.cs +++ b/Memory.Gui/MainWindow.xaml.cs @@ -19,6 +19,7 @@ namespace Memory.Gui private Game? game; private int _deckSize = 5; + // Property with propertychanged listener to update it in the ui public int DeckSize { get => _deckSize; set { _deckSize = value; @@ -36,6 +37,7 @@ namespace Memory.Gui private void StartGame(object sender, RoutedEventArgs args) { + // Check if the name is valid, otherwise display error string name = Name.Text; if (name.Length > 32 || name.Length < 2) { @@ -43,6 +45,7 @@ namespace Memory.Gui } else { + // Hide startscreen and show gamescreen and create a grid and draw the cards game = new(new ScoreHandler(), name, DeckSize); ErrorLabel.Visibility = Visibility.Hidden; StartScreen.Visibility = Visibility.Hidden; @@ -53,10 +56,12 @@ namespace Memory.Gui } } + // Callback functions for changing the size of the deck protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); private void Decrease(object sender, RoutedEventArgs args) => DeckSize = Math.Max(DeckSize - 1, 2); private void Increase(object sender, RoutedEventArgs args) => DeckSize = Math.Min(DeckSize + 1, 10); + // Draw the highscores private void DrawScores() { Highscores.Children.Clear(); @@ -77,6 +82,7 @@ namespace Memory.Gui } } + // Enable the finish screen with scores private void FinishGame() { DrawScores(); @@ -84,6 +90,7 @@ namespace Memory.Gui FinishScreen.Visibility = Visibility.Visible; } + // Draw grid private void CreateGrid() { Cards.ColumnDefinitions.Clear(); @@ -121,11 +128,13 @@ namespace Memory.Gui { Cards.Children.Clear(); Deck grid = Game.GetGridSize(DeckSize); + // Loop over cards to draw them for (int i = 0; i < game!.Cards.Count; i++) { Card card = game.Cards[i]; if (!card.Completed) { + // Draw card with image if card isn't completed Image image = new() { Source = new BitmapImage(new($"pack://application:,,,/images/{card.ID}.png")), @@ -138,11 +147,12 @@ namespace Memory.Gui Background = new SolidColorBrush(card.Selected() ? Color.FromRgb(0, 255, 0) : Color.FromRgb(255, 0, 0)), Padding = new Thickness(0) }; - + // Set the card in the correct grid position Grid.SetColumn(button, i % grid.Columns); Grid.SetRow(button, i / grid.Columns); button.Click += (object sender, RoutedEventArgs args) => { + // Onclick check if game is finished game.ClickCard(card); if (!game.IsFinished()) { diff --git a/Memory.Logic/Game.cs b/Memory.Logic/Game.cs index 4c7e0f3..9088244 100644 --- a/Memory.Logic/Game.cs +++ b/Memory.Logic/Game.cs @@ -15,11 +15,13 @@ public int Attempts { get; set; } = 0; public Score Scoring { get; } = new(player, 0); + // Formula to calculate score public void CalculateScore(long endTime) { Scoring.Points = (int)(Math.Pow(DeckSize * 2, 2) / ((endTime - StartTime) / 1000.0 * Attempts) * 1000.0); } + // Get the optimal grid size for the current amount of cards public static Deck GetGridSize(int deckSize) { for (int i = (int)Math.Sqrt(deckSize * 2); i > 0; i--) @@ -32,6 +34,7 @@ return new(1, deckSize * 2); } + // Create a random set of cards public static List CreateDeck(int pairs) { List cards = []; @@ -65,6 +68,7 @@ Card? choice2 = GetChoice2(); if (!card.Completed) { + // Set the card to choice1 or choice2 depending on the context if ((choice1 == null && choice2 == null) || (choice1 != null && choice2 != null)) { if (choice1 != null) @@ -83,6 +87,7 @@ Attempts++; if (choice1.Matches(card)) { + // If card matches, mark as complete and check if the game is finished choice1.Completed = true; card.Completed = true; if (IsFinished())