using System.Collections.Generic;
public static void Main()
Grid grid = new Grid(3, 3);
private void DrawGrid(Cell[,] grid)
for (int x = 0; x < grid.GetLength(0); x++)
for (int y = 0; y < grid.GetLength(1); y++)
Console.Write(grid[x, y].GetValue());
Random rand = new Random(3);
public Grid(int widthIn, int heightIn)
valueCount = new int[(sectorWidth * sectorHeight) + 1];
cells = new Cell[sectorWidth * sectorHeight, sectorWidth * sectorHeight];
for (int x = 0; x < cells.GetLength(0); x++)
for (int y = 0; y < cells.GetLength(1); y++)
cells[x, y] = new Cell(sectorWidth * sectorHeight);
for (int y = 0; y < cells.GetLength(1); y++)
for (int x = 0; x < cells.GetLength(0); x++)
if (x % sectorWidth == 0)
Console.Write(cells[x, y].GetValue() + " ");
if ((y + 1) % sectorHeight == 0)
return cells.GetLength(0);
public Cell GetCellAt(int x, int y)
public Cell[] GetSectorAt(int xIn, int yIn)
Cell[] sectorCells = new Cell[sectorWidth * sectorHeight];
while (xIn % sectorWidth != 0)
while (yIn % sectorHeight != 0)
for (int x = 0; x < sectorWidth; x++)
for (int y = 0; y < sectorHeight; y++)
sectorCells[x + (y * sectorWidth)] = cells[xIn + x, yIn + y];
public void FillCell(int x, int y, int intIn)
cells[x, y].ChooseOption(intIn);
RemoveFromColumn(x, intIn);
RemoveFromSector(x, y, intIn);
public bool RowHas(int rowY, int intIn)
for (int x = 0; x < sectorWidth * sectorHeight; x++)
if (cells[x, rowY].GetValue() == intIn)
public bool ColumnHas(int colX, int intIn)
for (int y = 0; y < sectorWidth * sectorHeight; y++)
if (cells[colX, y].GetValue() == intIn)
public bool SectorHas(int xIn, int yIn, int intIn)
Cell[] sectorCells = GetSectorAt(xIn, yIn);
for (int i = 0; i < sectorCells.Length; i++)
if (sectorCells[i].GetValue() == intIn)
public void RemoveFromRow(int rowY, int intIn)
for (int x = 0; x < cells.GetLength(0); x++)
if (cells[x, rowY].GetValue() != intIn)
cells[x, rowY].RemoveOption(intIn);
public void RemoveFromColumn(int colX, int intIn)
for (int y = 0; y < cells.GetLength(1); y++)
if (cells[colX, y].GetValue() != intIn)
cells[colX, y].RemoveOption(intIn);
public void RemoveFromSector(int xIn, int yIn, int intIn)
Cell[] sectorCells = GetSectorAt(xIn, yIn);
for (int i = 0; i < sectorCells.Length; i++)
if (!sectorCells[i].HasValue())
sectorCells[i].RemoveOption(intIn);
public void ClearAll(int intIn)
for (int x = 0; x < sectorWidth * sectorHeight; x++)
for (int y = 0; y < sectorWidth * sectorHeight; y++)
if (!cells[x, y].HasValue())
cells[x, y].AddOption(intIn);
else if (cells[x, y].GetValue() == intIn)
cells[x, y].FillOptions();
public List<int[]> GetCoordsWithOption(int intIn)
List<int[]> listOut = new List<int[]>();
for (int x = 0; x < sectorWidth * sectorHeight; x++)
for (int y = 0; y < sectorWidth * sectorHeight; y++)
if (!cells[x, y].HasValue() && cells[x, y].HasOption(intIn))
listOut.Add(new int[] { x, y });
public void FillSectorNecessary(int secStartX, int secStartY, int intIn)
for (int x = 0; x < sectorWidth; x++)
for (int y = 0; y < sectorHeight; y++)
if (!cells[secStartX + x, secStartY + y].HasValue() && cells[secStartX + x, secStartY + y].HasOption(intIn))
for (int x = 0; x < sectorWidth; x++)
for (int y = 0; y < sectorHeight; y++)
if (cells[secStartX + x, secStartY + y].HasOption(intIn))
FillCell(secStartX + x, secStartY + y, intIn);
Console.WriteLine("Filled a necessary " + intIn + " at " + (secStartX + x) + ", " + (secStartY + y));
public void FillGridNecessary(int intIn)
for (int i = 0; i < sectorWidth * sectorHeight; i++)
for (int j = 0; j < sectorWidth * sectorHeight; j++)
int secStartX = (j % sectorWidth) * sectorWidth;
int secStartY = (int)(j / sectorHeight) * sectorHeight;
FillSectorNecessary(secStartX, secStartY, intIn);
public void FillSectorsWith(int intIn)
while (valueCount[intIn] < sectorWidth * sectorHeight && safety < max)
int max2 = sectorWidth * sectorHeight;
for (int i = 0; i < max2; i++)
List<int[]> coordOptions = GetCoordsWithOption(intIn);
if (coordOptions.Count > 0)
int randIndex = rand.Next(0, coordOptions.Count);
int[] randCoord = coordOptions[randIndex];
bool shouldFill = !cells[randCoord[0], randCoord[1]].HasValue() &&
!RowHas(randCoord[1], intIn) && !ColumnHas(randCoord[0], intIn) && !SectorHas(randCoord[0], randCoord[1], intIn);
FillCell(randCoord[0], randCoord[1], intIn);
FillGridNecessary(intIn);
public void CreateSolution()
int valueMax = sectorWidth * sectorHeight;
for (int i = 1; i <= 8; i++)
public Cell(int optionCount)
options = new int[optionCount];
public int GetOptionCount()
for (int i = 0; i < options.Length; i++)
public bool HasOption(int intIn)
for (int i = 0; i < options.Length; i++)
if (GetOptionCount() == 1)
public void FillOptions()
for (int i = 0; i < options.Length; i++)
public void AddOption(int intIn)
options[intIn - 1] = intIn;
public void RemoveOption(int intIn)
for (int i = 0; i < options.Length; i++)
public void ChooseOption(int intIn)
for (int i = 0; i < options.Length; i++)
if (options.Length > 1 && options[i] != intIn)
if (GetOptionCount() == 1)
for (int i = 0; i < options.Length; i++)
for (int i = 0; i < options.Length; i++)
Console.Write(options[i] + ", ");