public void RemoveNode(PuzzleNode node) { // Remove edges referencing node for (int i = edges.Count - 1; i >= 0; i--) { if (edges[i].nodeA == node || edges[i].nodeB == node) { RemoveEdge(edges[i]); } } // Remove element if (node.element != null) { RemoveElement(node.element); } // Remove items for (int i = 0; i < items.Count; i++) { if (items[i].defaultNode == node) { RemoveItem(items[i]); } } // Remove node nodes.Remove(node); removeNode(node); }
private void Init() { lastNode = null; pieceList.Clear(); for (var i = 0; i < Container.childCount; i++) { var node = new PuzzleNode(); node.Show = false; var c = Container.GetChild(i); var t = c.GetComponent <UITexture>(); NGUITools.UpdateWidgetCollider(t.gameObject); node.Texture = t; var tTransform = t.transform; tTransform.gameObject.SetActive(false); tTransform.collider.enabled = false; var s = tTransform.GetChild(0); node.Select = s; node.Select.gameObject.SetActive(false); var index = i / MaxLength * 10 + i % MaxLength; pieceList.Add(index, node); var e = c.GetComponent <UIEventTrigger>(); e.onClick.Add(new EventDelegate(() => { OnTextureClick(index); })); tTransform.localScale = Vector3.one * 0.95f; } isInit = true; }
public void AddNode(PuzzleNode node) { nodes.Add(node); if (string.IsNullOrEmpty(node.name)) { char testChar = 'A'; while (true) { bool unique = true; foreach (PuzzleNode n in nodes) { if (n.name.Length > 0 && n.name[0] == testChar) { unique = false; break; } } if (unique) { break; } else { testChar++; } } node.name = string.Empty + testChar; } addNode(node); }
void CreatePuzzle(bool addInitialElements = false) { Puzzle puzzle = new Puzzle(); if (puzzleFront) { Destroy(puzzleFront.gameObject); } puzzleFront = Instantiate(puzzleFrontPrefab) as PuzzleFront; puzzleFront.CreatePuzzle(puzzle); puzzle.addEdge += e => DirtyPuzzle(); puzzle.removeEdge += e => DirtyPuzzle(); puzzle.addElement += e => DirtyPuzzle(); puzzle.removeElement += e => DirtyPuzzle(); puzzle.addItem += e => DirtyPuzzle(); puzzle.removeItem += e => DirtyPuzzle(); puzzle.addNode += e => DirtyPuzzle(); puzzle.removeNode += e => DirtyPuzzle(); puzzle.addReceiver += (e, f) => DirtyPuzzle(); puzzle.removeReceiver += (e, f) => DirtyPuzzle(); if (addInitialElements) { PuzzleNode node = new PuzzleNode(); PuzzlePlayer player = new PuzzlePlayer(); player.defaultNode = node; puzzle.AddNode(node); puzzle.AddItem(player); } RefreshData(); }
public void AddReceiver(PuzzleNode node, PuzzleReceiverElement receiver) { node.AddReceiver(receiver); if (addReceiver != null) { addReceiver(node, receiver); } }
public virtual bool CanPushBall(Puzzle puzzle, PuzzleState state, PuzzleNode nodeA, PuzzleNode nodeB, bool forward) { // A ball can be pushed from one node to another if both the edge and the receiving node allow it. // We want nodes to allow it by default if they allow bringing a ball. // For edges we want to now allow it by default in order to reduce state space edge explosion. // But it can be allowed by overriding for certain edge types where it can make a vital difference. return(this is PuzzleEdgeElement ? false : CanTakeBall(puzzle, state, nodeA, nodeB, forward)); }
public PuzzleStateNode CloneAndAddChild(string name, PuzzleNode node) { PuzzleStateNode n = new PuzzleStateNode(state.Clone()); n.step = step + 1; new PuzzleStateEdge(name, node, this, n); return(n); }
public void RemoveReceiver(PuzzleNode node, PuzzleReceiverElement receiver) { if (removeReceiver != null) { removeReceiver(node, receiver); } node.RemoveReceiver(receiver); }
private void SetState(PuzzleStateNode newState, bool animate) { PuzzleStateNode lastState = state; m_State = newState; stateChangeTime = Time.time; if (animate) { itemChangeTime = stateChangeTime + itemDelay; doneTime = stateChangeTime; } else { itemChangeTime = stateChangeTime; doneTime = stateChangeTime; } bool itemChange = false; foreach (var element in puzzle.dynamicElements) { object oldVal = puzzle.GetElementValue(lastState.state, element); object newVal = puzzle.GetElementValue(newState.state, element); if (!newVal.Equals(oldVal)) { PuzzleContainer container = puzzle.GetElementContainer(element); ContainerFront front = GetContainer(container); StartCoroutine(front.AnimateValue((bool)oldVal, (bool)newVal, animate)); itemChange = true; } } if (itemChange && animate) { doneTime += itemAndEffectDuration; } bool movement = false; foreach (var item in puzzle.items) { PuzzleNode oldNode = puzzle.GetItemNode(lastState.state, item); PuzzleNode newNode = puzzle.GetItemNode(newState.state, item); if (newNode != oldNode) { movement = true; } ItemFront front = GetItem(item); // Animate regardless of whether old and new node are the same. // Movement of other items may cause static item to change offset. StartCoroutine(front.AnimateNode(oldNode, newNode, state, animate)); } if (movement && animate) { itemChangeTime += moveDuration; doneTime += moveDuration; } }
// Callbacks public void AddNode(PuzzleNode node) { NodeFront nodeFront = Instantiate(nodePrefab) as NodeFront; nodeFront.transform.parent = transform; nodeFront.gameObject.name = "Node " + node.name; nodeFront.Set(this, node); nodes.Add(nodeFront); }
}//Update /* * Add Node True * If there's no duplicate entry, this adds a new node to the list * holding the GameObject's id and a triggered value of true - * then the function returns true. If unsuccessful, it returns false. */ public bool AddNodeTrue(GameObject hasItem) { if (!NoDuplicates(hasItem)){ return false; } PuzzleNode newNode = new PuzzleNode(hasItem, true); index.Add(newNode); return true; }//AddNodeTrue
}//AddNodeFalse /* * No Duplicates * This returns true if a scan of the list shows the GameObject's id * isn't already being tracked. Otherwise returns false. */ bool NoDuplicates(GameObject hasItem) { PuzzleNode result = ScanList(hasItem); if (result.item == null) { return true; } return false; }//NoDuplicates
public override void UpdateState(Puzzle puzzle, PuzzleState state, PuzzleNode node) { bool hasPlayer = puzzle.NodeHasItem <PuzzlePlayer> (state, node); bool hasBall = puzzle.NodeHasItem <PuzzleBall> (state, node); if (hasPlayer || hasBall) { node.TriggerValue(puzzle, state, true); } }
public bool NodeHasItem <T> (PuzzleState state, PuzzleNode node) { foreach (PuzzleItem item in items) { if (item is T && item.GetNode(this, state) == node) { return(true); } } return(false); }
public void SetItemNode(PuzzleState state, PuzzleItem item, PuzzleNode node) { int itemIndex = items.IndexOf(item); int nodeIndex = nodes.IndexOf(node); if (itemIndex < 0 || nodeIndex < 0) { return; } state.itemValues[itemIndex] = nodeIndex; }
public override void Set(PuzzleFront puzzle, PuzzleContainer container) { base.Set(puzzle, container); PuzzleNode node = container as PuzzleNode; if (node != null) { node.setPosition += SetPoint; SetPoint(node.position); } }
public void RemoveElement(PuzzleElement element) { // Remove receivers from this node. PuzzleNode node = GetElementContainer(element) as PuzzleNode; if (node != null) { for (int i = node.receiverElements.Count - 1; i >= 0; i--) { RemoveReceiver(node, node.receiverElements[i]); } } // Do callback first so it can perform proper lookup in puzzle removeElement(element); // Remove element from edges and nodes for (int i = 0; i < edges.Count; i++) { if (edges[i].element == element) { edges[i].element = null; } } for (int i = 0; i < nodes.Count; i++) { if (nodes[i].element == element) { nodes[i].element = null; } } PuzzleReceiverElement receiverElement = element as PuzzleReceiverElement; if (receiverElement != null) { for (int i = 0; i < nodes.Count; i++) { if (nodes[i].receiverElements.Contains(receiverElement)) { RemoveReceiver(nodes[i], receiverElement); } } } // Remove element if (element.dynamic) { dynamicElements.Remove(element); } else { staticElements.Remove(element); } }
public NodeFront GetNode(PuzzleNode node) { foreach (NodeFront nodeFront in nodes) { if (nodeFront.node == node) { return(nodeFront); } } return(null); }
public void RemoveNode(PuzzleNode node) { foreach (NodeFront nodeFront in nodes) { if (nodeFront.node == node) { Destroy(nodeFront.gameObject); nodes.Remove(nodeFront); break; } } }
public List <PuzzleItem> GetItemsInNode(PuzzleState state, PuzzleNode node) { List <PuzzleItem> itemList = new List <PuzzleItem> (); foreach (PuzzleItem item in items) { if (item.GetNode(this, state) == node) { itemList.Add(item); } } return(itemList); }
public List <T> GetItemsInNode <T> (PuzzleState state, PuzzleNode node) where T : PuzzleItem { List <T> itemList = new List <T> (); foreach (PuzzleItem item in items) { if (item is T && item.GetNode(this, state) == node) { itemList.Add(item as T); } } return(itemList); }
public List <PuzzleItem> GetDefaultItemsInNode(PuzzleNode node) { List <PuzzleItem> nodeItems = new List <PuzzleItem> (); foreach (PuzzleItem item in items) { if (item.defaultNode == node) { nodeItems.Add(item); } } return(nodeItems); }
public PuzzleStateEdge( string name, PuzzleNode actionNode, PuzzleStateNode fromNode, PuzzleStateNode toNode ) { this.name = name; this.actionNode = actionNode; this.fromNode = fromNode; this.toNode = toNode; fromNode.outgoing.Add(this); toNode.ingoing.Add(this); }
public static void OnClickNode(PuzzleNode node) { switch (node.Type) { case NodeType.Start: if (!IsPuzzleStarted) { StartPuzzle(node.PuzzleId); LastNode = node; node.IsMarked = true; node.StartLine(); } else { ResetPuzzle(); } break; case NodeType.Middle: if (IsPuzzleStarted && NodeDistance(LastNode, node) < MaxLineDistance && !node.IsMarked) { LastNode.FinishLine(node.transform.position); LastNode = node; node.IsMarked = true; node.StartLine(); } else { ResetPuzzle(); } break; case NodeType.Finish: node.IsMarked = true; if (IsPuzzleStarted && AreAllNodesMarked() && NodeDistance(LastNode, node) < MaxLineDistance) { LastNode.FinishLine(node.transform.position); FinishPuzzle(); } else { node.IsMarked = false; ResetPuzzle(); } break; } }
public IEnumerator AnimateNode(PuzzleNode oldNode, PuzzleNode newNode, PuzzleStateNode state, bool animate) { Vector3 newPos = GetPositionInNode(newNode, state); if (animate) { Vector3 oldPos = transform.position; float startTime = Time.time; while (Time.time < startTime + PuzzleFront.moveDuration) { transform.position = Vector3.Lerp(oldPos, newPos, (Time.time - startTime) / PuzzleFront.moveDuration); yield return(0); } } transform.position = newPos; }
public void AddStates(Puzzle puzzle, PuzzleStateNode parent, PuzzleNode nodeA, PuzzleNode nodeB, bool forward) { PuzzleState state = parent.state; PuzzleState next; PuzzleElement e = elementNotNull; PuzzleElement n = nodeB.elementNotNull; foreach (PuzzleItem player in puzzle.GetItemsInNode <PuzzlePlayer> (state, nodeA)) { // Walk if (e.CanWalk(puzzle, state, nodeA, nodeB, forward) && n.CanWalk(puzzle, state, nodeA, nodeB, forward)) { next = parent.CloneAndAddChild("Go here", nodeB).state; player.SetNode(puzzle, next, nodeB); } // Take or push ball List <PuzzleBall> balls = puzzle.GetItemsInNode <PuzzleBall> (state, nodeA); if (balls.Count > 0) { PuzzleBall ball = balls[0]; if (e.CanTakeBall(puzzle, state, nodeA, nodeB, forward) && n.CanTakeBall(puzzle, state, nodeA, nodeB, forward)) { next = parent.CloneAndAddChild("Bring ball here", nodeB).state; player.SetNode(puzzle, next, nodeB); ball.SetNode(puzzle, next, nodeB); } if (e.CanPushBall(puzzle, state, nodeA, nodeB, forward) && n.CanPushBall(puzzle, state, nodeA, nodeB, forward)) { next = parent.CloneAndAddChild("Push ball here", nodeB).state; ball.SetNode(puzzle, next, nodeB); } } // Hit toggle at other end if (e.CanSee(puzzle, state, nodeA, nodeB, forward) && n.CanSee(puzzle, state, nodeA, nodeB, forward)) { PuzzleToggle toggle = nodeB.element as PuzzleToggle; if (toggle != null) { next = parent.CloneAndAddChild("Shoot toggle", nodeB).state; nodeB.TriggerToggle(puzzle, next); } } } }
}//NoDuplicates /* * Flip Node * This returns true if a scan of the list shows the GameObject's id * is being tracked - then flips the target node's triggered boolean. * Otherwise returns false. * * If the timer is off, a successful flip starts it - so a puzzle will * start counting time from the moment the player interacts with its * first piece. * * A successful node flip to triggered will also start a scan that will * mark the puzzle as complete if all values in the list are true. */ public bool FlipNode(GameObject hasItem) { PuzzleNode result = ScanList(hasItem); if (result.item == null) { return false; } result.triggered = !result.triggered; if (runTimer == false) { StartTimer(); } if (result.triggered) { CheckStatus(); } return true; }//FlipNode
}//FlipNode /* * Scan List * This returns the PuzzleNode with a matching item id, if one exists * in index. Otherwise, this returns 'nullNode' a placeholder holding a * null value instead of a GameObject id and a triggered value of false. */ public PuzzleNode ScanList(GameObject hasItem) { PuzzleNode result = nullNode; if (hasItem == null) { return result; } //Debug.Log(hasItem); foreach (PuzzleNode entry in index) { if (entry.item == hasItem) { result = entry; break; } } return result; }//ScanList
private Vector3 GetPositionInNode(PuzzleNode node, PuzzleStateNode state) { Vector3 newPos = puzzle.GetNode(node).transform.position; if (state != null) { var items = puzzle.puzzle.GetItemsInNode(state.state, node); if (items.Count > 1) { int index = items.IndexOf(item); float offset = (index + 0.5f) / items.Count * 2 - 1; newPos += Vector3.right * offset * 0.3f; } } return(newPos); }
public void AddNodeToGrid(PuzzleNode node) { for (int col = 0; col < _puzzleGrid.GetLength(1); col++) { if (col > _puzzleGrid.GetLength(1)) { //puzzle grid is full Array.Clear(_puzzleGrid,0,GridHorizontalSize*_gridVerticalSize); } else { if (_puzzleGrid[_currentlySelectedRow, col] == null) { _puzzleGrid[_currentlySelectedRow, col] = node; break; } } } }
public void Reset() { undoStack.Clear(); m_State = puzzle.startNode; foreach (var element in puzzle.dynamicElements) { PuzzleContainer container = puzzle.GetElementContainer(element); ContainerFront front = GetContainer(container); front.SetElement(element); } foreach (var item in puzzle.items) { PuzzleNode newNode = item.defaultNode; ItemFront front = GetItem(item); front.SetNodePos(newNode, state); } }
static void Main(string[] args) { var target = new int[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 0 } }; var origin = new int[,] { { 1, 3, 6 }, { 4, 2, 0 }, { 7, 5, 8 } }; var targetState = new State(target); var originState = new State(origin); INode<State> pOrigin = new PuzzleNode(targetState, originState); INode<State> pTarget = new PuzzleNode(targetState, targetState); Solver<State> solver = new Solver<State>(pOrigin, pTarget); var result = solver.Solve(); do { Console.WriteLine(result.Content.ToDisplayString() + Environment.NewLine); result = result.Parent; } while (result != null); Console.Read(); }
private void Die() { var thisNode = new PuzzleNode((int) ShipColor); PuzzleGrid.Instance().AddNodeToGrid(thisNode); Destroy(gameObject); }