private static bool IsLockByWalls(GameBoard gameBoard, BoardPoint point) { int cntLock = 0; foreach (var dir in GameSettings.Directions) { var nextPoint = point.Shift(dir); var element = gameBoard.GetElementAt(nextPoint); if (element.IsBarrier()) { cntLock++; } } return(cntLock >= 3); }
private static void HandleEnemySnakeRec(BoardPoint prevPoint, BoardPoint point, Stack <BoardPoint> stack, ref bool isEvil) { stack.Push(point); var element = _gameBoard.GetElementAt(point); if (element.IsEnemyHead()) { if (element == BoardElement.EnemyHeadEvil) { isEvil = true; } return; } foreach (var dir in Utils.GetEnemyOpotDirections(element)) { var nextPoint = point.Shift(dir); if (!nextPoint.IsValidPoint(_size)) { continue; } if (nextPoint == prevPoint) { continue; } var nextElement = _gameBoard.GetElementAt(nextPoint); if (Utils.IsExtensionOfEnemyBody(element, nextElement)) { HandleEnemySnakeRec(point, nextPoint, stack, ref isEvil); return; } } }
// Суперкритична скорость, мб придумаю что-нибудь с оптимизацией private static void CalcMaxWeight(SnakeParameters snakeParameters, BoardPoint prevPoint, BoardPoint point, ref long maxWeight, int attackedSnakesIdMask = 0, int deltaLen = 0, long currentWeight = 0, int deep = 1) { var element = _gameBoard.GetElementAt(point); snakeParameters.EvilsDuration = Math.Max(0, snakeParameters.EvilsDuration - 1); if (element == BoardElement.FuryPill && (!GameSettings.CheckLengthsFromNearEnemySnakes || _lengthsFromNearEnemySnake[point.X, point.Y] > deep)) { snakeParameters.EvilsDuration += GameSettings.EvilPillTimeDuration; currentWeight += Math.Max(GameSettings.MultyWeight / 5, (_staticWeights[point.X, point.Y] - GameSettings.EvilWeightReducter * Math.Max(0, snakeParameters.EvilsDuration - GameSettings.EvilTimeDurationForReductEvilWeight))) / (deep + GameSettings.DeepReducterCoeff); } if (element == BoardElement.Apple && (!GameSettings.CheckLengthsFromNearEnemySnakes || _lengthsFromNearEnemySnake[point.X, point.Y] > deep)) { snakeParameters.Length += GameSettings.AppleLengthBooster; currentWeight += _staticWeights[point.X, point.Y] / (deep + GameSettings.DeepReducterCoeff); deltaLen++; } if (element == BoardElement.Stone && (!GameSettings.CheckLengthsFromNearEnemySnakes || _lengthsFromNearEnemySnake[point.X, point.Y] > deep)) { if (snakeParameters.EvilsDuration == 0) { snakeParameters.Length = Math.Max(snakeParameters.Length - GameSettings.StoneLengthReducter, 0); } currentWeight += _staticWeights[point.X, point.Y] / (deep + GameSettings.DeepReducterCoeff); snakeParameters.StonesCount++; } if (element == BoardElement.Gold && (!GameSettings.CheckLengthsFromNearEnemySnakes || _lengthsFromNearEnemySnake[point.X, point.Y] > deep)) { currentWeight += _staticWeights[point.X, point.Y] / (deep + GameSettings.DeepReducterCoeff); } if ((element.IsEnemyBody() || element.IsEnemyActiveHead()) && _enemyParts[point.X, point.Y] != null && (attackedSnakesIdMask & _enemyParts[point.X, point.Y].Value.Id) == 0) { attackedSnakesIdMask |= _enemyParts[point.X, point.Y].Value.Id; var coeff = _enemyParts[point.X, point.Y].Value.DistanceFromTali - deep; if (snakeParameters.EvilsDuration > 0) { currentWeight += coeff * GameSettings.EnemyPartOfBodyWeight / (deep + GameSettings.DeepReducterCoeff); } } if (deep >= GameSettings.DeepLimit) { maxWeight = Math.Max(maxWeight, currentWeight + 1); return; } var tempDistance = DistanceFromMyTail[point.X, point.Y]; DistanceFromMyTail[point.X, point.Y] = DistanceFromMyTail[prevPoint.X, prevPoint.Y] + 1; foreach (var dir in GameSettings.Directions) { var nextPoint = point.Shift(dir); var nextElement = _gameBoard.GetElementAt(nextPoint); if (nextElement.IsBarrier() || nextPoint == prevPoint || DistanceFromMyTail[nextPoint.X, nextPoint.Y] - deep + deltaLen > 0) { continue; } if (snakeParameters.EvilsDuration <= 1) { if (nextElement == BoardElement.Apple || nextElement == BoardElement.FuryPill || nextElement == BoardElement.Gold || nextElement == BoardElement.None || (nextElement.IsEnemySnakePart() && (_enemyParts[nextPoint.X, nextPoint.Y] == null || _enemyParts[nextPoint.X, nextPoint.Y].Value.DistanceFromTali - deep <= 0))) { CalcMaxWeight(snakeParameters, point, nextPoint, ref maxWeight, attackedSnakesIdMask, deltaLen, currentWeight, deep + 1); } } else { CalcMaxWeight(snakeParameters, point, nextPoint, ref maxWeight, attackedSnakesIdMask, deltaLen, currentWeight, deep + 1); } } DistanceFromMyTail[point.X, point.Y] = tempDistance; }