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

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

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

Собственно есть нейронная сеть(слизанная с хабра), там нейронная сеть была предназначена для распознавания изображений, то есть использовались двухмерные массивы я заменил его на одно мерный так как поле в крестики нолики можно записать в одну строку. Суть проблемы принятие решений нейронной сети по факту она их принимает ^_^, но как сделать так что бы она стремилась к победе.
using System;
 
namespace GA
{
    class Program
    {
        static Random _random = new Random();
 
        public static int length = 9; // Колличество входных параметров
 
        public class Neuron
        {
            public int[] weight; // Веса нейронов
            public int minimum = 50; // Порог
 
            /**
             * Конструктор нейрона, создает веси и устанавливает случайные значения
             */
            public Neuron()
            {
                weight = new int[length];
                randomizeWeights();
            }
 
            /**
             * ответы нейронов, жесткая пороговая
             * @param input - входной вектор
             * @return ответ 0 или 1
             */
            public int transferHard(int[] input)
            {
                int Power = 0;
                for (int r = 0; r < length; r++)
                {
 
                        Power += weight[r] * input[r];
                }
                //Debug.Log("Power: " + Power);
                return Power >= minimum ? 1 : 0;
            }
 
            /**
             * ответы нейронов с вероятностями
             * @param input - входной вектор
             * @return n вероятность
             */
            public int transfer(int[] input)
            {
                int Power = 0;
                for (int r = 0; r < length; r++)
                        Power += weight[r] * input[r];
 
                //Debug.Log("Power: " + Power);
                return Power;
            }
 
            void randomizeWeights()
            {
                for (int r = 0; r < length; r++)
                        weight[r] = _random.Next(0, 10);
            }
 
            /**
             * изменяет веса нейронов
             * @param input - входной вектор
             * @param d - разница между выходом нейрона и нужным выходом
             */
            public void changeWeights(int[] input, int d)
            {
                for (int r = 0; r < length; r++)
                        weight[r] += d * input[r];
            }
        }
        public class NeuralNetwork
        {
            public Neuron[] neurons;
 
            /**
             * Конструктор сети создает нейроны
             */
            public NeuralNetwork()
            {
                neurons = new Neuron[10];
 
                for (int i = 0; i < neurons.Length; i++)
                    neurons[i] = new Neuron();
            }
 
            /**
             * Функция распознавания символа, используется для обучения
             * @param input - входной вектор
             * @return массив из нуллей и единиц, ответы нейронов
             */
            int[] handleHard(int[] input)
            {
                int[] output = new int[neurons.Length];
                for (int i = 0; i < output.Length; i++)
                    output[i] = neurons[i].transferHard(input);
 
                return output;
            }
 
            /**
             * Функция распознавания, используется для конечново ответа
             * @param input -  входной вектор
             * @return массив из вероятностей, ответы нейронов
             */
            int[] handle(int[] input)
            {
                int[] output = new int[neurons.Length];
                for (int i = 0; i < output.Length; i++)
                    output[i] = neurons[i].transfer(input);
 
                return output;
            }
 
            /**
             * Ответ сети
             * @param input - входной вектор
             * @return индекс нейронов предназначенный для конкретного символа
             */
            public int getAnswer(int[] input)
            {
                int[] output = handle(input);
                int maxIndex = 0;
                for (int i = 1; i < output.Length; i++)
                    if (output[i] > output[maxIndex])
                        maxIndex = i;
 
                return maxIndex;
            }
 
            /**
             * Функция обучения
             * @param input - входной вектор
             * @param correctAnswer - правильный ответ
             */
            public void study(int[] input, int correctAnswer)
            {
                int[] correctOutput = new int[neurons.Length];
                correctOutput[correctAnswer] = 1;
 
                int[] output = handleHard(input);
                while (!compareArrays(correctOutput, output))
                {
                    for (int i = 0; i < neurons.Length; i++)
                    {
                        int dif = correctOutput[i] - output[i];
                        neurons[i].changeWeights(input, dif);
                    }
                    output = handleHard(input);
                }
            }
 
