using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Drawing; using System.IO; using System.Windows.Forms; using System.Text.RegularExpressions; namespace NonoGramme { internal class Grid { private readonly Color DEFAULT_FULL_COLOR = Color.Black; private readonly Color DEFAULT_EMPTY_COLOR = Color.LightGray; private readonly Color DEBUG_UNDISCOVERED_COLOR = Color.DarkOliveGreen; private readonly Color DEFAULT_BORDER_COLOR = Color.Pink; private readonly Color DEFAULT_ERROR_COLOR = Color.Purple; private Size _gridSize; private Line[] _horizontalLines; private Line[] _verticalLines; public Size GridSize { get => _gridSize; set => _gridSize = value; } internal Line[] HorizontalLines { get => _horizontalLines; set => _horizontalLines = value; } internal Line[] VerticalLines { get => _verticalLines; set => _verticalLines = value; } public Grid(Size size) { GridSize = size; HorizontalLines = new Line[size.Height]; VerticalLines = new Line[size.Width]; Populate(); } public Grid(string filePath) { ImportFromFile(filePath); } public void ImportFromFile(string filePath) { //GridSize = size; //HorizontalLines = new Line[size.Height]; //VerticalLines = new Line[size.Width]; string fileContent = File.ReadAllText(filePath); string catalogue = ""; string title = ""; string author = ""; string copyright = ""; string license = ""; Size size = new Size(0,0); List[] rows; List[] columns; string rawData = ""; //It would be smart to have a Header Struct to store all those metadatas Regex rx = new Regex(@"^catalogue ""(?.+)""",RegexOptions.Multiline| RegexOptions.IgnoreCase); MatchCollection matches = rx.Matches(fileContent); if (matches.Count > 0 && matches[0].Groups.Count > 0) { catalogue = matches[0].Groups[1].Value; } rx = new Regex(@"^title ""(?.+)""", RegexOptions.Multiline | RegexOptions.IgnoreCase); matches = rx.Matches(fileContent); if (matches.Count > 0 && matches[0].Groups.Count > 0) { title = matches[0].Groups[1].Value; } rx = new Regex(@"^by ""(?.+)""", RegexOptions.Multiline | RegexOptions.IgnoreCase); matches = rx.Matches(fileContent); if (matches.Count > 0 && matches[0].Groups.Count > 0) { author = matches[0].Groups[1].Value; } rx = new Regex(@"^copyright ""(?.+)""", RegexOptions.Multiline | RegexOptions.IgnoreCase); matches = rx.Matches(fileContent); if (matches.Count > 0 && matches[0].Groups.Count > 0) { copyright = matches[0].Groups[1].Value; } rx = new Regex(@"^license (?.+)$", RegexOptions.Multiline | RegexOptions.IgnoreCase); matches = rx.Matches(fileContent); if (matches.Count > 0 && matches[0].Groups.Count > 0) { license = matches[0].Groups[1].Value; } rx = new Regex(@"^height (?[0-9]+)\nwidth (?[0-9]+)", RegexOptions.Multiline | RegexOptions.IgnoreCase); matches = rx.Matches(fileContent); if (matches.Count > 0 && matches[0].Groups.Count > 0) { size =new Size(Convert.ToInt32(matches[0].Groups["width"].Value), Convert.ToInt32(matches[0].Groups["height"].Value)); } string TEST = ""; rows = new List[size.Height]; rx = new Regex(@"^rows\n(?[0-9,]+\r?\n)+", RegexOptions.Multiline); matches = rx.Matches(fileContent); if (matches.Count > 0 && matches[0].Groups.Count > 0) { /* foreach (GroupCollection group in matches[0].Groups) { TEST += @"\n"+group[0].Value; } */ } columns = new List[size.Height]; rx = new Regex(@"^columns\n([0-9,]+\r?\n)+", RegexOptions.Multiline); matches = rx.Matches(fileContent); if (matches.Count > 0 && matches[0].Groups.Count > 0) { //TODO } rx = new Regex(@"^goal ""([0-1]+)""", RegexOptions.Multiline | RegexOptions.IgnoreCase); matches = rx.Matches(fileContent); if (matches.Count > 0 && matches[0].Groups.Count > 0) { rawData = matches[0].Groups[1].Value; } //MessageBox.Show(rawData); if (rawData.Length != size.Width * size.Height) MessageBox.Show("The file contains conflicting datas"); //Filling the class with infos GridSize = size; HorizontalLines = new Line[GridSize.Height]; VerticalLines = new Line[GridSize.Width]; for (int y = 0; y < GridSize.Height; y++) { HorizontalLines[y] = new Line(GridSize.Width); for (int x = 0; x < GridSize.Width; x++) { if (y == 0) { VerticalLines[x] = new Line(GridSize.Height); } Tile.State tileState = Tile.State.Empty; int flatIndex = y * GridSize.Width + x; if (rawData[flatIndex] == 1) { tileState = Tile.State.Undiscovered; } HorizontalLines[y].Edit(x,tileState); VerticalLines[x].Edit(y,tileState); } } MessageBox.Show("File imported Successfully"); } private void Populate() { Random rnd = new Random(); for (int y = 0; y < GridSize.Height; y++) { HorizontalLines[y] = new Line(GridSize.Width); for (int x = 0; x < GridSize.Width; x++) { if (y == 0) { VerticalLines[x] = new Line(GridSize.Height); } Tile.State state; int rndResult = rnd.Next(1, 4); switch (rndResult) { case 2: state = Tile.State.Empty; break; case 3: state = Tile.State.Undiscovered; break; default: state = Tile.State.Empty; break; } HorizontalLines[y].Edit(x, state); VerticalLines[x].Edit(y, state); } } Console.WriteLine("Coucou"); } public void RefreshGrid() { foreach (Line line in HorizontalLines) { line.RecalculateHints(); } foreach (Line line in VerticalLines) { line.RecalculateHints(); } } public Bitmap Draw(Bitmap UI,Point offset) { RefreshGrid(); Size actualSize = new Size(UI.Width - offset.X, UI.Height - offset.Y); Size blocSize = new Size(actualSize.Width/GridSize.Width,actualSize.Height/GridSize.Height); using (Graphics g = Graphics.FromImage(UI)) { //Drawing the rows Text int rowCount = 0; string hints = ""; for (int i = 0; i < HorizontalLines.Count(); i++) { hints = HorizontalLines[i].GetHorizontalHints(); g.DrawString(hints,new Font("Arial",16),Brushes.Black,new Point(0,offset.Y + rowCount*blocSize.Height)); rowCount++; } //Drawing the columns Text int columnCount = 0; hints = ""; for (int i = 0; i < VerticalLines.Count(); i++) { hints = VerticalLines[i].GetVerticalHints(); g.DrawString(hints, new Font("Arial", 16), Brushes.Black, new Point(offset.Y + columnCount * blocSize.Width, 0)); columnCount++; } //Drawing the grid int row = 0; foreach (Line line in HorizontalLines) { int column = 0; foreach (Tile tile in line.Data) { Point position = new Point((column*blocSize.Width) + offset.X,(row*blocSize.Height) + offset.Y); switch (tile.CurrentState) { case Tile.State.Full: g.FillRectangle(new SolidBrush(DEFAULT_FULL_COLOR),new Rectangle(position,blocSize)); break; case Tile.State.Empty: g.FillRectangle(new SolidBrush(DEFAULT_EMPTY_COLOR), new Rectangle(position, blocSize)); break; case Tile.State.Discovered: g.FillRectangle(new SolidBrush(DEFAULT_EMPTY_COLOR), new Rectangle(position, blocSize)); break; case Tile.State.Undiscovered: g.FillRectangle(new SolidBrush(DEBUG_UNDISCOVERED_COLOR), new Rectangle(position, blocSize)); break; default: g.FillRectangle(new SolidBrush(DEFAULT_ERROR_COLOR), new Rectangle(position, blocSize)); break; } //We need to draw the outline AFTER the fill or it will be covered g.DrawRectangle(new Pen(DEFAULT_BORDER_COLOR), new Rectangle(position, blocSize)); column++; } row++; } } return UI; } } }