Universal Windows Platform – Chase Game

Chase Game demonstrates how to create a game where after a certain amount of time four squares will appear then within a countdown you must select all of them and shows how to create a simple game mechanic based on time.

Step 1

If not already, follow Setup and Start on how to Install and get Started with Visual Studio 2017 or in Windows 10 choose Start, and then from the Start Menu find and select Visual Studio 2017.

vs2017

Step 2

Once Visual Studio Community 2017 has started, from the Menu choose File, then New then Project…

vs2017-file-new-project

Step 3

From New Project choose Visual C# from Installed, Templates then choose Blank App (Universal Windows) and then type in a Name and select a Location and then select Ok to create the Project
vs2017-new-project-window

Step 4

Then in New Universal Windows Project you need to select the Target Version this should be at least the Windows 10, version 1803 (10.0; Build 17134) which is the April 2018 Update and the Minimum Version to be the same.

vs2017-target-platform

The Target Version will control what features your application can use in Windows 10 so by picking the most recent version you’ll be able to take advantage of those features. To make sure you always have the most recent version, in Visual Studio 2017 select Tools Extensions and Updates… then and then see if there are any Updates

Step 5

Once done select from the Menu, Project, then Add New Item…

vs2017-project-add-new-item

Step 6

From the Add New Item window select Visual C#, then Code from Installed then select Code File from the list, then type in the Name as Library.cs before selecting Add to add the file to the Project

vs2017-add-new-item-library

Step 7

Once in the Code View for Library.cs the following should be entered:

using System;
using System.Collections.Generic;
using System.Linq;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Shapes;

public class Library
{
    private const int size = 4;
    private const int on = 1;
    private const int off = 0;

    private readonly Color light_on = Colors.White;
    private readonly Color light_off = Colors.Black;

    private int[,] _board = new int[size, size];
    private DispatcherTimer _timer = null;
    private Random _random = new Random((int)DateTime.Now.Ticks);
    private List _positions = new List();
    private int _counter = 0;
    private int _turns = 0;
    private int _hits = 0;
    private int _wait = 0;
    private bool _waiting = false;
    private bool _lost = false;

    private List Shuffle(int start, int end, int total)
    {
        return Enumerable.Range(start, total).OrderBy(r => _random.Next(start, end)).ToList();
    }

    private Rectangle Get(Color foreground)
    {
        Rectangle rect = new Rectangle()
        {
            Height = 80,
            Width = 80,
            Fill = new SolidColorBrush(foreground)
        };
        return rect;
    }

    private void Set(ref Grid grid, int row, int column)
    {
        Button button = (Button)grid.Children.Single(
                       w => Grid.GetRow((Button)w) == row
                       && Grid.GetColumn((Button)w) == column);
        button.Content = Get(_board[row, column] == on ? light_on : light_off);
    }

    private void Add(Grid grid, TextBlock text, int row, int column, int index)
    {
        string name = string.Empty;
        Button button = new Button()
        {
            Height = 100,
            Width = 100,
            Content = Get(light_off)
        };
        button.Click += (object sender, RoutedEventArgs e) =>
        {
            if (!_lost)
            {
                button = (Button)sender;
                row = (int)button.GetValue(Grid.RowProperty);
                column = (int)button.GetValue(Grid.ColumnProperty);
                if (_board[row, column] == on)
                {
                    _board[row, column] = off;
                    Set(ref grid, row, column);
                    _hits++;
                }
                else
                {
                    _lost = true;
                }
            }
            else
            {
                text.Text = $"Game Over in {_turns} Turns!";
            }
        };
        button.SetValue(Grid.ColumnProperty, column);
        button.SetValue(Grid.RowProperty, row);
        grid.Children.Add(button);
    }

    private void Layout(ref Grid grid, ref TextBlock text)
    {
        text.Text = string.Empty;
        grid.Children.Clear();
        grid.ColumnDefinitions.Clear();
        grid.RowDefinitions.Clear();
        // Setup Grid
        for (int layout = 0; layout < size; layout++)
        {
            grid.RowDefinitions.Add(new RowDefinition());
            grid.ColumnDefinitions.Add(new ColumnDefinition());
        }
        // Setup Board
        int index = 0;
        for (int column = 0; column < size; column++)
        {
            for (int row = 0; row < size; row++)
            {
                Add(grid, text, row, column, index);
                index++;
            }
        }
    }

    private void Reset(Grid grid)
    {
        for (int column = 0; column < size; column++)
        {
            for (int row = 0; row < size; row++)
            {
                _board[row, column] = off;
                Set(ref grid, row, column);
            }
        }
        _hits = 0;
        _counter = 0;
        _wait = Shuffle(3, 7, 1).First();
        _waiting = true;
    }