            /**
             * Сравнение двух вектор
             * @param true - если массивы одинаковые, false - если нет
             */
            bool compareArrays(int[] a, int[] b)
            {
                if (a.Length != b.Length)
                    return false;
 
                for (int i = 0; i < a.Length; i++)
                    if (a[i] != b[i])
                        return false;
 
                return true;
            }
        }
 
        private static void Main(string[] args)
        {
            NeuralNetwork nw = new NeuralNetwork();
 
            int[] table = 
            {
                0, 0, 0,
                0, 0, 0,
                0, 0, 0
            };
 
            var win = false;
 
            while (!win)
            {
                #region PlayerInput
                int x; 
                do
                {
                input:
                    Console.Write("Введите номер клетки где поставить крестик: ");
                
                    try
                    {
                        x = Convert.ToInt16(Console.ReadLine());
                    }
                    catch (Exception ex)
                    {
                        goto input;
                    }
 
                } while (table[x-1] == 1 || table[x-1] == 2);
 
                table[x - 1] = 1;
                #endregion
 
                if (table[0] == 1 && table[1] == 1 && table[2] == 1 ||
                        table[0] == 2 && table[1] == 2 && table[2] == 2 ||
                        table[3] == 1 && table[4] == 1 && table[5] == 1 ||
                        table[3] == 2 && table[4] == 2 && table[5] == 2 ||
                        table[6] == 1 && table[7] == 1 && table[8] == 1 ||
                        table[6] == 2 && table[7] == 2 && table[8] == 2 ||
                        table[0] == 1 && table[4] == 1 && table[8] == 1 ||
                        table[0] == 2 && table[4] == 2 && table[8] == 2 ||
                        table[2] == 1 && table[4] == 1 && table[6] == 1 ||
                        table[2] == 2 && table[4] == 2 && table[6] == 2 ||
                        table[0] == 1 && table[3] == 1 && table[6] == 1 ||
                        table[0] == 2 && table[3] == 2 && table[6] == 2 ||
                        table[1] == 1 && table[4] == 1 && table[7] == 1 ||
                        table[1] == 2 && table[4] == 2 && table[7] == 2 ||
                        table[2] == 1 && table[5] == 1 && table[8] == 1 ||
                        table[2] == 2 && table[5] == 2 && table[8] == 2)
                {
                    win = true;
                }
                else
                {
 
                    #region WriteTable
 
                    for (int i = 0; i < table.Length; i++)
                    {
                        Console.Write(table[i] == 1 ? "X" : table[i] == 2 ? "O" : "-");
 
                        if ((i + 1)%3 == 0 && i != 0)
                        {
                            Console.WriteLine();
                        }
                    }
                    Console.WriteLine();
 
                    #endregion
 
                    #region NeuralNetwork
 
                    int o;
                    do
                    {
                        nw.study(table, _random.Next(0, 9));
                        o = nw.getAnswer(table);
                    } while (table[o] == 1 || table[o] == 2);
 
                    table[o] = 2;
 
                    #endregion
 
                    if (table[0] == 1 && table[1] == 1 && table[2] == 1 ||
                        table[0] == 2 && table[1] == 2 && table[2] == 2 ||
                        table[3] == 1 && table[4] == 1 && table[5] == 1 ||
                        table[3] == 2 && table[4] == 2 && table[5] == 2 ||
                        table[6] == 1 && table[7] == 1 && table[8] == 1 ||
                        table[6] == 2 && table[7] == 2 && table[8] == 2 ||
                        table[0] == 1 && table[4] == 1 && table[8] == 1 ||
                        table[0] == 2 && table[4] == 2 && table[8] == 2 ||
                        table[2] == 1 && table[4] == 1 && table[6] == 1 ||
                        table[2] == 2 && table[4] == 2 && table[6] == 2 ||
                        table[0] == 1 && table[3] == 1 && table[6] == 1 ||
                        table[0] == 2 && table[3] == 2 && table[6] == 2 ||
                        table[1] == 1 && table[4] == 1 && table[7] == 1 ||
                        table[1] == 2 && table[4] == 2 && table[7] == 2 ||
                        table[2] == 1 && table[5] == 1 && table[8] == 1 ||
                        table[2] == 2 && table[5] == 2 && table[8] == 2)
                    {
                        win = true;
                    }
 
                    #region WriteTable
 
                        for (int i = 0; i < table.Length; i++)
                        {
                            Console.Write(table[i] == 1 ? "X" : table[i] == 2 ? "O" : "-");
 
                            if ((i + 1)%3 == 0 && i != 0)
                            {
                                Console.WriteLine();
                            }
                        }
                        Console.WriteLine();
 
                        #endregion
                }
            }
 
            Console.WriteLine("Кто-то кого-то нагнул.");
            Console.ReadKey();
        }
    }
}

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

