Принятие решений нейронной сети в игре крестики нолики - C#

Узнай цену своей работы

Формулировка задачи:

Собственно есть нейронная сеть(слизанная с хабра), там нейронная сеть была предназначена для распознавания изображений, то есть использовались двухмерные массивы я заменил его на одно мерный так как поле в крестики нолики можно записать в одну строку. Суть проблемы принятие решений нейронной сети по факту она их принимает ^_^, но как сделать так что бы она стремилась к победе.
Листинг программы
  1. using System;
  2. namespace GA
  3. {
  4. class Program
  5. {
  6. static Random _random = new Random();
  7. public static int length = 9; // Колличество входных параметров
  8. public class Neuron
  9. {
  10. public int[] weight; // Веса нейронов
  11. public int minimum = 50; // Порог
  12. /**
  13. * Конструктор нейрона, создает веси и устанавливает случайные значения
  14. */
  15. public Neuron()
  16. {
  17. weight = new int[length];
  18. randomizeWeights();
  19. }
  20. /**
  21. * ответы нейронов, жесткая пороговая
  22. * @param input - входной вектор
  23. * @return ответ 0 или 1
  24. */
  25. public int transferHard(int[] input)
  26. {
  27. int Power = 0;
  28. for (int r = 0; r < length; r++)
  29. {
  30. Power += weight[r] * input[r];
  31. }
  32. //Debug.Log("Power: " + Power);
  33. return Power >= minimum ? 1 : 0;
  34. }
  35. /**
  36. * ответы нейронов с вероятностями
  37. * @param input - входной вектор
  38. * @return n вероятность
  39. */
  40. public int transfer(int[] input)
  41. {
  42. int Power = 0;
  43. for (int r = 0; r < length; r++)
  44. Power += weight[r] * input[r];
  45. //Debug.Log("Power: " + Power);
  46. return Power;
  47. }
  48. void randomizeWeights()
  49. {
  50. for (int r = 0; r < length; r++)
  51. weight[r] = _random.Next(0, 10);
  52. }
  53. /**
  54. * изменяет веса нейронов
  55. * @param input - входной вектор
  56. * @param d - разница между выходом нейрона и нужным выходом
  57. */
  58. public void changeWeights(int[] input, int d)
  59. {
  60. for (int r = 0; r < length; r++)
  61. weight[r] += d * input[r];
  62. }
  63. }
  64. public class NeuralNetwork
  65. {
  66. public Neuron[] neurons;
  67. /**
  68. * Конструктор сети создает нейроны
  69. */
  70. public NeuralNetwork()
  71. {
  72. neurons = new Neuron[10];
  73. for (int i = 0; i < neurons.Length; i++)
  74. neurons[i] = new Neuron();
  75. }
  76. /**
  77. * Функция распознавания символа, используется для обучения
  78. * @param input - входной вектор
  79. * @return массив из нуллей и единиц, ответы нейронов
  80. */
  81. int[] handleHard(int[] input)
  82. {
  83. int[] output = new int[neurons.Length];
  84. for (int i = 0; i < output.Length; i++)
  85. output[i] = neurons[i].transferHard(input);
  86. return output;
  87. }
  88. /**
  89. * Функция распознавания, используется для конечново ответа
  90. * @param input - входной вектор
  91. * @return массив из вероятностей, ответы нейронов
  92. */
  93. int[] handle(int[] input)
  94. {
  95. int[] output = new int[neurons.Length];
  96. for (int i = 0; i < output.Length; i++)
  97. output[i] = neurons[i].transfer(input);
  98. return output;
  99. }
  100. /**
  101. * Ответ сети
  102. * @param input - входной вектор
  103. * @return индекс нейронов предназначенный для конкретного символа
  104. */
  105. public int getAnswer(int[] input)
  106. {
  107. int[] output = handle(input);
  108. int maxIndex = 0;
  109. for (int i = 1; i < output.Length; i++)
  110. if (output[i] > output[maxIndex])
  111. maxIndex = i;
  112. return maxIndex;
  113. }
  114. /**
  115. * Функция обучения
  116. * @param input - входной вектор
  117. * @param correctAnswer - правильный ответ
  118. */
  119. public void study(int[] input, int correctAnswer)
  120. {
  121. int[] correctOutput = new int[neurons.Length];
  122. correctOutput[correctAnswer] = 1;
  123. int[] output = handleHard(input);
  124. while (!compareArrays(correctOutput, output))
  125. {
  126. for (int i = 0; i < neurons.Length; i++)
  127. {
  128. int dif = correctOutput[i] - output[i];
  129. neurons[i].changeWeights(input, dif);
  130. }
  131. output = handleHard(input);
  132. }
  133. }
  134. /**
  135. * Сравнение двух вектор
  136. * @param true - если массивы одинаковые, false - если нет
  137. */
  138. bool compareArrays(int[] a, int[] b)
  139. {
  140. if (a.Length != b.Length)
  141. return false;
  142. for (int i = 0; i < a.Length; i++)
  143. if (a[i] != b[i])
  144. return false;
  145. return true;
  146. }
  147. }
  148. private static void Main(string[] args)
  149. {
  150. NeuralNetwork nw = new NeuralNetwork();
  151. int[] table =
  152. {
  153. 0, 0, 0,
  154. 0, 0, 0,
  155. 0, 0, 0
  156. };
  157. var win = false;
  158. while (!win)
  159. {
  160. #region PlayerInput
  161. int x;
  162. do
  163. {
  164. input:
  165. Console.Write("Введите номер клетки где поставить крестик: ");
  166. try
  167. {
  168. x = Convert.ToInt16(Console.ReadLine());
  169. }
  170. catch (Exception ex)
  171. {
  172. goto input;
  173. }
  174. } while (table[x-1] == 1 || table[x-1] == 2);
  175. table[x - 1] = 1;
  176. #endregion
  177. if (table[0] == 1 && table[1] == 1 && table[2] == 1 ||
  178. table[0] == 2 && table[1] == 2 && table[2] == 2 ||
  179. table[3] == 1 && table[4] == 1 && table[5] == 1 ||
  180. table[3] == 2 && table[4] == 2 && table[5] == 2 ||
  181. table[6] == 1 && table[7] == 1 && table[8] == 1 ||
  182. table[6] == 2 && table[7] == 2 && table[8] == 2 ||
  183. table[0] == 1 && table[4] == 1 && table[8] == 1 ||
  184. table[0] == 2 && table[4] == 2 && table[8] == 2 ||
  185. table[2] == 1 && table[4] == 1 && table[6] == 1 ||
  186. table[2] == 2 && table[4] == 2 && table[6] == 2 ||
  187. table[0] == 1 && table[3] == 1 && table[6] == 1 ||
  188. table[0] == 2 && table[3] == 2 && table[6] == 2 ||
  189. table[1] == 1 && table[4] == 1 && table[7] == 1 ||
  190. table[1] == 2 && table[4] == 2 && table[7] == 2 ||
  191. table[2] == 1 && table[5] == 1 && table[8] == 1 ||
  192. table[2] == 2 && table[5] == 2 && table[8] == 2)
  193. {
  194. win = true;
  195. }
  196. else
  197. {
  198. #region WriteTable
  199. for (int i = 0; i < table.Length; i++)
  200. {
  201. Console.Write(table[i] == 1 ? "X" : table[i] == 2 ? "O" : "-");
  202. if ((i + 1)%3 == 0 && i != 0)
  203. {
  204. Console.WriteLine();
  205. }
  206. }
  207. Console.WriteLine();
  208. #endregion
  209. #region NeuralNetwork
  210. int o;
  211. do
  212. {
  213. nw.study(table, _random.Next(0, 9));
  214. o = nw.getAnswer(table);
  215. } while (table[o] == 1 || table[o] == 2);
  216. table[o] = 2;
  217. #endregion
  218. if (table[0] == 1 && table[1] == 1 && table[2] == 1 ||
  219. table[0] == 2 && table[1] == 2 && table[2] == 2 ||
  220. table[3] == 1 && table[4] == 1 && table[5] == 1 ||
  221. table[3] == 2 && table[4] == 2 && table[5] == 2 ||
  222. table[6] == 1 && table[7] == 1 && table[8] == 1 ||
  223. table[6] == 2 && table[7] == 2 && table[8] == 2 ||
  224. table[0] == 1 && table[4] == 1 && table[8] == 1 ||
  225. table[0] == 2 && table[4] == 2 && table[8] == 2 ||
  226. table[2] == 1 && table[4] == 1 && table[6] == 1 ||
  227. table[2] == 2 && table[4] == 2 && table[6] == 2 ||
  228. table[0] == 1 && table[3] == 1 && table[6] == 1 ||
  229. table[0] == 2 && table[3] == 2 && table[6] == 2 ||
  230. table[1] == 1 && table[4] == 1 && table[7] == 1 ||
  231. table[1] == 2 && table[4] == 2 && table[7] == 2 ||
  232. table[2] == 1 && table[5] == 1 && table[8] == 1 ||
  233. table[2] == 2 && table[5] == 2 && table[8] == 2)
  234. {
  235. win = true;
  236. }
  237. #region WriteTable
  238. for (int i = 0; i < table.Length; i++)
  239. {
  240. Console.Write(table[i] == 1 ? "X" : table[i] == 2 ? "O" : "-");
  241. if ((i + 1)%3 == 0 && i != 0)
  242. {
  243. Console.WriteLine();
  244. }
  245. }
  246. Console.WriteLine();
  247. #endregion
  248. }
  249. }
  250. Console.WriteLine("Кто-то кого-то нагнул.");
  251. Console.ReadKey();
  252. }
  253. }
  254. }