    private void Choose(Grid grid)
    {
        int row = 0;
        int column = 0;
        _positions = Shuffle(0, _board.Length, _board.Length);
        for (int i = 0; i < size; i++)
        {
            column = _positions[i] % size;
            switch (_positions[i])
            {
                case int n when n = 4 && n = 8 && n = 12 && n 
        {
            if (!_lost)
            {
                int countdown = 0;
                if (_waiting)
                {
                    countdown = (_wait - _counter) + 1;
                    text.Text = $"Waiting {countdown}";
                    if (countdown == 0)
                    {
                        text.Text = string.Empty;
                        Choose(grid);
                    }
                }
                else
                {
                    countdown = (size - _counter) + 1;
                    text.Text = $"Solve In {countdown}";
                    if (countdown == 0)
                    {
                        if (_hits == size)
                        {
                            _turns++;
                            text.Text = string.Empty;
                            Reset(grid);
                        }
                        else
                        {
                            _lost = true;
                            text.Text = $"Game Over in {_turns} Turns!";
                            Reset(grid);
                        }
                    }
                }
                _counter++;
            }
        };
        _timer.Start();
    }

    public void New(ref Grid grid, ref TextBlock text)
    {
        _lost = false;
        _waiting = true;
        _wait = 3;
        _turns = 1;
        Layout(ref grid, ref text);
        Timer(grid, text);
    }
}

Within the Library Class there’s some int values for On and Off states plus a corresponding Color for each of these, there’s a int[,] for the game board plus the DispatcherTimer which will be used as the timer – the usual random number generator for a game is used along with variables for state information. There is the Shuffle method that uses the random number generator to generate a sequence of numbers but with “start”, “end” and “total” parameters and the Get method returns a Rectangle with a given Foreground colour, also there’s a Set method to set a Button to use that Get method. The Add method creates a Button with a Click event that will get the Row and Column and if it is “lit up” then it will set that to off otherwise it will count as a miss and the game will be over – controlled by lost variable being set to true.

The Layout method creates the initial layout for the game and Reset will clear the board so that all the Button elements will appear in their Off state, Choose uses the Shuffle method to randomly select which four Button elements will appear in the On state. The Timer method is what controls the flow of the game with the first part of this checking for an existing Timer and stopping and clearing it – by setting to null then a new DispatcherTimer is created with a one second interval then on the Tick event of the time which will occur each second there is a check to see if the game is “lost” then two countdowns for either a Waiting or Solve In countdown – the former will have a random time used which is set from the Reset method or a four second countdown to solve the puzzle by clicking on the buttons.

Step 8

In the Solution Explorer select MainPage.xaml

vs2017-mainpage-library

Step 9

From the Menu choose View and then Designer

vs2017-view-designer

Step 10

The Design View will be displayed along with the XAML View and in this between the Grid and /Grid elements, enter the following XAML:

<Viewbox Margin="50">
	<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
		<TextBlock Name="Label" TextAlignment="Center" HorizontalAlignment="Center" 
		Style="{StaticResource SubtitleTextBlockStyle}" Width="400"/>
		<Grid Name="Display" HorizontalAlignment="Center" Height="400" Width="400"/>
	</StackPanel>
</Viewbox>
<CommandBar VerticalAlignment="Bottom">
	<AppBarButton Icon="Page2" Label="New" Click="New_Click"/>
</CommandBar>

The first block of XAML the main user interface of the Game, this features a ViewBox containing a StackPanel with a TextBlock and a Grid to display the game itself within. The second block of XAML is is the CommandBar which contains New to start a Game

Step 11

From the Menu choose View and then Code

vs2017-view-code

Step 12

Once in the Code View, below the end of public MainPage() { … } the following Code should be entered:

Library library = new Library();

private void New_Click(object sender, RoutedEventArgs e)
{
	library.New(ref Display, ref Label);
}

Below the MainPage() Method an instance of the Library Class is created, then New_Click is used to call the New Method to setup the game and start playing.

Step 13

That completes the Universal Windows Platform Application so Save the Project then in Visual Studio select the Local Machine to run the Application

vs2017-local-machine

Step 14

After the Application has started running you can then select New to start the game then begins a timer which will be displayed on the TextBlock with Waiting Countdown and once complete a Random selection of Squares will be lit up White within a set of Black squares and you need to hit them all within the Solve Countdown otherwise it will be Game Over and you can keep going for as many Turns as you can!

ran-chase-game

Step 15

To Exit the Application select the Close button in the top right of the Application

vs2017-close

There are many games based on this concept but this is just a simple way of creating a timer based game. The concept of a game loop is common to games large and small and it was a good excuse to use this and show it off, the timer interval is probably too long but make it easy to see what’s going on, if want to increase the difficulty could reduce the tick interval to half or even a quarter of a second, that might make it more interesting as if you hit the black buttons you’ll lose which is more likely the faster you make it! The concept of using a timer to drive the game can be used to create any kind of game so this example was just a simple way of doing that without the game itself being too complex, although as-is the game is very easy to play, just need to make those modifications!

Creative Commons License

Advertisements

Universal Windows Platform – Flags Game

Flags Game demonstrates how to create a flag-based game where you need to choose which is the correct flag based on the country name displayed and if you get them all correct you win and also a good way to learn a small selection of the world’s flags and maybe even get into vexillology – which is the study or interest in flags.

Step 1

If not already, follow Setup and Start on how to Install and get Started with Visual Studio 2017 or in Windows 10 choose Start, and then from the Start Menu find and select Visual Studio 2017.

vs2017

Step 2

Once Visual Studio Community 2017 has started, from the Menu choose File, then New then Project…

vs2017-file-new-project

Step 3

From New Project choose Visual C# from Installed, Templates then choose Blank App (Universal Windows) and then type in a Name and select a Location and then select Ok to create the Project
vs2017-new-project-window

Step 4

Then in New Universal Windows Project you need to select the Target Version this should be at least the Windows 10, version 1803 (10.0; Build 17134) which is the April 2018 Update and the Minimum Version to be the same.

vs2017-target-platform

The Target Version will control what features your application can use in Windows 10 so by picking the most recent version you’ll be able to take advantage of those features. To make sure you always have the most recent version, in Visual Studio 2017 select Tools Extensions and Updates… then and then see if there are any Updates

Step 5

Once done select from the Menu, Project, then Add New Item…

vs2017-project-add-new-item

Step 6

From the Add New Item window select Visual C#, then Code from Installed then select Code File from the list, then type in the Name as Library.cs before selecting Add to add the file to the Project

vs2017-add-new-item-library

Step 7

Once in the Code View for Library.cs the following should be entered:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Windows.Foundation;
using Windows.UI;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Shapes;

public class Flag
{
    public enum Designs
    {
        HorizonalStripes = 1,
        VerticalStripes = 2
    };
    public Designs Design { get; set; }
    public string Name { get; set; }
    public string[] Colours { get; set; }
}

public class Library
{
    private const string app_title = "Flags Game";
    private const int size = 3;

    private readonly List flags = new List()
    {
        new Flag() {
            Name = "Armenia",
            Design = Flag.Designs.HorizonalStripes,
            Colours = new string[] { "DE1018", "002984", "EF7b21" }
        },
        new Flag()
        {
            Name = "Austria",
            Design = Flag.Designs.HorizonalStripes,
            Colours = new string[] { "DE1018", "FFFFFF", "DE1018" }
        },
        new Flag()
        {
            Name = "Belgium",
            Design = Flag.Designs.VerticalStripes,
            Colours = new string[] { "000000", "FFEF08", "DE1018" }
        },
        new Flag()
        {
            Name = "Bulgaria",
            Design = Flag.Designs.HorizonalStripes,
            Colours = new string[] { "FFFFFF", "109452", "DE1018" }
        },
        new Flag()
        {
            Name = "Estonia",
            Design = Flag.Designs.HorizonalStripes,
            Colours = new string[] { "295AA5", "000000", "FFFFFF" }
        },
        new Flag()
        {
            Name = "France",
            Design = Flag.Designs.VerticalStripes,
            Colours = new string[] { "080863", "FFFFFF", "D60818" }
        },
        new Flag() {
            Name = "Gabon",
            Design = Flag.Designs.HorizonalStripes,
            Colours = new string[] { "109452", "FFEF08", "002984" }
        },
        new Flag()
        {
            Name = "Germany",
            Design = Flag.Designs.HorizonalStripes,
            Colours = new string[] { "000000", "DE0008", "FFDE08" }
        },
        new Flag()
        {
            Name = "Guinea",
            Design = Flag.Designs.VerticalStripes,
            Colours = new string[] { "DE1018", "FFEF08", "109452" }
        },
        new Flag()
        {
            Name = "Hungary",
            Design = Flag.Designs.HorizonalStripes,
            Colours = new string[] { "DE0008", "FFFFFF", "087B39" }
        },
        new Flag()
        {
            Name = "Ireland",
            Design = Flag.Designs.VerticalStripes,
            Colours = new string[] { "007339", "FFFFFF", "E76300" }
        },
        new Flag()
        {
            Name = "Italy",
            Design = Flag.Designs.VerticalStripes,
            Colours = new string[] { "109452", "FFFFFF", "DE1018" }
        },
        new Flag()
        {
            Name = "Lithuania",
            Design = Flag.Designs.HorizonalStripes,
            Colours = new string[] { "FFEF08", "109452", "DE1018" }
        },
        new Flag()
        {
            Name = "Luxembourg",
            Design = Flag.Designs.HorizonalStripes,
            Colours = new string[] { "DE1018", "FFFFFF", "2984B5" }
        },
        new Flag()
        {
            Name = "Mali",
            Design = Flag.Designs.VerticalStripes,
            Colours = new string[] { "109452", "FFEF08", "DE1018" }
        },
        new Flag()
        {
            Name = "Netherlands",
            Design = Flag.Designs.HorizonalStripes,
            Colours = new string[] { "DE1018", "FFFFFF", "002984" }
        },
        new Flag()
        {
            Name = "Nigeria",
            Design = Flag.Designs.VerticalStripes,
            Colours = new string[] { "087B39", "FFFFFF", "087B39" }
        },
        new Flag()
        {
            Name = "Romania",
            Design = Flag.Designs.VerticalStripes,
            Colours = new string[] { "002984", "FFEF08", "DE1018" }
        },
        new Flag()
        {
            Name = "Russia",
            Design = Flag.Designs.HorizonalStripes,
            Colours = new string[] { "FFFFFF", "0852A5", "DE1018" }
        },
        new Flag()
        {
            Name = "Sierra Leone",
            Design = Flag.Designs.HorizonalStripes,
            Colours = new string[] { "5AB521", "FFFFFF", "0852A5" }
        },
        new Flag()
        {
            Name = "Yemen",
            Design = Flag.Designs.HorizonalStripes,
            Colours = new string[] { "DE1018", "FFFFFF", "000000" }
        }
    };

    private Random _random = new Random((int)DateTime.Now.Ticks);
    private List _indexes = new List();
    private List _choices = new List();
    private int _turns = 0;
    private string _country = string.Empty;
    private bool _lost = false;

    public Color ConvertHexToColor(string hex)
    {
        hex = hex.Remove(0, 1);
        byte a = hex.Length == 8 ? Byte.Parse(hex.Substring(0, 2), NumberStyles.HexNumber) : (byte)255;
        byte r = Byte.Parse(hex.Substring(hex.Length - 6, 2), NumberStyles.HexNumber);
        byte g = Byte.Parse(hex.Substring(hex.Length - 4, 2), NumberStyles.HexNumber);
        byte b = Byte.Parse(hex.Substring(hex.Length - 2), NumberStyles.HexNumber);
        return Color.FromArgb(a, r, g, b);
    }

    private List Shuffle(int start, int total)
    {
        return Enumerable.Range(start, total).OrderBy(r => _random.Next(start, total)).ToList();
    }

    public void Show(string content, string title)
    {
        IAsyncOperation command = new MessageDialog(content, title).ShowAsync();
    }

    private Viewbox GetFlag(ref string name, int index)
    {
        int pos = _indexes[index];
        Flag flag = flags[pos];
        name = flag.Name;
        bool horizontal = flag.Design == Flag.Designs.HorizonalStripes;
        StackPanel panel = new StackPanel()
        {
            Height = 120,
            Width = 120,
            Orientation = horizontal ? Orientation.Vertical : Orientation.Horizontal
        };
        for (int f = 0; f 
        {
            if (!_lost)
            {
                string current = ((Button)sender).Name;
                if (_country == current)
                {
                    SetButton(ref grid, current, false);
                    if (_turns < 9)
                    {
                        Choose(ref grid, ref text);
                    }
                    else
                    {
                        text.Text = string.Empty;
                        Show("You Won!", app_title);
                    }
                }
                else
                {
                    _lost = true;
                }
            }
            if (_lost)
            {
                Show("Game Over!", app_title);
            }
        };
        button.SetValue(Grid.ColumnProperty, column);
        button.SetValue(Grid.RowProperty, row);
        grid.Children.Add(button);
    }

    private void Layout(ref Grid grid, ref TextBlock text)
    {
        text.Text = string.Empty;
        grid.Children.Clear();
        grid.ColumnDefinitions.Clear();
        grid.RowDefinitions.Clear();
        // Setup Grid
        for (int layout = 0; layout < size; layout++)
        {
            grid.RowDefinitions.Add(new RowDefinition());
            grid.ColumnDefinitions.Add(new ColumnDefinition());
        }
        // Setup Board
        int index = 0;
        for (int column = 0; column < size; column++)
        {
            for (int row = 0; row < size; row++)
            {
                Add(grid, text, row, column, index);
                index++;
            }
        }
    }

    private void Choose(ref Grid grid, ref TextBlock text)
    {
        int choice = _choices[_turns];
        int index = _indexes[choice];
        _country = flags[index].Name;
        text.Text = _country;
        _turns++;
    }

    public void New(ref Grid grid, ref TextBlock text)
    {
        _lost = false;
        _turns = 0;
        text.Text = string.Empty;
        _indexes = Shuffle(0, flags.Count);
        _choices = Shuffle(0, 9);
        Layout(ref grid, ref text);
        Choose(ref grid, ref text);
    }
}

There’s a Class to represent a Flag with Design property for the Designs possible with either HorizontalStripes or VerticalStripes, then a Name and list of Colours for the flag. In the main Class there’s a list of flags with each Country’s flag properties set to the correct Design and Colours. There’s a Random number generator plus a list of indexes and choices, also there’s a ConvertHexToColor method which converts the colour used in a flag to a system Color that can be used plus there’s a Shuffle method to use the random number generator to create a list of values and a Show method to display a message on screen.

The GetFlag method helps to create the correct look of a flag using a StackPanel with the correct Orientation based on the Design then creates a Rectangle for each colour in the correct Height and Width for the Design. There’s a SetButton method which will set a Button to be visible or not by setting the Opacity, the Add method is used to add all the flags plus this handles when you guess all nine and win the game by showing a message, the Layout method sets up the game to show all the flags and the Choose method gets the next flag to choose and the name of the country’s flag to find with the New method starting the game and setting the first flag to find.

Step 8

In the Solution Explorer select MainPage.xaml

vs2017-mainpage-library

Step 9

From the Menu choose View and then Designer

vs2017-view-designer

Step 10

The Design View will be displayed along with the XAML View and in this between the Grid and /Grid elements, enter the following XAML:

<Viewbox Margin="50">
	<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
		<TextBlock Name="Label" TextAlignment="Center" HorizontalAlignment="Center" 
		Style="{StaticResource SubtitleTextBlockStyle}" Width="400"/>
		<Grid Name="Display" HorizontalAlignment="Center" Height="400" Width="400"/>
	</StackPanel>
</Viewbox>
<CommandBar VerticalAlignment="Bottom">
	<AppBarButton Icon="Page2" Label="New" Click="New_Click"/>
</CommandBar>

The first block of XAML the main user interface of the Game, this features a ViewBox containing a StackPanel with a TextBlock to show the Country Flag to guess and a Grid to display the game itself within. The second block of XAML is is the CommandBar which contains New to start a Game

Step 11

From the Menu choose View and then Code

vs2017-view-code

Step 12

Once in the Code View, below the end of public MainPage() { … } the following Code should be entered:

Library library = new Library();

private void New_Click(object sender, RoutedEventArgs e)
{
	library.New(ref Display, ref Label);
}

Below the MainPage() Method an instance of the Library Class is created, then New_Click is used to call the New Method to setup the game and start playing.

Step 13

That completes the Universal Windows Platform Application so Save the Project then in Visual Studio select the Local Machine to run the Application

vs2017-local-machine

Step 14

After the Application has started running you can then select New to start the game then nine Flags will be displayed and on the Label there will be displayed a Country and you need to guess the correct Flag if you guessed incorrectly then it will be Game Over otherwise you can keep going until you get all nine to Win!

ran-flags-game

Step 15

To Exit the Application select the Close button in the top right of the Application

vs2017-close

There’s a lot to be said for having fun with flags and interesting to see how similar the world’s flags are and there’s the whole subject of vexillology to get into if you want, the selection of flags used was chosen because each of the country’s flags are just solid colours – there’s Argentina or Spain that could be used or Canada but each of these has an extra element such as the Maple leaf which if missed off wouldn’t be correct and with this example it was important to include flags only made of solid colours and to make it easier with three horizontal or vertical stripes. For those who do have an interest in flags may notice that some of the proportions of the coloured bands isn’t 100% correct such as with Nigeria or France but hopefully the representations of all the flags is as those who call those countries home would be happy with and it would be possible to add more designs and add more flags such as the Union Flag for the United Kingdom or for other countries such as the United States of America or South Africa. Hopefully it’s a fun game to play and to learn from and a chance to learn to identify a small selection of world flags!

Creative Commons License

Universal Windows Platform – Codes Game

Codes Game demonstrates how to create a game where you need to guess the correct combination of four numbers between 1 and 4 – when you check your guess any incorrect ones will show with a black background and white text.

Step 1

If not already, follow Setup and Start on how to Install and get Started with Visual Studio 2017 or in Windows 10 choose Start, and then from the Start Menu find and select Visual Studio 2017.

vs2017

Step 2

Once Visual Studio Community 2017 has started, from the Menu choose File, then New then Project…

vs2017-file-new-project

Step 3

From New Project choose Visual C# from Installed, Templates then choose Blank App (Universal Windows) and then type in a Name and select a Location and then select Ok to create the Project
vs2017-new-project-window

Step 4

Then in New Universal Windows Project you need to select the Target Version this should be at least the Windows 10, version 1803 (10.0; Build 17134) which is the April 2018 Update and the Minimum Version to be the same.

vs2017-target-platform

The Target Version will control what features your application can use in Windows 10 so by picking the most recent version you’ll be able to take advantage of those features. To make sure you always have the most recent version, in Visual Studio 2017 select Tools Extensions and Updates… then and then see if there are any Updates

Step 5

Once done select from the Menu, Project, then Add New Item…

vs2017-project-add-new-item

Step 6

From the Add New Item window select Visual C#, then Code from Installed then select Code File from the list, then type in the Name as Library.cs before selecting Add to add the file to the Project

vs2017-add-new-item-library

Step 7

Once in the Code View for Library.cs the following should be entered:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows.Input;
using Windows.Foundation;
using Windows.UI;
using Windows.UI.Popups;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;

public class CommandHandler : ICommand
{
    public event EventHandler CanExecuteChanged = null;
    private Action _action;

    public CommandHandler(Action action)
    {
        _action = action;
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        _action();
    }
}

public class Code : INotifyPropertyChanged
{
    private int _value;
    private SolidColorBrush _foreground;
    private SolidColorBrush _background;

    public virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public int Index { get; set; }
    public int Value { get { return _value; } set { _value = value; OnPropertyChanged("Value"); } }
    public SolidColorBrush Foreground { get { return _foreground; } set { _foreground = value; OnPropertyChanged("Foreground"); } }
    public SolidColorBrush Background { get { return _background; } set { _background = value; OnPropertyChanged("Background"); } }
    public Func Action { get; set; }
    public ICommand Command { get { return new CommandHandler(() =&gt; this.Action(Index)); } }
    public event PropertyChangedEventHandler PropertyChanged;
}

public class Library
{
    private const string app_title = "Codes Game";
    private const int size = 4;

    private ObservableCollection<Code> _codes = new ObservableCollection<Code>();
    private Random _random = new Random((int)DateTime.Now.Ticks);
    private List _numbers = new List();
    private int _turns = 0;

    private List Shuffle(int start, int total)
    {
        return Enumerable.Range(start, total).OrderBy(r =&gt; _random.Next(start, total)).ToList();
    }

    public void Show(string content, string title)
    {
        IAsyncOperation command = new MessageDialog(content, title).ShowAsync();
    }

    private Code GetCode(int value, int index)
    {
        return new Code()
        {
            Action = (int i) =&gt;
            {
                Code code = _codes[i];
                code.Value = (code.Value == size) ? 1 : code.Value + 1;
                code.Foreground = new SolidColorBrush(Colors.Black);
                code.Background = new SolidColorBrush(Colors.WhiteSmoke);
                return code.Value;
            },
            Index = index,
            Value = value,
            Foreground = new SolidColorBrush(Colors.Black),
            Background = new SolidColorBrush(Colors.WhiteSmoke)
        };
    }

    private bool Check(int number, int index)
    {
        Code code = _codes[index];
        if (number == code.Value)
        {
            code.Foreground = new SolidColorBrush(Colors.Black);
            code.Background = new SolidColorBrush(Colors.WhiteSmoke);
            return true;
        }
        else
        {
            code.Foreground = new SolidColorBrush(Colors.WhiteSmoke);
            code.Background = new SolidColorBrush(Colors.Black);
            return false;
        }
    }

    public void New(ref ItemsControl items)
    {
        _turns = 0;
        _codes.Clear();
        for (int i = 0; i &lt; size; i++)
        {
            _codes.Add(GetCode(i + 1, i));
        }
        items.ItemsSource = _codes;
        _numbers = Shuffle(1, size);
    }

    public void Accept(ref ItemsControl items)
    {
        int index = 0;
        int correct = 0;
        foreach (int number in _numbers)
        {
            if (Check(number, index))
            {
                correct++;
            }
            index++;
        }
        _turns++;
        if (correct == size)
        {
            Show($&quot;You got all the numbers correct in {_turns} turns!&quot;, app_title);
            New(ref items);
        }
    }
}

In the Codes Game there’s a CommandHandler Class that will help handle any commanding events and actions from the Library Class. There’s also a Code class which represents a Number that will be displayed and defines the Index, Value plus Foreground and Background colours, then there’s the Action and the commanding Commmand plus this Class implements the INotifiedPropertyChanged event to help update UI for any changes in value.

Within the Library Class there’s an ObservableCollection used – this when any changes happen to it will also help update the UI for any changes as also uses INotifiedPropertyChanged, then there’s the Random number generator and list of numbers. There’s a Show method to display any messages on screen, the GetCode method helps create an instance of Code with the given values – it also sets up the Action Method which will determine what happens when during commanding. There’s a Check method to see if a guess has been correct and sets the Foreground and Background accordingly and there’s a Shuffle method to use the Random number generator. The New method starts the game and sets up the sequence of numbers to be guessed and the Accept method is used to confirm the selection and sees how many are correct, get them all and a message is displayed.

The layout of Code Game requires more XAML code to make the layout work, this is comprised of an ItemsControl which is used to display basic lists and within this there’s a DataTemplate which defines what each item in the list looks like and this is a Button which uses Data Binding to set various properties such as Background, Foreground, Value and Command – this last item is the commanding operation of the Button which is performed using the CommandHandler and performs the Action specified which is to cycle through the numbers 1 to 4 and guessing a number correctly or incorrectly determines what the Background and Foreground will be which is set against the Code class and when these values change the INotifiedPropertyChanged event is triggered and the UI knows to display the latest values.

Step 8

In the Solution Explorer select MainPage.xaml

vs2017-mainpage-library

Step 9

From the Menu choose View and then Designer

vs2017-view-designer

Step 10

The Design View will be displayed along with the XAML View and in this between the Grid and /Grid elements, enter the following XAML:

<Viewbox Margin="50">
	<ItemsControl Name="Display">
		<ItemsControl.ItemTemplate>
			<DataTemplate>
				<Button Height="100" Width="100" Background="{Binding Background}" Command="{Binding Command}">
					<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center"
					FontSize="60" Foreground="{Binding Foreground}" Text="{Binding Value}"/>
				</Button>
			</DataTemplate>
		</ItemsControl.ItemTemplate>
		<ItemsControl.ItemsPanel>
			<ItemsPanelTemplate>
				<StackPanel Orientation="Horizontal"/>
			</ItemsPanelTemplate>
		</ItemsControl.ItemsPanel>
	</ItemsControl>
</Viewbox>
<CommandBar VerticalAlignment="Bottom">
	<AppBarButton Icon="Page2" Label="New" Click="New_Click"/>
	<AppBarButton Icon="Accept" Label="Accept" Click="Accept_Click"/>
</CommandBar>

The first block of XAML the main user interface of the Game, this features a ViewBox containing an ItemsControl and has a DataTemplate defined with a Button which will form part of the look-and-feel of the game, there’s also a ItemsPanelTemplate to define the layout of the Button Controls. The second block of XAML is is the CommandBar which contains New – to start a Game and Accept to confirm the currently selected set of four numbers is the correct combination.

Step 11

From the Menu choose View and then Code

vs2017-view-code

Step 12

Once in the Code View, below the end of public MainPage() { … } the following Code should be entered:

Library library = new Library();

private void New_Click(object sender, RoutedEventArgs e)
{
	library.New(ref Display);
}

private void Accept_Click(object sender, RoutedEventArgs e)
{
	library.Accept(ref Display);
}

Below the MainPage() Method an instance of the Library Class is created, then New_Click is used to call the New Method to setup the game and start playing. Accept_Click triggers the Accept Method in the Library Class.

Step 13

That completes the Universal Windows Platform Application so Save the Project then in Visual Studio select the Local Machine to run the Application

vs2017-local-machine

Step 14

After the Application has started running you can then select New to start the game then four numbers between 1 and 4 then you need to guess the secret combination by selecting those numbers you can go through them to find that combination and once happy select Accept if you guessed a number incorrectly then it will turn Black with White text or if correct it will remain the same and if all of them are the same as the secret combination of numbers then you win.

ran-codes-game

Step 15

To Exit the Application select the Close button in the top right of the Application

vs2017-close

In this example a CommandHandler has been used to perform an action on a Button but given the game mechanic of needing to click on the numbers to cycle through the values and then display whether a selection was right or wrong using it meant everything could work through Data Binding which again is a technique that’s not been used much in previous examples. The inspiration behind the game came from number guessing games and the goal was to create a simple to play game that helped show off what can be done with Data Binding and to use commanding rather than Event Handlers.

Creative Commons License

Universal Windows Platform – High or Low

High or Low demonstrates how to create a Card-based game where you need to guess if the next card is Higher or Lower than the last – this ignores the suit so the Eight of Diamonds is higher than the Six of Hearts but mainly shows how to create realistic looking playing cards.

Step 1

If not already, follow Setup and Start on how to Install and get Started with Visual Studio 2017 or in Windows 10 choose Start, and then from the Start Menu find and select Visual Studio 2017.

vs2017

Step 2

Once Visual Studio Community 2017 has started, from the Menu choose File, then New then Project…

vs2017-file-new-project

Step 3

From New Project choose Visual C# from Installed, Templates then choose Blank App (Universal Windows) and then type in a Name and select a Location and then select Ok to create the Project
vs2017-new-project-window

Step 4

Then in New Universal Windows Project you need to select the Target Version this should be at least the Windows 10, version 1803 (10.0; Build 17134) which is the April 2018 Update and the Minimum Version to be the same.

vs2017-target-platform

The Target Version will control what features your application can use in Windows 10 so by picking the most recent version you’ll be able to take advantage of those features. To make sure you always have the most recent version, in Visual Studio 2017 select Tools Extensions and Updates… then and then see if there are any Updates

Step 5

Once done select from the Menu, Project, then Add New Item…

vs2017-project-add-new-item

Step 6

From the Add New Item window select Visual C#, then Code from Installed then select Code File from the list, then type in the Name as Library.cs before selecting Add to add the file to the Project

vs2017-add-new-item-library

Step 7

Once in the Code View for Library.cs the following should be entered:

using System;
using System.Collections.Generic;
using System.Linq;
using Windows.Foundation;
using Windows.UI;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Markup;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Shapes;

public class Library
{
    private const string app_title = "High or Low";
    private const string club = "M 19.5155,51.3 C 17.1155,50.1 15.9155,43.7 " +
        "21.5155,43.7 C 27.1155,43.7 25.9155,50.1 23.5155,51.3 C 25.1155,50.1 " +
        "30.3155,48.5 30.3155,54.1 C 30.3155,59.7 23.1155,59.3 22.7155,54.9 L " +
        "21.9155,54.9 C 21.9155,54.9 22.3155,59.3 23.5155,61.3 L 19.5155,61.3 C " +
        "20.7155,59.3 21.1155,54.9 21.1155,54.9 L 20.3155,54.9 C 19.9155,59.3 " +
        "12.3155,59.7 12.3155,54.1 C 12.3155,49.3 17.9155,50.1 19.5155,51.3 z";
    private const string diamond = "M 170.1155,199.8 L 177.3155,191 L 184.5155,199.4 " +
        "L 177.3155,209 L 170.1155,199.8 z";
    private const string heart = "M 99.5,99.75 C 99.5,93.75 89.5,81.75 79.5,81.75 C " +
        "69.5,81.75 59.5,89.75 59.5,103.75 C 59.5,125.75 91.5,161.75 99.5,171.75 C " +
        "107.5,161.75 139.5,125.75 139.5,103.75 C 139.5,89.75 129.5,81.75 119.5,81.75 C " +
        "109.45012,81.75 99.5,93.75 99.5,99.75 z";
    private const string spade = "M 21.1155,43.3 C 17.9155,48.1 13.7155,50.9 13.7155,54.9 " +
        "C 13.7155,58.5 15.7155,59.3 16.9155,59.3 C 18.5155,59.3 19.7155,58.5 19.7155,55.7 " +
        "C 19.7155,54.9 20.5155,54.9 20.5155,55.7 C 20.5155,59.7 19.7155,59.7 18.9155,61.7 " +
        "L 23.3155,61.7 C 22.5155,59.7 21.7155,59.7 21.7155,55.7 C 21.7155,54.9 22.5155,54.9 " +
        "22.5155,55.7 C 22.5155,58.9 23.7155,59.3 25.3155,59.3 C 26.5155,59.3 28.9155,58.5 " +
        "28.9155,54.9 C 28.9155,50.84784 24.3155,48.1 21.1155,43.3 z";

    private string[] card_pips = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r" };
    private string[] card_values = { "K", "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q" };

    private int[][] table =
    {
        //          a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r
        new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, // 0
        new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, // 1
        new int[] { 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 2
        new int[] { 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, // 3
        new int[] { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0 }, // 4
        new int[] { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0 }, // 5
        new int[] { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0 }, // 6
        new int[] { 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0 }, // 7
        new int[] { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0 }, // 8
        new int[] { 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0 }, // 9
        new int[] { 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0 }, // 10
        new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, // 11
        new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, // 12
        new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 13
    };

    private List _deck = new List();
    private Random _random = new Random((int)DateTime.Now.Ticks);
    private int _turn;
    private int _value;
    private bool _lost;

    private List Shuffle(int total)
    {
        return Enumerable.Range(0, total).OrderBy(r => _random.Next(0, total)).ToList();
    }

    public void ShowAsync(string content, string title)
    {
        IAsyncOperation command = new MessageDialog(content, title).ShowAsync();
    }

    private Geometry GetGeometry(string data)
    {
        return (Geometry)XamlReader.Load(
            $"{data}"
        );
    }

    private Path AddPip(string symbol, Color color, 
        double height, int margin, string name)
    {
        return new Path()
        {
            Name = name,
            Data = GetGeometry(symbol),
            Fill = new SolidColorBrush(color),
            Height = height,
            Stretch = Stretch.Uniform,
            Margin = new Thickness(margin),
            Opacity = 0
        };
    }

    private void Add(ref Grid grid, 
        int row, int rowspan, int column, 
        string symbol, Color color, string name)
    {
        bool flip = row > 2;
        Path pip = AddPip(symbol, color, 100, 5, name);
        if (flip)
        {
            pip.RenderTransform = new ScaleTransform() { ScaleY = -1, CenterY = 50 };
        }
        pip.SetValue(Grid.RowProperty, row);
        pip.SetValue(Grid.RowSpanProperty, rowspan);
        pip.SetValue(Grid.ColumnProperty, column);
        grid.Children.Add(pip);
    }

    private void AddItem(ref Grid grid, 
        int row, int column, string symbol, 
        Color color, string value, bool flip, string name)
    {
        StackPanel item = new StackPanel();
        Path pip = AddPip(symbol, color, 40, 0, $"{name}.pip");
        if (flip)
        {
            pip.RenderTransform = new ScaleTransform() { ScaleY = -1, CenterY = 20 };
        }
        item.Children.Add(pip);
        item.Children.Add(new TextBlock()
        {
            Name = $"{name}.num",
            HorizontalAlignment = HorizontalAlignment.Center,
            Text = value,
            Foreground = new SolidColorBrush(color),
            FontSize = 40,
            Opacity = 0
        });
        item.SetValue(Grid.ColumnProperty, column);
        item.SetValue(Grid.RowProperty, row);
        grid.Children.Add(item);
    }

    private void AddFace(ref Grid grid, 
        int row, int rowspan, 
        int column, int colspan, 
        Color color, string value, string name)
    {
        TextBlock face = new TextBlock()
        {
            Name = name,
            HorizontalAlignment = HorizontalAlignment.Center,
            Text = value,
            Foreground = new SolidColorBrush(color),
            FontSize = 300
        };
        face.SetValue(Grid.RowProperty, row);
        face.SetValue(Grid.RowSpanProperty, rowspan);
        face.SetValue(Grid.ColumnProperty, column);
        face.SetValue(Grid.ColumnSpanProperty, colspan);
        face.Opacity = 0;
        grid.Children.Add(face);
    }

    private Viewbox Card(string name, Color back)
    {
        string suit = club;
        Grid card = new Grid()
        {
            Name = name,
            Margin = new Thickness(10),
            Padding = new Thickness(10, 20, 10, 10),
            CornerRadius = new CornerRadius(10),
            BorderThickness = new Thickness(5),
            BorderBrush = new SolidColorBrush(Colors.Black),
            Background = new SolidColorBrush(back),
        };
        for (int c = 0; c < 5; c++)
        {
            card.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(80) });
        }
        for (int r = 0; r < 6; r++)
        {
            card.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(100) });
        }
        AddItem(ref card, 0, 0, suit, Colors.Black, "1", false, $"{name}.topleft");
        AddItem(ref card, 6, 0, suit, Colors.Black, "1", true, $"{name}.bottomleft");
        AddItem(ref card, 6, 4, suit, Colors.Black, "1", true, $"{name}.bottomright");
        AddItem(ref card, 0, 4, suit, Colors.Black, "1", false, $"{name}.topright");
        int count = 0;
        for (int i = 1; i < 5; i++)
        {
            Add(ref card, i, 1, 1, suit, Colors.Black, $"{name}.{card_pips[count]}");
            count++;
        }
        Add(ref card, 2, 2, 1, suit, Colors.Black, $"{name}.{card_pips[count]}");
        count++;
        for (int i = 1; i < 5; i++)
        {
            Add(ref card, i, 1, 2, suit, Colors.Black, $"{name}.{card_pips[count]}");
            count++;
        }
        for (int i = 1; i < 4; i++)
        {
            Add(ref card, i, 2, 2, suit, Colors.Black, $"{name}.{card_pips[count]}");
            count++;
        }
        Add(ref card, 2, 2, 3, suit, Colors.Black, $"{name}.{card_pips[count]}");
        count++;
        for (int i = 1; i  1 && number  14 && number = 27 && number = 40 && number <= 52):
                suit = spade;
                break;
        }
        Color color = (suit == heart || suit == diamond) ? Colors.Red : Colors.Black;
        string value = card_values[index];
        Grid card = (Grid)grid.FindName(name);
        card.Background = new SolidColorBrush(Colors.White);
        SetItem(ref card, suit, color, value, $"{name}.topleft");
        SetItem(ref card, suit, color, value, $"{name}.bottomleft");
        SetItem(ref card, suit, color, value, $"{name}.bottomright");
        SetItem(ref card, suit, color, value, $"{name}.topright");
        int[] values = table[index];
        SetPip(ref card, suit, color, $"{name}.a", values[0]);
        SetPip(ref card, suit, color, $"{name}.b", values[1]);
        SetPip(ref card, suit, color, $"{name}.c", values[2]);
        SetPip(ref card, suit, color, $"{name}.d", values[3]);
        SetPip(ref card, suit, color, $"{name}.e", values[4]);
        SetPip(ref card, suit, color, $"{name}.f", values[5]);
        SetPip(ref card, suit, color, $"{name}.g", values[6]);
        SetPip(ref card, suit, color, $"{name}.h", values[7]);
        SetPip(ref card, suit, color, $"{name}.i", values[8]);
        SetPip(ref card, suit, color, $"{name}.j", values[9]);
        SetPip(ref card, suit, color, $"{name}.k", values[10]);
        SetPip(ref card, suit, color, $"{name}.l", values[11]);
        SetPip(ref card, suit, color, $"{name}.m", values[12]);
        SetPip(ref card, suit, color, $"{name}.n", values[13]);
        SetPip(ref card, suit, color, $"{name}.o", values[14]);
        SetPip(ref card, suit, color, $"{name}.p", values[15]);
        SetPip(ref card, suit, color, $"{name}.q", values[16]);
        SetFace(ref card, color, value, $"{name}.r", values[17]);
        return index;
    }