textual
Листинг программы
using System;
using System.Windows.Forms;
 
namespace NeuralNetwork
{
    public partial class Form1 : Form
    {
        #region NeuralNetwork
 
        private static Random _random = new Random();
        public static int length = 9; // Колличество входных параметров
 
        public class Neuron
        {
            public int[] weight; // Веса нейронов
            public int minimum = 50; // Порог
 
            /**
             * Конструктор нейрона, создает веси и устанавливает случайные значения
             */
 
            public Neuron()
            {
                weight = new int[length];
                randomizeWeights();
            }
 
            /**
             * ответы нейронов, жесткая пороговая
             * @param input - входной вектор
             * @return ответ 0 или 1
             */
 
            public int transferHard(int[] input)
            {
                int Power = 0;
                for (int r = 0; r < length; r++)
                {
 
                    Power += weight[r]*input[r];
                }
                //Debug.Log("Power: " + Power);
                return Power >= minimum ? 1 : 0;
            }
 
            /**
             * ответы нейронов с вероятностями
             * @param input - входной вектор
             * @return n вероятность
             */
 
            public int transfer(int[] input)
            {
                int Power = 0;
                for (int r = 0; r < length; r++)
                    Power += weight[r]*input[r];
 
                //Debug.Log("Power: " + Power);
                return Power;
            }
 
            private void randomizeWeights()
            {
                for (int r = 0; r < length; r++)
                    weight[r] = _random.Next(0, 10);
            }
 
            /**
             * изменяет веса нейронов
             * @param input - входной вектор
             * @param d - разница между выходом нейрона и нужным выходом
             */
 
            public void changeWeights(int[] input, int d)
            {
                for (int r = 0; r < length; r++)
                    weight[r] += d*input[r];
            }
        }
 
        public class NeuralNetwork
        {
            public Neuron[] neurons;
 
            /**
             * Конструктор сети создает нейроны
             */
 
            public NeuralNetwork()
            {
                neurons = new Neuron[9];
 
                for (int i = 0; i < neurons.Length; i++)
                    neurons[i] = new Neuron();
            }
 
            /**
             * Функция распознавания символа, используется для обучения
             * @param input - входной вектор
             * @return массив из нуллей и единиц, ответы нейронов
             */
 
            private int[] handleHard(int[] input)
            {
                int[] output = new int[neurons.Length];
                for (int i = 0; i < output.Length; i++)
                    output[i] = neurons[i].transferHard(input);
 
                return output;
            }
 
            /**
             * Функция распознавания, используется для конечново ответа
             * @param input -  входной вектор
             * @return массив из вероятностей, ответы нейронов
             */
 
            private int[] handle(int[] input)
            {
                int[] output = new int[neurons.Length];
                for (int i = 0; i < output.Length; i++)
                    output[i] = neurons[i].transfer(input);
 
                return output;
            }
 
            /**
             * Ответ сети
             * @param input - входной вектор
             * @return индекс нейронов предназначенный для конкретного символа
             */
 
            public int getAnswer(int[] input)
            {
                int[] output = handle(input);
                int maxIndex = 0;
                for (int i = 1; i < output.Length; i++)
                    if (output[i] > output[maxIndex])
                        maxIndex = i;
 
                return maxIndex;
            }
 
            /**
             * Функция обучения
             * @param input - входной вектор
             * @param correctAnswer - правильный ответ
             */
 
