/// <summary> /// Обработка нажатия ЛКМ на изображении доски /// </summary> /// <param name="sender">Объект события</param> /// <param name="e">Аргументы события</param> private void pictureGraphics_MouseClick(object sender, MouseEventArgs e) { //Перевод координаты мыши в координаты клеток доски var mouse_point = new Point(e.X / pixelSize, e.Y / pixelSize); //Включаем режим рисования var gdi = Graphics.FromImage(BoardBitmap); if (startPosition == null) { startPosition = new KnightPoint(mouse_point.X, mouse_point.Y); //Отмечаем начальную клетку зелёным цветом gdi.FillRectangle(new SolidBrush(Color.Green), mouse_point.X * pixelSize, mouse_point.Y * pixelSize, pixelSize, pixelSize); lblStatus.Text = "Укажите конечную позицию на доске"; lblStatus.ForeColor = Color.Red; } else if (endPosition == null) { endPosition = new KnightPoint(mouse_point.X, mouse_point.Y); //Отмечаем конечную клетку красным цветом gdi.FillRectangle(new SolidBrush(Color.Red), mouse_point.X * pixelSize, mouse_point.Y * pixelSize, pixelSize, pixelSize); lblStatus.Text = "Ход конем!"; lblStatus.ForeColor = Color.Blue; //Запуск передвижения коня KnightTour(); } pictureGraphics.Image = new Bitmap(BoardBitmap); //Отключение режима рисования gdi.Dispose(); }
/// <summary> /// Создание коня /// </summary> /// <param name="startPosition">Начальная позиция</param> /// <param name="endPosition">Конечная позиция</param> /// <param name="board">Доска</param> public Knight(KnightPoint startPosition, KnightPoint endPosition, Board board) { Position = startPosition; Finish = endPosition; Rought.Add(startPosition); Board = board; Board.SetCellVisited(startPosition); Board.SetCellVisited(endPosition); }
/// <summary> /// Меню: создание новой доски /// </summary> /// <param name="sender">Объект события</param> /// <param name="e">Аргументы события</param> private void createNewToolStripMenuItem_Click(object sender, EventArgs e) { pictureGraphics.Image = null; pictureGraphics.Enabled = false; startPosition = endPosition = null; GameBoard = null; Knight = null; StartForm start = new StartForm(); start.Show(this); }
/// <summary> /// Поиск пути бэктрекингом /// </summary> /// <param name="point">Позиция коня</param> /// <returns>Найден ли путь</returns> public bool MoveNextBacktrackingRecursive(KnightPoint point) { var nextPoint = new KnightPoint(); if (Rought.Count >= Board.Width * Board.Height) { Position = point; Rought.Remove(nextPoint); Board.SetCellUnvisited(nextPoint); return(true); } for (int k = 0; k < 8; k++) { nextPoint.X = point.X + Directions[k].X; nextPoint.Y = point.Y + Directions[k].Y; if (Rought.Count == (Board.Width * Board.Height - 1) && IsValid(nextPoint)) { Rought.Add(nextPoint); Board.SetCellVisited(nextPoint); Position = nextPoint; if (MoveNextBacktrackingRecursive(nextPoint)) { return(true); } else { Position = point; Rought.Remove(nextPoint); Board.SetCellUnvisited(nextPoint); } } else if (IsValid(nextPoint) && (nextPoint.X != Finish.X || nextPoint.Y != Finish.Y)) { Rought.Add(nextPoint); Board.SetCellVisited(nextPoint); Position = nextPoint; if (MoveNextBacktrackingRecursive(nextPoint)) { return(true); } else { Position = point; Rought.Remove(nextPoint); Board.SetCellUnvisited(nextPoint); } } } return(false); }
/// <summary> /// Передвижение коня /// </summary> public bool MoveNext() { List <KnightPoint> knightDirections = Directions; if (Position.X >= Board.Width / 2 && Position.Y < Board.Height) { knightDirections = Directions90; } if (Position.X < Board.Width / 2 && Position.Y < Board.Height) { knightDirections = DirectionsN; } if (Position.X >= Board.Width / 2 && Position.Y >= Board.Height) { knightDirections = DirectionsN90; } List <BoardCell> neighbors = Board.FindNotVisitedNeighbors(Position, knightDirections); KnightPoint targetPoint = new KnightPoint(); int min = knightDirections.Count; if (Rought.Count > Board.Width * Board.Height - 1) { Board.SetCellUnvisited(Finish); } foreach (var n in neighbors) { int notVisitedCount = Board.FindNotVisitedNeighbors(n.Position, knightDirections).Count; if (notVisitedCount <= min) { min = notVisitedCount; targetPoint = new KnightPoint(n.Position.X, n.Position.Y); } } if (targetPoint.X != -1 && targetPoint.Y != -1) { Position = targetPoint; Rought.Add(targetPoint); Board.SetCellVisited(targetPoint); return(true); } return(false); }
/// <summary> /// Проверка, находится ли точка в приделах стола /// </summary> /// <param name="point">Проверяемая точка</param> /// <returns>Принадлежность</returns> bool IsValid(KnightPoint point) { return(point.X >= 0 && point.X < Board.Width && point.Y >= 0 && point.Y < Board.Height && !Board.GetCell(point).Visited); }
/// <summary> /// Создание клетки /// </summary> /// <param name="point">Координата клетки</param> /// <param name="visited">Посещённость</param> public BoardCell(KnightPoint point, bool visited = false) { Position = point; Visited = visited; }