public void OnCollision(PlayingMapAttributes.Snake snake, PlayingMap currentMap, PlayingMap previousMap) { var tailPos = previousMap.Snake.Find(x => x == snake).Cordinates.Last(); snake.Cordinates.Add(tailPos); snake.Cordinates.RemoveAt(0); }
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); }
public static bool CollisionWithOtherObject(Cordinates cordinate, PlayingMap map, bool leaveDeadBody) { foreach (var barrier in map.Barriers) { if (barrier == cordinate) { return(true); } } foreach (var food in map.Food.FoodCordinates) { if (food == cordinate) { return(true); } } foreach (var snake in map.Snake) { if (!snake.IsAlive && !leaveDeadBody) { foreach (var coord in snake.Cordinates) { if (coord == cordinate) { return(true); } } } } return(false); }
void Start() { EndGame = false; TimePause = Time.time + GameInits.Pause; GameLogic = new CustomisingLogic ( GameInits.GameoverPredicates, GameInits.SnakeNames, GameInits.Assembly, GameInits.MapSize, GameInits.FoodCount, GameInits.LeftDeadSnakeBody ); Map = GameLogic.GetCurrentPlayingMap(); SetTileBases(); FillBackground(); SetGridScale(); ShowFood(); ShowSnakes(); ShowBarriers(); SetUpStatisticsTable(); }
/// <summary> /// Базовый конструктор /// Base constructor /// </summary> /// <param name="snakeFactory">Производство змеек/Snakes factory</param> /// <param name="mapSideSize">Сторона карты/Map's edge</param> /// <param name="foodCount">Максимальное колличество еды/Max amount of food</param> public GameLogicBase(HashSet <GameLogicsAttributes.GameoverPredicates> gameoverPredicates, ISnakeFactory snakeFactory, int mapSideSize, int foodCount, List <string> snakeNames, bool leftDeadSnakeBody = false, GameLogicsAttributes.Barriers barriers = GameLogicsAttributes.Barriers.None) { BarriersType = barriers; this.SnakeFactory = snakeFactory; this.SnakesForLogic = new GameLogicsAttributes.SnakesForLogic(); Map = new PlayingMap(mapSideSize, foodCount); LeftDeadSnakeBody = leftDeadSnakeBody; InitialGameoverPredicate(gameoverPredicates); if (snakeNames.Count == 0) { snakeNames.Add(nameof(PlayerArrows)); } var snakesCordinates = GetInitialSnakesCordinates(mapSideSize, snakeNames.Count); for (int i = 0; i < snakeNames.Count; i++) { var snake = snakeFactory.GetSnakeByName(snakeNames[i], snakesCordinates[i]); snake.ID = i; SnakesForLogic.Snakes.Add(snake); } foreach (var snake in SnakesForLogic.Snakes) { Map.Snake.Add(new PlayingMapAttributes.Snake(snake.SnakeName, snake.SnakeBody, snake, snake.Statistics)); } InsertBarriers(Map); InsertFood(Map); }
public override void AddSnakes(PlayingMap currentMap) { foreach (var snake in Snakes) { currentMap.Snake.Add(snake); } Snakes.Clear(); }
/// <summary> /// Метот считывает все следующие шаги змеек. /// Производит логические операции /// Method reads all next steps of snakes and make logic operations /// </summary> /// <returns>Возвращает карту с новым положением объектов /// Returns map with new location of objects</returns> public override PlayingMap GetNextPlayingMap() { var previousMap = new PlayingMap(Map); Map.Snake.Clear(); ReadNextSnakesPathwayAndMove(previousMap); CheckCollisionWithFoodAndRemoveFood(previousMap); foreach (var snake in Map.Snake) { if (snake.FoundFoodAfterStep) { CollisionWithFood.OnCollision(snake, Map, previousMap); } } foreach (var snake in Map.Snake) { if (snake.IsAlive && CollisionWithBarrier(snake, Map)) { CollisionWithBarrier.OnCollision(snake, Map, previousMap); } } while (SnakesHaveCollisionsWithOtherSnakes(Map)) { foreach (var snake in Map.Snake) { if (CollisionWithSnakes(snake, Map)) { CollisionWithSnake.OnCollision(snake, Map, previousMap); } } } foreach (var snake in Map.Snake) { if (snake.IsAlive) { DidStepsWithoutFood.OnStepDid(snake, Map, previousMap, this); } } foreach (var snake in Map.Snake) { if (snake.Cordinates.Count >= AchievedLength.Length) { AchievedLength.OnAchievedLength(snake, Map, previousMap, this); } } AchievedLength.AddSnakes(Map); InsertFood(Map); return(Map); }
/// <summary> /// Метод проверяет колизию с едой /// </summary> /// <param name="cordinate">Кординаты для проверки</param> /// <param name="map">Карта с объектами</param> /// <returns>True если есть колизия с едой</returns> public static bool CollisionWithFood(SnakeAttribute.Cordinates cordinate, PlayingMap map) { foreach (var food in map.Food.FoodCordinates) { if (food == cordinate) { return(true); } } return(false); }
public static bool SnakesHaveCollisionsWithOtherSnakes(PlayingMap map) { foreach (var snake in map.Snake) { if (CollisionWithSnakes(snake, map)) { return(true); } } return(false); }
/// <summary> /// Метод проверяет колизию со змейками /// </summary> /// <param name="cordinate">Кординаты для проверки</param> /// <param name="map">Карта с объектами</param> /// <returns>True если есть колизия со змейкой</returns> protected bool CollisionWithSnakes(SnakeAttribute.Cordinates cordinate, PlayingMap map) { foreach (var snake in map.Snake) { foreach (var snakesCordinates in snake.Cordinates) { if (snakesCordinates == cordinate) { return(true); } } } return(false); }
/// <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 void Play() { while (End == false) { PlayingMap.Render(); Console.WriteLine("남은 지뢰 개수: " + LeftMine + "남은 노드 개수" + LeftNode); AnswerMap.Render(); GetInput(); if (LeftNode == 0) { Console.WriteLine("Congraturations!"); return; } Console.Clear(); } }
/// <summary> /// Метод добавляющий еду на карту в зависимости /// от максимально возможного ее количества. /// Следует вызывать только после того как все /// змейки будут перемещены /// Method which adds food to the map based on max amoung of it's instances. /// Should be called only when all snakes had been moved. /// </summary> public void InsertFood(PlayingMap map) { System.Random random = new System.Random(); while (map.Food.FoodCordinates.Count < map.Food.MaxCount) { SnakeAttribute.Cordinates foodCordinates = new SnakeAttribute.Cordinates (random.Next(0, map.sideSize), random.Next(0, map.sideSize)); if (!CollisionWithSnakes(foodCordinates, map) && !CollisionWithFood(foodCordinates, map) && !CollisionWithBarriers(foodCordinates, map)) { map.Food.FoodCordinates.Add(foodCordinates); } } }
public override SnakeAttribute.SnakePathway GetNextPathway(PlayingMap map) { foreach (var path in (SnakeAttribute.SnakePathway[])(Enum.GetValues(typeof(SnakeAttribute.SnakePathway)))) { SnakePathwaysWeights[path] = 0; } foreach (var path in (SnakeAttribute.SnakePathway[])(Enum.GetValues(typeof(SnakeAttribute.SnakePathway)))) { for (int xFactor = -1; xFactor <= 1; xFactor++) { for (int yFactor = -1; yFactor <= 1; yFactor++) { CheckOtherSide(map, xFactor, yFactor, path); } } } // Поиск самого маленького возможного веса, чтобы не допустить похода под себя =D // Finding minimum weight, so that snake doesn't step under itself int minWeight = Math.Abs(8 * SnakeAttribute.SnakeGenes.MinGenesValue * Genes.FoodGenes.Count * Genes.FoodGenes.Count) * 2; switch (LastPathway) { case SnakeAttribute.SnakePathway.Up: SnakePathwaysWeights[SnakeAttribute.SnakePathway.Down] -= minWeight; break; case SnakeAttribute.SnakePathway.Down: SnakePathwaysWeights[SnakeAttribute.SnakePathway.Up] -= minWeight; break; case SnakeAttribute.SnakePathway.Right: SnakePathwaysWeights[SnakeAttribute.SnakePathway.Left] -= minWeight; break; case SnakeAttribute.SnakePathway.Left: SnakePathwaysWeights[SnakeAttribute.SnakePathway.Right] -= minWeight; break; } SnakePathwaysWeights[GetNearPathwayToFood(map)] += 20; var paths = FindMaxWeights(); return(paths[UnityEngine.Random.Range(0, paths.Count - 1)]); }
private static void CheckOtherSide(PlayingMap map, int xFactor, int yFactor, Cordinates point, ref double minDistance, ref Cordinates nearestFoodCor) { foreach (var food in map.Food.FoodCordinates) { double dist = Math.Sqrt( Math.Pow(point.X - (food.X + map.sideSize * xFactor), 2) + Math.Pow(point.Y - (food.Y + map.sideSize * yFactor), 2)); if (dist < minDistance) { minDistance = dist; nearestFoodCor = food; nearestFoodCor.X += xFactor * map.sideSize; nearestFoodCor.Y += yFactor * map.sideSize; } } }
public override void OnAchievedLength(PlayingMapAttributes.Snake snake, PlayingMap currentMap, PlayingMap previousMap, GameLogicBase gl) { snake.SnakeB.Statistics.Length = snake.Cordinates.Count(); List <Cordinates> cordinates = new List <Cordinates>(); var count = snake.Cordinates.Count; for (int i = count - 1; i >= Length / 2; i--) { cordinates.Add(new Cordinates(snake.Cordinates[i])); snake.Cordinates.RemoveAt(i); } string name = Names[new Random().Next(0, Names.Count)]; var newSnake = gl.AddSnake(name, cordinates); newSnake.Statistics.Length = newSnake.SnakeBody.Count; Snakes.Add(new PlayingMapAttributes.Snake(newSnake)); }
public static bool CollisionWithSnakes(PlayingMapAttributes.Snake s, PlayingMap map) { foreach (var snake in map.Snake) { for (int i = 0; i < snake.Cordinates.Count; i++) { if (!(snake == s && i == 0)) { if (snake.Cordinates[i] == s.SnakeB.Head) { return(true); } } } } return(false); }
/// <summary> /// Метод просчитывает растояние до еды, /// если идти через стены или не обязательно /// Method counts distance to the food, should you go through walls or not /// </summary> /// <param name="map">Карта/Map</param> /// <param name="xFactor">Множитель кординаты X/Multiplier of X coordinate</param> /// <param name="yFactor">Множитель кординаты Y/Multiplier of Y coordinate</param> private void CheckOtherSide(PlayingMap map, int xFactor, int yFactor) { // Ищем ближайшую еду foreach (var food in map.Food.FoodCordinates) { double dist = Math.Sqrt( Math.Pow(Head.X - (food.X + map.sideSize * xFactor), 2) + Math.Pow(Head.Y - (food.Y + map.sideSize * yFactor), 2)); if (dist < minDistance) { minDistance = dist; nearestFoodCor = food; XFactor = xFactor; YFactor = yFactor; } } }
public static MapForNN GetMapFromPoint(Cordinates point, int size, PlayingMap playingMap) { int xPadding = point.X - size / 2; int yPadding = point.Y - size / 2; List <MapCoordConverter> coordList = new List <MapCoordConverter>(); for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { int x = xPadding + i; int y = yPadding + j; if (x < 0) { x += playingMap.sideSize; } if (y < 0) { y += playingMap.sideSize; } if (x >= playingMap.sideSize) { x -= playingMap.sideSize; } if (x >= playingMap.sideSize) { x -= playingMap.sideSize; } coordList.Add(new MapCoordConverter() { PMapCoord = new Cordinates(x, y), NNMapCoord = new Cordinates(i, j) }); } } return(CreateMap(size, coordList, playingMap, point)); }
/// <summary> /// Метод используется для окончательной проверки коллизий /// после сделанного змейкой шага /// Method is used to final determination of collision after snake takes a step /// </summary> /// <param name="head">Голова змейки/Snake's head</param> /// <param name="map">Игровая карта/Game map</param> /// <param name="snake">Змейка/Snake</param> /// <returns>True если есть коллизия со змейкой или барьером/Returns true is there is collision with snake or obstacle</returns> private bool HasCollisionAfterStep(SnakeAttribute.Cordinates head, PlayingMap map, PlayingMapAttributes.Snake snake) { if (CollisionWithFood(head, map)) { Debug.Log("Error: Unexpected food element"); Map.Food.FoodCordinates.RemoveAll(c => c == head); } if (!snake.IsAlive) { return(false); } if (CollisionWithSnakes(head, map) || CollisionWithBarriers(head, map)) { return(true); } return(false); }
private void CheckCollisionWithFoodAndRemoveFood(PlayingMap previousMap) { HashSet <SnakeAttribute.Cordinates> foodCoordsToRemove = new HashSet <SnakeAttribute.Cordinates>(); foreach (var snake in Map.Snake) { if (snake.IsAlive) { if (CollisionWithFood(snake.SnakeB.Head, previousMap)) { snake.SnakeB.Statistics.EatenFood++; snake.SnakeB.Statistics.Length = snake.Cordinates.Count; snake.FoundFoodAfterStep = true; foodCoordsToRemove.Add(snake.SnakeB.Head); } } } Map.Food.FoodCordinates = Map.Food.FoodCordinates.Where(x => !foodCoordsToRemove.Contains(x)).ToList(); }
void Start() { GameLogic = new StandartLogic ( GameInits.GameoverPredicates, GameInits.SnakeNames, new AssemblySnakeFactory(), GameInits.MapSize, GameInits.FoodCount, GameInits.LeftDeadSnakeBody ); Map = GameLogic.GetCurrentPlayingMap(); SimbolMap = new string[Map.sideSize, Map.sideSize]; FillMapEmptyObjects(); InsertElements(); //ShowMapConsole(); ShowMapTexture(); }
private static void FindNearestFood(ref MapForNN map, PlayingMap pMap, Cordinates point) { Cordinates nearFood = pMap.Food.FoodCordinates[0]; double minDist = Math.Sqrt( Math.Pow(point.X - (pMap.Food.FoodCordinates[0].X), 2) + Math.Pow(point.Y - (pMap.Food.FoodCordinates[0].Y), 2));; for (int xFactor = -1; xFactor <= 1; xFactor++) { for (int yFactor = -1; yFactor <= 1; yFactor++) { CheckOtherSide(pMap, xFactor, yFactor, point, ref minDist, ref nearFood); } } if (point.X < nearFood.X) { map.NearestFoodHorizontal = SnakePathway.Right; } else if (point.X > nearFood.X) { map.NearestFoodHorizontal = SnakePathway.Left; } else { map.NearestFoodHorizontal = null; } if (point.Y < nearFood.Y) { map.NearestFoodVertical = SnakePathway.Down; } else if (point.Y > nearFood.Y) { map.NearestFoodVertical = SnakePathway.Up; } else { map.NearestFoodVertical = null; } }
void Update() { if (EndGame || GameLogic.IsGameEnded()) { var statistics = GameLogic.GetSnakeStatistics(); GameInits.SnakeStatistics = statistics; SceneManager.LoadScene(3); } if (TimePause <= Time.time && !GameLogic.IsGameEnded()) { TimePause = Time.time + GameInits.Pause; Map = GameLogic.GetNextPlayingMap(); SnakesTileMap.ClearAllTiles(); ShowFood(); ShowSnakes(); ShowBarriers(); UpdateStatisticsTable(); } }
private void ReadNextSnakesPathwayAndMove(PlayingMap previousMap) { foreach (var snake in SnakesForLogic.Snakes) { if (!snake.IsAlive) { if (LeftDeadSnakeBody) { Map.Snake.Add(new PlayingMapAttributes.Snake(snake)); } continue; } var pathway = snake.GetNextPathway(previousMap); snake.Statistics.Steps++; var headCoord = snake.Head; switch (pathway) { case SnakeAttribute.SnakePathway.Up: headCoord.Y = (headCoord.Y - 1 != -1) ? --headCoord.Y : Map.sideSize - 1; break; case SnakeAttribute.SnakePathway.Right: headCoord.X = (headCoord.X + 1 != Map.sideSize) ? ++headCoord.X : 0; break; case SnakeAttribute.SnakePathway.Down: headCoord.Y = (headCoord.Y + 1 != Map.sideSize) ? ++headCoord.Y : 0; break; case SnakeAttribute.SnakePathway.Left: headCoord.X = (headCoord.X - 1 != -1) ? --headCoord.X : Map.sideSize - 1; break; } snake.SnakeBody.Insert(0, headCoord); snake.SnakeBody.RemoveAt(snake.SnakeBody.Count - 1); Map.Snake.Add(new PlayingMapAttributes.Snake(snake)); } }
public void OnStepDid(PlayingMapAttributes.Snake snake, PlayingMap currentMap, PlayingMap previousMap, GameLogicBase gl) { if (!DidStepsWithoutFoodById.ContainsKey(snake.SnakeB.ID)) { DidStepsWithoutFoodById.Add(snake.SnakeB.ID, 0); } if (snake.FoundFoodAfterStep) { DidStepsWithoutFoodById[snake.SnakeB.ID] = 0; } else { DidStepsWithoutFoodById[snake.SnakeB.ID]++; } if (DidStepsWithoutFoodById[snake.SnakeB.ID] == StepsWithoutFood) { DidStepsWithoutFoodById[snake.SnakeB.ID] = 0; OnStepsWithoutFoodDid(snake, currentMap, previousMap, gl); } }
private void Update() { if (!GameLogic.IsGameEnded()) { Thread.Sleep(100); Map = GameLogic.GetNextPlayingMap(); FillMapEmptyObjects(); InsertElements(); //ShowMapConsole(); ShowMapTexture(); } else { cccc++; string fileName = "Bug" + cccc.ToString() + ".txt"; // Check if file already exists. If yes, delete it. if (File.Exists(fileName)) { File.Delete(fileName); } // Create a new file using (FileStream fs = File.Create(fileName)) { // Add some text to file Byte[] title = new UTF8Encoding(true).GetBytes("New Text File"); fs.Write(title, 0, title.Length); byte[] author = new UTF8Encoding(true).GetBytes("Mahesh Chand"); fs.Write(author, 0, author.Length); } Map = GameLogic.GetNextPlayingMap(); var statistics = GameLogic.GetSnakeStatistics(); GameInits.SnakeStatistics = statistics; SceneManager.LoadScene(3); } }
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); }
public static bool CollisionWithBarrier(PlayingMapAttributes.Snake s, PlayingMap map) { foreach (var barrier in map.Barriers) { if (barrier == s.SnakeB.Head) { return(true); } } foreach (var snake in map.Snake) { if (!snake.IsAlive) { foreach (var coord in snake.Cordinates) { if (coord == s.SnakeB.Head) { return(true); } } } } return(false); }
private static MapForNN CreateMap(int size, List <MapCoordConverter> coordList, PlayingMap pMap, Cordinates point) { var map = new MapForNN(size); foreach (var c in pMap.Barriers) { var coord = coordList.Where(x => x.PMapCoord == c).ToArray(); if (coord.Length > 0) { map.Map[coord[0].NNMapCoord.X, coord[0].NNMapCoord.Y] = ObjectTypes.Barrier; } } foreach (var c in pMap.Food.FoodCordinates) { var coord = coordList.Where(x => x.PMapCoord == c).ToArray(); if (coord.Length > 0) { map.Map[coord[0].NNMapCoord.X, coord[0].NNMapCoord.Y] = ObjectTypes.Food; } } foreach (var snake in pMap.Snake) { foreach (var c in snake.Cordinates) { var coord = coordList.Where(x => x.PMapCoord == c).ToArray(); if (coord.Length > 0) { map.Map[coord[0].NNMapCoord.X, coord[0].NNMapCoord.Y] = ObjectTypes.Snake; } } } FindNearestFood(ref map, pMap, point); return(map); }