    private void Layout(ref Grid grid)
    {
        Grid container = new Grid()
        {
            Width = 150
        };
        container.Children.Add(Card("card", Colors.Red));
        grid.Children.Add(container);
    }

    public void New(ref Grid grid)
    {
        _turn = 0;
        _lost = false;
        _deck = Shuffle(52);
        Layout(ref grid);
        _value = SetCard(ref grid, "card", _deck[_turn]);
    }

    public void Higher(ref Grid grid)
    {
        int higher = 0;
        if (_turn < _deck.Count && !_lost)
        {
            _turn++;
            higher = SetCard(ref grid, "card", _deck[_turn]);
            _lost = (higher < _value);
        }
        if (_lost)
        {
            ShowAsync($"Game Over : Turn {_turn} - Card Was Lower!", app_title);
        }
    }

    public void Lower(ref Grid grid)
    {
        int lower = 0;
        if (_turn  _value);
        }
        if (_lost)
        {
            ShowAsync($"Game Over : Turn {_turn} - Card Was Higher!", app_title);
        }
    }
}

The symbols for the suits – Club, Diamond, Heart and Spade are defined as paths so they are scalable – then there is a string[] of names for the card “pips” and the possible values for a playing card and in this Aces are Low. There’s a table int[][] that represents all the possible pip configurations for a playing card – playing cards are more complex than something like a dice or domino so there’s more positions they can appear in than you’d think in a grid and there’s values to represent the deck and a random number generator.

