194 lines
6.8 KiB
C#
194 lines
6.8 KiB
C#
|
/*
|
||
|
Wordsearch Creator
|
||
|
Copyright (C) 2023 Tesses
|
||
|
|
||
|
This program is free software: you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation, either version 3 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
using System.Text;
|
||
|
using SixLabors.Fonts;
|
||
|
using SixLabors.ImageSharp;
|
||
|
using SixLabors.ImageSharp.Drawing.Processing;
|
||
|
using SixLabors.ImageSharp.PixelFormats;
|
||
|
using SixLabors.ImageSharp.Processing;
|
||
|
|
||
|
namespace WordSearch
|
||
|
{
|
||
|
public class WordSearchGenerator
|
||
|
{
|
||
|
Random rand=new Random((int)(DateTime.Now.Ticks % int.MaxValue));
|
||
|
List<string> words = new List<string>();
|
||
|
List<string> wordsOg = new List<string>();
|
||
|
int largestWord=0;
|
||
|
public IReadOnlyList<string> Words => wordsOg;
|
||
|
public int LargestWord => largestWord;
|
||
|
|
||
|
public void AddWord(string word)
|
||
|
{
|
||
|
if(string.IsNullOrWhiteSpace(word)) return;
|
||
|
if(word.Length > largestWord) largestWord = word.Length;
|
||
|
words.Add(word.Replace(" ","").ToUpper());
|
||
|
wordsOg.Add(word);
|
||
|
}
|
||
|
public override string ToString()
|
||
|
{
|
||
|
StringBuilder builder=new StringBuilder();
|
||
|
var grid=GenerateGrid();
|
||
|
for(int y=0;y<largestWord;y++)
|
||
|
{
|
||
|
for(int x=0;x<largestWord;x++)
|
||
|
{
|
||
|
builder.Append(grid[x,y]);
|
||
|
}
|
||
|
builder.AppendLine();
|
||
|
}
|
||
|
builder.AppendLine();
|
||
|
foreach(var word in words)
|
||
|
{
|
||
|
builder.AppendLine(word);
|
||
|
}
|
||
|
return builder.ToString();
|
||
|
}
|
||
|
public Image<Rgb24> GenerateImage(Font font,Rgb24 foreground,Rgb24 background)
|
||
|
{
|
||
|
var grid=GenerateGrid();
|
||
|
StringBuilder b = new StringBuilder();
|
||
|
for(int y = 0;y<largestWord;y++)
|
||
|
{
|
||
|
for(int x=0;x<largestWord;x++)
|
||
|
{
|
||
|
if(x>0)
|
||
|
b.Append(' ');
|
||
|
b.Append(grid[x,y]);
|
||
|
}
|
||
|
b.AppendLine();
|
||
|
b.AppendLine();
|
||
|
}
|
||
|
|
||
|
for(int i = 0;i<wordsOg.Count;i++)
|
||
|
{
|
||
|
b.Append(wordsOg[i]);
|
||
|
if((i % 3) == 2)
|
||
|
{
|
||
|
b.AppendLine();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
b.Append(' ');
|
||
|
}
|
||
|
}
|
||
|
b.AppendLine();
|
||
|
string text= b.ToString();
|
||
|
var sz=TextMeasurer.MeasureSize(text,new TextOptions(font));
|
||
|
|
||
|
Image<Rgb24> image = new Image<Rgb24>((int)Math.Ceiling(sz.Width)+40,(int)Math.Ceiling(sz.Height)+40,background);
|
||
|
image.Mutate(e=>e.DrawText(text,font,foreground,new PointF(20,20)));
|
||
|
return image;
|
||
|
}
|
||
|
public char[,] GenerateGrid()
|
||
|
{
|
||
|
DateTime mustbeDoneBefore=DateTime.Now.AddMinutes(1);
|
||
|
char[,] grid = new char[largestWord,largestWord];
|
||
|
|
||
|
|
||
|
foreach(var word in words)
|
||
|
{
|
||
|
err:
|
||
|
if(DateTime.Now > mustbeDoneBefore) throw new Exception();
|
||
|
|
||
|
int x=rand.Next(0,largestWord);
|
||
|
int y = rand.Next(0,largestWord);
|
||
|
int mode = rand.Next(0,4);
|
||
|
|
||
|
switch(mode)
|
||
|
{
|
||
|
case 0:
|
||
|
//Horizontal
|
||
|
if(x+word.Length>largestWord) goto err;
|
||
|
for(int i = 0;i<word.Length;i++)
|
||
|
{
|
||
|
if(DateTime.Now > mustbeDoneBefore) throw new Exception();
|
||
|
|
||
|
//check whether these are all zeros
|
||
|
if(grid[x+i,y] != 0) goto err;
|
||
|
}
|
||
|
for(int i =0;i<word.Length;i++)
|
||
|
{
|
||
|
|
||
|
grid[x+i,y] = word[i];
|
||
|
}
|
||
|
break;
|
||
|
case 1:
|
||
|
if(y+word.Length>largestWord) goto err;
|
||
|
for(int i = 0;i<word.Length;i++)
|
||
|
{
|
||
|
if(DateTime.Now > mustbeDoneBefore) throw new Exception();
|
||
|
|
||
|
//check whether these are all zeros
|
||
|
if(grid[x,y+i] != 0) goto err;
|
||
|
}
|
||
|
for(int i =0;i<word.Length;i++)
|
||
|
{
|
||
|
grid[x,y+i] = word[i];
|
||
|
}
|
||
|
break;
|
||
|
case 2: //\
|
||
|
if(y+word.Length>largestWord || x+word.Length> largestWord) goto err;
|
||
|
for(int i = 0;i<word.Length;i++)
|
||
|
{
|
||
|
if(DateTime.Now > mustbeDoneBefore) throw new Exception();
|
||
|
|
||
|
//check whether these are all zeros
|
||
|
if(grid[x+i,y+i] != 0) goto err;
|
||
|
}
|
||
|
for(int i =0;i<word.Length;i++)
|
||
|
{
|
||
|
grid[x+i,y+i] = word[i];
|
||
|
}
|
||
|
break;
|
||
|
case 3:// /
|
||
|
if(y+word.Length>largestWord || x-word.Length< 0) goto err;
|
||
|
for(int i = 0;i<word.Length;i++)
|
||
|
{
|
||
|
if(DateTime.Now > mustbeDoneBefore) throw new Exception();
|
||
|
|
||
|
//check whether these are all zeros
|
||
|
if(grid[x-i,y+i] != 0) goto err;
|
||
|
}
|
||
|
for(int i =0;i<word.Length;i++)
|
||
|
{
|
||
|
grid[x-i,y+i] = word[i];
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
for(int y=0;y<largestWord;y++)
|
||
|
{
|
||
|
for(int x = 0;x<largestWord;x++)
|
||
|
{
|
||
|
if(grid[x,y] == 0)
|
||
|
{
|
||
|
int val=rand.Next(0,26);
|
||
|
if(val < 26)
|
||
|
{
|
||
|
grid[x,y] = (char)(val+'A');
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return grid;
|
||
|
}
|
||
|
}
|
||
|
}
|