/// <summary>
        /// Computer turn
        /// </summary>
        public void ComputerTurn()
        {
            // Init
            List <Point[]>[] comp_turns = new List <Point[]> [3];
            for (int i = 0; i < 3; i++)
            {
                comp_turns[i] = new List <Point[]>();
            }
            Evaluator estimator = new Evaluator(_state);

            // Search and categorization of moves
            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    // Finding "ally" checkers
                    if (_state.checkers[j, i] != null && _state.checkers[j, i].belong_to == Belonging.RedRose)
                    {
                        // Determining the moving range of the checkers
                        int distance;
                        if (_state.checkers[j, i].king && Properties.Settings.Default.rules_russian)
                        {
                            distance = Properties.Settings.Default.high_bound + 1;
                        }
                        else
                        {
                            distance = 1;
                        }

                        // Building a list of moves
                        var computer_list = estimator.GetComputerMoves(new Point(j, i), distance, Belonging.WhiteRose);

                        // Categorization of moves
                        if (computer_list[0].Count > 0)
                        {
                            // 1 category moves (beating checkers)
                            foreach (var item in computer_list[0])
                            {
                                comp_turns[0].Add(new Point[] { new Point(j, i), item });
                            }
                        }
                        else if (computer_list[1].Count > 0)
                        {
                            // 2 category moves (safe position)
                            foreach (var item in computer_list[1])
                            {
                                comp_turns[1].Add(new Point[] { new Point(j, i), item });
                            }
                        }
                        else if (computer_list[2].Count > 0)
                        {
                            // 3 category moves (dangerous position)
                            foreach (var item in computer_list[2])
                            {
                                comp_turns[2].Add(new Point[] { new Point(j, i), item });
                            }
                        }
                    }
                }
            }

            // Running a move / chain of moves by computer
            Random rand  = new Random();
            Ruler  ruler = new Ruler(_screen);

            List <Point[]>[] temp_comp_turns = new List <Point[]> [comp_turns.Length];

            if (Properties.Settings.Default.give_away)
            {
                if (Properties.Settings.Default.force_beating)
                {
                    for (int i = 1; i < comp_turns.Length; i++)
                    {
                        temp_comp_turns[i] = comp_turns[comp_turns.Length - i];
                    }
                    temp_comp_turns[0] = comp_turns[0];
                }
                else
                {
                    for (int i = 0; i < comp_turns.Length; i++)
                    {
                        temp_comp_turns[i] = comp_turns[comp_turns.Length - 1 - i];
                    }
                }

                comp_turns = temp_comp_turns;
            }

            // Attempt to perform a move of category 1
            if (comp_turns[0].Count > 0)
            {
#if DEBUG
                ShowDebugMessage(1);
#endif
                // Getting a list of possible moves
                var   turn_list = comp_turns[0];
                var   turn      = turn_list[rand.Next(turn_list.Count - 1)];
                Point direction = new Point(Math.Sign(turn[1].X - turn[0].X), Math.Sign(turn[1].Y - turn[0].Y));

                // Taking checkers
                for (int y = turn[0].Y + direction.Y, x = turn[0].X + direction.X;
                     y != turn[1].Y;
                     y += direction.Y, x += direction.X)
                {
                    if (_state.checkers[x, y] != null)
                    {
                        if (_state.checkers[x, y].belong_to == Belonging.WhiteRose)
                        {
                            _state.checkers[x, y] = null;
                        }
                    }
                }

                // Moving a checker to a new position
                _state.checkers[turn[1].X, turn[1].Y]      = _state.checkers[turn[0].X, turn[0].Y];
                _state.checkers[turn[0].X, turn[0].Y]      = null;
                _state.checkers[turn[1].X, turn[1].Y].rect = ruler.GetCellRelativeCoord(turn[1]);

                // Check for the need to convert checkers into a king
                if (!_state.checkers[turn[1].X, turn[1].Y].king)
                {
                    // For white checkers
                    if (turn[1].Y == Properties.Settings.Default.low_bound && _state.checkers[turn[1].X, turn[1].Y].belong_to == Belonging.WhiteRose)
                    {
                        _state.checkers[turn[1].X, turn[1].Y].king = true;
                        _state.checkers[turn[1].X, turn[1].Y].img  = Properties.Resources.whiteking;
                    }
                    // For red checkers
                    else if (turn[1].Y == Properties.Settings.Default.high_bound && _state.checkers[turn[1].X, turn[1].Y].belong_to == Belonging.RedRose)
                    {
                        _state.checkers[turn[1].X, turn[1].Y].king = true;
                        _state.checkers[turn[1].X, turn[1].Y].img  = Properties.Resources.redking;
                    }
                }

                // Determining the possibility of continuing the turn
                var next_move = _estimator.NeedCheckerBeating(turn[1],
                                                              _state.checkers[turn[1].X, turn[1].Y].king && Properties.Settings.Default.rules_russian ?
                                                              Properties.Settings.Default.high_bound + 1 :
                                                              1,
                                                              Belonging.WhiteRose);
                bool  to_king            = false;
                Point inv_last_direction = new Point();

                // Continuing the movement
                while (next_move.Count > 0)
                {
                    // Determination of new coordinates
                    turn[0] = turn[1];
                    turn[1] = new Point(turn[0].X + next_move.First.Value.direction.X * next_move.First.Value.minimum_distance, turn[0].Y + next_move.First.Value.direction.Y * next_move.First.Value.minimum_distance);

                    // Cutting off an invalid move after setting a king
                    if (to_king && inv_last_direction == new Point(Math.Sign(turn[1].X - turn[0].X), Math.Sign(turn[1].Y - turn[0].Y)))
                    {
                        // If there is another move - reassigning the end position
                        if (next_move.Count > 1)
                        {
                            turn[1] = new Point(turn[0].X + next_move.First.Next.Value.direction.X * next_move.First.Next.Value.minimum_distance, turn[0].Y + next_move.First.Next.Value.direction.Y * next_move.First.Next.Value.minimum_distance);
                        }
                        else
                        {
                            break;
                        }
                    }

                    // Moving a checker to a new position
                    _state.checkers[turn[1].X, turn[1].Y]      = _state.checkers[turn[0].X, turn[0].Y];
                    _state.checkers[turn[0].X, turn[0].Y]      = null;
                    _state.checkers[turn[1].X, turn[1].Y].rect = ruler.GetCellRelativeCoord(turn[1]);

                    // Remove beaten checkers
                    Point dir_beat = new Point(Math.Sign(turn[1].X - turn[0].X), Math.Sign(turn[1].Y - turn[0].Y));
                    for (int y = turn[0].Y + dir_beat.Y, x = turn[0].X + dir_beat.X;
                         y != turn[1].Y;
                         y += dir_beat.Y, x += dir_beat.X)
                    {
                        if (_state.checkers[x, y] != null)
                        {
                            if (_state.checkers[x, y].belong_to == Belonging.WhiteRose)
                            {
                                _state.checkers[x, y] = null;
                            }
                        }
                    }

                    // Check for the need to convert checkers into a king
                    if (!_state.checkers[turn[1].X, turn[1].Y].king)
                    {
                        // For white checkers
                        if (turn[1].Y == Properties.Settings.Default.low_bound && _state.checkers[turn[1].X, turn[1].Y].belong_to == Belonging.WhiteRose)
                        {
                            _state.checkers[turn[1].X, turn[1].Y].king = true;
                            _state.checkers[turn[1].X, turn[1].Y].img  = Properties.Resources.whiteking;
                            to_king            = true;
                            inv_last_direction = new Point(-dir_beat.X, -dir_beat.Y);
                        }
                        // For red checkers
                        else if (turn[1].Y == Properties.Settings.Default.high_bound && _state.checkers[turn[1].X, turn[1].Y].belong_to == Belonging.RedRose)
                        {
                            _state.checkers[turn[1].X, turn[1].Y].king = true;
                            _state.checkers[turn[1].X, turn[1].Y].img  = Properties.Resources.redking;
                            to_king = true;
                        }
                    }

                    // Determining the need to continue the turn
                    next_move = _estimator.NeedCheckerBeating(turn[1],
                                                              _state.checkers[turn[1].X, turn[1].Y].king && Properties.Settings.Default.rules_russian ?
                                                              Properties.Settings.Default.high_bound + 1 :
                                                              1,
                                                              Belonging.WhiteRose);
                }

                // Turn owner swap
                _state.turn = Belonging.WhiteRose;

                // Check of conditions of loss of the opponent
                bool enemy_has_checkers = false;
                bool enemy_can_move     = false;
                for (int i = 0; i < 8; i++)
                {
                    for (int j = 0; j < 8; j++)
                    {
                        // Check for opponent’s checkers
                        if (_state.checkers[j, i] != null && _state.checkers[j, i].belong_to == _state.turn)
                        {
                            // Definition of the enemy
                            Belonging new_enemy;
                            int       distance = 1;
                            if (_state.turn == Belonging.RedRose)
                            {
                                new_enemy = Belonging.WhiteRose;
                            }
                            else
                            {
                                new_enemy = Belonging.RedRose;
                            }

                            // Determining the distance of the move checkers
                            if (_state.checkers[j, i].king)
                            {
                                if (Properties.Settings.Default.rules_russian)
                                {
                                    distance = Properties.Settings.Default.high_bound + 1;
                                }
                                else
                                {
                                    distance = 1;
                                }
                            }
                            enemy_has_checkers = true;

                            // Determining the possibility of moving checkers
                            if (_estimator.CanMove(new Point(j, i), distance, new_enemy))
                            {
                                enemy_can_move = true;
                            }
                        }
                    }
                }

                // Check win / lose event
                if (!enemy_has_checkers || !enemy_can_move)
                {
                    // Winning Report
                    CheckForVictory();
                }
            }
            // Attempt to perform a 2 category move
            else if (comp_turns[1].Count > 0)
            {
#if DEBUG
                ShowDebugMessage(2);
#endif
                // Getting a list of possible moves
                var turn_list = comp_turns[1];
                var turn      = turn_list[rand.Next(turn_list.Count - 1)];

                // Moving a checker to a new position
                _state.checkers[turn[1].X, turn[1].Y]      = _state.checkers[turn[0].X, turn[0].Y];
                _state.checkers[turn[0].X, turn[0].Y]      = null;
                _state.checkers[turn[1].X, turn[1].Y].rect = ruler.GetCellRelativeCoord(turn[1]);

                // Check for the need to convert checkers into a king
                if (!_state.checkers[turn[1].X, turn[1].Y].king)
                {
                    // For white checkers
                    if (turn[1].Y == Properties.Settings.Default.low_bound && _state.checkers[turn[1].X, turn[1].Y].belong_to == Belonging.WhiteRose)
                    {
                        _state.checkers[turn[1].X, turn[1].Y].king = true;
                        _state.checkers[turn[1].X, turn[1].Y].img  = Properties.Resources.whiteking;
                    }
                    // For red checkers
                    else if (turn[1].Y == Properties.Settings.Default.high_bound && _state.checkers[turn[1].X, turn[1].Y].belong_to == Belonging.RedRose)
                    {
                        _state.checkers[turn[1].X, turn[1].Y].king = true;
                        _state.checkers[turn[1].X, turn[1].Y].img  = Properties.Resources.redking;
                    }
                }

                // Turn owner swap
                _state.turn = Belonging.WhiteRose;
            }
            // Attempt to perform a 3 category move
            else if (comp_turns[2].Count > 0)
            {
#if DEBUG
                ShowDebugMessage(3);
#endif
                // Getting a list of possible moves
                var turn_list = comp_turns[2];
                var turn      = turn_list[rand.Next(turn_list.Count - 1)];

                // Moving a checker to a new position
                _state.checkers[turn[1].X, turn[1].Y]      = _state.checkers[turn[0].X, turn[0].Y];
                _state.checkers[turn[0].X, turn[0].Y]      = null;
                _state.checkers[turn[1].X, turn[1].Y].rect = ruler.GetCellRelativeCoord(turn[1]);

                // Check for the need to convert checkers into a king
                if (!_state.checkers[turn[1].X, turn[1].Y].king)
                {
                    // For white checkers
                    if (turn[1].Y == Properties.Settings.Default.low_bound && _state.checkers[turn[1].X, turn[1].Y].belong_to == Belonging.WhiteRose)
                    {
                        _state.checkers[turn[1].X, turn[1].Y].king = true;
                        _state.checkers[turn[1].X, turn[1].Y].img  = Properties.Resources.whiteking;
                    }
                    // For red checkers
                    else if (turn[1].Y == Properties.Settings.Default.high_bound && _state.checkers[turn[1].X, turn[1].Y].belong_to == Belonging.RedRose)
                    {
                        _state.checkers[turn[1].X, turn[1].Y].king = true;
                        _state.checkers[turn[1].X, turn[1].Y].img  = Properties.Resources.redking;
                    }
                }

                // Turn owner swap
                _state.turn = Belonging.WhiteRose;
            }
            else
            {
                // Winning Report
                CheckForVictory();
            }

            // Invalidation the scene
            _screen.Invalidate();
        }
        /// <summary>
        /// Event handler for releasing a mouse button by user
        /// </summary>
        /// <param name="e">Mouse options</param>
        public void MouseUp(MouseEventArgs e)
        {
            // Checker is not selected
            if (_drag == null)
            {
                return;
            }

            // Definition of the field under the cursor at the moment of pressing
            Ruler  ruler             = new Ruler(_screen);
            Point? cell_intersection = ruler.GetCellIntersection(e.Location);
            Reason status            = Reason.OK;
            bool   beating;

            // Assessment of the possibility and correctness of move
            if (cell_intersection.HasValue)
            {
                // Verify that the selected cell matches the game logic
                if (_state.checkers[cell_intersection.Value.X, cell_intersection.Value.Y] == null && cell_intersection.Value.X % 2 == cell_intersection.Value.Y % 2)
                {
                    // Checking the move correctness
                    status = _estimator.EvaluateStep(_clicked.Value, cell_intersection.Value, out beating);

                    // Move is correct
                    if (status == Reason.OK)
                    {
                        // Moving checkers to a new position
                        _state.checkers[cell_intersection.Value.X, cell_intersection.Value.Y]      = _drag;
                        _state.checkers[cell_intersection.Value.X, cell_intersection.Value.Y].rect =
                            ruler.GetCellRelativeCoord(new Point(cell_intersection.Value.X, cell_intersection.Value.Y));
                        _state.checkers[_clicked.Value.X, _clicked.Value.Y] = null;

                        // Check for the need to convert checkers into a king
                        if (!_state.checkers[cell_intersection.Value.X, cell_intersection.Value.Y].king)
                        {
                            // For white checkers
                            if (cell_intersection.Value.Y == Properties.Settings.Default.low_bound && _drag.belong_to == Belonging.WhiteRose)
                            {
                                _state.checkers[cell_intersection.Value.X, cell_intersection.Value.Y].king = true;
                                _state.checkers[cell_intersection.Value.X, cell_intersection.Value.Y].img  = Properties.Resources.whiteking;
                            }
                            // For red checkers
                            else if (cell_intersection.Value.Y == Properties.Settings.Default.high_bound && _drag.belong_to == Belonging.RedRose)
                            {
                                _state.checkers[cell_intersection.Value.X, cell_intersection.Value.Y].king = true;
                                _state.checkers[cell_intersection.Value.X, cell_intersection.Value.Y].img  = Properties.Resources.redking;
                            }
                        }

                        // Determining the possibility of continuing the turn
                        var next_move = _estimator.NeedCheckerBeating(cell_intersection.Value,
                                                                      _state.checkers[cell_intersection.Value.X, cell_intersection.Value.Y].king && Properties.Settings.Default.rules_russian ?
                                                                      Properties.Settings.Default.high_bound + 1 :
                                                                      1,
                                                                      _state.checkers[cell_intersection.Value.X, cell_intersection.Value.Y].belong_to == Belonging.RedRose ?
                                                                      Belonging.WhiteRose :
                                                                      Belonging.RedRose);

                        // Check the need of continuing the turn
                        if (next_move.Count > 0)
                        {
                            // The need to beat (mandatory continuation of the course)
                            if (beating)
                            {
                                ShowContiniousTurnMessage();
                                _continious = cell_intersection.Value;
                            }
                            else
                            {
                                // Moving side swap
                                if (_state.turn == Belonging.RedRose)
                                {
                                    _state.turn = Belonging.WhiteRose;
                                }
                                else
                                {
                                    _state.turn = Belonging.RedRose;
                                }

                                // Check of conditions of loss of the opponent
                                bool enemy_has_checkers = false;
                                bool enemy_can_move     = false;
                                for (int i = 0; i < 8; i++)
                                {
                                    for (int j = 0; j < 8; j++)
                                    {
                                        // Check for opponent’s checkers
                                        if (_state.checkers[j, i] != null && _state.checkers[j, i].belong_to == _state.turn)
                                        {
                                            // Definition of the enemy
                                            Belonging new_enemy;
                                            int       distance = 1;
                                            if (_state.turn == Belonging.RedRose)
                                            {
                                                new_enemy = Belonging.WhiteRose;
                                            }
                                            else
                                            {
                                                new_enemy = Belonging.RedRose;
                                            }

                                            // Determining the distance of the checkers move
                                            if (_state.checkers[j, i].king)
                                            {
                                                if (Properties.Settings.Default.rules_russian)
                                                {
                                                    distance = Properties.Settings.Default.high_bound + 1;
                                                }
                                                else
                                                {
                                                    distance = 1;
                                                }
                                            }
                                            enemy_has_checkers = true;

                                            // Determining the possibility of moving
                                            if (_estimator.CanMove(new Point(j, i), distance, new_enemy))
                                            {
                                                enemy_can_move = true;
                                            }
                                        }
                                    }
                                }

                                // Check win / lose event
                                if (!enemy_has_checkers || !enemy_can_move)
                                {
                                    // Winning Report
                                    CheckForVictory();
                                }
                                else
                                {
                                    // Computer turn
                                    ComputerTurn();

                                    // Message about changing turn owner
                                    ShowTurnOwnerMessage();
                                }

                                // Moving checker reset
                                _continious = null;
                            }
                        }
                        else
                        {
                            // Moving side swap
                            if (_state.turn == Belonging.RedRose)
                            {
                                _state.turn = Belonging.WhiteRose;
                            }
                            else
                            {
                                _state.turn = Belonging.RedRose;
                            }

                            // Check of conditions of loss of the opponent
                            bool enemy_has_checkers = false;
                            bool enemy_can_move     = false;
                            for (int i = 0; i < 8; i++)
                            {
                                for (int j = 0; j < 8; j++)
                                {
                                    // Check for opponent’s checkers
                                    if (_state.checkers[j, i] != null && _state.checkers[j, i].belong_to == _state.turn)
                                    {
                                        // Definition of the enemy
                                        Belonging new_enemy;
                                        int       distance = 1;
                                        if (_state.turn == Belonging.RedRose)
                                        {
                                            new_enemy = Belonging.WhiteRose;
                                        }
                                        else
                                        {
                                            new_enemy = Belonging.RedRose;
                                        }

                                        // Determining the distance of the checkers move
                                        if (_state.checkers[j, i].king)
                                        {
                                            if (Properties.Settings.Default.rules_russian)
                                            {
                                                distance = Properties.Settings.Default.high_bound + 1;
                                            }
                                            else
                                            {
                                                distance = 1;
                                            }
                                        }
                                        enemy_has_checkers = true;

                                        // Determining the possibility of moving
                                        if (_estimator.CanMove(new Point(j, i), distance, new_enemy))
                                        {
                                            enemy_can_move = true;
                                        }
                                    }
                                }
                            }

                            // Check win / lose event
                            if (!enemy_has_checkers || !enemy_can_move)
                            {
                                // Winning Report
                                CheckForVictory();
                            }
                            else
                            {
                                // Computer turn
                                ComputerTurn();

                                // Message about changing turn owner
                                ShowTurnOwnerMessage();
                            }

                            // Moving checker reset
                            _continious = null;
                        }
                    }
                    else
                    {
                        // Return to the previous position
                        _state.checkers[_clicked.Value.X, _clicked.Value.Y].rect =
                            ruler.GetCellRelativeCoord(new Point(_clicked.Value.X, _clicked.Value.Y));
                    }
                }
                else
                {
                    // Return to the previous position
                    status = Reason.ImpossibleTurn;
                    _state.checkers[_clicked.Value.X, _clicked.Value.Y].rect =
                        ruler.GetCellRelativeCoord(new Point(_clicked.Value.X, _clicked.Value.Y));
                }
            }
            else if (_clicked != null)
            {
                // Return to the previous position
                status = Reason.ImpossibleTurn;
                _state.checkers[_clicked.Value.X, _clicked.Value.Y].rect =
                    ruler.GetCellRelativeCoord(new Point(_clicked.Value.X, _clicked.Value.Y));
            }

            // Reset selected checker
            this._clicked = null;
            this._drag    = null;

            // The message about the incorrectness of the move (if incorrect, an internal check is performed)
            ShowIncorrectTurnMessage(status);
        }