using System.Collections.Generic;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO.Compression;
public Tile[,] Grid { get; set; }
public Tile [][] GridArrays
get { return Grid?.ToJaggedArray(); }
set { Grid = value?.To2dArray(); }
public int Width { get; set; }
public int Height { get; set; }
public int NumberOfMines { get; set; }
public int X { get; set; }
public int Y { get; set; }
public int NeighbourMines { get; set; }
public bool IsMine { get; set; }
public bool IsRevealed { get; set; }
public bool IsFlagged { get; set; }
public static class ListExtensions
public static T [][] ToJaggedArray<T>(this T [,] twoDimensionalArray)
int rowsFirstIndex = twoDimensionalArray.GetLowerBound(0);
int rowsLastIndex = twoDimensionalArray.GetUpperBound(0);
int numberOfRows = rowsLastIndex + 1;
int columnsFirstIndex = twoDimensionalArray.GetLowerBound(1);
int columnsLastIndex = twoDimensionalArray.GetUpperBound(1);
int numberOfColumns = columnsLastIndex + 1;
T[][] jaggedArray = new T[numberOfRows][];
for (int i = rowsFirstIndex; i <= rowsLastIndex; i++)
jaggedArray[i] = new T[numberOfColumns];
for (int j = columnsFirstIndex; j <= columnsLastIndex; j++)
jaggedArray[i][j] = twoDimensionalArray[i + rowsFirstIndex, j + columnsFirstIndex];
public static T[,] To2dArray<T>(this IReadOnlyList<IReadOnlyList<T>> arrays)
var minorLength = arrays.Max(i => i.Count);
var array2d = new T[arrays.Count, minorLength];
for (int i = 0; i < arrays.Count; i++)
for (int j = 0; j < minorLength; j++)
array2d[i, j] = array[j];
public static void Test()
int width = 2, height = 3;
Grid = Enumerable.Range(0, width).Select(row => Enumerable.Range(0, height).Select(col => new Tile { X = row, Y = col }).ToList()).ToList().To2dArray()
var ms2 = xml.LoadFromXml<Minesweeper>();
Assert.IsTrue(ms.Grid.GetLength(0) == ms2.Grid.GetLength(0) && ms.Grid.GetLength(1) == ms2.Grid.GetLength(1));
Assert.IsTrue(ms.Grid.Cast<Tile>().Select(g => new { g.X, g.Y }).SequenceEqual(ms.Grid.Cast<Tile>().Select(g => new { g.X, g.Y })));
public static class XmlSerializationHelper
public static T LoadFromXml<T>(this string xmlString, XmlSerializer serial = null)
serial = serial ?? new XmlSerializer(typeof(T));
using (var reader = new StringReader(xmlString))
return (T)serial.Deserialize(reader);
public static string GetXml<T>(this T obj, XmlSerializer serializer = null, bool omitStandardNamespaces = false)
XmlSerializerNamespaces ns = null;
if (omitStandardNamespaces)
ns = new XmlSerializerNamespaces();
using (var textWriter = new StringWriter())
var settings = new XmlWriterSettings() { Indent = true };
using (var xmlWriter = XmlWriter.Create(textWriter, settings))
(serializer ?? new XmlSerializer(obj.GetType())).Serialize(xmlWriter, obj, ns);
return textWriter.ToString();
public static void Main()
Console.WriteLine("Environment version: {0} ({1})", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , GetNetCoreVersion());
Console.WriteLine("Failed with unhandled exception: ");
public static string GetNetCoreVersion()
var assembly = typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly;
var assemblyPath = assembly.CodeBase.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
int netCoreAppIndex = Array.IndexOf(assemblyPath, "Microsoft.NETCore.App");
if (netCoreAppIndex > 0 && netCoreAppIndex < assemblyPath.Length - 2)
return assemblyPath[netCoreAppIndex + 1];