Решение задачи: «Принятие решений нейронной сети в игре крестики нолики»

textual
Листинг программы
  1. using System;
  2. using System.Windows.Forms;
  3.  
  4. namespace NeuralNetwork
  5. {
  6.     public partial class Form1 : Form
  7.     {
  8.         #region NeuralNetwork
  9.  
  10.         private static Random _random = new Random();
  11.         public static int length = 9; // Колличество входных параметров
  12.  
  13.         public class Neuron
  14.         {
  15.             public int[] weight; // Веса нейронов
  16.             public int minimum = 50; // Порог
  17.  
  18.             /**
  19.              * Конструктор нейрона, создает веси и устанавливает случайные значения
  20.              */
  21.  
  22.             public Neuron()
  23.             {
  24.                 weight = new int[length];
  25.                 randomizeWeights();
  26.             }
  27.  
  28.             /**
  29.              * ответы нейронов, жесткая пороговая
  30.              * @param input - входной вектор
  31.              * @return ответ 0 или 1
  32.              */
  33.  
  34.             public int transferHard(int[] input)
  35.             {
  36.                 int Power = 0;
  37.                 for (int r = 0; r < length; r++)
  38.                 {
  39.  
  40.                     Power += weight[r]*input[r];
  41.                 }
  42.                 //Debug.Log("Power: " + Power);
  43.                 return Power >= minimum ? 1 : 0;
  44.             }
  45.  
  46.             /**
  47.              * ответы нейронов с вероятностями
  48.              * @param input - входной вектор
  49.              * @return n вероятность
  50.              */
  51.  
  52.             public int transfer(int[] input)
  53.             {
  54.                 int Power = 0;
  55.                 for (int r = 0; r < length; r++)
  56.                     Power += weight[r]*input[r];
  57.  
  58.                 //Debug.Log("Power: " + Power);
  59.                 return Power;
  60.             }
  61.  
  62.             private void randomizeWeights()
  63.             {
  64.                 for (int r = 0; r < length; r++)
  65.                     weight[r] = _random.Next(0, 10);
  66.             }
  67.  
  68.             /**
  69.              * изменяет веса нейронов
  70.              * @param input - входной вектор
  71.              * @param d - разница между выходом нейрона и нужным выходом
  72.              */
  73.  
  74.             public void changeWeights(int[] input, int d)
  75.             {
  76.                 for (int r = 0; r < length; r++)
  77.                     weight[r] += d*input[r];
  78.             }
  79.         }
  80.  
  81.         public class NeuralNetwork
  82.         {
  83.             public Neuron[] neurons;
  84.  
  85.             /**
  86.              * Конструктор сети создает нейроны
  87.              */
  88.  
  89.             public NeuralNetwork()
  90.             {
  91.                 neurons = new Neuron[9];
  92.  
  93.                 for (int i = 0; i < neurons.Length; i++)
  94.                     neurons[i] = new Neuron();
  95.             }
  96.  
  97.             /**
  98.              * Функция распознавания символа, используется для обучения
  99.              * @param input - входной вектор
  100.              * @return массив из нуллей и единиц, ответы нейронов
  101.              */
  102.  
  103.             private int[] handleHard(int[] input)
  104.             {
  105.                 int[] output = new int[neurons.Length];
  106.                 for (int i = 0; i < output.Length; i++)
  107.                     output[i] = neurons[i].transferHard(input);
  108.  
  109.                 return output;
  110.             }
  111.  
  112.             /**
  113.              * Функция распознавания, используется для конечново ответа
  114.              * @param input -  входной вектор
  115.              * @return массив из вероятностей, ответы нейронов
  116.              */
  117.  
  118.             private int[] handle(int[] input)
  119.             {
  120.                 int[] output = new int[neurons.Length];
  121.                 for (int i = 0; i < output.Length; i++)
  122.                     output[i] = neurons[i].transfer(input);
  123.  
  124.                 return output;
  125.             }
  126.  
  127.             /**
  128.              * Ответ сети
  129.              * @param input - входной вектор
  130.              * @return индекс нейронов предназначенный для конкретного символа
  131.              */
  132.  
  133.             public int getAnswer(int[] input)
  134.             {
  135.                 int[] output = handle(input);
  136.                 int maxIndex = 0;
  137.                 for (int i = 1; i < output.Length; i++)
  138.                     if (output[i] > output[maxIndex])
  139.                         maxIndex = i;
  140.  
  141.                 return maxIndex;
  142.             }
  143.  
  144.             /**
  145.              * Функция обучения
  146.              * @param input - входной вектор
  147.              * @param correctAnswer - правильный ответ
  148.              */
  149.  
  150.             public void study(int[] input, int correctAnswer)
  151.             {
  152.                 int[] correctOutput = new int[neurons.Length];
  153.                 correctOutput[correctAnswer] = 1;
  154.  
  155.                 int[] output = handleHard(input);
  156.                 while (!compareArrays(correctOutput, output))
  157.                 {
  158.                     for (int i = 0; i < neurons.Length; i++)
  159.                     {
  160.                         int dif = correctOutput[i] - output[i];
  161.                         neurons[i].changeWeights(input, dif);
  162.                     }
  163.                     output = handleHard(input);
  164.                 }
  165.             }
  166.  
  167.             /**
  168.              * Сравнение двух вектор
  169.              * @param true - если массивы одинаковые, false - если нет
  170.              */
  171.  
  172.             private bool compareArrays(int[] a, int[] b)
  173.             {
  174.                 if (a.Length != b.Length)
  175.                     return false;
  176.  
  177.                 for (int i = 0; i < a.Length; i++)
  178.                     if (a[i] != b[i])
  179.                         return false;
  180.  
  181.                 return true;
  182.             }
  183.         }
  184.  
  185.         #endregion
  186.  
  187.         private NeuralNetwork nw = new NeuralNetwork();
  188.  
  189.         private int[] _table =
  190.         {
  191.             0, 0, 0,
  192.             0, 0, 0,
  193.             0, 0, 0
  194.         };
  195.  
  196.         public Form1()
  197.         {
  198.             InitializeComponent();
  199.  
  200.             #region Начальное обучение. Основанное на рандоме.
  201.  
  202.             for (int i = 0; i < 4608; i++)
  203.             {
  204.                 answer1:
  205.                 int a = _random.Next(0, 9);
  206.                 if (_table[a] != 1 && _table[a] != 2)
  207.                     _table[a] = 1;
  208.                 else
  209.                     goto answer1;
  210.  
  211.                 CheckWin();
  212.  
  213.                 answer:
  214.  
  215.                 int answer = nw.getAnswer(_table);
  216.  
  217.                 if (_table[answer] != 1 && _table[answer] != 2)
  218.                 {
  219.  
  220.                     _table[answer] = 2;
  221.  
  222.                     if (answer == 0)
  223.                         button1.Text = @"O";
  224.                     if (answer == 1)
  225.                         button2.Text = @"O";
  226.                     if (answer == 2)
  227.                         button3.Text = @"O";
  228.                     if (answer == 3)
  229.                         button4.Text = @"O";
  230.                     if (answer == 4)
  231.                         button5.Text = @"O";
  232.                     if (answer == 5)
  233.                         button6.Text = @"O";
  234.                     if (answer == 6)
  235.                         button7.Text = @"O";
  236.                     if (answer == 7)
  237.                         button8.Text = @"O";
  238.                     if (answer == 8)
  239.                         button9.Text = @"O";
  240.  
  241.                     CheckWin();
  242.  
  243.                 }
  244.                 else
  245.                 {
  246.                     int index = _random.Next(0, 9);
  247.                     nw.study(_table, index);
  248.                     goto answer;
  249.                 }
  250.             }
  251.  
  252.             TableEmpty();
  253.             textBox1.Text = String.Empty;
  254.  
  255.             #endregion
  256.         }
  257.  
  258.         public void CheckWin()
  259.         {
  260.             if (_table[0] == 1 && _table[1] == 1 && _table[2] == 1 ||
  261.                 _table[3] == 1 && _table[4] == 1 && _table[5] == 1 ||
  262.                 _table[6] == 1 && _table[7] == 1 && _table[8] == 1 ||
  263.                 _table[0] == 1 && _table[4] == 1 && _table[8] == 1 ||
  264.                 _table[2] == 1 && _table[4] == 1 && _table[6] == 1 ||
  265.                 _table[0] == 1 && _table[3] == 1 && _table[6] == 1 ||
  266.                 _table[1] == 1 && _table[4] == 1 && _table[7] == 1 ||
  267.                 _table[2] == 1 && _table[5] == 1 && _table[8] == 1)
  268.             {
  269.                 textBox1.Text += @"Вы победили
  270. ";
  271.                 nw.study(_table, _random.Next(0, 9));
  272.                 TableEmpty();
  273.             }
  274.             else
  275.             {
  276.                 if (_table[0] == 2 && _table[1] == 2 && _table[2] == 2 ||
  277.                     _table[3] == 2 && _table[4] == 2 && _table[5] == 2 ||
  278.                     _table[6] == 2 && _table[7] == 2 && _table[8] == 2 ||
  279.                     _table[0] == 2 && _table[4] == 2 && _table[8] == 2 ||
  280.                     _table[2] == 2 && _table[4] == 2 && _table[6] == 2 ||
  281.                     _table[0] == 2 && _table[3] == 2 && _table[6] == 2 ||
  282.                     _table[1] == 2 && _table[4] == 2 && _table[7] == 2 ||
  283.                     _table[2] == 2 && _table[5] == 2 && _table[8] == 2)
  284.                 {
  285.                     textBox1.Text += @"Победила нейронная сеть
  286. ";
  287.                     nw.study(_table, _random.Next(0, 9));
  288.                     TableEmpty();
  289.                 }
  290.                 else
  291.                 {
  292.                     int counter = 0;
  293.                     for (int i = 0; i < _table.Length; i++)
  294.                     {
  295.                         if (_table[i] != 1 && _table[i] != 2)
  296.                             counter++;
  297.                     }
  298.                     if (counter == 0)
  299.                     {
  300.                         textBox1.Text += @"Ничья!
  301. ";
  302.                         nw.study(_table, _random.Next(0, 9));
  303.                         TableEmpty();
  304.                     }
  305.                 }
  306.             }
  307.  
  308.         }
  309.  
  310.         #region Кнопки
  311.  
  312.         private void button1_Click(object sender, EventArgs e)
  313.         {
  314.             if (_table[0] != 1 && _table[0] != 2)
  315.             {
  316.                 _table[0] = 1;
  317.                 button1.Text = @"X";
  318.                 CheckWin();
  319.  
  320.                 Answer();
  321.             }
  322.         }
  323.  
  324.         private void button2_Click(object sender, EventArgs e)
  325.         {
  326.             if (_table[1] != 1 && _table[1] != 2)
  327.             {
  328.                 _table[1] = 1;
  329.                 button2.Text = @"X";
  330.                 CheckWin();
  331.  
  332.                 Answer();
  333.             }
  334.         }
  335.  
  336.         private void button3_Click(object sender, EventArgs e)
  337.         {
  338.             if (_table[2] != 1 && _table[2] != 2)
  339.             {
  340.                 _table[2] = 1;
  341.                 button3.Text = @"X";
  342.                 CheckWin();
  343.  
  344.                 Answer();
  345.             }
  346.         }
  347.  
  348.         private void button4_Click(object sender, EventArgs e)
  349.         {
  350.             if (_table[3] != 1 && _table[3] != 2)
  351.             {
  352.                 _table[3] = 1;
  353.                 button4.Text = @"X";
  354.                 CheckWin();
  355.  
  356.                 Answer();
  357.             }
  358.         }
  359.  
  360.         private void button5_Click(object sender, EventArgs e)
  361.         {
  362.             if (_table[4] != 1 && _table[4] != 2)
  363.             {
  364.                 _table[4] = 1;
  365.                 button5.Text = @"X";
  366.                 CheckWin();
  367.  
  368.                 Answer();
  369.             }
  370.         }
  371.  
  372.         private void button6_Click(object sender, EventArgs e)
  373.         {
  374.             if (_table[5] != 1 && _table[5] != 2)
  375.             {
  376.                 _table[5] = 1;
  377.                 button6.Text = @"X";
  378.                 CheckWin();
  379.  
  380.                 Answer();
  381.             }
  382.         }
  383.  
  384.         private void button7_Click(object sender, EventArgs e)
  385.         {
  386.             if (_table[6] != 1 && _table[6] != 2)
  387.             {
  388.                 _table[6] = 1;
  389.                 button7.Text = @"X";
  390.                 CheckWin();
  391.  
  392.                 Answer();
  393.             }
  394.         }
  395.  
  396.         private void button8_Click(object sender, EventArgs e)
  397.         {
  398.             if (_table[7] != 1 && _table[7] != 2)
  399.             {
  400.                 _table[7] = 1;
  401.                 button8.Text = @"X";
  402.                 CheckWin();
  403.  
  404.                 Answer();
  405.             }
  406.         }
  407.  
  408.         private void button9_Click(object sender, EventArgs e)
  409.         {
  410.             if (_table[8] != 1 && _table[8] != 2)
  411.             {
  412.                 _table[8] = 1;
  413.                 button9.Text = @"X";
  414.                 CheckWin();
  415.  
  416.                 Answer();
  417.             }
  418.         }
  419.  
  420.         #endregion
  421.  
  422.         public void TableEmpty()
  423.         {
  424.             _table = new[]
  425.             {
  426.                 0, 0, 0,
  427.                 0, 0, 0,
  428.                 0, 0, 0
  429.             };
  430.  
  431.             button1.Text = "";
  432.             button2.Text = "";
  433.             button3.Text = "";
  434.             button4.Text = "";
  435.             button5.Text = "";
  436.             button6.Text = "";
  437.             button7.Text = "";
  438.             button8.Text = "";
  439.             button9.Text = "";
  440.         }
  441.  
  442.         public void Answer()
  443.         {
  444.             answer:
  445.  
  446.             int answer = nw.getAnswer(_table);
  447.  
  448.             if (_table[answer] != 1 && _table[answer] != 2)
  449.             {
  450.  
  451.                 _table[answer] = 2;
  452.  
  453.                 if (answer == 0)
  454.                     button1.Text = @"O";
  455.                 if (answer == 1)
  456.                     button2.Text = @"O";
  457.                 if (answer == 2)
  458.                     button3.Text = @"O";
  459.                 if (answer == 3)
  460.                     button4.Text = @"O";
  461.                 if (answer == 4)
  462.                     button5.Text = @"O";
  463.                 if (answer == 5)
  464.                     button6.Text = @"O";
  465.                 if (answer == 6)
  466.                     button7.Text = @"O";
  467.                 if (answer == 7)
  468.                     button8.Text = @"O";
  469.                 if (answer == 8)
  470.                     button9.Text = @"O";
  471.  
  472.                 CheckWin();
  473.  
  474.             }
  475.             else
  476.             {
  477.                 int index = _random.Next(0, 9);
  478.                 nw.study(_table, index);
  479.                 goto answer;
  480.             }
  481.  
  482.         }
  483.     }
  484. }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

15   голосов , оценка 4.4 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы