public override SnakeAttribute.SnakePathway GetNextPathway(PlayingMap map) { SnakeAttribute.SnakePathway path = LastPathway; if (Input.GetKey(KeyCode.W) && LastPathway != SnakeAttribute.SnakePathway.Down) { path = SnakeAttribute.SnakePathway.Up; } if (Input.GetKey(KeyCode.D) && LastPathway != SnakeAttribute.SnakePathway.Left) { path = SnakeAttribute.SnakePathway.Right; } if (Input.GetKey(KeyCode.S) && LastPathway != SnakeAttribute.SnakePathway.Up) { path = SnakeAttribute.SnakePathway.Down; } if (Input.GetKey(KeyCode.A) && LastPathway != SnakeAttribute.SnakePathway.Right) { path = SnakeAttribute.SnakePathway.Left; } LastPathway = path; return(path); }
/// <summary> /// Метод просчитывает вес решений /// если идти через стены или не обязательно /// Method that calculates decision weights and determines whether should you go through the walls or not /// </summary> /// <param name="map">Карта/Map</param> /// <param name="xFactor">Множитель кординаты X/X coordinate multiplier</param> /// <param name="yFactor">Множитель кординаты Y/Y coordinate multiplier</param> /// <param name="path">Путь/Path</param> protected void CheckOtherSide(PlayingMap map, int xFactor, int yFactor, SnakeAttribute.SnakePathway path) { int genesSize = Genes.FoodGenes[SnakeAttribute.SnakePathway.Up].GetLength(0); int genesCenter = genesSize / 2; foreach (var food in map.Food.FoodCordinates) { if (xFactor * map.sideSize + food.X - Head.X + genesCenter < genesSize && yFactor * map.sideSize + food.Y - Head.Y + genesCenter < genesSize && xFactor * map.sideSize + food.X - Head.X + genesCenter >= 0 && yFactor * map.sideSize + food.Y - Head.Y + genesCenter >= 0) // TODO: Оптимищировать используя Math.Abs() { SnakePathwaysWeights[path] += Genes.FoodGenes[path][yFactor * map.sideSize + food.Y - Head.Y + genesCenter, xFactor *map.sideSize + food.X - Head.X + genesCenter]; } } foreach (var barrier in map.Barriers) { if (xFactor * map.sideSize + barrier.X - Head.X + genesCenter < genesSize && yFactor * map.sideSize + barrier.Y - Head.Y + genesCenter < genesSize && xFactor * map.sideSize + barrier.X - Head.X + genesCenter >= 0 && yFactor * map.sideSize + barrier.Y - Head.Y + genesCenter >= 0) { SnakePathwaysWeights[path] += Genes.BarrierGenes[path][yFactor * map.sideSize + barrier.Y - Head.Y + genesCenter, xFactor *map.sideSize + barrier.X - Head.X + genesCenter]; } } foreach (var snake in map.Snake) { foreach (var snakeCordinates in snake.Cordinates) { if (xFactor * map.sideSize + snakeCordinates.X - Head.X + genesCenter < genesSize && yFactor * map.sideSize + snakeCordinates.Y - Head.Y + genesCenter < genesSize && xFactor * map.sideSize + snakeCordinates.X - Head.X + genesCenter >= 0 && yFactor * map.sideSize + snakeCordinates.Y - Head.Y + genesCenter >= 0) { SnakePathwaysWeights[path] += Genes.BarrierGenes[path] [yFactor * map.sideSize + snakeCordinates.Y - Head.Y + genesCenter, xFactor *map.sideSize + snakeCordinates.X - Head.X + genesCenter]; } } } }
public override SnakeAttribute.SnakePathway GetNextPathway(PlayingMap map) { SnakeAttribute.SnakePathway path = LastPathway; bool correctPathway = false; while (!correctPathway) { int randPathNum = Random.Range(0, 4); if (randPathNum == 0 && LastPathway != SnakeAttribute.SnakePathway.Down) { path = SnakeAttribute.SnakePathway.Up; correctPathway = true; } if (randPathNum == 1 && LastPathway != SnakeAttribute.SnakePathway.Left) { path = SnakeAttribute.SnakePathway.Right; correctPathway = true; } if (randPathNum == 2 && LastPathway != SnakeAttribute.SnakePathway.Up) { path = SnakeAttribute.SnakePathway.Down; correctPathway = true; } if (randPathNum == 3 && LastPathway != SnakeAttribute.SnakePathway.Right) { path = SnakeAttribute.SnakePathway.Left; correctPathway = true; } } LastPathway = path; return(path); }
private SnakeAttribute.SnakePathway GetNearPathwayToFood(PlayingMap map) { SnakeAttribute.SnakePathway path = LastPathway; minDistance = Math.Pow(map.sideSize, 2); // Смотрим все проходы за стены // Checking all pather beyond walls for (int xFactor = -1; xFactor <= 1; xFactor++) { for (int yFactor = -1; yFactor <= 1; yFactor++) { CheckOtherSide(map, xFactor, yFactor); } } List <SnakeAttribute.SnakePathway> correctPathways = new List <SnakeAttribute.SnakePathway>(); // Выбираем направления // Choosing direction if (Head.Y < nearestFoodCor.Y + map.sideSize * YFactor) { correctPathways.Add(SnakeAttribute.SnakePathway.Down); } else { correctPathways.Add(SnakeAttribute.SnakePathway.Up); } if (Head.X < nearestFoodCor.X + map.sideSize * XFactor) { correctPathways.Add(SnakeAttribute.SnakePathway.Right); } else { correctPathways.Add(SnakeAttribute.SnakePathway.Left); } bool isLongestPathVertical = (Math.Abs(Head.X - nearestFoodCor.X + map.sideSize * XFactor) > Math.Abs(Head.Y - nearestFoodCor.Y + map.sideSize * YFactor)) ? false : true; // Смотрим не пойдет ли змейка в себя // Checking if snake collides with itself foreach (var pathway in correctPathways) { if (pathway == SnakeAttribute.SnakePathway.Up && LastPathway == SnakeAttribute.SnakePathway.Down) { correctPathways.Remove(pathway); break; } if (pathway == SnakeAttribute.SnakePathway.Right && LastPathway == SnakeAttribute.SnakePathway.Left) { correctPathways.Remove(pathway); break; } if (pathway == SnakeAttribute.SnakePathway.Down && LastPathway == SnakeAttribute.SnakePathway.Up) { correctPathways.Remove(pathway); break; } if (pathway == SnakeAttribute.SnakePathway.Left && LastPathway == SnakeAttribute.SnakePathway.Right) { correctPathways.Remove(pathway); break; } } // Выбераем окончательный путь // Coosing final path if (correctPathways.Count > 1) { foreach (var pathway in correctPathways) { if (isLongestPathVertical) { if (pathway == SnakeAttribute.SnakePathway.Down || pathway == SnakeAttribute.SnakePathway.Up) { path = pathway; break; } break; } path = pathway; } } else { path = correctPathways[0]; } LastPathway = path; return(path); }
/// <summary> /// Метот считывает все следующие шаги змеек. /// Производит логические операции /// Method reads all next steps of snakes and make logic operations /// </summary> /// <returns>Возвращает карту с новым положением объектов</returns> /// Returns map with new location of objects public override PlayingMap GetNextPlayingMap() { PlayingMap tempMap = new PlayingMap(Map); Map.Snake.Clear(); // Считываем следующие направления //Reads next directions foreach (var snake in SnakesForLogic.Snakes) { // Если змейка мертва у нее ничего не просим //In case of snake's dead dont ask for anything if (!snake.IsAlive) { if (LeftDeadSnakeBody) { Map.Snake.Add(new PlayingMapAttributes.Snake(snake.SnakeName, snake.SnakeBody, snake, snake.Statistics)); } continue; } SnakeAttribute.SnakePathway snakePathway = snake.GetNextPathway(tempMap); snake.Statistics.Steps++; SnakeAttribute.Cordinates snakeHead = snake.Head; // Если змейка после шага погибает, мы ее не передвигаем //In case a snake dies after making a step, we don't move it switch (snakePathway) { case SnakeAttribute.SnakePathway.Up: snakeHead.Y = (snakeHead.Y - 1 != -1) ? --snakeHead.Y : Map.sideSize - 1; ReactionToMapsObjectsOnNewPosition(snakeHead, snake, tempMap); break; case SnakeAttribute.SnakePathway.Right: snakeHead.X = (snakeHead.X + 1 != Map.sideSize) ? ++snakeHead.X : 0; ReactionToMapsObjectsOnNewPosition(snakeHead, snake, tempMap); break; case SnakeAttribute.SnakePathway.Down: snakeHead.Y = (snakeHead.Y + 1 != Map.sideSize) ? ++snakeHead.Y : 0; ReactionToMapsObjectsOnNewPosition(snakeHead, snake, tempMap); break; case SnakeAttribute.SnakePathway.Left: snakeHead.X = (snakeHead.X - 1 != -1) ? --snakeHead.X : Map.sideSize - 1; ReactionToMapsObjectsOnNewPosition(snakeHead, snake, tempMap); break; default: throw new ArgumentException(nameof(snakePathway), "Unknown pathway"); } // Проверяем жива ли змейка после хода //Checking whether snake is alinve if (!snake.IsAlive) { if (LeftDeadSnakeBody) { Map.Snake.Add(new PlayingMapAttributes.Snake(snake.SnakeName, snake.SnakeBody, snake, snake.Statistics)); } } else { Map.Snake.Add(new PlayingMapAttributes.Snake(snake.SnakeName, snake.SnakeBody, snake, snake.Statistics)); } } // Окончательная проверка того живы ли змейки //Last check of snake's alive state foreach (var snake in SnakesForLogic.Snakes) { PlayingMap tempMapForColisionChecking = new PlayingMap(Map); var snakeForMap = new PlayingMapAttributes.Snake (snake.SnakeName, new List <SnakeAttribute.Cordinates>(snake.SnakeBody), snake, snake.Statistics); // Удаляем голову змейки из карты, чтобы у нее не было коллизии с собой //Delete snake's head from the map, so that it doesn't collide with itself tempMapForColisionChecking.Snake.RemoveAll(s => snakeForMap == s); var head = snakeForMap.Cordinates[0]; snakeForMap.Cordinates.RemoveAt(0); tempMapForColisionChecking.Snake.Add(snakeForMap); // Если обнаруживается коллизия укорачиваем змейку с головы //If snake collides shortening it starting from head if (HasCollisionAfterStep(head, tempMapForColisionChecking, snakeForMap)) { snakeForMap = new PlayingMapAttributes.Snake(snake.SnakeName, snake.SnakeBody, snake, snake.Statistics); Map.Snake.RemoveAll(s => snakeForMap == s); snakeForMap.Cordinates.RemoveAt(0); Map.Snake.Add(snakeForMap); } } Map.Food = tempMap.Food; InsertFood(Map); UpdateLengthStatistics(); return(Map); }