323 lines
13 KiB
C#
323 lines
13 KiB
C#
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.Red;
|
|
private readonly Color DEFAULT_EMPTY_COLOR = Color.LightGray;
|
|
private readonly Color DEFAULT_UNDISCOVERED_COLOR = Color.DarkOliveGreen;
|
|
private readonly Color DEFAULT_DISCOVERED_COLOR = Color.Black;
|
|
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;
|
|
|
|
private Point _gridOffset;
|
|
private Size _drawedBlocSize;
|
|
|
|
public Size GridSize { get => _gridSize; set => _gridSize = value; }
|
|
public Line[] HorizontalLines { get => _horizontalLines; set => _horizontalLines = value; }
|
|
public Line[] VerticalLines { get => _verticalLines; set => _verticalLines = value; }
|
|
public Point GridOffset
|
|
{
|
|
get { return _gridOffset; }
|
|
set { if (value.X >= 0 && value.Y >= 0) { _gridOffset = value; } else { _gridOffset = new Point(-1, -1); }}
|
|
}
|
|
|
|
public Size DrawedBlocSize { get => _drawedBlocSize; set => _drawedBlocSize = value; }
|
|
|
|
public Grid(Size size)
|
|
{
|
|
GridSize = size;
|
|
HorizontalLines = new Line[size.Height];
|
|
VerticalLines = new Line[size.Width];
|
|
GridOffset = new Point(-1,-1);
|
|
Populate();
|
|
}
|
|
public Grid(string filePath)
|
|
{
|
|
ImportFromFile(filePath);
|
|
}
|
|
public void Click(Point position)
|
|
{
|
|
//MessageBox.Show(position.ToString());
|
|
if (GridOffset != new Point(-1, -1))
|
|
{
|
|
//The Grid has been Drawned and has a valid offset
|
|
if (position.X >= GridOffset.X && position.Y >= GridOffset.Y)
|
|
{
|
|
//The click is on the grid
|
|
Point relativePoint = new Point(position.X-GridOffset.X, position.Y-GridOffset.Y);
|
|
Point reducedIndex = new Point(relativePoint.X / DrawedBlocSize.Width,relativePoint.Y / DrawedBlocSize.Height);
|
|
//int flatIndex = position.Y * HorizontalLines.Count() + position.X;
|
|
HorizontalLines[reducedIndex.Y].Click(reducedIndex.X);
|
|
VerticalLines[reducedIndex.X].Click(reducedIndex.Y);
|
|
}
|
|
}
|
|
}
|
|
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<int>[] rows;
|
|
List<int>[] columns;
|
|
string rawData = "";
|
|
|
|
//It would be smart to have a Header Struct to store all those metadatas
|
|
Regex rx = new Regex(@"^catalogue ""(?<content>.+)""",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 ""(?<content>.+)""", 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 ""(?<content>.+)""", 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 ""(?<content>.+)""", 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 (?<content>.+)$", 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 (?<height>[0-9]+)\nwidth (?<width>[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));
|
|
}
|
|
*/
|
|
|
|
int height = 0;
|
|
int width = 0;
|
|
|
|
rx = new Regex(@"^height (?<height>[0-9]+)", RegexOptions.Multiline | RegexOptions.IgnoreCase);
|
|
matches = rx.Matches(fileContent);
|
|
if (matches.Count > 0 && matches[0].Groups.Count > 0)
|
|
{
|
|
height = Convert.ToInt32(matches[0].Groups[1].Value);
|
|
}
|
|
rx = new Regex(@"^width (?<height>[0-9]+)", RegexOptions.Multiline | RegexOptions.IgnoreCase);
|
|
matches = rx.Matches(fileContent);
|
|
if (matches.Count > 0 && matches[0].Groups.Count > 0)
|
|
{
|
|
width = Convert.ToInt32(matches[0].Groups[1].Value);
|
|
}
|
|
|
|
size = new Size(width,height);
|
|
|
|
//string TEST = "";
|
|
rows = new List<int>[size.Height];
|
|
rx = new Regex(@"^rows\n(?<row>[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<int>[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;
|
|
}
|
|
|
|
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);
|
|
|
|
DrawedBlocSize = blocSize;
|
|
GridOffset = offset;
|
|
|
|
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_DISCOVERED_COLOR), new Rectangle(position, blocSize));
|
|
break;
|
|
case Tile.State.Undiscovered:
|
|
g.FillRectangle(new SolidBrush(DEFAULT_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;
|
|
}
|
|
}
|
|
}
|