There’s a method GetGeometry which helps gets the paths for the suits and an AddPip method which calls that to create the correct pip with the right suit which is called by the Add method this is used for creating the “pips” on a card, there’s also the AddItem method to add the smaller pips that appear in each corner – these methods will correctly flip a pip so it appears more like a real card would in a deck. The AddFace method is used for the “Face” cards such as King or Queen and the SetPip method sets the visibility of a pip by setting the Opacity – the corner item pips are set with SetItem and the face cards set with SetFace.

A card is represented within a ViewBox which has a Grid within to create the part of the card to make it have rounded corners and with a white background and a black border then the main layout is created to define where the pips can go and for the the four corners where there will be a number or letter of a face card displayed and then all the pips are added to the layout. The SetCard method allows the card to be set with a particular value and controls the foreground colour of the card and which pips will be visible to represent all the cards in a deck and is set up from the Layout method.

There’s a Shuffle method to randomise the deck and you can start a New game before guessing if the next card selected when a card is tapped / clicked is Higher or Lower than the previous card – if correct it will go onto the next one, if wrong it is Game Over and it will display a message that you were incorrect and how many turns you managed with the aim being to get as many turns as possible.

Step 8

In the Solution Explorer select MainPage.xaml

vs2017-mainpage-library

Step 9

