public long Problem1(string input) { var info = input.Split(' '); var players = int.Parse(info[0]); var steps = int.Parse(info[6]); var currentNode = new RingNode(0); currentNode.Next = currentNode; currentNode.Prev = currentNode; var scores = Enumerable.Range(0, players).ToDictionary(it => it, it => (long)0); for (var i = 1; i <= steps; i++) { if (i % 23 == 0) { var toRemove = currentNode.Prev.Prev.Prev.Prev.Prev.Prev.Prev; currentNode = toRemove.Next; toRemove.Remove(); var currentPlayer = i % players; scores[currentPlayer] = scores[currentPlayer] + i + toRemove.Value; } else { var addedNode = new RingNode(i); addedNode.InsertAfter(currentNode.Next); currentNode = addedNode; } } return(scores.Values.Max()); }
public ExerciseStep(PinNode fromNode, PinNode toNode, RingNode ringNode, int stepIndex) { from = fromNode; to = toNode; ring = ringNode; index = stepIndex; }
private static Vector2[] RetracePath(RingNode startingNode, RingNode targetRingNode, Vector2[] pathToStartingRingNode) { var ringNodes = new List <RingPosition>(); var currentRingNode = targetRingNode; while (currentRingNode != startingNode) { ringNodes.Add(currentRingNode.RingPosition); currentRingNode = currentRingNode.ParentRing; } ringNodes.Add(startingNode.RingPosition); var positions = ringNodes.Select(t => (Vector2)t.transform.position).ToList(); positions.Reverse(); if (pathToStartingRingNode != null && pathToStartingRingNode.Length > 0) { for (var i = pathToStartingRingNode.Length - 1; i > 0; i--) { positions.Insert(0, pathToStartingRingNode[i]); } } return(positions.ToArray()); }
public void Remove() { Prev.Next = Next; Next.Prev = Prev; Prev = null; Next = null; }
private void visitPath(ExercisePath path) { //Adding the step to the solution ExerciseStep step = new ExerciseStep(getPinContainingRing(path.from), path.destination, path.from, solution.Count + 1); solution.Add(step); path.from.step = step.index; //Changing the exercise status step.from.ringPop(); //Remove the node from the current pin //Are we moving the biggest ring? (it is only moved once) if (step.ring.size == biggestRing.size) { solutionPinIndex = step.to.index; step.ring.isSolved = true; } //is this the final position for the ring? else if (step.to.index == solutionPinIndex) { RingNode rn = step.to.ringPeek(); if (rn.isSolved && rn.size == step.ring.size + 1) { step.ring.isSolved = true; } } step.to.ringPush(step.ring); //Adding the ring to the destination //Erase pending paths from the previous step if (solution.Count > 1) { solution[solution.Count - 2].ring.emptyPendingPaths(); } }
public void InsertAfter(RingNode item) { Next = item.Next; Next.Prev = this; Prev = item; Prev.Next = this; }
public static Vector2[] Path(IUnitEnemy unitEnemy, RingNode startingNode, RingNode targetRingNode) { if (!targetRingNode.IsWalkable() || !startingNode.IsWalkable()) { return(null); } Vector2[] pathToStartingRingNode = null; if (unitEnemy != null) { pathToStartingRingNode = Pathfinder.Path(unitEnemy, startingNode.RingPosition.transform.position); } var openSet = new Heap <RingNode>(RingManager.Instance.AllPositions.Count); var closedSet = new HashSet <RingNode>(); openSet.Add(startingNode); while (openSet.Count > 0) { var currentNode = openSet.RemoveFirst(); closedSet.Add(currentNode); if (currentNode == targetRingNode) { return(RetracePath(startingNode, targetRingNode, pathToStartingRingNode)); } foreach (var neighbor in RingManager.Instance.GetNeighborsFor(currentNode)) { if (!neighbor.IsWalkable() || closedSet.Contains(neighbor)) { continue; } var newMovementCostToNeighbor = currentNode.GCost + GetDistance(currentNode, neighbor); if (newMovementCostToNeighbor < neighbor.GCost || !openSet.Contains(neighbor)) { neighbor.GCost = newMovementCostToNeighbor; neighbor.HCost = GetDistance(neighbor, targetRingNode); neighbor.ParentRing = currentNode; if (!openSet.Contains(neighbor)) { openSet.Add(neighbor); } else { openSet.UpdateItem(neighbor); } } } } return(null); }
/** * Remove and return the last ring (Last In First Out) **/ public RingNode ringPop() { if (!isEmpty()) { RingNode result = ringStack[ringStack.Count - 1]; ringStack.RemoveAt(ringStack.Count - 1); return(result); } return(null); }
private void fillPendingPaths(RingNode ring) { PinNode pin; for (int i = 0; i < pins.Count; i++) { pin = pins[i]; //This ring could fit in the pin if (pin.isEmpty() || ring.size < pin.ringPeek().size) { //NEW PATH ExercisePath path = new ExercisePath(0, pin, ring); //Calculate the path weight (so we can decide wich path is better) //Less weight makes a better path //if is occupied then it weights more than an empty one if (!pin.isEmpty()) { path.weight += 1; //If the firs ring in the pin isn't solved it could have advantage based on size if (!pin.ringPeek().isSolved) { //Better than an empty one. path.weight -= (pin.getFirstUnsolvedRing().size - ring.size) * 2; } } //If the path is the solution for this ring it has more weight if (pin.isEmpty()) { //Is the biggest one if (ring.size == biggestRing.size) { path.weight -= rings.Count * 2; } } else { RingNode rn = pin.ringPeek(); if (rn.isSolved && ring.size + 1 == pin.ringPeek().size) { path.weight -= rings.Count * 2; } } //add the path to the ring ring.addPath(path); } } }
private bool DoRingFitInAnyPin(RingNode ring) { foreach (PinNode pin in pins) { if (pin.isEmpty() || ring.size < pin.ringPeek().size) { return(true); } } //No fit return(false); }
private PinNode getPinContainingRing(RingNode ring) { for (int i = 0; i < pins.Count; i++) { /*getPinContainingRing * We use size to check for the ring since there was a nasty bug with GetInstanceID */ if (!pins[i].isEmpty() && pins[i].ringPeek().size == ring.size) { return(pins[i]); } } return(null); }
private RingNode getBestRingToMove(List <RingNode> options) { RingNode result = null; bool couldBeMoved; //choose foreach (RingNode ring in options) { //could be moved? couldBeMoved = false; if (!ring.isSolved) { for (int i = 0; i < pins.Count; i++) { //This ring could fit in the Path if (pins[i].isEmpty() || ring.size < pins[i].ringPeek().size) { couldBeMoved = true; break; } } } if (!couldBeMoved) { continue; } //There is no choice if (result == null) { result = ring; } //if this is the last ring in the solution then it isn't the best choice else if (solution.Count == 0 || solution[solution.Count - 1].ring.size != ring.size) { result = ring; } } return(result); }
public List <RingNode> GetNeighborsFor(RingNode currentNode) { var neighbors = new List <RingNode>(); foreach (var ringPosition in _allPositions) { var xDistanceSquared = (ringPosition.transform.position.x - currentNode.RingPosition.transform.position.x) * (ringPosition.transform.position.x - currentNode.RingPosition.transform.position.x); var yDistanceSquared = (ringPosition.transform.position.y - currentNode.RingPosition.transform.position.y) * (ringPosition.transform.position.y - currentNode.RingPosition.transform.position.y); var distance = xDistanceSquared + yDistanceSquared; if (distance < _neighborCheckRadius * _neighborCheckRadius || distance == _neighborCheckRadius * _neighborCheckRadius) { neighbors.Add(ringPosition.RingNode); } } return(neighbors); }
private static void HandleDiagnostics(HttpListenerContext httpCtx, uint httpReqId) { Console.WriteLine("FRONTEND: [{0}] Handling Diagnostics request from client {1}", httpReqId, httpCtx.Request.RemoteEndPoint); Console.WriteLine("FRONTEND: [{0}] Reading current ring setup", httpReqId); RingNode[] ringNodeArray; if (nodeRing.IsEmpty) ringNodeArray = new RingNode[0]; else ringNodeArray = nodeRing.ToArray().Select(kvp => new RingNode { RingId = kvp.Key, NodeGuid = kvp.Value, NodeUri = storageNodes[kvp.Value].ToString() }).ToArray(); var ringNodeSerializer = new XmlSerializer(ringNodeArray.GetType(), new XmlRootAttribute { ElementName = "Ring" }); httpCtx.Response.StatusCode = (int)HttpStatusCode.OK; httpCtx.Response.ContentType = MediaTypeNames.Text.Xml; using (var targetStream = new MemoryStream()) { Console.WriteLine("FRONTEND: [{0}] Serializing ring status to XML", httpReqId); ringNodeSerializer.Serialize(targetStream, ringNodeArray); targetStream.Flush(); Console.WriteLine("FRONTEND: [{0}] Sending XMl response to client", httpReqId); httpCtx.Response.Close(targetStream.ToArray(), willBlock: false); } }
private static int GetDistance(RingNode nodeA, RingNode nodeB) { return((int)Vector2.Distance(nodeA.RingPosition.transform.position, nodeB.RingPosition.transform.position)); }
public void SetRingNode() { RingNode = new RingNode(this); }
private void CheckNodeObjects(SystemObject obj) { var currentParent = ExtractParents(obj); if (currentParent.Ring.HasValue) { var parentnode = _nodes.Where(m => m.BodyId == currentParent.Ring).FirstOrDefault(); var childnode = _nodes.Where(m => m.BodyId == obj.Id).FirstOrDefault(); if (parentnode == null) { parentnode = new RingNode(currentParent.Ring.Value); _nodes.Add(parentnode); } if (childnode == null) { childnode = SystemNode.CreateNodeFromObject(obj); _nodes.Add(childnode); } parentnode.ChildList.Add(childnode); childnode.ParentList.Add(parentnode); UpdateStarsystemMap?.Invoke(childnode); return; } if (currentParent.Planet.HasValue) { var parentnode = _nodes.Where(m => m.BodyId == currentParent.Planet).FirstOrDefault(); var childnode = _nodes.Where(m => m.BodyId == obj.Id).FirstOrDefault(); if (parentnode == null) { parentnode = new PlanetNode(currentParent.Planet.Value); _nodes.Add(parentnode); } if (childnode == null) { childnode = SystemNode.CreateNodeFromObject(obj); _nodes.Add(childnode); } parentnode.ChildList.Add(childnode); childnode.ParentList.Add(parentnode); UpdateStarsystemMap?.Invoke(childnode); return; } if (currentParent.Star.HasValue) { var parentnode = _nodes.Where(m => m.BodyId == currentParent.Star).FirstOrDefault(); var childnode = _nodes.Where(m => m.BodyId == obj.Id).FirstOrDefault(); if (parentnode == null) { parentnode = new StarNode(currentParent.Star.Value); _nodes.Add(parentnode); } if (childnode == null) { childnode = SystemNode.CreateNodeFromObject(obj); _nodes.Add(childnode); } parentnode.ChildList.Add(childnode); childnode.ParentList.Add(parentnode); UpdateStarsystemMap?.Invoke(childnode); return; } if (currentParent.Null.HasValue) { var parentnode = _nodes.Where(m => m.BodyId == currentParent.Null).FirstOrDefault(); var childnode = _nodes.Where(m => m.BodyId == obj.Id).FirstOrDefault(); if (parentnode == null) { parentnode = new BarycenterNode(currentParent.Null.Value); _nodes.Add(parentnode); } if (childnode == null) { childnode = SystemNode.CreateNodeFromObject(obj); _nodes.Add(childnode); } parentnode.ChildList.Add(childnode); childnode.ParentList.Add(parentnode); UpdateStarsystemMap?.Invoke(childnode); return; } }
public override void Process(uint seed) { if (World.Networked || World.Size < MinWorldSize) { return; } int[,] array = TerrainPath.CreateRoadCostmap(ref seed); PathFinder pathFinder = new PathFinder(array); int length = array.GetLength(0); int num = length / 4; int num2 = 4; int stepcount = num / num2; int num3 = length / 2; int pos_x = num; int pos_x2 = length - num; int pos_y = num; int pos_y2 = length - num; int num4 = 0; int dir_x = -num2; int dir_x2 = num2; int dir_y = -num2; int dir_y2 = num2; List <RingNode> list = ((World.Size >= 5000) ? new List <RingNode> { new RingNode(num3, pos_y2, num4, dir_y, stepcount), new RingNode(pos_x2, pos_y2, dir_x, dir_y, stepcount), new RingNode(pos_x2, num3, dir_x, num4, stepcount), new RingNode(pos_x2, pos_y, dir_x, dir_y2, stepcount), new RingNode(num3, pos_y, num4, dir_y2, stepcount), new RingNode(pos_x, pos_y, dir_x2, dir_y2, stepcount), new RingNode(pos_x, num3, dir_x2, num4, stepcount), new RingNode(pos_x, pos_y2, dir_x2, dir_y, stepcount) } : new List <RingNode> { new RingNode(pos_x2, pos_y2, dir_x, dir_y, stepcount), new RingNode(pos_x2, pos_y, dir_x, dir_y2, stepcount), new RingNode(pos_x, pos_y, dir_x2, dir_y2, stepcount), new RingNode(pos_x, pos_y2, dir_x2, dir_y, stepcount) }); for (int i = 0; i < list.Count; i++) { RingNode ringNode = list[i]; RingNode next = list[(i + 1) % list.Count]; RingNode prev = list[(i - 1 + list.Count) % list.Count]; ringNode.next = next; ringNode.prev = prev; while (!pathFinder.IsWalkable(ringNode.position)) { if (ringNode.attempts <= 0) { return; } ringNode.position += ringNode.direction; ringNode.attempts--; } } foreach (RingNode item in list) { item.path = pathFinder.FindPath(item.position, item.next.position, 250000); } bool flag = false; while (!flag) { flag = true; PathFinder.Point point = new PathFinder.Point(0, 0); foreach (RingNode item2 in list) { point += item2.position; } point /= list.Count; float num5 = float.MinValue; RingNode ringNode2 = null; foreach (RingNode item3 in list) { if (item3.path == null) { float num6 = new Vector2(item3.position.x - point.x, item3.position.y - point.y).magnitude; if (item3.prev.path == null) { num6 *= 1.5f; } if (num6 > num5) { num5 = num6; ringNode2 = item3; } } } if (ringNode2 == null) { continue; } do { if (ringNode2.attempts <= 0) { return; } ringNode2.position += ringNode2.direction; ringNode2.attempts--; }while (!pathFinder.IsWalkable(ringNode2.position)); ringNode2.path = pathFinder.FindPath(ringNode2.position, ringNode2.next.position, 250000); ringNode2.prev.path = pathFinder.FindPath(ringNode2.prev.position, ringNode2.position, 250000); flag = false; } if (!flag) { return; } for (int j = 0; j < list.Count; j++) { RingNode ringNode3 = list[j]; RingNode ringNode4 = list[(j + 1) % list.Count]; for (PathFinder.Node node = ringNode3.path; node != null; node = node.next) { for (PathFinder.Node node2 = ringNode4.path; node2 != null; node2 = node2.next) { if (Mathf.Abs(node.point.x - node2.point.x) <= 1 && Mathf.Abs(node.point.y - node2.point.y) <= 1) { node.next = null; ringNode4.path = node2; break; } } } } PathFinder.Node node3 = null; PathFinder.Node node4 = null; foreach (RingNode item4 in list) { if (node3 == null) { node3 = item4.path; node4 = item4.path; } else { node4.next = item4.path; } while (node4.next != null) { node4 = node4.next; } } node4.next = new PathFinder.Node(node3.point, node3.cost, node3.heuristic); List <Vector3> list2 = new List <Vector3>(); for (PathFinder.Node node5 = node3; node5 != null; node5 = node5.next) { float normX = ((float)node5.point.x + 0.5f) / (float)length; float normZ = ((float)node5.point.y + 0.5f) / (float)length; float x = TerrainMeta.DenormalizeX(normX); float z = TerrainMeta.DenormalizeZ(normZ); float y = Mathf.Max(TerrainMeta.HeightMap.GetHeight(normX, normZ), 1f); list2.Add(new Vector3(x, y, z)); } if (list2.Count >= 2) { int count = TerrainMeta.Path.Roads.Count; PathList pathList = new PathList("Road " + count, list2.ToArray()); pathList.Width = 12f; pathList.InnerPadding = 1f; pathList.OuterPadding = 1f; pathList.InnerFade = 1f; pathList.OuterFade = 8f; pathList.RandomScale = 0.75f; pathList.MeshOffset = 0f; pathList.TerrainOffset = -0.125f; pathList.Topology = 2048; pathList.Splat = 128; pathList.Start = false; pathList.End = false; pathList.ProcgenStartNode = node3; pathList.ProcgenEndNode = node4; pathList.Path.Smoothen(4); pathList.Path.RecalculateTangents(); pathList.AdjustPlacementMap(24f); TerrainMeta.Path.Roads.Add(pathList); } }
public ExercisePath(int pathWeight, PinNode destinationPin, RingNode fromRing) { weight = pathWeight; destination = destinationPin; from = fromRing; }
/** * Ring added to the stack */ public void ringPush(RingNode ring) { ringStack.Add(ring); }