/** * Get/set neighbors of this pipe. * null is used if no neighbor is present */ public void setNeighbor(Orientation direction, PipeElement pipe) { switch (direction) { case Orientation.NORTH: north = pipe; break; case Orientation.SOUTH: south = pipe; break; case Orientation.EAST: east = pipe; break; case Orientation.WEST: west = pipe; break; } // auto-set in the opposite direction if needed if (pipe.getNeighbor(direction.opposite()) != this) { pipe.setNeighbor(direction.opposite(), this); } }
private void instanciatePipeGrid(PipeElement[,] grid) { objectGrid = new PipeElementScript[GRID_SIZE, GRID_SIZE]; for (int y = 0; y < GRID_SIZE; y++) { for (int x = 0; x < GRID_SIZE; x++) { if (grid[x, y] != null) { PipeElement origin = grid[x, y]; PipeElementScript prefab = null; switch (origin.type) { case PipeElement.Type.PIPE_I: prefab = pipeI; break; case PipeElement.Type.PIPE_L: prefab = pipeL; break; case PipeElement.Type.PIPE_IN: prefab = pipeIn; break; case PipeElement.Type.PIPE_OUT: prefab = pipeOut; break; } PipeElementScript pipeSprite = (PipeElementScript)Instantiate(prefab); // set internal pipe element pipeSprite.setPipeElement(origin); // set to the appropriate parent (Pipe Container) and position inside pipeSprite.transform.parent = parentArea; pipeSprite.transform.localPosition = new Vector3(x + ORIGIN_X, -y + ORIGIN_Y, 0); // not very clever, allow/disallow rotation depending on pipe type if (origin.type == PipeElement.Type.PIPE_IN || origin.type == PipeElement.Type.PIPE_OUT) { pipeSprite.setTouchEnable(false); } objectGrid[x, y] = pipeSprite; } } } }
private bool isValidPath(int x, int y, PipeElement.Orientation from) { // before anything else, check if (x;y) is the valid output if (x == outputX && y == outputY && from == outputOrientation) { // create the win path winPath = new LinkedList <PipeElementScript>(); return(true); } // check if the given (x;y) is a valid pipe PipeElement target = getPipeFromGrid(x, y); if (target == null) { return(false); } // check if the (x;y) pipe may be connected with the origin direction PipeElement.Orientation outDir; if (!target.getDirectionConnected(from, out outDir)) { return(false); } // it's the time for... recursion \o/ int newX, newY; getNeighborCoordinates(x, y, outDir, out newX, out newY); if (isValidPath(newX, newY, outDir.opposite())) { // okay, we are part of the win path, add ourself on top winPath.AddFirst(objectGrid[x, y]); return(true); } return(false); }
/** * Read a level from an XML document. */ private PipeElement[,] instanciateLevelFromXml(TextAsset document) { XmlDocument xml = new XmlDocument(); PipeElement[,] grid = new PipeElement[GRID_SIZE, GRID_SIZE]; // load the document and get the level(s) xml.LoadXml(document.text); XmlNodeList levelNodes = xml.GetElementsByTagName("level"); XmlAttribute levelEstimatedTime = levelNodes[0].Attributes["estimatedTime"]; if (levelEstimatedTime != null) { // use it as the base time for countdown timer timebar.maxTime = int.Parse(levelEstimatedTime.Value); } // start and destination pipes // TODO init XmlNodeList pipeNodes = levelNodes[0].ChildNodes; foreach (XmlNode curNode in pipeNodes) { if (curNode.Name == "pipe") { int x = 0; int y = 0; PipeElement.Orientation orientation = PipeElement.Orientation.NORTH; PipeElement.Type type = PipeElement.Type.PIPE_I; // add the pipe if possible x = int.Parse(curNode.Attributes["x"].Value); y = int.Parse(curNode.Attributes["y"].Value); switch (curNode.Attributes["type"].Value) { case "L": type = PipeElement.Type.PIPE_L; break; case "I": type = PipeElement.Type.PIPE_I; break; case "in": type = PipeElement.Type.PIPE_IN; break; case "out": type = PipeElement.Type.PIPE_OUT; break; } XmlAttribute dirAttribute = curNode.Attributes["dir"]; if (dirAttribute == null) { orientation = OrientationMethods.randomOrientation(); } else { orientation = OrientationMethods.fromString(dirAttribute.Value); } if (x >= 0 && x < GRID_SIZE && y >= 0 && y < GRID_SIZE) { // add the new pipe to the grid, and set its neighbors PipeElement toAdd = new PipeElement(type, orientation); grid[x, y] = toAdd; if (toAdd.type == PipeElement.Type.PIPE_IN) { inputX = x; inputY = y; inputOrientation = orientation; } else if (toAdd.type == PipeElement.Type.PIPE_OUT) { outputX = x; outputY = y; outputOrientation = orientation; } // set neighbors // TODO neighbors } } else { } } return(grid); }
public void setPipeElement(PipeElement element) { this.element = element; // set orientation gameObject.transform.localEulerAngles = new Vector3(0, 0, element.orientation.toDegrees()); }
private bool isValidPath(int x, int y, PipeElement.Orientation from) { // before anything else, check if (x;y) is the valid output if(x == outputX && y == outputY && from == outputOrientation) { // create the win path winPath = new LinkedList<PipeElementScript>(); return true; } // check if the given (x;y) is a valid pipe PipeElement target = getPipeFromGrid(x, y); if(target == null) return false; // check if the (x;y) pipe may be connected with the origin direction PipeElement.Orientation outDir; if(!target.getDirectionConnected(from, out outDir)) return false; // it's the time for... recursion \o/ int newX, newY; getNeighborCoordinates(x, y, outDir, out newX, out newY); if(isValidPath(newX, newY, outDir.opposite())) { // okay, we are part of the win path, add ourself on top winPath.AddFirst(objectGrid[x, y]); return true; } return false; }
private void instanciatePipeGrid(PipeElement[,] grid) { objectGrid = new PipeElementScript[GRID_SIZE, GRID_SIZE]; for (int y=0; y<GRID_SIZE; y++) { for (int x=0; x<GRID_SIZE; x++) { if(grid[x, y] != null) { PipeElement origin = grid[x, y]; PipeElementScript prefab = null; switch(origin.type) { case PipeElement.Type.PIPE_I: prefab = pipeI; break; case PipeElement.Type.PIPE_L: prefab = pipeL; break; case PipeElement.Type.PIPE_IN: prefab = pipeIn; break; case PipeElement.Type.PIPE_OUT: prefab = pipeOut; break; } PipeElementScript pipeSprite = (PipeElementScript) Instantiate(prefab); // set internal pipe element pipeSprite.setPipeElement (origin); // set to the appropriate parent (Pipe Container) and position inside pipeSprite.transform.parent = parentArea; pipeSprite.transform.localPosition = new Vector3 (x + ORIGIN_X, -y + ORIGIN_Y, 0); // not very clever, allow/disallow rotation depending on pipe type if(origin.type == PipeElement.Type.PIPE_IN || origin.type == PipeElement.Type.PIPE_OUT) pipeSprite.setTouchEnable(false); objectGrid[x, y] = pipeSprite; } } } }
/** * Read a level from an XML document. */ private PipeElement[,] instanciateLevelFromXml(TextAsset document) { XmlDocument xml = new XmlDocument (); PipeElement[,] grid = new PipeElement[GRID_SIZE, GRID_SIZE]; // load the document and get the level(s) xml.LoadXml(document.text); XmlNodeList levelNodes = xml.GetElementsByTagName("level"); XmlAttribute levelEstimatedTime = levelNodes[0].Attributes["estimatedTime"]; if(levelEstimatedTime != null) { // use it as the base time for countdown timer timebar.maxTime = int.Parse(levelEstimatedTime.Value); } // start and destination pipes // TODO init XmlNodeList pipeNodes = levelNodes[0].ChildNodes; foreach (XmlNode curNode in pipeNodes) { if(curNode.Name == "pipe") { int x=0; int y=0; PipeElement.Orientation orientation = PipeElement.Orientation.NORTH; PipeElement.Type type = PipeElement.Type.PIPE_I; // add the pipe if possible x = int.Parse(curNode.Attributes["x"].Value); y = int.Parse(curNode.Attributes["y"].Value); switch(curNode.Attributes["type"].Value) { case "L": type = PipeElement.Type.PIPE_L; break; case "I": type = PipeElement.Type.PIPE_I; break; case "in": type = PipeElement.Type.PIPE_IN; break; case "out": type = PipeElement.Type.PIPE_OUT; break; } XmlAttribute dirAttribute = curNode.Attributes["dir"]; if(dirAttribute == null) { orientation = OrientationMethods.randomOrientation(); } else { orientation = OrientationMethods.fromString(dirAttribute.Value); } if(x >= 0 && x < GRID_SIZE && y >= 0 && y < GRID_SIZE) { // add the new pipe to the grid, and set its neighbors PipeElement toAdd = new PipeElement(type, orientation); grid[x, y] = toAdd; if(toAdd.type == PipeElement.Type.PIPE_IN) { inputX = x; inputY = y; inputOrientation = orientation; } else if(toAdd.type == PipeElement.Type.PIPE_OUT) { outputX = x; outputY = y; outputOrientation = orientation; } // set neighbors // TODO neighbors } } else { } } return grid; }
private void getNeighborCoordinates(int x, int y, PipeElement.Orientation dir, out int newX, out int newY) { newX = x; newY = y; switch(dir) { case PipeElement.Orientation.NORTH: newY--; break; case PipeElement.Orientation.SOUTH: newY++; break; case PipeElement.Orientation.EAST: newX++; break; case PipeElement.Orientation.WEST: newX--; break; } }