From the Menu choose View and then Designer

vs2017-view-designer

Step 10

The Design View will be displayed along with the XAML View and in this between the Grid and /Grid elements, enter the following XAML:

<Viewbox>
	<Grid Margin="50" Name="Display" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Viewbox>
<CommandBar VerticalAlignment="Bottom">
	<AppBarButton Icon="Page2" Label="New" Click="New_Click"/>
	<AppBarButton Icon="Add" Label="Higher" Click="Higher_Click"/>
	<AppBarButton Icon="Remove" Label="Lower" Click="Lower_Click"/>
</CommandBar>

The first block of XAML the main user interface of the Application, this features a ViewBox containing a Grid Control that will be use for the contents of the game. The second block of XAML is is the CommandBar which contains New – to start a Game, Higher to state if the next Card will be a higher value than the current one and Lower to state if the next Card will be a lower value than the current one.

Step 11

From the Menu choose View and then Code

vs2017-view-code

Step 12

Once in the Code View, below the end of public MainPage() { … } the following Code should be entered:

Library library = new Library();

private void New_Click(object sender, RoutedEventArgs e)
{
	library.New(ref Display);
}

private void Higher_Click(object sender, RoutedEventArgs e)
{
	library.Higher(ref Display);
}

private void Lower_Click(object sender, RoutedEventArgs e)
{
	library.Lower(ref Display);
}

Below the MainPage() Method an instance of the Library Class is created, then New_Click is used to call the New Method to setup the game and start playing. Higher_Click and Lower_Click are Event Handlers that will trigger their respective Methods in the Library Class.

Step 13

That completes the Universal Windows Platform Application so Save the Project then in Visual Studio select the Local Machine to run the Application

vs2017-local-machine

Step 14

After the Application has started running you can then select New to start the game then select either Higher or Lower to guess if the next Card is has High or Low value compared to the previous one if you guess incorrectly then you lose.

ran-high-or-low

Step 15

To Exit the Application select the Close button in the top right of the Application

vs2017-close

The main aim of this example was to perfect the look and feel of a playing card so these could then be used in other examples or games, even if the game itself is rather simple getting the cards to look correct was a real challenge with many hours of work going into them including making sure the pips are placed accurately and those that should appear upside down do so, when compared with a standard deck of playing cards this example should hopefully demonstrate a close resemblance to the real thing.

Creative Commons License

Universal Windows Platform – Deal or Not

Deal or Not demonstrates how to create a box-opening game where every so often there is a Deal and you can choose Not to accept it and Continue but risk winning a smaller amount – the last box at the end will be the winning amount or the Deal if you took that or you can see what the other boxes contained if you did Deal but you won’t win those!

Step 1

If not already, follow Setup and Start on how to Install and get Started with Visual Studio 2017 or in Windows 10 choose Start, and then from the Start Menu find and select Visual Studio 2017.

vs2017

Step 2

Once Visual Studio Community 2017 has started, from the Menu choose File, then New then Project…

vs2017-file-new-project

Step 3

From New Project choose Visual C# from Installed, Templates then choose Blank App (Universal Windows) and then type in a Name and select a Location and then select Ok to create the Project
vs2017-new-project-window

Step 4

Then in New Universal Windows Project you need to select the Target Version this should be at least the Windows 10, version 1803 (10.0; Build 17134) which is the April 2018 Update and the Minimum Version to be the same.

vs2017-target-platform

The Target Version will control what features your application can use in Windows 10 so by picking the most recent version you’ll be able to take advantage of those features. To make sure you always have the most recent version, in Visual Studio 2017 select Tools Extensions and Updates… then and then see if there are any Updates

Step 5

Once done select from the Menu, Project, then Add New Item…

vs2017-project-add-new-item

Step 6

From the Add New Item window select Visual C#, then Code from Installed then select Code File from the list, then type in the Name as Library.cs before selecting Add to add the file to the Project

vs2017-add-new-item-library

Step 7

Once in the Code View for Library.cs the following should be entered:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Windows.UI;
using Windows.UI.Text;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Shapes;

public class Library
{
    private const string app_title = "Deal or Not";
    private double[] box_values =
    {
            0.01, 0.10, 0.50, 1, 5, 10, 50, 100, 250, 500, 750,
            1000, 3000, 5000, 10000, 15000, 20000, 35000, 50000, 75000, 100000, 250000
    };
    private string[] box_colors =
    {
        "0026ff", "0039ff", "004dff", "0060ff", "0073ff", "0086ff", "0099ff", "0099ff", "0099ff", "00acff", "00bfff",
        "ff5900", "ff4d00", "ff4000", "ff3300", "ff2600", "ff2600", "ff2600", "ff2600", "ff1a00", "ff1c00", "ff0d00",
    };
    private string[] box_names = {
        "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
        "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v"
    };

    private ContentDialog _dialog;
    static TaskCompletionSource _awaiter = new TaskCompletionSource();
    private Random _random = new Random((int)DateTime.Now.Ticks);
    private List _amounts = new List();
    private double _amount;
    private bool _dealt;
    private int _turn;

    private Color ConvertHexToColor(string hex)
    {
        hex = hex.Remove(0, 1);
        byte a = hex.Length == 8 ? Byte.Parse(hex.Substring(0, 2), NumberStyles.HexNumber) : (byte)255;
        byte r = Byte.Parse(hex.Substring(hex.Length - 6, 2), NumberStyles.HexNumber);
        byte g = Byte.Parse(hex.Substring(hex.Length - 4, 2), NumberStyles.HexNumber);
        byte b = Byte.Parse(hex.Substring(hex.Length - 2), NumberStyles.HexNumber);
        return Color.FromArgb(a, r, g, b);
    }

    private async Task ShowDialogAsync(string primary, string secondary, object content)
    {
        if (_dialog != null)
        {
            _dialog.Hide();
        }
        _dialog = new ContentDialog()
        {
            Title = app_title,
            PrimaryButtonText = primary,
            SecondaryButtonText = secondary,
            Content = content
        };
        return await _dialog.ShowAsync();
    }

    private List Shuffle(int total)
    {
        return Enumerable.Range(0, total).OrderBy(r => _random.Next(0, total)).ToList();
    }

    private Grid GetAmount(double value, Color background)
    {
        Grid grid = new Grid()
        {
            Background = new SolidColorBrush(background)
        };
        TextBlock text = new TextBlock()
        {
            Text = String.Format(new CultureInfo("en-GB"), "{0:c}", value),
            HorizontalAlignment = HorizontalAlignment.Center,
            VerticalAlignment = VerticalAlignment.Center,
            Foreground = new SolidColorBrush(Colors.White),
            Margin = new Thickness(10),
            FontSize = 33
        };
        grid.Children.Add(text);
        return grid;
    }

    private double GetOffer()
    {
        int count = 0;
        double total = 0.0;
        foreach (double amount in _amounts)
        {
            total += amount;
            count++;
        }
        double average = total / count;
        double offer = (average * _turn) / 10;
        return Math.Round(offer, 0);
    }

    private Color GetBackground(double amount)
    {
        int position = 0;
        while (amount != box_values[position])
        {
            position++;
        }
        return ConvertHexToColor($"#ff{box_colors[position]}");
    }

