using Memory.Data; using Memory.Logic; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Data; using System.Windows.Media.Imaging; using System.ComponentModel; namespace Memory.Gui { public partial class MainWindow : Window, INotifyPropertyChanged { public const int SCOREPADDING = 160; public const int SCOREMARGIN = 30; public const int GRIDWIDTH = 700; public const int GRIDHEIGHT = 500; 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; OnPropertyChanged(nameof(DeckSize)); } } public event PropertyChangedEventHandler? PropertyChanged; public MainWindow() { InitializeComponent(); DataContext = this; } 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) { ErrorLabel.Visibility = Visibility.Visible; } 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; FinishScreen.Visibility = Visibility.Hidden; GameScreen.Visibility = Visibility.Visible; CreateGrid(); Redraw(); } } // 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(); OwnScore.Content = $"Your score: {game!.Scoring.Points}"; List highscores = game.ScoreHandler.GetTopScores(); for (int i = 0; i < highscores.Count; i++) { Score score = highscores[i]; Label label = new() { Content = $"{i+1}. {score.Name}: {score.Points}", HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Top, FontSize = 30, Margin = new Thickness(0, SCOREPADDING + SCOREMARGIN * i, 0, 0) }; Highscores.Children.Add(label); } } // Enable the finish screen with scores private void FinishGame() { DrawScores(); GameScreen.Visibility = Visibility.Hidden; FinishScreen.Visibility = Visibility.Visible; } // Draw grid private void CreateGrid() { Cards.ColumnDefinitions.Clear(); Cards.RowDefinitions.Clear(); Deck grid = Game.GetGridSize(DeckSize); int columns = grid.Columns; int rows = grid.Rows; for (int i = 0; i < columns; i++) { ColumnDefinition colDef = new() { Width = new(1, GridUnitType.Star) }; Cards.ColumnDefinitions.Add(colDef); } for (int i = 0; i < rows; i++) { RowDefinition rowDef = new() { Height = new(1, GridUnitType.Star) }; Cards.RowDefinitions.Add(rowDef); } if (rows > columns) { Cards.Width = GRIDWIDTH * (double)columns / rows; } else if (columns > rows) { Cards.Height = GRIDHEIGHT * (double)rows / columns; } } private void Redraw() { 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")), Stretch = Stretch.Fill, }; Button button = new() { Content = card.Selected() ? image : null, FontSize = 30, 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()) { Redraw(); } else { FinishGame(); } }; Cards.Children.Add(button); } } } } }