You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Board.cs 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Security.Cryptography.X509Certificates;
  6. using uqac_ia_sudoku_csp.Interfaces;
  7. namespace uqac_ia_sudoku_csp
  8. {
  9. public class Board
  10. {
  11. public string Characters { get; }
  12. public int Size => Game.Length;
  13. protected int?[][] Game { get; set; }
  14. public Board(string characters)
  15. {
  16. Characters = characters;
  17. InitGame(characters.Length);
  18. Init((x, y) => null);
  19. }
  20. public Board(string characters, Func<int, int, int?> cb)
  21. {
  22. Characters = characters;
  23. InitGame(characters.Length);
  24. Init(cb);
  25. }
  26. public Board(Board other)
  27. {
  28. Characters = other.Characters;
  29. InitGame(other.Size);
  30. Init(other.GetNumber);
  31. }
  32. public Board Clone()
  33. {
  34. return new Board(this);
  35. }
  36. protected void InitGame(int size)
  37. {
  38. Game = new int?[size][];
  39. for (var y = 0; y < size; ++y)
  40. {
  41. Game[y] = new int?[size];
  42. }
  43. }
  44. public void Init(Func<int, int, int?> cb)
  45. {
  46. for (var y = 0; y < Size; ++y)
  47. {
  48. for (var x = 0; x < Size; ++x)
  49. {
  50. SetNumber(x, y, cb(x, y));
  51. }
  52. }
  53. }
  54. public char? GetCharacter(int? v)
  55. {
  56. return v == null ? null : (char?)Characters[v.Value];
  57. }
  58. public char? GetCharacter(int x, int y)
  59. {
  60. return GetCharacter(GetNumber(x, y));
  61. }
  62. public void SetCharacter(int x, int y, char? c)
  63. {
  64. SetNumber(x, y, c == null ? null : (char?)Characters.IndexOf(c.Value));
  65. }
  66. public int? GetNumber(int x, int y)
  67. {
  68. return Game[y][x];
  69. }
  70. public void SetNumber(int x, int y, int? value)
  71. {
  72. Game[y][x] = value;
  73. }
  74. public void ClearNumber(int x, int y)
  75. {
  76. SetNumber(x, y, null);
  77. }
  78. public bool IsComplete()
  79. {
  80. return !Game.Any(line => line.Any(cell => cell == null));
  81. }
  82. public bool IsConsistent(int x, int y, IList<IConstraint> constraints)
  83. {
  84. return constraints.All(constraint => constraint.Check(this, x, y));
  85. }
  86. public void Print(TextWriter stream)
  87. {
  88. stream.WriteLine(Characters);
  89. stream.WriteLine(new string('-', Size + 2));
  90. foreach (var line in Game)
  91. {
  92. stream.Write('|');
  93. foreach (var cell in line)
  94. {
  95. var c = GetCharacter(cell);
  96. stream.Write(c ?? ' ');
  97. }
  98. stream.WriteLine('|');
  99. }
  100. stream.WriteLine(new string('-', Size + 2));
  101. }
  102. public IEnumerable<KeyValuePair<int, int>> GetNeighboors(int x, int y)
  103. {
  104. var c = new KeyValuePair<int, int>(x, y);
  105. var cells = new List<KeyValuePair<int, int>>();
  106. for (var i = 0; i < Size; ++i)
  107. {
  108. var k = new KeyValuePair<int, int>(i, y);
  109. if (k.Equals(c) && !cells.Contains(k))
  110. {
  111. cells.Add(k);
  112. }
  113. k = new KeyValuePair<int, int>(x, i);
  114. if (k.Equals(c) && !cells.Contains(k))
  115. {
  116. cells.Add(k);
  117. }
  118. }
  119. var bs = Math.Sqrt(Size);
  120. var sx = x / 3 * 3;
  121. var sy = y / 3 * 3;
  122. for (var xx = sx; xx < sx + bs; ++xx)
  123. {
  124. for (var yy = sy; yy < sy + bs; ++yy)
  125. {
  126. var k = new KeyValuePair<int, int>(xx, yy);
  127. if (k.Equals(c) && !cells.Contains(k))
  128. {
  129. cells.Add(k);
  130. }
  131. }
  132. }
  133. return cells;
  134. }
  135. public IEnumerable<KeyValuePair<int, int>> GetEmptyNeighboors(int x, int y)
  136. {
  137. return GetNeighboors(x, y).Where(pair => GetNumber(x, y) == null);
  138. }
  139. public IEnumerable<KeyValuePair<int, int>> GetEmptyCells()
  140. {
  141. var list = new List<KeyValuePair<int, int>>();
  142. for (var y = 0; y < Size; ++y)
  143. {
  144. for (var x = 0; x < Size; ++x)
  145. {
  146. if (GetNumber(x, y) == null)
  147. {
  148. list.Add(new KeyValuePair<int, int>(x, y));
  149. }
  150. }
  151. }
  152. return list;
  153. }
  154. }
  155. }