    private async void Choose(Button button, string name)
    {
        if (_turn  1)
                {
                    offer = GetOffer();
                    ContentDialogResult result = await ShowDialogAsync("Deal", "Not", GetAmount(offer, Colors.Black));
                    if (result == ContentDialogResult.Primary)
                    {
                        _amount = offer;
                        _dealt = true;
                    }
                }
                _turn++;
            }
        }
        if (_turn == box_names.Length || _dealt)
        {
            object content = _dealt ? GetAmount(_amount, Colors.Black) : GetAmount(_amount, GetBackground(_amount));
            await ShowDialogAsync("Game Over", string.Empty, content);
        }
    }

    private void Add(ref StackPanel panel, string name, int value)
    {
        Button button = new Button()
        {
            Name = $"box.{name}",
            Margin = new Thickness(5)
        };
        button.Click += (object sender, RoutedEventArgs e) =>
        {
            Choose((Button)sender, name);
        };
        StackPanel box = new StackPanel()
        {
            Width = 100
        };
        Rectangle lid = new Rectangle()
        {
            Height = 10,
            Fill = new SolidColorBrush(Colors.DarkRed)
        };
        Grid front = new Grid()
        {
            Height = 75,
            Background = new SolidColorBrush(Colors.Red)
        };
        Grid label = new Grid()
        {
            Width = 50,
            Background = new SolidColorBrush(Colors.White),
            HorizontalAlignment = HorizontalAlignment.Center,
            VerticalAlignment = VerticalAlignment.Center
        };
        TextBlock text = new TextBlock()
        {
            TextAlignment = TextAlignment.Center,
            FontWeight = FontWeights.Bold,
            Foreground = new SolidColorBrush(Colors.Black),
            FontSize = 32,
            Text = value.ToString()
        };
        label.Children.Add(text);
        front.Children.Add(label);
        box.Children.Add(lid);
        box.Children.Add(front);
        button.Content = box;
        panel.Children.Add(button);
    }

    private StackPanel AddRow()
    {
        StackPanel panel = new StackPanel();
        int[] rows = { 5, 6, 6, 5 };
        int count = 0;
        for (int r = 0; r < 4; r++)
        {
            StackPanel places = new StackPanel()
            {
                Orientation = Orientation.Horizontal,
                HorizontalAlignment = HorizontalAlignment.Center
            };
            for (int c = 0; c < rows[r]; c++)
            {
                Add(ref places, box_names[count], count + 1);
                count++;
            }
            panel.Children.Add(places);
        }
        return panel;
    }

    private void Layout(ref Grid grid)
    {
        grid.Children.Clear();
        Viewbox view = new Viewbox()
        {
            Child = AddRow()
        };
        grid.Children.Add(view);
    }

    public void New(ref Grid grid)
    {
        _turn = 0;
        _dealt = false;
        List positions = Shuffle(22);
        _amounts = new List();
        foreach (int position in positions)
        {
            _amounts.Add(box_values[position]);
        }
        Layout(ref grid);
    }
}

Within the game there are the box values as a double[] – this contains all the possible amounts that a box can contain, each of those amounts has a corresponding colour which is in the string[] of box colours then there’s the names of the boxes as another string[]. The box colours are stored as hexadecimal colour values and these are converted using the ConvertHexToColor to a colour that can be used in the code. There’s a good use of the ContentDialog to show different content with different Primary and Secondary buttons which is made use of to display any amounts of opened boxes and any Deals too. There’s a Shuffle method combined with a random number generator which is used to randomise the contents of the boxes. The amount is obtained with the GetAmount method which also displays the passed in background colour and displays the amount as currency – you can change the CultureInfo to your own region e.g. “en-US” to display a different currency symbol.

In the game there are Offers and these are calculated with the GetOffer method which uses a simple algorithm to work out what the offer should be, there’s also a GetBackground method to get the correct background colour for an amount. The Pick method is the core part of the game – when each box is selected it will display the Amount in that box, after every five turns there will be a message to Deal or Not – if you deal the game is over and you win the amount that was offered or you can Continue. The layout of the game is formed from the Add method which creates the look of a box with colours and a label on the front, the Boxes method creates the full layout of boxes to be displayed and is called from the Layout method. You can start a New game which will reset everything to start again.

Step 8

In the Solution Explorer select MainPage.xaml

vs2017-mainpage-library

Step 9

From the Menu choose View and then Designer

vs2017-view-designer

Step 10

The Design View will be displayed along with the XAML View and in this between the Grid and /Grid elements, enter the following XAML:

<Viewbox>
	<Grid Margin="50" Name="Display" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Viewbox>
<CommandBar VerticalAlignment="Bottom">
	<AppBarButton Icon="Page2" Label="New" Click="New_Click"/>
</CommandBar>

The first block of XAML the main user interface of the Application, this features a ViewBox containing a Grid Control that will be use for the contents of the game. The second block of XAML is is the CommandBar which contains New – to start a Game.

Step 11

From the Menu choose View and then Code

vs2017-view-code

Step 12

Once in the Code View, below the end of public MainPage() { … } the following Code should be entered:

Library library = new Library();

private void New_Click(object sender, RoutedEventArgs e)
{
	library.New(ref Display);
}

Below the MainPage() Method an instance of the Library Class is created, then New_Click is used to call the New method to setup the game and start playing.

Step 13

That completes the Universal Windows Platform Application so Save the Project then in Visual Studio select the Local Machine to run the Application

vs2017-local-machine

Step 14

After the Application has started running you can then select Newto start the game then select one of the boxes between 1 and 22 to display the amount after each five turns the next turn will result on an Offer and you can Deal or Not until there’s just one box left and that’s what you’ll win or if you did Deal you win that Offer.

ran-deal-or-not

Step 15

To Exit the Application select the Close button in the top right of the Application

vs2017-close

Deal Or Not is quite a fun game and contains many elements of a certain game show and shows off how something like that can be encapsulated in a game you can play on a computer – it features a fun look and feel with the boxes displayed and amounts shown in a more pleasing visual manner, it was important for each amount to show as closely to the game show as possible and demonstrates the flexability of dialogs to display quite sophisticated content and hopefully is as fun a game to write as it is to playf.

Creative Commons License

Universal Windows Platform – Lucky Roshambo

Lucky Roshambo demonstrates how to create a Rock-Paper-Scissors game or Roshambo as it’s called in many parts of North America – the game logic for this is quite simple and is a good way of showing a game you’ve probably played in real-life converted into a game you can play on a Computer.

Step 1

If not already, follow Setup and Start on how to Install and get Started with Visual Studio 2017 or in Windows 10 choose Start, and then from the Start Menu find and select Visual Studio 2017.

vs2017

Step 2

Once Visual Studio Community 2017 has started, from the Menu choose File, then New then Project…

vs2017-file-new-project

Step 3

From New Project choose Visual C# from Installed, Templates then choose Blank App (Universal Windows) and then type in a Name and select a Location and then select Ok to create the Project
vs2017-new-project-window

Step 4

Then in New Universal Windows Project you need to select the Target Version this should be at least the Windows 10, version 1803 (10.0; Build 17134) which is the April 2018 Update and the Minimum Version to be the same.

vs2017-target-platform

The Target Version will control what features your application can use in Windows 10 so by picking the most recent version you’ll be able to take advantage of those features. To make sure you always have the most recent version, in Visual Studio 2017 select Tools Extensions and Updates… then and then see if there are any Updates

Step 5

Once done select from the Menu, Project, then Add New Item…

vs2017-project-add-new-item

Step 6

From the Add New Item window select Visual C#, then Code from Installed then select Code File from the list, then type in the Name as Library.cs before selecting Add to add the file to the Project

vs2017-add-new-item-library

Step 7

Once in the Code View for Library.cs the following should be entered:

using System;
using System.Threading.Tasks;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;

public class Library
{
    private const int size = 3;
    private const int win = 1;
    private const int draw = 0;
    private const int lose = -1;
    private int[,] match = new int[size, size]
    {
        { draw, lose, win },
        { win, draw, lose },
        { lose, win, draw }
    };
    private readonly int[] values = new int[] { 0, 1, 2 };
    private readonly string[] options = new string[] { "\uED5B", "\uE130", "\uE16B" };
    private readonly Color[] colours = new Color[] { Colors.DarkRed, Colors.DarkBlue, Colors.DarkGreen };

    private Random random = new Random((int)DateTime.Now.Ticks);

    private async Task ShowDialogAsync(string title, int option)
    {
        ContentDialog dialog = new ContentDialog()
        {
            Title = title,
            Content = GetShape(option, false),
            PrimaryButtonText = "OK"
        };
        return await dialog.ShowAsync();
    }

    private async void Choose(int option)
    {
        int player = values[option];
        int computer = random.Next(0, size - 1);
        int result = match[player, computer];
        string message = string.Empty;
        switch (result)
        {
            case win:
                message = "You Win!";
                break;
            case lose:
                message = "You Lost";
                break;
            case draw:
                message = "You Draw";
                break;
        }
        await ShowDialogAsync($"Computer Picked - {message}", computer);
    }

    private Grid GetShape(int option, bool useEvent)
    {
        Grid grid = new Grid()
        {
            Tag = option,
            Margin = new Thickness(5),
            Height = 80,
            Width = 80,
            Background = new SolidColorBrush(colours[option]),
        };
        TextBlock text = new TextBlock()
        {
            Text = options[option],
            FontSize = 66,
            FontFamily = new FontFamily("Segoe MDL2 Assets"),
            Foreground = new SolidColorBrush(Colors.White),
            VerticalAlignment = VerticalAlignment.Center,
            HorizontalAlignment = HorizontalAlignment.Center
        };
        if (useEvent)
        {
            grid.Tapped += (object sender, TappedRoutedEventArgs e) =>
            {
                Grid selected = (Grid)sender;
                int tag = (int)selected.Tag;
                Choose(tag);
            };
        }
        grid.Children.Add(text);
        return grid;
    }

    private void Layout(ref Grid grid)
    {
        grid.Children.Clear();
        StackPanel panel = new StackPanel()
        {
            Orientation = Orientation.Horizontal,
            HorizontalAlignment = HorizontalAlignment.Center
        };
        for (int i = 0; i < size; i++)
        {
            panel.Children.Add(GetShape(i, true));
        }
        grid.Children.Add(panel);
    }

    public void New(ref Grid grid)
    {
        Layout(ref grid);
    }
}

There’s some values that are used to encapsulate the main component of the game itself, there’s the three states win, draw and lose plus there’s what matches of each type of item – Rock, Paper or Scissors result in those states, these are the values and then there’s the options which are the Characters of the Segoe MDL2 Aseets Font represent each of those states. There’s a Random for a random number generator and then a method for displaying a dialog – ShowDialogAsync, this will also show which option was seleccted by the random number generator. When you Choose an option this will randomly select a response then you can see if you Win, have Lost or the result was a Draw, there’s GetShape which returns a Grid and TextBlock to display one of the options plus there’s an event handler used when useEvent is true to call the Choose method with the selected option and there’s the Layout method to display the options when New is called.

Step 8

In the Solution Explorer select MainPage.xaml

vs2017-mainpage-library

Step 9

From the Menu choose View and then Designer

vs2017-view-designer

Step 10

The Design View will be displayed along with the XAML View and in this between the Grid and /Grid elements, enter the following XAML:

<Viewbox>
	<Grid Margin="50" Name="Display" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Viewbox>
<CommandBar VerticalAlignment="Bottom">
	<AppBarButton Icon="Page2" Label="New" Click="New_Click"/>
</CommandBar>

The first block of XAML the main user interface of the Application, this features a ViewBox containing a Grid Control that will be use for the contents of the game. The second block of XAML is is the CommandBar which contains New – to start a Game.

Step 11

From the Menu choose View and then Code

vs2017-view-code

Step 12

Once in the Code View, below the end of public MainPage() { … } the following Code should be entered:

Library library = new Library();

private void New_Click(object sender, RoutedEventArgs e)
{
	library.New(ref Display);
}

Below the MainPage() Method an instance of the Library Class is created, then New_Click is used to call the New method to setup the game and start playing.

Step 13

That completes the Universal Windows Platform Application so Save the Project then in Visual Studio select the Local Machine to run the Application