            public void study(int[] input, int correctAnswer)
            {
                int[] correctOutput = new int[neurons.Length];
                correctOutput[correctAnswer] = 1;
 
                int[] output = handleHard(input);
                while (!compareArrays(correctOutput, output))
                {
                    for (int i = 0; i < neurons.Length; i++)
                    {
                        int dif = correctOutput[i] - output[i];
                        neurons[i].changeWeights(input, dif);
                    }
                    output = handleHard(input);
                }
            }
 
            /**
             * Сравнение двух вектор
             * @param true - если массивы одинаковые, false - если нет
             */
 
            private bool compareArrays(int[] a, int[] b)
            {
                if (a.Length != b.Length)
                    return false;
 
                for (int i = 0; i < a.Length; i++)
                    if (a[i] != b[i])
                        return false;
 
                return true;
            }
        }
 
        #endregion
 
        private NeuralNetwork nw = new NeuralNetwork();
 
        private int[] _table =
        {
            0, 0, 0,
            0, 0, 0,
            0, 0, 0
        };
 
        public Form1()
        {
            InitializeComponent();
 
            #region Начальное обучение. Основанное на рандоме.
 
            for (int i = 0; i < 4608; i++)
            {
                answer1:
                int a = _random.Next(0, 9);
                if (_table[a] != 1 && _table[a] != 2)
                    _table[a] = 1;
                else
                    goto answer1;
 
                CheckWin();
 
                answer:
 
                int answer = nw.getAnswer(_table);
 
                if (_table[answer] != 1 && _table[answer] != 2)
                {
 
                    _table[answer] = 2;
 
                    if (answer == 0)
                        button1.Text = @"O";
                    if (answer == 1)
                        button2.Text = @"O";
                    if (answer == 2)
                        button3.Text = @"O";
                    if (answer == 3)
                        button4.Text = @"O";
                    if (answer == 4)
                        button5.Text = @"O";
                    if (answer == 5)
                        button6.Text = @"O";
                    if (answer == 6)
                        button7.Text = @"O";
                    if (answer == 7)
                        button8.Text = @"O";
                    if (answer == 8)
                        button9.Text = @"O";
 
                    CheckWin();
 
                }
                else
                {
                    int index = _random.Next(0, 9);
                    nw.study(_table, index);
                    goto answer;
                }
            }
 
            TableEmpty();
            textBox1.Text = String.Empty;
 
            #endregion
        }
 
        public void CheckWin()
        {
            if (_table[0] == 1 && _table[1] == 1 && _table[2] == 1 ||
                _table[3] == 1 && _table[4] == 1 && _table[5] == 1 ||
                _table[6] == 1 && _table[7] == 1 && _table[8] == 1 ||
                _table[0] == 1 && _table[4] == 1 && _table[8] == 1 ||
                _table[2] == 1 && _table[4] == 1 && _table[6] == 1 ||
                _table[0] == 1 && _table[3] == 1 && _table[6] == 1 ||
                _table[1] == 1 && _table[4] == 1 && _table[7] == 1 ||
                _table[2] == 1 && _table[5] == 1 && _table[8] == 1)
            {
                textBox1.Text += @"Вы победили
";
                nw.study(_table, _random.Next(0, 9));
                TableEmpty();
            }
            else
            {
                if (_table[0] == 2 && _table[1] == 2 && _table[2] == 2 ||
                    _table[3] == 2 && _table[4] == 2 && _table[5] == 2 ||
                    _table[6] == 2 && _table[7] == 2 && _table[8] == 2 ||
                    _table[0] == 2 && _table[4] == 2 && _table[8] == 2 ||
                    _table[2] == 2 && _table[4] == 2 && _table[6] == 2 ||
                    _table[0] == 2 && _table[3] == 2 && _table[6] == 2 ||
                    _table[1] == 2 && _table[4] == 2 && _table[7] == 2 ||
                    _table[2] == 2 && _table[5] == 2 && _table[8] == 2)
                {
                    textBox1.Text += @"Победила нейронная сеть
";
                    nw.study(_table, _random.Next(0, 9));
                    TableEmpty();
                }
                else
                {
                    int counter = 0;
                    for (int i = 0; i < _table.Length; i++)
                    {
                        if (_table[i] != 1 && _table[i] != 2)
                            counter++;
                    }
                    if (counter == 0)
                    {
                        textBox1.Text += @"Ничья!
";
                        nw.study(_table, _random.Next(0, 9));
                        TableEmpty();
                    }
                }
            }
 
        }
 
