public void CreateHintOneShot(PairInt position, PairInt direction, Texture2D tex) { HintArrow hint = CreateHintArrow(); hint.hintPosition = position; hint.hintDirection = direction; hint.tex = tex; hint.moveDuration /= 2; hint.IsOneShot = true; }
/// <summary> /// Invoked when it needs to swap to a different location /// </summary> public void MoveBy(PairInt from, PairInt delta, bool isBackground) { moveFrom = new Vector3(from.x, from.y, 0); // isBackground makes tiles that the user DIDN'T click on move // slighitly behind the one they did click on, so whatever they // interacted with will show in front of the other one if(isBackground) { moveFrom.z += .1f; } transform.position = moveFrom; moveBy = new Vector3(delta.x, delta.y, 0); moveStarted = Time.time; }
public void ReachingDefinitions() { Queue <BasicBlock> queue = new Queue <BasicBlock>(Blocks); do { BasicBlock b = queue.Dequeue(); HashSet <PairInt> old = new HashSet <PairInt>(b.ReachOut); b.ReachIn = new HashSet <PairInt>(); foreach (BasicBlock p in b.Prev) { b.ReachIn.UnionWith(p.ReachOut); } b.ReachOut = new HashSet <PairInt>(b.ReachIn); b.ReachOut.ExceptWith(b.ReachKill); b.ReachOut.UnionWith(b.ReachGen); if (!b.ReachOut.SetEquals(old)) { foreach (BasicBlock s in b.Next) { queue.Enqueue(s); } } }while (queue.Count != 0); for (int i = 0; i < Blocks.Count; ++i) { BasicBlock b = Blocks[i]; HashSet <PairInt> reachin = new HashSet <PairInt>(b.ReachIn); for (int j = 0; j < b.List.Count; ++j) { TExp inst = b.List[j]; LivenessNode node = inst.LivenessNode; PairInt q = new PairInt(i, j); foreach (Temp.Temp t in node.Use) { foreach (PairInt p in reachin) { if (Blocks[p.i].List[p.j].LivenessNode.Def.Contains(t)) { SetOf(DefineUseChain, t, p).Add(q); SetOf(UseDefineChain, t, q).Add(p); } } } reachin.ExceptWith(inst.ReachingDefinitionNode.Kill); reachin.UnionWith(inst.ReachingDefinitionNode.Gen); } } }
void SetArrowPosition() { Debug.Log(currentScreen + " " + oldScreen + " " + index); int limitsIndex = System.Array .BinarySearch(screens, currentScreen); PairInt limit; if (limitsIndex >= 0 && limits.Length > 0) { limit = limits[limitsIndex]; } else { limit = new PairInt(0, 0); } if (currentScreen != oldScreen) { index = limit.x; } if (Input.GetButtonDown("Up")) { index--; } if (Input.GetButtonDown("Down")) { index++; } if (index < limit.x) { index = limit.y; } if (index > limit.y) { index = limit.x; } arrow.transform.position = new Vector3(arrow.transform.position.x, screenDictionary[currentScreen].GetChild(index) .transform.position.y, transform.position.z); }
// Avanzar el robot hacia delante. public void moveUP() { int x = GUI_Layout.S.board_def[x_coord, z_coord].x; int y = GUI_Layout.S.board_def[x_coord, z_coord].height; int z = GUI_Layout.S.board_def[x_coord, z_coord].z; //1.- Comprobar que se puede mover a la nueva posicion int newpos_x = x + _x; int newpos_z = z + _z; //1.1- esta dentro del tablero if (newpos_x < 0 || newpos_z < 0 || newpos_x >= GUI_Layout.S.MAX_SIZE || newpos_z > GUI_Layout.S.MAX_SIZE) { return; } //Si hay alguna casilla que llegue al destino, la cogemos PairInt pp = getCasillaPosibleDestino(newpos_x, newpos_z); if (pp == null) { return; } //1.3 Está a la misma altura if (GUI_Layout.S.board_def[pp.x, pp.y].getNextPosition().y != this.y) { return; } //2.- Mover this.mvt.Avanza(); this.x = newpos_x; this.z = newpos_z; this.x_coord = pp.x; this.z_coord = pp.y; }
void OnTriggerEnter2D(Collider2D other) { Debug.Log("enter collider"); if (_clicked) { _position = PuzzleController.board[boardCoordinate.a,boardCoordinate.b].position; _element = PuzzleController.board[boardCoordinate.a,boardCoordinate.b].elementCode; //temp from other (puzzleCont) PairInt tempCoor = other.gameObject.GetComponent<ElementController>().boardCoordinate; //int tempElement = PuzzleController.board[tempCoor.a, tempCoor.b].elementCode; //Vector3 tempPosition = PuzzleController.board[tempCoor.a, tempCoor.b].position; //assign other -> this value other.GetComponent<ElementController>()._position = PuzzleController.board[boardCoordinate.a,boardCoordinate.b].position; other.GetComponent<ElementController>()._element = PuzzleController.board[boardCoordinate.a,boardCoordinate.b].elementCode; //assign this -> temp value _position = PuzzleController.board[tempCoor.a,tempCoor.b].position; _element = PuzzleController.board[tempCoor.a,tempCoor.b].elementCode; //move pos other.GetComponent<Transform>().position = other.GetComponent<ElementController>()._position; //move coord other.gameObject.GetComponent<ElementController>().boardCoordinate = boardCoordinate; boardCoordinate = tempCoor; //save to puzzleCont PuzzleController.board[boardCoordinate.a,boardCoordinate.b].position = _position; PuzzleController.board[boardCoordinate.a,boardCoordinate.b].elementCode = _element; PuzzleController.board[tempCoor.a,tempCoor.b].position = other.GetComponent<ElementController>()._position; PuzzleController.board[tempCoor.a,tempCoor.b].elementCode = other.GetComponent<ElementController>()._element; Debug.Log("[4] [3] : " + PuzzleController.board[4,3].elementCode); Debug.Log("[3] [3] : " + PuzzleController.board[3,3].elementCode); } }
// Ejecuta la siguiente accion. // Utiliza el sistema de pila para simular las llamadas a funcion. // De esta maenra se consiguen llamadas recursivas, y coloreado de la // interfaz. public void Next() { if (this.recording) { return; } if (this.llamadas.Count > 0) { PairInt pi = this.llamadas.Pop(); if (pi.y < 0) //si acabamos una rutina, apagamos el ultimo elemento { Actions_Layout.S.lightCube(pi.x, this.acciones[pi.x].Count - 1, false); Invoke("Next", 1); } else { this.ejecutaAccion(pi.x, pi.y); } } }
private ContactSimple GetAnyNotDiffusion(PairInt inCnt) { if (GetPoint(inCnt, Layers.siliconTrace).name != Material.diffusionName) return new ContactSimple(inCnt, Layers.siliconTrace); foreach (PairInt curPoint in inCnt.GetArroundPoints(wide)) if (GetPoint(curPoint, Layers.siliconTrace).name != Material.diffusionName) return new ContactSimple(inCnt, Layers.siliconTrace); return new ContactSimple(inCnt, Layers.siliconTrace); }
/// <summary> /// Attempts to swap a tile in the given direction. Makes sure /// it's not off the board, finds the appropriate other tile and /// moves it too, moves it back if it isn't a match, etc. /// </summary> /// <param name="current"></param> /// <param name="delta"></param> /// <returns></returns> public void SwapTile(Tile current, PairInt delta, bool userStarted = true) { StartCoroutine(ISwapTile(current, delta, userStarted)); }
/// <summary> /// Internal funciton to invoke the actual movement of a tile. /// Assumes position is valid, tile exists, etc. /// Used by SwapTile & refillBoard /// </summary> private void MoveTile(Tile tile, PairInt from, PairInt delta, bool isBackground=false) { tile.MoveBy(from, delta, isBackground); PairInt target = from + delta; board[target.x, target.y] = tile; tile.UpdateName(target); }
public TempPairInt(Temp.Temp temp, PairInt pair) { Temp = temp; Pair = pair; }
public NodeDistance(int name1, int name2, int size, bool inCon, bool inFixed) { names = new PairInt(name1, name2); distance = size; connected = inCon; isFixed = inFixed; }
public void ReachingDefinitions() { Queue<BasicBlock> queue = new Queue<BasicBlock>(Blocks); do { BasicBlock b = queue.Dequeue(); HashSet<PairInt> old = new HashSet<PairInt>(b.ReachOut); b.ReachIn = new HashSet<PairInt>(); foreach (BasicBlock p in b.Prev) { b.ReachIn.UnionWith(p.ReachOut); } b.ReachOut = new HashSet<PairInt>(b.ReachIn); b.ReachOut.ExceptWith(b.ReachKill); b.ReachOut.UnionWith(b.ReachGen); if (!b.ReachOut.SetEquals(old)) { foreach (BasicBlock s in b.Next) queue.Enqueue(s); } } while (queue.Count != 0); for (int i = 0; i < Blocks.Count; ++i) { BasicBlock b = Blocks[i]; HashSet<PairInt> reachin = new HashSet<PairInt>(b.ReachIn); for (int j = 0; j < b.List.Count; ++j) { TExp inst = b.List[j]; LivenessNode node = inst.LivenessNode; PairInt q = new PairInt(i, j); foreach (Temp.Temp t in node.Use) foreach (PairInt p in reachin) if (Blocks[p.i].List[p.j].LivenessNode.Def.Contains(t)) { SetOf(DefineUseChain, t, p).Add(q); SetOf(UseDefineChain, t, q).Add(p); } reachin.ExceptWith(inst.ReachingDefinitionNode.Kill); reachin.UnionWith(inst.ReachingDefinitionNode.Gen); } } }
private bool IsDiffusionLimit(PairInt inCnt, int inLayer1, int inLayer2) { if ( ((inLayer1 == Layers.metal1Trace) && (inLayer2 == Layers.siliconTrace)) || ((inLayer1 == Layers.siliconTrace) && (inLayer2 == Layers.metal1Trace)) ) { if (GetPoint(inCnt, Layers.contactTrace).name == Material.diffusionName) return false; } return true; }
/*private void SetPointWithExept(PairInt inCnt, List<NodePoint> best) { NodePoint bestPoint = best[0]; NodePoint bestMet1 = best[1]; NodePoint bestSil = best[2]; SetOneOfBest_old(inCnt, Layers.metal1Trace, bestMet1); SetOneOfBest_old(inCnt, Layers.siliconTrace, bestSil); } /*private void SetPointWithDiffusExept(PairInt inCnt, BestPointSet pnt, List<BestPointSet> best) { foreach (int lay in Params.LayersRange[pnt.point.layer]) { BestPointSet bst = best.Find(el => el.isOneLayer && (el.layer == replased)); SetOneOfBest(inCnt, Layers.metal1Trace, bestMet1); SetOneOfBest(inCnt, Layers.siliconTrace, bestSil); } }*/ bool IsJumpAble(PairInt inCnt, int inLayer) { string curName = GetPoint(inCnt, inLayer).name; if (curName == Material.blankName) return true; if (curName == Material.diffusionName ) return false; ContactSimple centrCnt = new ContactSimple(inCnt, inLayer); foreach(ContactSimple cnt in centrCnt.GetNeborPoints(wide))//GetArroundPoints(wide)) if (GetPoint(cnt).name != curName) return false; return true; }
private NodePointLayer GetPointLayer(PairInt inCnt, int inLayer) { return new NodePointLayer(layoutMap[inCnt.x][inCnt.y][inLayer], inLayer); }
private bool IsBridge2(List<Section> sections, PairInt inPnt, int inLayer, string inName) { if (sections.Count == 0) { if (inLayer == Layers.metal1Trace && Params.UsedLayers.Count > 2 && GetPoint(inPnt, Layers.siliconTrace).name == inName && GetPoint(inPnt, Layers.contactTrace).name != Material.diffusionName && GetPoint(inPnt, Layers.metal2Trace).name == inName) return true; } else if (sections.Count == 1)//!!!!!!!!!! { foreach(int curLayer in Params.allLayersRange.Keys)//.UsedLayers) { if ( curLayer != inLayer && IsPointsConnected(inPnt, inLayer, curLayer, inName) && //GetPoint(inPnt, curLayer).name == inName (sections[0].points.FindIndex(el => IsPointsConnected(el, inLayer, curLayer, inName) && ConnectedPoints(new ContactSimple(el, curLayer), new ContactSimple(inPnt, curLayer))) < 0) ) //GetPoint(el, curLayer).name == inName) < 0) ) return true; } return false; } return false; }
/*private NodePoint GetOppositePoint(ContactSimple inCnt) { int oppositeLayer = Layers.siliconTrace; if (inCnt.layer == Layers.siliconTrace) oppositeLayer = Layers.metal1Trace; return layoutMap[inCnt.x][inCnt.y][oppositeLayer]; }*/ private NodePoint GetPoint(PairInt inCnt, int inLayer) { return layoutMap[inCnt.x][inCnt.y][inLayer]; }
//, List<int> layers) /* private List<NodePoint> GetBest_old(PairInt inCnt) { List<NodePointLayer> metArround = new List<NodePointLayer>(); List<NodePointLayer> silArround = new List<NodePointLayer>(); List<NodePointLayer> allArround = new List<NodePointLayer>(); foreach (PairInt cnt in inCnt.GetArroundPoints(wide)) { metArround.Add(GetPointLayer(cnt, Layers.metal1Trace)); silArround.Add(GetPointLayer(cnt, Layers.siliconTrace)); } metArround.Add(GetPointLayer(inCnt, Layers.metal1Trace)); silArround.Add(GetPointLayer(inCnt, Layers.siliconTrace)); allArround.AddRange(metArround); allArround.AddRange(silArround); //NodePoint bestMet = conflictManager.GetBest(metArround); //NodePoint bestSil = conflictManager.GetBest(silArround); bool b = false; if ((inCnt.x == 13 || inCnt.x == 21) && (inCnt.y == 33)) b = true; List<NodePoint> best = new List<NodePoint>(); best.Add(conflictManager.GetBest(allArround)); best.Add(conflictManager.GetBest(metArround)); best.Add(conflictManager.GetBest(silArround)); return best; }*/ private List<BestPointSet> GetBest(PairInt inCnt) { Dictionary<int, List<NodePointLayer>> oneRange = new Dictionary<int, List<NodePointLayer>>(); foreach (int layer1 in Params.UsedLayers) oneRange.Add(layer1, new List<NodePointLayer>()); foreach (PairInt cnt in inCnt.GetArroundPoints(wide)) { foreach (int layer1 in Params.UsedLayers) oneRange[layer1].Add(GetPointLayer(cnt, layer1)); } foreach (int layer1 in Params.UsedLayers) { oneRange[layer1].Add(GetPointLayer(inCnt, layer1)); } List<BestPointSet> bestSet = new List<BestPointSet>(); foreach (int layer1 in Params.UsedLayers) { List<NodePointLayer> allArround = new List<NodePointLayer>(); allArround.AddRange(oneRange[layer1]); foreach(int layer2 in Params.LayersRange[layer1]) { allArround.AddRange(oneRange[layer2]); } bestSet.Add(new BestPointSet(conflictManager.GetBest(allArround), layer1, false)); if (Params.UsedLayers.Count < 3) break; } foreach (int layer1 in Params.UsedLayers) { bestSet.Add(new BestPointSet(conflictManager.GetBest(oneRange[layer1]), layer1, true)); NodePoint ndp = GetPoint(inCnt, layer1); if ( ndp.isSource ) { NodePoint ndPoint = DefineSourcePoint(inCnt, layer1); if (ndPoint.name != ndp.name) bestSet.Add(new BestPointSet(new NodePointLayer(ndPoint, layer1), layer1, true)); //oneRange[layer1].Add(new NodePointLayer(ndp, nameSource)); } /*if ( ndp.isSource ) { string nameSource = DefineSourceName(inCnt, layer1); if (nameSource != ndp.name) bestSet.Add(new BestPointSet(new NodePointLayer(ndp, layer1, nameSource), layer1, true)); //oneRange[layer1].Add(new NodePointLayer(ndp, nameSource)); }*/ } return bestSet; }
private NodePoint GetAnyPoint(PairInt inCnt, int inLayer) { if ( (inCnt.x >= 0) && (inCnt.x < wide) && (inCnt.y < Params.topEdge) && (inCnt.y >= 0) ) return layoutMap[inCnt.x][inCnt.y][inLayer]; return blank; }
public void PropagateAllNotCross() { countMaxPrior = 0; int yStart = 0; for (int x = 0; x < wide; x++) { for (int y = yStart; y < Params.topEdge; y += 2) { PairInt coord = new PairInt(x, y); SetPointNotCross(coord); } if (yStart == 0) yStart = 1; else yStart = 0; } yStart = 1; for (int x = 0; x < wide; x++) { for (int y = yStart; y < Params.topEdge; y += 2) { PairInt coord = new PairInt(x, y); SetPointNotCross(coord); } if (yStart == 0) yStart = 1; else yStart = 0; } }
private bool IsPointsConnected(PairInt inPnt, int inLayer, int relatedLayer, string inName) { if ((inLayer != relatedLayer) && (inLayer == Layers.siliconTrace || relatedLayer == Layers.siliconTrace))// && { if (GetPoint(inPnt, Layers.contactTrace).name == Material.diffusionName || GetPoint(inPnt, relatedLayer).name != inName) return false; return true; } else { if (GetPoint(inPnt, relatedLayer).name == inName) return true; return false; } }
/* * public void updatePosition(int newx, int newz, int origx, int origz){ * this.original_x = origx; * this.original_z = origz; * * this.transform.parent = GUI_Layout.S.board[this.original_x, this.original_z].transform; * this.transform.localPosition = new Vector3(0, this.transform.position.y, 0); * } */ /* Devuelve las coordenadas de una casilla que en el siguiente movimiento va a estar en la posición * pasada por parámetro. */ private PairInt getCasillaPosibleDestino(int x1, int z1) { float eps = 0.7f; float x = this.transform.position.x / 2.0f + _x; float z = this.transform.position.z / 2.0f + _z; GUI_Layout S = GUI_Layout.S; PairInt aux = null; //centro aux = S.current_board[x1, z1]; if (aux != null && Mathf.Abs(S.board_def[aux.x, aux.y].getNextPosition().x - x) < eps && Mathf.Abs(S.board_def[aux.x, aux.y].getNextPosition().z - z) < eps) { return(aux); } //norte if (x1 > 0) { aux = S.current_board[x1 - 1, z1]; if (aux != null && Mathf.Abs(S.board_def[aux.x, aux.y].getNextPosition().x - x) < eps && Mathf.Abs(S.board_def[aux.x, aux.y].getNextPosition().z - z) < eps) { return(aux); } } //sur if (x1 + 1 < GUI_Layout.S.MAX_SIZE) { aux = S.current_board[x1 + 1, z1]; if (aux != null && Mathf.Abs(S.board_def[aux.x, aux.y].getNextPosition().x - x) < eps && Mathf.Abs(S.board_def[aux.x, aux.y].getNextPosition().z - z) < eps) { return(aux); } } //este if (z1 > 0) { aux = S.current_board[x1, z1 - 1]; if (aux != null && Mathf.Abs(S.board_def[aux.x, aux.y].getNextPosition().x - x) < eps && Mathf.Abs(S.board_def[aux.x, aux.y].getNextPosition().z - z) < eps) { return(aux); } } //oeste if (z1 + 1 < GUI_Layout.S.MAX_SIZE) { aux = S.current_board[x1, z1 + 1]; if (aux != null && Mathf.Abs(S.board_def[aux.x, aux.y].getNextPosition().x - x) < 0.4f && Mathf.Abs(S.board_def[aux.x, aux.y].getNextPosition().z - z) < 0.4f) { return(aux); } } return(null); }
private bool SetNextCont(PairInt inChanged, int layerChanged, NodePoint inSample) { /*bool b = false; if (inChanged.x == 33 && (inChanged.y == 16 || inChanged.y == 18) && layerChanged == Layers.metal1Trace && inSample.name != "N6859613") b = false;*/ if (inSample.name == Material.blankName) return true; string curName = inSample.name; List<string> deletedNames = new List<string>(); ContactSimple curPoint = new ContactSimple(inChanged, layerChanged); List<ContactSimple> cntArround = curPoint.GetArroundPoints(wide); List<PairInt> cntArea = inChanged.GetBigArround(wide); cntArea.Add(inChanged); foreach (ContactSimple cntUnit in cntArround) { string unitName = GetPoint(cntUnit).name; if (unitName != curName && unitName!= Material.blankName && unitName != Material.diffusionName) { /*if (cntUnit.x == 33 && (cntUnit.y == 16 || cntUnit.y == 18) && cntUnit.layer == Layers.metal1Trace) b = false;*/ if (deletedNames.FindIndex(el => el == unitName) >= 0) { bool rem = CheckNebors(new ContactSimple(cntUnit, cntUnit.layer)); if (!rem) { layoutMap[cntUnit.x][cntUnit.y][cntUnit.layer].isReplace = rem; return false; } } deletedNames.Add(unitName); SetContact(cntUnit, Material.blankName, 0, 0, -1); //cntAdded.Add(cntUnit); if (GetPoint(cntUnit).isSource) { foreach (ContactSimple smp in GetSourceContacts(cntUnit, curName)) if (smp != cntUnit) cntArea.Add(smp); //cntArea.Add(GetSourceContacts //GetNearSource(cntUnit)); } //List<PairInt> cntForCheck = new List<PairInt>(); foreach (ContactSimple cnt in cntUnit.GetNeborPoints(wide)) { /*string bn = GetPoint(cnt).name; /*if (cnt.x == 38 && cnt.y == 14 && cnt.layer == 1 && bn != Material.blankName) b = false;*/ if ((GetPoint(cnt).name != curName) && (cntArea.FindIndex(el => el == cnt) < 0)) { cntArea.Add(cnt); //cntForCheck.Add(cnt); } } } } layoutMap[inChanged.x][inChanged.y][layerChanged].isReplace = false; layoutMap[inChanged.x][inChanged.y][layerChanged].name = inSample.name; layoutMap[inChanged.x][inChanged.y][layerChanged].numberNode = inSample.numberNode; layoutMap[inChanged.x][inChanged.y][layerChanged].priority = inSample.priority; layoutMap[inChanged.x][inChanged.y][layerChanged].number = inSample.number; foreach (PairInt cntUnit in cntArea) { foreach (int lay in Params.LayersRange[layerChanged]) { layoutMap[cntUnit.x][cntUnit.y][lay].isReplace = CheckNebors(new ContactSimple(cntUnit, lay)); } /*bool b; if (cntUnit.x == 20 && cntUnit.y == 16) b = true; layoutMap[cntUnit.x][cntUnit.y][Layers.metal1Trace].isReplace = CheckNebors(new ContactSimple(cntUnit, Layers.metal1Trace)); layoutMap[cntUnit.x][cntUnit.y][Layers.siliconTrace].isReplace = CheckNebors(new ContactSimple(cntUnit, Layers.siliconTrace));*/ } return true; }
// Saltar hacia delante public void jump() { int x = GUI_Layout.S.board_def[x_coord, z_coord].x; int y = GUI_Layout.S.board_def[x_coord, z_coord].height; int z = GUI_Layout.S.board_def[x_coord, z_coord].z; //1.- Comprobar que se puede mover a la nueva posicion int newpos_x = x + _x; int newpos_z = z + _z; //1.1- esta dentro del tablero if (newpos_x < 0 || newpos_z < 0 || newpos_x >= GUI_Layout.S.MAX_SIZE || newpos_z > GUI_Layout.S.MAX_SIZE) { return; } // Debug.Log("B"); //Si hay alguna casilla que llegue al destino, la cogemos PairInt pp = getCasillaPosibleDestino(newpos_x, newpos_z); if (pp == null) { return; } //Debug.Log("C " + pp.x + " , " + pp.y + " - " + GUI_Layout.S.board_def[pp.x, pp.y].height); //Debug.Log("C" + " YO: " + x_coord + z_coord);// + " , " + pp.y + " - " + GUI_Layout.S.board_def[pp.x, pp.y].height); //1.3 Está a la misma altura if (GUI_Layout.S.board_def[pp.x, pp.y].getNextPosition().y == this.y) { return; } // Debug.Log("D" + pp.x + " , " + pp.y + " - " + GUI_Layout.S.board_def[pp.x, pp.y].height); //1.3- esta a una altura de diferencia if (!(y == GUI_Layout.S.board_def [pp.x, pp.y].height + 1 || y == GUI_Layout.S.board_def [pp.x, pp.y].height - 1)) { return; } //Debug.Log("E"); //2.- Mover if (y > GUI_Layout.S.board_def [pp.x, pp.y].height) { this.mvt.JumpDown(); } else { this.mvt.JumpUp(); } this.x = newpos_x; this.z = newpos_z; this.y = GUI_Layout.S.board_def [pp.x, pp.y].height; this.x_coord = pp.x; this.z_coord = pp.y; }
public bool FindMatch(out PairInt position, out PairInt direction) { position = null; direction = null; // for any given position, we look for any of the following for (int x = 0; x < boardSize; x++) { for (int y = 0; y < boardSize; y++) { // we check for a number of potential positions, where // X is the current postion, x is a tile we'll be checking // for the same type, and . is a tile that doesn't matter Tile tile = board[x,y]; int max = boardSize - 1; // ------------------------------------- // horizontal match, tile on right joins // xx.X if (x >= 3) { if (IsMatch(tile, board[x - 2, y], board[x - 3, y])) { position = new PairInt(x, y); direction = new PairInt(-1, 0); return true; } } // ..X // xx. if (x >= 2 && y >= 1) { if (IsMatch(tile, board[x - 1, y - 1], board[x - 2, y - 1])) { position = new PairInt(x, y); direction = new PairInt(0, -1); return true; } } // xx. // ..X if (x >= 2 && y <= max - 1) { if (IsMatch(tile, board[x - 1, y + 1], board[x - 2, y + 1])) { position = new PairInt(x, y); direction = new PairInt(0, 1); return true; } } // ------------------------------------- // horizontal match, tile on left joins // X.xx if (x <= max-3) { if (IsMatch(tile, board[x + 2, y], board[x + 3, y])) { position = new PairInt(x, y); direction = new PairInt(1, 0); return true; } } // X.. // .xx if (x <= max - 2 && y >= 1) { if (IsMatch(tile, board[x + 1, y - 1], board[x + 2, y - 1])) { position = new PairInt(x, y); direction = new PairInt(0, -1); return true; } } // .xx // X.. if (x <= max - 2 && y <= max - 1) { if (IsMatch(tile, board[x + 1, y + 1], board[x + 2, y + 1])) { position = new PairInt(x, y); direction = new PairInt(0, 1); return true; } } // ------------------------------------- // horizontal match, tile in middle joins // .X. // x.x if (x >= 1 && x <= max - 1 && y >= 1) { if (IsMatch(tile, board[x - 1, y - 1], board[x + 1, y - 1])) { position = new PairInt(x, y); direction = new PairInt(0, -1); return true; } } // x.x // .X. if (x >= 1 && x <= max - 1 && y <= max - 1) { if (IsMatch(tile, board[x - 1, y + 1], board[x + 1, y + 1])) { position = new PairInt(x, y); direction = new PairInt(0, 1); return true; } } // ------------------------------------- // vertical match, tile on top joins // X // . // x // x if (y >= 3) { if (IsMatch(tile, board[x, y - 2], board[x, y - 3])) { position = new PairInt(x, y); direction = new PairInt(0, -1); return true; } } // X. // .x // .x if (x <= max - 1 && y >= 2) { if (IsMatch(tile, board[x + 1, y - 1], board[x + 1, y - 2])) { position = new PairInt(x, y); direction = new PairInt(1, 0); return true; } } // .X // x. // x. if (x >= 1 && y >= 2) { if (IsMatch(tile, board[x - 1, y - 1], board[x - 1, y - 2])) { position = new PairInt(x, y); direction = new PairInt(-1, 0); return true; } } // ------------------------------------- // vertical match, tile on bottom joins // x // x // . // X if (y <= max - 3) { if (IsMatch(tile, board[x, y + 2], board[x, y + 3])) { position = new PairInt(x, y); direction = new PairInt(0,1); return true; } } // .x // .x // X. if (x <= max - 1 && y <= max - 2) { if (IsMatch(tile, board[x + 1, y + 1], board[x + 1, y + 2])) { position = new PairInt(x, y); direction = new PairInt(1,0); return true; } } // x. // x. // .X if (x >= 1 && y <= max - 2) { if (IsMatch(tile, board[x - 1, y + 1], board[x - 1, y + 2])) { position = new PairInt(x, y); direction = new PairInt(-1,0); return true; } } // ------------------------------------- // vertical match, tile in middle joins // x. // .X // x. if (x >= 1 && y >= 1 && y <= max - 1) { if (IsMatch(tile, board[x - 1, y - 1], board[x - 1, y + 1])) { position = new PairInt(x, y); direction = new PairInt(-1,0); return true; } } // .x // X. // .x if (x <= max - 1 && y >= 1 && y <= max - 1) { if (IsMatch(tile, board[x + 1, y - 1], board[x + 1, y + 1])) { position = new PairInt(x, y); direction = new PairInt(1,0); return true; } } } } return false; }
private HashSet<PairInt> SetOf(Dictionary<TempPairInt, HashSet<PairInt>> chain, Temp.Temp t, PairInt p) { TempPairInt key = new TempPairInt(t, p); if (chain[key] == null) chain.Add(key, new HashSet<PairInt>()); return chain[key]; }
private string DefineSourceName(PairInt inCnt, int inLayer) { ContactSimple fndCnt = new ContactSimple(inCnt, inLayer); fndCnt.y = Params.lineN; if ( inCnt.y < Params.lineMiddle ) fndCnt.y = Params.lineP; foreach (Node nd in nodeList) { foreach(ContactSimple cnt in nd.arcCollection) if (cnt == fndCnt) return nd.name; } return ""; }
private HashSet <PairInt> SetOf(Dictionary <TempPairInt, HashSet <PairInt> > chain, Temp.Temp t, PairInt p) { TempPairInt key = new TempPairInt(t, p); if (chain[key] == null) { chain.Add(key, new HashSet <PairInt>()); } return(chain[key]); }
/*private void SetPoint_old(PairInt inCnt) { bool replased = false; foreach (int curLayer in Params.UsedLayers) if (GetPoint(inCnt, curLayer).isReplace) replased = true; if (!replased) return; //if ((!GetPoint(inCnt, Layers.metal1Trace).isReplace) && // (!GetPoint(inCnt, Layers.siliconTrace).isReplace)) // return; bool b; if (inCnt.x == 20 && inCnt.y == 16 ) b = false; List<NodePoint> best = GetBest_old(inCnt); NodePoint bestPoint = best[0]; NodePoint bestMet1 = best[1]; NodePoint bestSil = best[2]; if (diffusionExeption.FindIndex(el => el == bestPoint.name) >= 0) { SetPointWithExept(inCnt, best); return; } if (bestPoint == bestMet1) { bool useBestPoint = false; if (GetPoint(inCnt, Layers.metal1Trace).isReplace) { if (SetOneOfBest_old(inCnt, Layers.metal1Trace, bestPoint) && GetPoint(inCnt, Layers.contactTrace).name != Material.diffusionName && IsJumpAble(inCnt, Layers.siliconTrace) && SetOneOfBest_old(inCnt, Layers.siliconTrace, bestPoint)) useBestPoint = true; } if (!useBestPoint) SetOneOfBest_old(inCnt, Layers.siliconTrace, bestSil); } else { bool useBestPoint = false; if (GetPoint(inCnt, Layers.siliconTrace).isReplace) { if (SetOneOfBest_old(inCnt, Layers.siliconTrace, bestPoint) && GetPoint(inCnt, Layers.contactTrace).name != Material.diffusionName && IsJumpAble(inCnt, Layers.metal1Trace) && SetOneOfBest_old(inCnt, Layers.metal1Trace, bestPoint)) useBestPoint = true; } if (!useBestPoint) SetOneOfBest_old(inCnt, Layers.metal1Trace, bestMet1); } }*/ private void SetPoint(PairInt inCnt) { bool replased = false; foreach (int curLayer in Params.UsedLayers) if (GetPoint(inCnt, curLayer).isReplace) replased = true; if (!replased) return; //if (inCnt.x == 12 && inCnt.y == 24 && (AddingSpace(layoutMap[13][24][Layers.metal2Trace].name) == "66204")) // replased = true; bool b = false; if (inCnt.x == 27 && inCnt.y == 17 )//"N6859613") b = false; List<BestPointSet> best = GetBest(inCnt); List<int> closedLayers = new List<int>(); if (Params.UsedLayers.Count > 2) best = SortBestPoints(best); if ( inCnt.x == 14 && (inCnt.y == 38) )// || inCnt.y == 37) ) { ContactSimple tmp = new ContactSimple(inCnt, 0); List<ContactSimple> tp = tmp.GetAnyNeborPoints(); List<NodePoint> p = new List<NodePoint> (); foreach(ContactSimple t in tp) p.Add(GetPoint(t)); p.Add(GetPoint(tmp)); } foreach (BestPointSet bestPoint in best) { if ((!bestPoint.isOneLayer) && (closedLayers.FindIndex(el => el == bestPoint.point.layer) < 0)) { if (diffusionException.FindIndex(el => el == bestPoint.point.name) >= 0) { if (Params.IsDiffusExeptionLayer(bestPoint.point.layer)) { SetOneOfBest(inCnt, bestPoint.point.layer, bestPoint.point); closedLayers.Add(bestPoint.point.layer); } } else { if (SetOneOfBest(inCnt, bestPoint.point.layer, bestPoint.point)) { foreach (int related in Params.LayersRange[bestPoint.point.layer]) { if ((related != bestPoint.point.layer) && IsDiffusionLimit(inCnt, related, bestPoint.point.layer) && IsJumpAble(inCnt, related) && SetOneOfBest(inCnt, related, bestPoint.point)) closedLayers.Add(related); } } else { foreach (int lay in DefineSameLayers(inCnt, bestPoint, best)) { if (SetOneOfBest(inCnt, lay, bestPoint.point)) { foreach (int related in Params.LayersRange[lay]) { if ((related != lay) && IsDiffusionLimit(inCnt, related, lay) && IsJumpAble(inCnt, related) && SetOneOfBest(inCnt, related, bestPoint.point)) closedLayers.Add(related); } } } } closedLayers.Add(bestPoint.point.layer); } } } foreach (BestPointSet bestPoint in best) { if ((bestPoint.isOneLayer) && (closedLayers.FindIndex(el => el == bestPoint.point.layer) < 0)) { SetOneOfBest(inCnt, bestPoint.point.layer, bestPoint.point); } } }
public void SwapTile(PairInt position, PairInt delta, bool userStarted = true) { SwapTile(board[position.x, position.y], delta, userStarted); }
private void SetPointNotCross(PairInt inCnt) { bool replased = false; foreach (int curLayer in Params.UsedLayers) if (GetPoint(inCnt, curLayer).isReplace) replased = true; if (!replased) return; List<BestPointSet> best = GetBest(inCnt); foreach (BestPointSet bestPoint in best) { if (bestPoint.isOneLayer && IsPointFree(new ContactSimple(inCnt, bestPoint.point.layer), bestPoint.point.name)) { SetOneOfBest(inCnt, bestPoint.point.layer, bestPoint.point); } } }
private IEnumerator ISwapTile(Tile current, PairInt delta, bool userStarted) { idleStart = -1; PairInt currentPos = GetPosition(current); PairInt otherPos = currentPos + delta; if(otherPos.x < 0 || otherPos.x >= boardSize || otherPos.y < 0 || otherPos.y >= boardSize) { yield break; // trying to moving outside board } Tile other = board[otherPos.x, otherPos.y]; if (other == null) { yield break; // matched gap that hasn't filled yet } if (current.IsBusy || other.IsBusy) { yield break; // currently moving or falling } MoveTile(current, currentPos, delta); MoveTile(other, otherPos, delta.GetOpposite(), true); while (current.IsBusy || other.IsBusy) { yield return 0; } selection.transform.parent = transform; selection.SetActive(false); // get the list of squares involved in a match by swapping those HashSet<Tile> matches = GetAllMatches(); if (matches.Count == 0) { // didn't work, move the squares back MoveTile(current, currentPos+delta, delta.GetOpposite()); MoveTile(other, otherPos-delta, delta, true); AudioSource.PlayClipAtPoint(matchBadSound, Camera.main.transform.position); yield break; } else { if (userStarted) { HandleMatches(current.type, matches); } else { HandleMatches(TileType.None, matches); } } }
public void PropagateAll() { countMaxPrior = 0; int yStart = 0; for (int x = 0; x < wide; x++) { for (int y = yStart; y < Params.topEdge; y += 2) { PairInt coord = new PairInt(x, y); SetPoint(coord); if (GetPoint(coord, Layers.metal1Trace).priority == 99) countMaxPrior++; if (GetPoint(coord, Layers.siliconTrace).priority == 99) countMaxPrior++; } if (yStart == 0) yStart = 1; else yStart = 0; } yStart = 1; for (int x = 0; x < wide; x++) { for (int y = yStart; y < Params.topEdge; y += 2) { PairInt coord = new PairInt(x, y); SetPoint(coord); if (GetPoint(coord, Layers.metal1Trace).priority == 99) countMaxPrior++; if (GetPoint(coord, Layers.siliconTrace).priority == 99) countMaxPrior++; } if (yStart == 0) yStart = 1; else yStart = 0; } }
private void SetNextCont_old(PairInt inChanged, int layerChanged, NodePoint inSample) { bool b = false; if (inChanged.x == 33 && (inChanged.y == 16 || inChanged.y == 18) && layerChanged == Layers.metal1Trace && inSample.name != "N6859613") b = false; if (inSample.name == Material.blankName) return; layoutMap[inChanged.x][inChanged.y][layerChanged].isReplace = false; layoutMap[inChanged.x][inChanged.y][layerChanged].name = inSample.name; layoutMap[inChanged.x][inChanged.y][layerChanged].numberNode = inSample.numberNode; layoutMap[inChanged.x][inChanged.y][layerChanged].priority = inSample.priority; layoutMap[inChanged.x][inChanged.y][layerChanged].number = inSample.number; string curName = inSample.name; ContactSimple curPoint = new ContactSimple(inChanged, layerChanged); List<ContactSimple> cntArround = curPoint.GetArroundPoints(wide); List<PairInt> cntArea = inChanged.GetBigArround(wide); cntArea.Add(inChanged); foreach (ContactSimple cntUnit in cntArround) { string unitName = GetPoint(cntUnit).name; if (unitName != curName && unitName!= Material.blankName && unitName != Material.diffusionName) { if (cntUnit.x == 33 && (cntUnit.y == 16 || cntUnit.y == 18) && cntUnit.layer == Layers.metal1Trace) b = false; SetContact(cntUnit, Material.blankName, 0, 0, -1); //cntAdded.Add(cntUnit); if (GetPoint(cntUnit).isSource) { foreach (ContactSimple smp in GetSourceContacts(cntUnit, curName)) if (smp != cntUnit) cntArea.Add(smp); //cntArea.Add(GetSourceContacts //GetNearSource(cntUnit)); } foreach (ContactSimple cnt in cntUnit.GetNeborPoints(wide)) { string bn = GetPoint(cnt).name; if (cnt.x == 38 && cnt.y == 14 && cnt.layer == 1 && bn != Material.blankName) b = false; if ((GetPoint(cnt).name != curName) && (cntArea.FindIndex(el => el == cnt) < 0)) cntArea.Add(cnt); } } } foreach (PairInt cntUnit in cntArea) { foreach (int lay in Params.LayersRange[layerChanged]) { layoutMap[cntUnit.x][cntUnit.y][lay].isReplace = CheckNebors(new ContactSimple(cntUnit, lay)); } } }
private NodePoint DefineSourcePoint(PairInt inCnt, int inLayer) { if (inCnt.y == Params.VccPosition || inCnt.y == Params.GndPosition) return GetPoint(new ContactSimple(inCnt, inLayer)); ContactSimple fndCnt = new ContactSimple(inCnt, inLayer); fndCnt.y = Params.lineN; if ( inCnt.y < Params.lineMiddle ) fndCnt.y = Params.lineP; foreach (Node nd in nodeList) { foreach(ContactSimple cnt in nd.arcCollection) { if (cnt == fndCnt) { List<ContactSimple> startWave = FindStartPoint(cnt, nd.name); NodePoint nd2 = GetPoint(startWave[0]); return nd2;//new NodePoint(nd2.name, nd2.priority, ); //nd.name; } } } return GetPoint(new ContactSimple(inCnt, inLayer)); }
public void OnMouseUp() { Vector3 MouseUpVec = Camera.main.ScreenToWorldPoint(Input.mousePosition); MouseUpVec.z = 0f; MouseUpVec /= thisKnot.GlobalRate; if (Display.IsDrawKnotMode()) { if (DraggedNode != null) { //ノードマウスダウンから始めたとき if ((MouseUpVec - MouseDownVec).magnitude < 0.05f && DraggedNode.ThisBead.Joint) { // ノードをクリック -> クロシングチェンジ //ビーズのデータの変更 Bead bd = DraggedNode.ThisBead; Bead tmp = bd.N1; bd.N1 = bd.U2; bd.U2 = bd.N2; bd.N2 = bd.U1; bd.U1 = tmp; //ノードのデータの変更 DraggedNode.Theta -= Mathf.PI / 2f; float rtmp = DraggedNode.R[0]; DraggedNode.R[0] = DraggedNode.R[3]; DraggedNode.R[3] = DraggedNode.R[2]; DraggedNode.R[2] = DraggedNode.R[1]; DraggedNode.R[1] = rtmp; //エッジのデータの変更 Edge[] AllEdges = FindObjectsOfType <Edge>(); for (int e = 0; e < AllEdges.Length; e++) { Edge ed = AllEdges[e]; if (ed.ANodeID == DraggedNode.ID) { ed.ANodeRID = (ed.ANodeRID + 1) % 4; } else if (ed.BNodeID == DraggedNode.ID) { ed.BNodeRID = (ed.BNodeRID + 1) % 4; } } } //ノードをドラッグしたときは後処理なし DraggedNode = null; } // フリーカーブを描いているとき else if (StartFreeCurveBead != null) { // スポットを消去する //Spot[] NodeSpots = FindObjectsOfType<Spot>(); //for(int i= NodeSpots.Length; i>=0; i--) //{ // Destroy(NodeSpots[i].gameObject); //} ////終了地点がノードでないことが要件 bool NoProc = false; //終了地点がノードだったら、非処理フラグを立てる thisKnot.GetAllThings(); for (int n = 0; n < thisKnot.AllNodes.Length; n++) { if ((thisKnot.AllNodes[n].Position - MouseUpVec).magnitude < 0.2f) { NoProc = true; } } //終了地点がビーズだったら、処理に入る。 //終了地点がビーズでなかったら、非処理フラグを立てる Bead EndFreeCurveBead = null; if (!NoProc) { NoProc = true; for (int b = 0; b < thisKnot.AllBeads.Length; b++) { if ((thisKnot.AllBeads[b].Position - MouseUpVec).magnitude < 0.15f) { NoProc = false; // 終了ビーズを記録 EndFreeCurveBead = thisKnot.AllBeads[b]; break; } } } //非処理フラグが立っていたらフリーカーブを消去して終わり if (NoProc) { thisFreeLoop.FreeCurve.Clear(); } else// 処理に入る { // 開始ビーズから終了ビーズをたどる方法を探索 // 開始ビーズから終了ビーズの間にクロシングがどのように表れるかを調査。 // first : 0:何もなし、1:オーバーのみ、2:アンダーのみ // second : ビーズ距離 PairInt GotoN1 = thisKnot.FindBeadAlongCurve(StartFreeCurveBead, StartFreeCurveBead.N1, EndFreeCurveBead); PairInt GotoN2 = thisKnot.FindBeadAlongCurve(StartFreeCurveBead, StartFreeCurveBead.N2, EndFreeCurveBead); //Debug.Log(GotoN1.first + "," + GotoN2.first); bool BothOK = (GotoN1.first != -1) && (GotoN2.first != -1); // オーバーのみ、またはアンダーのみの時には処理を開始(どちらともとれる場合には、短いほう) if (GotoN1.first != -1 || (BothOK && GotoN1.second < GotoN2.second)) { // 開始ビーズから終了ビーズまでの既存のビーズラインを消去 thisKnot.DeleteBeadsFromTo(StartFreeCurveBead, StartFreeCurveBead.N1, EndFreeCurveBead); // フリーループにあたる部分をビーズへと変換 thisKnot.FreeCurve2Bead(StartFreeCurveBead, EndFreeCurveBead, GotoN1.first); // 旧フリーループと旧ビーズとの交点を探してジョイントにする。 } else if (GotoN2.first != -1 || (BothOK && GotoN1.second > GotoN2.second)) { // 開始ビーズから終了ビーズまでの既存のビーズラインを消去 thisKnot.DeleteBeadsFromTo(StartFreeCurveBead, StartFreeCurveBead.N2, EndFreeCurveBead); // フリーループにあたる部分をビーズへと変換 thisKnot.FreeCurve2Bead(StartFreeCurveBead, EndFreeCurveBead, GotoN2.first); // 旧フリーループと旧ビーズとの交点を探してジョイントにする。 } else //書き換える条件を満たしていないとき {//すべてを消去して終了 thisFreeLoop.FreeCurve.Clear(); Display.SetDrawKnotMode(); } // グラフ構造を書き換える // 形を整える //thisKnot.Modify(); //thisKnot.UpdateBeads(); } } else if (StartFreeLoop) { StartFreeLoop = false;//必ずフリーループモードは終了 if (!thisFreeLoop.CircleEffectEnable) { thisFreeLoop.FreeCurve.Clear(); Display.SetDrawKnotMode(); // フリーループモードから抜けたことが直感的にわかりにくい。 } else { // まず1列のbeadの列を作る。 int BeadCount = thisKnot.GetMaxIDOfBead(); int freeCurveSize = thisFreeLoop.FreeCurve.Count; for (int b = 0; b < freeCurveSize; b++) { //ビーズを追加(ID番号=BeadCount + 1 + b) thisKnot.AddBead(thisFreeLoop.FreeCurve[b], BeadCount + 1 + b); } //FreeCurveをクリアしておく thisFreeLoop.CircleEffect.GetComponent <LineRenderer>().enabled = thisFreeLoop.CircleEffectEnable = false; thisFreeLoop.FreeCurve.Clear(); thisKnot.AllBeads = FindObjectsOfType <Bead>(); // N1,N2, NumOfNbhdを設定 for (int b = 0; b < freeCurveSize; b++) { Bead bd = thisKnot.GetBeadByID(BeadCount + 1 + b); bd.N1 = thisKnot.GetBeadByID(BeadCount + 1 + (b + 1) % freeCurveSize); bd.N2 = thisKnot.GetBeadByID(BeadCount + 1 + (b + freeCurveSize - 1) % freeCurveSize); bd.NumOfNbhd = 2; } //重複も許して交点を検出 List <PairInt> meets = new List <PairInt>(); for (int b1 = 0; b1 < thisKnot.GetMaxIDOfBead() + 1; b1++) { Bead b1c = thisKnot.GetBeadByID(b1); if (b1c == null) { continue; } Bead b1n = b1c.N1; Bead b1p = b1c.N2; if (b1n == null || b1p == null) { continue; } for (int b2 = BeadCount + 1; b2 < BeadCount + freeCurveSize; b2++) { if (b1 >= b2) { continue; } Bead b2c = thisKnot.GetBeadByID(b2); if (b2c == null) { continue; } Bead b2n = b2c.N1; Bead b2p = b2c.N2; if (b2n == null || b2p == null) { continue; } if (b1c == b2n || b1c == b2p || b1n == b2c || b1n == b2p) { continue; // そもそも異なる場所である保証。 } if (GetMeetPairOfNewFreeCurve(b1, b1n, b1p, b2, b2n, b2p, meets)) { meets.Add(new PairInt(b1, b2)); } } } if (meets.Count == 0) { // ある程度の長さがありかつ交点の個数が0ならば、トリビアルな成分を追加する。 if (freeCurveSize > 20) { Bead Bd = thisKnot.GetBeadByID(BeadCount + 1 + 1); Bd.MidJoint = true; Bd = thisKnot.GetBeadByID(BeadCount + 1 + Mathf.FloorToInt(freeCurveSize / 3)); Bd.MidJoint = true; Bd = thisKnot.GetBeadByID(BeadCount + 1 + Mathf.FloorToInt(2 * freeCurveSize / 3)); Bd.MidJoint = true; // BeadsからNodeEdgeを更新する thisKnot.CreateNodesEdgesFromBeads(); // 形を整える thisKnot.GetAllThings(); thisKnot.Modify(); thisKnot.UpdateBeads(); } else {// 交点の個数が0ならば、新規Beadを全部捨てる。 thisKnot.AllBeads = FindObjectsOfType <Bead>(); for (int i = 0; i < thisKnot.AllBeads.Length; i++) { Bead bd = thisKnot.AllBeads[i]; if (bd.ID > BeadCount) { bd.N1 = bd.N2 = null; bd.NumOfNbhd = 0; bd.Active = false; } } } //モードを戻しておく Display.SetDrawKnotMode(); } else {// さもなくば、交点に当たるところをJointにする for (int i = 0; i < meets.Count; i++) { int b1 = meets[i].first; int b2 = meets[i].second; Bead bd1 = thisKnot.GetBeadByID(b1); Bead bd2 = thisKnot.GetBeadByID(b2); if (bd1 == null || bd2 == null) { continue; } if (bd1.N1 == null || bd2.N1 == null || bd2.N2 == null) { continue; } bd1.Joint = true; //Nbhdの繋ぎ替え // これをどちらにどちらをつなぐかは、選ぶ必要がある。 float bd1x = bd1.Position.x; float bd1y = bd1.Position.y; float n1x = bd1.N1.Position.x - bd1x; float n1y = bd1.N1.Position.y - bd1y; float bd2n1x = bd2.N1.Position.x - bd1x; float bd2n1y = bd2.N1.Position.y - bd1y; float bd2n2x = bd2.N2.Position.x - bd1x; float bd2n2y = bd2.N2.Position.y - bd1y; if (n1x * bd2n1y - n1y * bd2n1x > 0 && n1x * bd2n2y - n1y * bd2n2x < 0) { bd1.U1 = bd2.N1; bd1.U2 = bd2.N2; } else { bd1.U1 = bd2.N2; bd1.U2 = bd2.N1; } if (bd2.N1.N1 == bd2) { bd2.N1.N1 = bd1; } else if (bd2.N1.N2 == bd2) { bd2.N1.N2 = bd1; } if (bd2.N2.N1 == bd2) { bd2.N2.N1 = bd1; } else if (bd2.N2.N2 == bd2) { bd2.N2.N2 = bd1; } //消去 bd2.Active = false;// // Joint-Jointとなるエッジには間にMidJointを必ず追加する。 for (int r1 = 0; r1 < 4; r1++) { PairInt br2 = thisKnot.FindEndOfEdgeOnBead(bd1, r1, true); Bead endBead = thisKnot.FindBeadByID(br2.first); if (endBead != null && endBead.Joint) { // ジョイント間のビーズ数を数える。 int count = thisKnot.CountBeadsOnEdge(bd1, r1); // midJointを作る Bead midJointBead = thisKnot.GetBeadOnEdge(bd1, r1, Mathf.FloorToInt(count / 2)); if (midJointBead != null) { midJointBead.MidJoint = true; } //Debug.Log(bd.ID + "," + r1 + "->" + br2.first + "," + br2.second + "(" + count + ")"); } } } thisKnot.AllBeads = FindObjectsOfType <Bead>(); // BeadsからNodeEdgeを更新する thisKnot.CreateNodesEdgesFromBeads(); // 形を整える thisKnot.GetAllThings(); thisKnot.Modify(); thisKnot.UpdateBeads(); } } } } else if (Display.IsFreeLoopMode()) { StartFreeLoop = false;//必ずフリーループモードは終了 //スタート地点に近くない場所で終了した場合には、すべてを消去して終了 if (!thisFreeLoop.CircleEffectEnable) { thisFreeLoop.FreeCurve.Clear(); Display.SetDrawKnotMode(); // フリーループモードから抜けたことが直感的にわかりにくい。 } else // { //以下は長い処理なので、メソッド化が望ましい。 //スタート地点に近い場所で終わった場合は、まずはBeadへと変換する。 // すべてのビーズを消す(不要) thisKnot.ClearAll(); // まず1列のbeadの列を作る。 int freeCurveSize = thisFreeLoop.FreeCurve.Count; for (int b = 0; b < freeCurveSize; b++) { //ビーズを追加(b=ID番号) thisKnot.AddBead(thisFreeLoop.FreeCurve[b], b); } //FreeCurveをクリアしておく thisFreeLoop.CircleEffect.GetComponent <LineRenderer>().enabled = thisFreeLoop.CircleEffectEnable = false; thisFreeLoop.FreeCurve.Clear(); // 新規ビーズのデータを整える thisKnot.AllBeads = FindObjectsOfType <Bead>(); freeCurveSize = thisKnot.AllBeads.Length;// おそらく無意味 for (int b = 0; b < freeCurveSize; b++) { // N1,N2, NumOfNbhdを設定 Bead bd = thisKnot.AllBeads[b]; bd.N1 = thisKnot.AllBeads[(b + 1) % freeCurveSize]; bd.N2 = thisKnot.AllBeads[(b + freeCurveSize - 1) % freeCurveSize]; bd.NumOfNbhd = 2; } //モードを戻しておく Display.SetDrawKnotMode(); //重複も許して交点を検出 List <PairInt> meets = new List <PairInt>(); for (int b1 = 0; b1 < freeCurveSize; b1++) { int b1n = (b1 + 1) % freeCurveSize; int b1p = (b1 + freeCurveSize - 1) % freeCurveSize; for (int b2 = b1 + 1; b2 < freeCurveSize; b2++) { int b2n = (b2 + 1) % freeCurveSize; int b2p = (b2 + freeCurveSize - 1) % freeCurveSize; //int difference = (b2 - b1 + freeCurveSize) % freeCurveSize;//なぜ? int difference = b2 - b1; if (2 < difference && difference < freeCurveSize - 2) {// そもそも異なる場所である保証。 float x1 = thisKnot.AllBeads[b1p].Position.x; float y1 = thisKnot.AllBeads[b1p].Position.y; float x2 = thisKnot.AllBeads[b1n].Position.x; float y2 = thisKnot.AllBeads[b1n].Position.y; float x3 = thisKnot.AllBeads[b2p].Position.x; float y3 = thisKnot.AllBeads[b2p].Position.y; float x4 = thisKnot.AllBeads[b2n].Position.x; float y4 = thisKnot.AllBeads[b2n].Position.y; // (x2-x1)s+x1 = (x4-x3)t+x3 // (y2-y1)s+y1 = (y4-y3)t+y3 // (x2-x1)s - (x4-x3)t = +x3-x1 // (y2-y1)s - (y4-y3)t = +y3-y1 float a = x2 - x1; float b = -x4 + x3; float c = y2 - y1; float d = -y4 + y3; float p = x3 - x1; float q = y3 - y1; float s1 = p * d - b * q; // s = s1/st float t1 = a * q - p * c; // t = t1/st float st = a * d - b * c; if (st < 0) { st *= -1; s1 *= -1; t1 *= -1; } if (0 < s1 && s1 < st && 0 < t1 && t1 < st) { // 線分が交わっている条件 //重複を排してListに貯める bool OK = true; for (int mt = 0; mt < meets.Count; mt++) { int m1 = meets[mt].first; int m2 = meets[mt].second; if (Math.Abs(b1 - m1) <= 2 && Math.Abs(b2 - m2) <= 2) { //Debug.Log("(" + b1 + "," + b2 + ")=(" + m1 + "," + m2 + ")"); OK = false; break; } } if (OK) { meets.Add(new PairInt(b1, b2)); } } } } } if (meets.Count == 0) {// ある程度の長さがありかつ交点の個数が0ならば、トリビアルな成分を追加する。 if (freeCurveSize > 20) { Bead Bd = thisKnot.AllBeads[1]; Bd.MidJoint = true; Bd = thisKnot.AllBeads[Mathf.FloorToInt(freeCurveSize / 3)]; Bd.MidJoint = true; Bd = thisKnot.AllBeads[Mathf.FloorToInt(2 * freeCurveSize / 3)]; Bd.MidJoint = true; // BeadsからNodeEdgeを更新する thisKnot.CreateNodesEdgesFromBeads(); // 形を整える thisKnot.GetAllThings(); thisKnot.Modify(); thisKnot.UpdateBeads(); } else { // 全体が短くてかつ交点の個数が0ならば、Beadを全部捨てる。 thisKnot.ClearAllBeads(); } //モードを戻しておく Display.SetDrawKnotMode(); } else {// さもなくば、交点に当たるところをJointにする for (int i = 0; i < meets.Count; i++) { int b1 = meets[i].first; int b2 = meets[i].second; Bead bd1 = thisKnot.AllBeads[b1]; Bead bd2 = thisKnot.AllBeads[b2]; bd1.Joint = true; //Nbhdの繋ぎ替え // これをどちらにどちらをつなぐかは、選ぶ必要がある。 float bd1x = bd1.Position.x; float bd1y = bd1.Position.y; float n1x = bd1.N1.Position.x - bd1x; float n1y = bd1.N1.Position.y - bd1y; float bd2n1x = bd2.N1.Position.x - bd1x; float bd2n1y = bd2.N1.Position.y - bd1y; float bd2n2x = bd2.N2.Position.x - bd1x; float bd2n2y = bd2.N2.Position.y - bd1y; if (n1x * bd2n1y - n1y * bd2n1x > 0 && n1x * bd2n2y - n1y * bd2n2x < 0) { bd1.U1 = bd2.N1; bd1.U2 = bd2.N2; } else { bd1.U1 = bd2.N2; bd1.U2 = bd2.N1; } thisKnot.AllBeads[b2 - 1].N1 = bd1; thisKnot.AllBeads[b2 + 1].N2 = bd1; //消去 bd2.Active = false;// } thisKnot.AllBeads = FindObjectsOfType <Bead>(); freeCurveSize = thisKnot.AllBeads.Length; // Joint-Jointとなるエッジには間にMidJointを必ず追加する。 for (int b1 = 0; b1 < freeCurveSize; b1++) { Bead bd = thisKnot.AllBeads[b1]; if (bd.Joint) { for (int r1 = 0; r1 < 4; r1++) { PairInt br2 = thisKnot.FindEndOfEdgeOnBead(bd, r1, true); Bead endBead = thisKnot.FindBeadByID(br2.first); if (endBead != null && endBead.Joint) { // ジョイント間のビーズ数を数える。 int count = thisKnot.CountBeadsOnEdge(bd, r1); // midJointを作る Bead midJointBead = thisKnot.GetBeadOnEdge(bd, r1, Mathf.FloorToInt(count / 2)); if (midJointBead != null) { midJointBead.MidJoint = true; } //Debug.Log(bd.ID + "," + r1 + "->" + br2.first + "," + br2.second + "(" + count + ")"); } } } } // BeadsからNodeEdgeを更新する thisKnot.CreateNodesEdgesFromBeads(); // 形を整える thisKnot.GetAllThings(); thisKnot.Modify(); thisKnot.UpdateBeads(); // thisKnot.AdjustEdgeLine(); //モードを戻す Display.SetDrawKnotMode(); } } } else if (Display.IsEditKnotMode()) { } else if (Display.IsMenuMode()) { } }
/*private bool SetOneOfBest_old(PairInt inCnt, int inLayer, NodePoint inSample) { bool noLayer = false; int sourceBest = 0; ContactSimple simple = new ContactSimple(inCnt, inLayer); List<ContactSimple> arround = simple.GetArroundPoints(wide); foreach (ContactSimple cntArround in arround) { NodePoint pn = GetPoint(cntArround); if ((GetPoint(cntArround).name != inSample.name) && (!GetPoint(cntArround).isReplace) && (GetPoint(cntArround).name != Material.diffusionName)) noLayer = true; if (!noLayer && GetPoint(cntArround).isSource && (GetPoint(cntArround).name != inSample.name)) sourceBest++; } int sourseCount = 0; if ((sourceBest > 1) && (diffusionExeption.FindIndex(el => el == inSample.name) >= 0)) { foreach (ContactSimple cnt in GetSourceContacts(new ContactSimple(inCnt, inLayer), inSample.name)) { if (GetPoint(cnt).name == inSample.name) sourseCount++; } if (sourseCount > sourceBest) sourceBest = 1; } if (!noLayer && (sourceBest < 2) && (GetPoint(inCnt, inLayer).isReplace)) { SetNextCont(inCnt, inLayer, inSample);//error gap in line return true; } return false; }*/ private bool SetOneOfBest(PairInt inCnt, int inLayer, NodePointLayer inSample) { NodePoint crPnt = GetPoint(inCnt, inLayer); if (!crPnt.isReplace || inSample.name == Material.blankName || crPnt.name == inSample.name) return false; ContactSimple curCentr = new ContactSimple(inCnt, inLayer); SetContact(curCentr, Material.blankName, 0, 0, -1); /*layoutMap[inChanged.x][inChanged.y][layerChanged].isReplace = false; layoutMap[inChanged.x][inChanged.y][layerChanged].name = inSample.name; layoutMap[inChanged.x][inChanged.y][layerChanged].numberNode = inSample.numberNode; layoutMap[inChanged.x][inChanged.y][layerChanged].priority = inSample.priority; layoutMap[inChanged.x][inChanged.y][layerChanged].number = inSample.number; */ string curName = inSample.name; //ContactSimple curPoint = new ContactSimple(inChanged, layerChanged); List<ContactSimple> cntArround = curCentr.GetArroundPoints(wide); //List<PairInt> cntCheckRepl = inCnt.GetBigArround(wide); //cntCheckRepl.Add(inCnt); bool contSetting = true; bool retValue = true; //foreach (ContactSimple cntUnit in cntArround) while (contSetting) { contSetting = false; retValue = true; List<string> namesChanged = new List<string>(); foreach (ContactSimple cntUnit in cntArround) { NodePoint unitPnt = GetPoint(cntUnit); string unitName = unitPnt.name; if (unitName != curName && unitPnt.isReplace && unitName!= Material.blankName && unitName != Material.diffusionName) { contSetting = true; if (cntUnit.x == 29 && (cntUnit.y == 38) && cntUnit.layer == Layers.siliconTrace && unitName == "INC")//4 point !!!!! != 737 { List<NodePoint> ps = new List<NodePoint>(); foreach (ContactSimple cnt in cntUnit.GetNeborPoints(wide)) ps.Add(GetPoint(cnt)); contSetting = true; } namesChanged.Add(unitName); SetContact(cntUnit, Material.blankName, 0, 0, -1); //cntAdded.Add(cntUnit); if (GetPoint(cntUnit).isSource) { foreach (ContactSimple smp in GetSourceContacts(cntUnit, curName)) if (smp != cntUnit) layoutMap[smp.x][smp.y][smp.layer].isReplace = CheckNebors(new ContactSimple(smp, smp.layer)); //cntCheckRepl.Add(smp); } foreach (ContactSimple cnt in cntUnit.GetNeborPoints(wide)) { /*string bn = GetPoint(cnt).name; if (cnt.x == 38 && cnt.y == 14 && cnt.layer == 1 && bn != Material.blankName) b = false;*/ foreach (int lay in Params.LayersRange[inLayer]) { //if (GetPoint(cnt, lay).name == unitName)//curName) && (cntCheckRepl.FindIndex(el => el == cnt) < 0)) layoutMap[cnt.x][cnt.y][lay].isReplace = CheckNebors(new ContactSimple(cnt, lay)); //cntCheckRepl.Add(cnt); } } } else if (unitName != curName && unitName!= Material.blankName && unitName != Material.diffusionName) { retValue = false; if (namesChanged.FindIndex(el => el == unitPnt.name) >= 0)//--------delete layoutMap[cntUnit.x][cntUnit.y][cntUnit.layer].isReplace = CheckNebors(new ContactSimple(cntUnit, cntUnit.layer)); } } } if (retValue) { layoutMap[inCnt.x][inCnt.y][inLayer].isReplace = false; layoutMap[inCnt.x][inCnt.y][inLayer].name = inSample.name; layoutMap[inCnt.x][inCnt.y][inLayer].numberNode = inSample.numberNode; layoutMap[inCnt.x][inCnt.y][inLayer].priority = inSample.priority; layoutMap[inCnt.x][inCnt.y][inLayer].number = inSample.number; } List<PairInt> checkRepl = inCnt.GetBigArround(wide); checkRepl.Add(inCnt); foreach (PairInt cntUnit in checkRepl) { foreach (int lay in Params.LayersRange[inLayer]) { //if (GetPoint(cntUnit, lay).name == curName) layoutMap[cntUnit.x][cntUnit.y][lay].isReplace = CheckNebors(new ContactSimple(cntUnit, lay)); } } return retValue; //-------------------------- /*bool noLayer = false; int sourceBest = 0; ContactSimple simple = new ContactSimple(inCnt, inLayer); List<ContactSimple> arround = simple.GetArroundPoints(wide); foreach (ContactSimple cntArround in arround) { NodePoint pn = GetPoint(cntArround); if ((GetPoint(cntArround).name != inSample.name) && (!GetPoint(cntArround).isReplace) && (GetPoint(cntArround).name != Material.diffusionName)) noLayer = true; if (!noLayer && GetPoint(cntArround).isSource && (GetPoint(cntArround).name != inSample.name)) sourceBest++; } int sourseCount = 0; if ((sourceBest > 1) && (diffusionException.FindIndex(el => el == inSample.name) >= 0)) { foreach (ContactSimple cnt in GetSourceContacts(new ContactSimple(inCnt, inLayer), inSample.name)) { if (GetPoint(cnt).name == inSample.name) sourseCount++; } if (sourseCount > sourceBest) sourceBest = 1; } if (!noLayer && (sourceBest < 2) && (GetPoint(inCnt, inLayer).isReplace)) { if (!SetNextCont(inCnt, inLayer, inSample)) return false; return true; }*/ //return false; }