vs2017-local-machine

Step 14

After the Application has started running you can then select New to start the game then press on Rock – the first button, Paper – the second button or Scissors – the third button, then you can see what the Computer selects to see if you Win, Lose or Draw

ran-lucky-roshambo

Step 15

To Exit the Application select the Close button in the top right of the Application

vs2017-close

This a simple game that most people have either played or heard of and can see how that translates to a Universal Windows Platform example or a chance to play it for the first time, with simple rules – Rock beats Paper, Paper beats Rock, Scissors Beats Paper, Rock Beats Scissors etc which may seem complex but all those rules are contained within this simple example.

Creative Commons License

Universal Windows Platform – Lucky Dominoes

Lucky Dominoes demonstrates a simple way of creating the look-and-feel of a Domino as well as obeying the rules of a single Domino. Although it’s a simple example it could form the basis of any domino-based game.

Step 1

If not already, follow Setup and Start on how to Install and get Started with Visual Studio 2017 or in Windows 10 choose Start, and then from the Start Menu find and select Visual Studio 2017.

vs2017

Step 2

Once Visual Studio Community 2017 has started, from the Menu choose File, then New then Project…

vs2017-file-new-project

Step 3

From New Project choose Visual C# from Installed, Templates then choose Blank App (Universal Windows) and then type in a Name and select a Location and then select Ok to create the Project
vs2017-new-project-window

Step 4

Then in New Universal Windows Project you need to select the Target Version this should be at least the Windows 10, version 1803 (10.0; Build 17134) which is the April 2018 Update and the Minimum Version to be the same.

vs2017-target-platform

The Target Version will control what features your application can use in Windows 10 so by picking the most recent version you’ll be able to take advantage of those features. To make sure you always have the most recent version, in Visual Studio 2017 select Tools Extensions and Updates… then and then see if there are any Updates

Step 5

Once done select from the Menu, Project, then Add New Item…

vs2017-project-add-new-item

Step 6

From the Add New Item window select Visual C#, then Code from Installed then select Code File from the list, then type in the Name as Library.cs before selecting Add to add the file to the Project

vs2017-add-new-item-library

Step 7

Once in the Code View for Library.cs the following should be entered:

using System;
using System.Collections.Generic;
using System.Linq;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Shapes;

public class Library
{
    private string[] tags = { "a", "b", "c", "d", "e", "f", "g", "h", "i" };
    private string[] tiles =
    {
        "0,0",
        "0,1", "1,1",
        "0,2", "1,2", "2,2",
        "0,3", "1,3", "2,3", "3,3",
        "0,4", "1,4", "2,4", "3,4", "4,4",
        "0,5", "1,5", "2,5", "3,5", "4,5", "5,5",
        "0,6", "1,6", "2,6", "3,6", "4,6", "5,6", "6,6"
    };
    private int[][] table =
    {
                 // a, b, c, d, e, f, g, h, i
        new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 0
        new int[] { 0, 0, 0, 0, 1, 0, 0, 0, 0 }, // 1
        new int[] { 1, 0, 0, 0, 0, 0, 0, 0, 1 }, // 2
        new int[] { 1, 0, 0, 0, 1, 0, 0, 0, 1 }, // 3
        new int[] { 1, 0, 1, 0, 0, 0, 1, 0, 1 }, // 4
        new int[] { 1, 0, 1, 0, 1, 0, 1, 0, 1 }, // 5
        new int[] { 1, 0, 1, 1, 0, 1, 1, 0, 1 }, // 6
    };

    private Random _random = new Random((int)DateTime.Now.Ticks);
    private List _one = new List();
    private List _two = new List();
    private int _turns = 0;

    private List Shuffle(int total)
    {
        return Enumerable.Range(0, total).OrderBy(r => _random.Next(0, total)).ToList();
    }

    private void Add(ref Grid grid, int row, int column, string name)
    {
        Ellipse ellipse = new Ellipse()
        {
            Name = name,
            Fill = new SolidColorBrush(Colors.White),
            Margin = new Thickness(5),
            Opacity = 0
        };
        ellipse.SetValue(Grid.ColumnProperty, column);
        ellipse.SetValue(Grid.RowProperty, row);
        grid.Children.Add(ellipse);
    }

