Esempio n. 1
0
        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());
        }
Esempio n. 2
0
 public ExerciseStep(PinNode fromNode, PinNode toNode, RingNode ringNode, int stepIndex)
 {
     from  = fromNode;
     to    = toNode;
     ring  = ringNode;
     index = stepIndex;
 }
Esempio n. 3
0
    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());
    }
Esempio n. 4
0
 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();
        }
    }
Esempio n. 6
0
 public void InsertAfter(RingNode item)
 {
     Next      = item.Next;
     Next.Prev = this;
     Prev      = item;
     Prev.Next = this;
 }
Esempio n. 7
0
    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);
    }
Esempio n. 8
0
    /**
     * 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);
            }
        }
    }
Esempio n. 10
0
    private bool DoRingFitInAnyPin(RingNode ring)
    {
        foreach (PinNode pin in pins)
        {
            if (pin.isEmpty() || ring.size < pin.ringPeek().size)
            {
                return(true);
            }
        }

        //No fit
        return(false);
    }
Esempio n. 11
0
    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);
    }
Esempio n. 12
0
    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);
    }
Esempio n. 13
0
    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);
            }
        }
Esempio n. 15
0
 private static int GetDistance(RingNode nodeA, RingNode nodeB)
 {
     return((int)Vector2.Distance(nodeA.RingPosition.transform.position, nodeB.RingPosition.transform.position));
 }
Esempio n. 16
0
 public void SetRingNode()
 {
     RingNode = new RingNode(this);
 }
Esempio n. 17
0
        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;
            }
        }
Esempio n. 18
0
    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);
        }
    }
Esempio n. 19
0
 public ExercisePath(int pathWeight, PinNode destinationPin, RingNode fromRing)
 {
     weight      = pathWeight;
     destination = destinationPin;
     from        = fromRing;
 }
Esempio n. 20
0
 /**
  * Ring added to the stack
  */
 public void ringPush(RingNode ring)
 {
     ringStack.Add(ring);
 }