        #region Кнопки
 
        private void button1_Click(object sender, EventArgs e)
        {
            if (_table[0] != 1 && _table[0] != 2)
            {
                _table[0] = 1;
                button1.Text = @"X";
                CheckWin();
 
                Answer();
            }
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            if (_table[1] != 1 && _table[1] != 2)
            {
                _table[1] = 1;
                button2.Text = @"X";
                CheckWin();
 
                Answer();
            }
        }
 
        private void button3_Click(object sender, EventArgs e)
        {
            if (_table[2] != 1 && _table[2] != 2)
            {
                _table[2] = 1;
                button3.Text = @"X";
                CheckWin();
 
                Answer();
            }
        }
 
        private void button4_Click(object sender, EventArgs e)
        {
            if (_table[3] != 1 && _table[3] != 2)
            {
                _table[3] = 1;
                button4.Text = @"X";
                CheckWin();
 
                Answer();
            }
        }
 
        private void button5_Click(object sender, EventArgs e)
        {
            if (_table[4] != 1 && _table[4] != 2)
            {
                _table[4] = 1;
                button5.Text = @"X";
                CheckWin();
 
                Answer();
            }
        }
 
        private void button6_Click(object sender, EventArgs e)
        {
            if (_table[5] != 1 && _table[5] != 2)
            {
                _table[5] = 1;
                button6.Text = @"X";
                CheckWin();
 
                Answer();
            }
        }
 
        private void button7_Click(object sender, EventArgs e)
        {
            if (_table[6] != 1 && _table[6] != 2)
            {
                _table[6] = 1;
                button7.Text = @"X";
                CheckWin();
 
                Answer();
            }
        }
 
        private void button8_Click(object sender, EventArgs e)
        {
            if (_table[7] != 1 && _table[7] != 2)
            {
                _table[7] = 1;
                button8.Text = @"X";
                CheckWin();
 
                Answer();
            }
        }
 
        private void button9_Click(object sender, EventArgs e)
        {
            if (_table[8] != 1 && _table[8] != 2)
            {
                _table[8] = 1;
                button9.Text = @"X";
                CheckWin();
 
                Answer();
            }
        }
 
        #endregion
 
        public void TableEmpty()
        {
            _table = new[]
            {
                0, 0, 0,
                0, 0, 0,
                0, 0, 0
            };
 
            button1.Text = "";
            button2.Text = "";
            button3.Text = "";
            button4.Text = "";
            button5.Text = "";
            button6.Text = "";
            button7.Text = "";
            button8.Text = "";
            button9.Text = "";
        }
 
        public void Answer()
        {
            answer:
 
            int answer = nw.getAnswer(_table);
 
            if (_table[answer] != 1 && _table[answer] != 2)
            {
 
                _table[answer] = 2;
 
                if (answer == 0)
                    button1.Text = @"O";
                if (answer == 1)
                    button2.Text = @"O";
                if (answer == 2)
                    button3.Text = @"O";
                if (answer == 3)
                    button4.Text = @"O";
                if (answer == 4)
                    button5.Text = @"O";
                if (answer == 5)
                    button6.Text = @"O";
                if (answer == 6)
                    button7.Text = @"O";
                if (answer == 7)
                    button8.Text = @"O";
                if (answer == 8)
                    button9.Text = @"O";
 
                CheckWin();
 
            }
            else
            {
                int index = _random.Next(0, 9);
                nw.study(_table, index);
                goto answer;
            }
 
        }
    }
}

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


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

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

15   голосов , оценка 4.4 из 5
Похожие ответы