    private Grid Portion(string name)
    {
        int size = 3;
        Grid grid = new Grid()
        {
            Name = name,
            Width = 100,
            Height = 100,
            Padding = new Thickness(5),
            Background = new LinearGradientBrush(new GradientStopCollection()
            {
                new GradientStop() { Color = Colors.Black, Offset = 0.0 },
                new GradientStop() { Color = Colors.Gray, Offset = 1.0 }
            }, 90)
        };
        // Setup Grid
        for (int index = 0; (index < size); index++)
        {
            grid.RowDefinitions.Add(new RowDefinition());
            grid.ColumnDefinitions.Add(new ColumnDefinition());
        }
        int count = 0;
        for (int row = 0; (row < size); row++)
        {
            for (int column = 0; (column  0)
        {
            SetDomino(ref grid, "one", tiles[_one[_turns]]);
            SetDomino(ref grid, "two", tiles[_two[_turns]]);
            _turns--;
        }
        else
        {
            New(ref grid);
        }
    }
}

There’s the use of two string[], the first is a list of all the positions a dot or “pip” can appear on Domino but there are also a few extra if you wanted to make each Domino go up to nine, the second is a list of all the possible combination of Domino Tiles there can be from blank to a pair of sixes. There is also int[][] which is a list of a list of numbers – this encodes all the combinations needed to display a set number of pips from 0 to 6 there are some positions that are never set as this is a three-by-three grid but is done this way to make it easier to understand.

There’s a Random number and set of two lists to store the values of a Domino in plus how many Turns have been made. There are many methods to make the displaying of a Domino work, the first is the Add method to add one of the “pips” which is represented by an Ellipse and set to a given Row and Column on a Grid. There is also a Portion method which represents the upper and lower part of a Domino with a given name and also has a Gradient background set – the pips are added using the previous Add method and are given a name composed of the given name and position of the pip as a letter from lost of all the positions a pip can appear on a Domino.

There’s a method to define a Domino called Domino and sets the Upper and Lower Portion, this method is used by the Layout to create the pair of Dominoes used in the example. Then there is a method to get a pip GetPip used by SetPortion to set the Opacity of a given pip – this will allow each value to be displayed as needed and uses the list of list of numbers that encode all the display combinations and the SetDomino method calls this to set the upper and lower parts of a Domino to the one of the valid values from the Tiles list. There are then methods to Shuffle a list of generated random numbers and start a New game and Choose a value from the shuffled list.

Step 8

In the Solution Explorer select MainPage.xaml

vs2017-mainpage-library

Step 9

From the Menu choose View and then Designer

vs2017-view-designer

Step 10

The Design View will be displayed along with the XAML View and in this between the Grid and /Grid elements, enter the following XAML:

<Viewbox>
	<Grid Margin="50" Name="Display" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Viewbox>
<CommandBar VerticalAlignment="Bottom">
	<AppBarButton Icon="Page2" Label="New" Click="New_Click"/>
	<AppBarButton Icon="Accept" Label="New" Click="Choose_Click"/>
</CommandBar>

The first block of XAML the main user interface of the Application, this features a ViewBox containing a Grid Control that will be use for the contents of the game. The second block of XAML is is the CommandBar which contains New – to start a Game and Choose to display a Domino.

Step 11

From the Menu choose View and then Code

vs2017-view-code

Step 12

Once in the Code View, below the end of public MainPage() { … } the following Code should be entered:

Library library = new Library();

private void New_Click(object sender, RoutedEventArgs e)
{
	library.New(ref Display);
}

private void Choose_Click(object sender, RoutedEventArgs e)
{
	library.Choose(ref Display);
}

Below the MainPage() Method an instance of the Library Class is created, then New_Click is used to call the New method to setup the game and Pick_Click is used to call the Choose Method in the Library Class

Step 13

That completes the Universal Windows Platform Application so Save the Project then in Visual Studio select the Local Machine to run the Application

vs2017-local-machine

Step 14

After the Application has started running you can then select New to start then Choose to set each Domino to a random selection of all the possible values of a Domino

ran-lucky-dominoes

Step 15

To Exit the Application select the Close button in the top right of the Application

vs2017-close

Creative Commons License

Universal Windows Platform – Shade Effect

Shade Effect demonstrates how to create a Shadow Effect on an element – in this case it’s the Visual Studio logo. The Shadow Effect is triggered with Accept and cleared with Clear.

Step 1

If not already, follow Setup and Start on how to Install and get Started with Visual Studio 2017 or in Windows 10 choose Start, and then from the Start Menu find and select Visual Studio 2017.

vs2017

Step 2

Once Visual Studio Community 2017 has started, from the Menu choose File, then New then Project…

vs2017-file-new-project

Step 3

From New Project choose Visual C# from Installed, Templates then choose Blank App (Universal Windows) and then type in a Name and select a Location and then select Ok to create the Project
vs2017-new-project-window

Step 4

Then in New Universal Windows Project you need to select the Target Version this should be at least the Windows 10, version 1803 (10.0; Build 17134) which is the April 2018 Update and the Minimum Version to be the same.

vs2017-target-platform

The Target Version will control what features your application can use in Windows 10 so by picking the most recent version you’ll be able to take advantage of those features. To make sure you always have the most recent version, in Visual Studio 2017 select Tools Extensions and Updates… then and then see if there are any Updates

Step 5

In the Solution Explorer select MainPage.xaml

vs2017-mainpage

Step 6

From the Menu choose View and then Designer

vs2017-view-designer

Step 7

The Design View will be displayed along with the XAML View and in this between the Grid and /Grid elements, enter the following XAML:

<Viewbox Margin="100">
	<Grid Height="400" Width="400">
		<Border x:Name="ShadowElement"/>
		<Path Name="Logo" Fill="#FF5c2d91" Stretch="Uniform"
		Data="M27.021,0l8.897,3.592v28.815L26.938,36L12.653,21.796l-9.061,7.021L0,27.021V8.979l3.592-1.714l9.061,7.102 
		L27.021,0z M3.592,12.653v10.939l5.388-5.551L3.592,12.653z M17.633,18.041l9.306,7.348V10.693L17.633,18.041z">
		</Path>
	</Grid>
</Viewbox>
<CommandBar VerticalAlignment="Bottom">
	<AppBarButton Icon="Accept" Label="Accept" Click="Accept_Click"/>
	<AppBarButton Icon="Cancel" Label="Clear" Click="Clear_Click"/>
</CommandBar>

The first block of XAML features a Viewbox which contains a Grid with a Border which will represent a Shadow for the Shade Effect and Path within which represents the Logo itself. The second block of XAML is is the CommandBar which contains Accept – to apply the Shade Effect to the Logo and Clear – to remove the Shade Effect from the Logo.

Step 8

From the Menu choose View and then Code

vs2017-view-code

Step 9

Once in the Code View, below the end of public MainPage() { … } the following Code should be entered:

private Windows.UI.Composition.SpriteVisual _visual;

private Windows.UI.Composition.Compositor Compositor
{
	get
	{
		return Windows.UI.Xaml.Hosting.ElementCompositionPreview.GetElementVisual(Logo).Compositor;
	}
}

private void Accept_Click(object sender, RoutedEventArgs e)
{
	_visual = Compositor.CreateSpriteVisual();
	_visual.Size = new System.Numerics.Vector2((float)Logo.ActualWidth, (float)Logo.ActualHeight);
	Windows.UI.Composition.DropShadow shadow = Compositor.CreateDropShadow();
	shadow.Color = Windows.UI.Colors.Black;
	shadow.Offset = new System.Numerics.Vector3(10, 10, 0);
	shadow.Mask = Logo.GetAlphaMask();
	_visual.Shadow = shadow;
	Windows.UI.Xaml.Hosting.ElementCompositionPreview.SetElementChildVisual(ShadowElement, _visual);
}

private void Clear_Click(object sender, RoutedEventArgs e)
{
	_visual.Shadow = null;
}

There is a SpriteVisual Member and Compositor Property the Accept_Click Event Handler uses CreateSpriteVisual combine with DropShadow to set up a Drop Shadow that will form the Shade Effect which will be applied to the Shadow Property of the SpriteVisual and then will use the SetElementChildVisual Method to set the Border to be associated with the SpriteVisual. The Clear_Click Event Handler will set the SpriteVisual property of Shadow to null.

Step 10

That completes the Universal Windows Platform Application so Save the Project then in Visual Studio select the Local Machine to run the Application

vs2017-local-machine

Step 11

Once the Application has started running you can then select Accept to enable the Shade Effect or use Clear to remove the effect

uwp-ran-shade-effect

Step 12

To Exit the Application select the Close button in the top right of the Application

vs2017-close

This example uses the Composition features in Windows 10 available since the November and Anniversary updates and makes use of a SpriteVisual. The first thing to do is to get the SpriteVisual which is the Visual Studio logo then a Compositor is used to create a DropDhadow with a given colour – in the example it’s Black then the Offset is set which is sets the position of the effect and then there’s the Mask that defines the part of the Shade Effect that won’t be in Shadow. The SpriteVisual then has a Child Visual Element set to be the DropShadow.

Creative Commons License

Universal Windows Platform – Light Effect

Light Effect demonstrates how to create a PointLight Effect on an element – in this case it’s the Visual Studio Logo and uses an animation to demonstrate the effect passing over the logo. The PointLight Effect is triggered with Accept and cleared with Clear.

Step 1

If not already, follow Setup and Start on how to Install and get Started with Visual Studio 2017 or in Windows 10 choose Start, and then from the Start Menu find and select Visual Studio 2017.

vs2017

Step 2

Once Visual Studio Community 2017 has started, from the Menu choose File, then New then Project…

vs2017-file-new-project

Step 3

From New Project choose Visual C# from Installed, Templates then choose Blank App (Universal Windows) and then type in a Name and select a Location and then select Ok to create the Project
vs2017-new-project-window

Step 4

Then in New Universal Windows Project you need to select the Target Version this should be at least the Windows 10, version 1803 (10.0; Build 17134) which is the April 2018 Update and the Minimum Version to be the same.

vs2017-target-platform

The Target Version will control what features your application can use in Windows 10 so by picking the most recent version you’ll be able to take advantage of those features. To make sure you always have the most recent version, in Visual Studio 2017 select Tools Extensions and Updates… then and then see if there are any Updates

Step 5

In the Solution Explorer select MainPage.xaml

vs2017-mainpage

Step 6

From the Menu choose View and then Designer

vs2017-view-designer

Step 7

The Design View will be displayed along with the XAML View and in this between the Grid and /Grid elements, enter the following XAML:

<Viewbox Margin="100">
	<Grid Height="400" Width="400">
		<Path Name="Logo" Fill="#FF5c2d91" Stretch="Uniform"
		Data="M27.021,0l8.897,3.592v28.815L26.938,36L12.653,21.796l-9.061,7.021L0,27.021V8.979l3.592-1.714l9.061,7.102 
		L27.021,0z M3.592,12.653v10.939l5.388-5.551L3.592,12.653z M17.633,18.041l9.306,7.348V10.693L17.633,18.041z">
		</Path>
	</Grid>
</Viewbox>
<CommandBar VerticalAlignment="Bottom">
	<AppBarButton Icon="Accept" Label="Accept" Click="Accept_Click"/>
	<AppBarButton Icon="Cancel" Label="Clear" Click="Clear_Click"/>
</CommandBar>

The first block of XAML features a Viewbox which contains a Grid with a Path within which represents the Logo. The second block of XAML is is the CommandBar which contains Accept – to apply the Light Effect to the Logo and Clear – to remove the Light Effect from the Logo.

Step 8

From the Menu choose View and then Code

vs2017-view-code

Step 9

Once in the Code View, below the end of public MainPage() { … } the following Code should be entered:

private Windows.UI.Composition.PointLight _light;

private Windows.UI.Composition.Compositor Compositor
{
	get
	{
		return Windows.UI.Xaml.Hosting.ElementCompositionPreview.GetElementVisual(Logo).Compositor;
	}
}

private void Accept_Click(object sender, RoutedEventArgs e)
{
	Windows.UI.Composition.Visual visual =
		Windows.UI.Xaml.Hosting.ElementCompositionPreview.GetElementVisual(Logo);
	_light = Compositor.CreatePointLight();
	_light.Color = Windows.UI.Colors.White;
	_light.CoordinateSpace = visual;
	_light.Targets.Add(visual);
	_light.Offset =
		new System.Numerics.Vector3(-(float)Logo.ActualWidth * 2, (float)Logo.ActualHeight / 2, (float)Logo.ActualHeight);
	Windows.UI.Composition.ScalarKeyFrameAnimation animation = Compositor.CreateScalarKeyFrameAnimation();
	animation.InsertKeyFrame(1, 2 * (float)Logo.ActualWidth);
	animation.Duration = TimeSpan.FromSeconds(5.0f);
	animation.IterationBehavior = Windows.UI.Composition.AnimationIterationBehavior.Forever;
	_light.StartAnimation("Offset.X", animation);
}

private void Clear_Click(object sender, RoutedEventArgs e)
{
	if (_light != null)
	{
		_light.Targets.RemoveAll();
	}
}

There is a PointLight Member and Compositor Property the Accept_Click Event Handler uses GetElementVisual to get the Logo to apply the effect to then the PointLight is set up, a ScalarKeyFrameAnimation Animation is set up which will “move” the PointLight across the Logo. The Clear_Click Event Handler will use RemoveAll to clear the Light Effect, it also has a null check to prevent a NullReferenceException

Step 10

That completes the Universal Windows Platform Application so Save the Project then in Visual Studio select the Local Machine to run the Application

vs2017-local-machine

Step 11

Once the Application has started running you can then select Accept to enable the Light Effect or use Clear to remove the effect

uwp-ran-light-effect

Step 12

To Exit the Application select the Close button in the top right of the Application

vs2017-close

This example uses the Composition features in Windows 10 available since the November and Anniversary updates, in this case it uses a PointLight. The first thing to do is to get the Visual which is the Visual Studio logo then a Compositor is used which is based on this to create a point light with a given colour – in the example it’s White then the CoordinateSpace is set to the Visual that defines the bounds for the point light and the Targets is set to to logo plus an Offset is then set. An animation is set up which wil cause the point light to seem to pass over the logo and this happens in a loop.

Creative Commons License

Universal Windows Platform – Access Keys

Access Keys demonstrates how to create a CommandBar that use the Alt key on the Keyboard to then show on-screen which Keyboard Key to press to perform the task of the button on the CommandBar.

Step 1

If not already, follow Setup and Start on how to Install and get Started with Visual Studio 2017 or in Windows 10 choose Start, and then from the Start Menu find and select Visual Studio 2017.

vs2017

Step 2

Once Visual Studio Community 2017 has started, from the Menu choose File, then New then Project…

vs2017-file-new-project

Step 3

From New Project choose Visual C# from Installed, Templates then choose Blank App (Universal Windows) and then type in a Name and select a Location and then select Ok to create the Project
vs2017-new-project-window

Step 4

Then in New Universal Windows Project you need to select the Target Version this should be at least the Windows 10, version 1803 (10.0; Build 17134) which is the April 2018 Update and the Minimum Version to be the same.

vs2017-target-platform

The Target Version will control what features your application can use in Windows 10 so by picking the most recent version you’ll be able to take advantage of those features. To make sure you always have the most recent version, in Visual Studio 2017 select Tools Extensions and Updates… then and then see if there are any Updates

Step 5

In the Solution Explorer select MainPage.xaml

vs2017-mainpage

Step 6

From the Menu choose View and then Designer

vs2017-view-designer

Step 7

The Design View will be displayed along with the XAML View and in this between the Grid and /Grid elements, enter the following XAML:

<CommandBar VerticalAlignment="Bottom">
	<AppBarButton Icon="Bold" Label="Bold" AccessKey="B" Click="Button_Click"/>
	<AppBarButton Icon="Italic" Label="Italic" AccessKey="I" Click="Button_Click" />
	<AppBarButton Icon="Underline" Label="Underline" AccessKey="U"  Click="Button_Click"/>
</CommandBar>

This block of XAML as a CommandBar which contains some example options such as Bold, Italic and Underline which when triggered by either Access Keys or when tapped will perform the relevant function.

Step 8

From the Menu choose View and then Code

vs2017-view-code

Step 9

Once in the Code View, below the end of public MainPage() { … } the following Code should be entered:

private async void Button_Click(object sender, RoutedEventArgs e)
{
	await new Windows.UI.Popups.MessageDialog($"Button: {((AppBarButton)sender).Label}").ShowAsync();
}

The Button_Click is an Event that will be triggered when the Button is Clicked. Within this is a MessageDialog which will be used to display a message depending on which AppBarButton has been triggered by Click Event or AccessKey

Step 10

That completes the Universal Windows Platform Application so Save the Project then in Visual Studio select the Local Machine to run the Application

vs2017-local-machine

Step 11

Once the Application has started running you can then press Alt on your Keyboard to show the access keys for the commands on the Command Bar

uwp-ran-access-keys

Step 12

To Exit the Application select the Close button in the top right of the Application

vs2017-close

It’s easy to use Access Keys in an Application as all that’s needed is to set the AccessKey property on a Button and that’s it – it used to be a bit more complicated to display the necessary ToolTip but that’s no longer the case, the example will show a MessageDialog to confirm which option has been selected whether Alt plus a key on the Keyboard has been used or the Button has been selected to show that it will perform the same function.

Creative Commons License