private List <Vector2> GetBoundsFromGroup(List <List <GameObject> > blocks, int rowIndex, int columnIndex) { List <Vector2> bounds = new List <Vector2>(); if (blocks.Count >= 2) { int numColumns = blocks[0].Count; int numRows = blocks.Count; print("numColumns:" + numColumns); print("numRows:" + numRows); BlocksUtil.LogRows(blocks); bounds.Add(new Vector2(columnIndex * Block.BlockSize, rowIndex * Block.BlockSize)); bounds.Add(new Vector2((columnIndex + numColumns) * Block.BlockSize, (rowIndex + numRows) * Block.BlockSize)); print(columnIndex * Block.BlockSize + " " + rowIndex * Block.BlockSize + " " + (columnIndex + numColumns) * Block.BlockSize + " " + (rowIndex + numRows) * Block.BlockSize); } else { bounds.Add(Vector2.zero); bounds.Add(Vector2.zero); } return(bounds); }
/// <summary> /// Returns all blocks from same row below /// </summary> /// <param name="b"></param> /// <returns></returns> private List <GameObject> GetBlocksFromRowBelow(GameObject b) { int index = this.blockManager.GetRows().FindIndex(row => row.IndexOf(b) >= 0); print("BOUNDARIES: rowIndex" + index); if (index == -1) { print("BOUNDARIES: error"); print(b.GetComponent <Block>().GetColumnIndexes()); print(b.GetComponent <Block>().GetYIndexes()); BlocksUtil.LogRows(this.blockManager.GetRows()); } return(this.blockManager.GetRows()[index - 1]); //Todo Careful here }
/// <summary> /// /// </summary> /// <param name="b"></param> /// <param name="index"></param> private void MoveBlockAtIndex(GameObject b, int index) { print("SetColumIndex MoveBlockAtIndex: " + b.GetComponent <Block>().color + " " + index); int currentBlockIndex = this.sameRowBlocks.IndexOf(b); print(currentBlockIndex); this.sameRowBlocks.RemoveAt(currentBlockIndex); this.sameRowBlocks.Insert(index, draggingBlock); print("SetColumIndex MoveBlockAtIndex after: " + BlocksUtil.LogList(this.sameRowBlocks)); int startIndex = Mathf.Min(index, currentBlockIndex); int endIndex = Mathf.Max(index, currentBlockIndex); for (int iB = startIndex; iB <= endIndex; iB++) { Block block = this.sameRowBlocks[iB]?.GetComponent <Block>(); //avoid dragging block if (this.sameRowBlocks[iB] != b) { if (block != null) { block.SetColumIndex(iB); } else { //GameObject blockAtTheBottom = this.EnablePhysicsForBlocksAtColumnIndex(iB, b.GetComponent<RectTransform>().position.y); //if (blockAtTheBottom) //{ // print("blockAtTheBottom: " + blockAtTheBottom.GetComponent<Block>().GetColumnIndexes()[0] + " " + blockAtTheBottom.GetComponent<Block>().color); // //Insert the falling block to the row (iB should be equal to blockAtTheBottom.GetComponent<Block>().GetColumnIndex() // this.sameRowBlocks[blockAtTheBottom.GetComponent<Block>().GetColumnIndexes()[0]] = blockAtTheBottom; // string s = ""; // for (int iB2 = 0; iB2 < this.sameRowBlocks.Count; iB2++) // { // s += (this.sameRowBlocks[iB2] != null ? this.sameRowBlocks[iB2].GetComponent<Block>().color.ToString() : "___") + " "; // } // print("Big Total Row is: " + s); //} } } } }
/// <summary> /// /// </summary> /// <param name="columnIndex"></param> /// <param name="positionY"></param> /// <returns>Returns the block at the bottom</returns> private GameObject EnablePhysicsForBlocksAtColumnIndex(int columnIndex, float positionY) { List <GameObject> blocks = this.GetBlocksOnTop(columnIndex, positionY); print("EnablePhysicsForBlocksAtColumnIndex:" + BlocksUtil.LogList(blocks)); //get toppest block from the column and wait for the block to finish to fall down, then InvalidateBlock //as some blocks might finish the motion after the draggingBlock finish its own one. if (blocks.Count > 0) { blocks.Last().GetComponent <PhysicsBlock>().OnPhysicsComplete += OnTopBlockPhysicsComplete; } for (int iB = 0; iB < blocks.Count; iB++) { blocks[iB].GetComponent <PhysicsBlock>().enablePhysics = true; } // can be null when moving block on the top row return(blocks.Count > 0 ? blocks[0] : null); }
public void InvalidateRows() { print("=====InvalidateRows====="); print("this.blocks.Count:" + this.blocks.Count); int count = 0; this.rows = this.blocks // repeat block in different rows if spread in multiple yIndexes .SelectMany(b => b.GetComponent <Block>().GetYIndexes().Select((yIndex, i) => new KeyValuePair <int, GameObject>(yIndex, b))) .GroupBy(item => item.Key) .OrderBy(grp => grp.Key) .Select(grp => grp.Select(kv => kv.Value)) .Select(grp => { return(grp // repeat block in different columns if spread in multiple columnIndexes .SelectMany(b => b.GetComponent <Block>().GetColumnIndexes().Select((columnIndex, i) => new KeyValuePair <int, GameObject>(columnIndex, b))) .OrderBy(item => item.Key) .Select(kv => kv.Value)); }) .Select(grp => { List <GameObject> grpList = grp.ToList(); List <GameObject> result = new List <GameObject>(); int index = 0; while (result.Count < numColumns) { if (count == 12) { print("count:" + result.Count + " " + grpList.Count); if (index < grpList.Count && grpList[index] != null) { print(grpList[index].GetComponent <Block>().color + " " + String.Join(",", grpList[index].GetComponent <Block>().GetColumnIndexes().ToArray())); } } if (index < grpList.Count && (grpList[index].GetComponent <Block>().GetColumnIndexes().IndexOf(result.Count) >= 0 || grpList[index].GetComponent <Block>().GetColumnIndexes().IndexOf(result.Count - 1) >= 0)) { if (count == 12) { print("=>add " + grpList[index].GetComponent <Block>().color + " " + String.Join(",", grpList[index].GetComponent <Block>().GetColumnIndexes().ToArray())); } result.Add(grpList[index]); index++; } else { result.Add(null); if (count == 12) { print("=>add null"); } } //if (index >= grpList.Count) //{ // //print("GetBlocksFromSameRowThan Add Null1"); // result.Add(null); // index++; //} //else if (grpList[index].GetComponent<Block>().GetColumnIndexes().IndexOf(result.Count) >= 0) // <= to keep draggingBlock when dragging //{ // //print("GetBlocksFromSameRowThan Element " + grpList[index].GetComponent<Block>().color); // result.Add(grpList[index]); // index++; //} //else //{ // //print("GetBlocksFromSameRowThan Add Null2"); // result.Add(null); //} } count++; return(result); }) .Select(grp => grp.ToList()) .ToList(); print("*********"); //BlocksUtil.LogRows(this.blocks // // repeat block in different rows if spread in multiple yIndexes // .SelectMany(b => b.GetComponent<Block>().GetYIndexes().Select((yIndex, i) => new KeyValuePair<int, GameObject>(yIndex, b))) // .GroupBy(item => item.Key) // .OrderBy(grp => grp.Key) // .Select(grp => grp.Select(kv => kv.Value)) // .Select(grp => // { // return grp // // repeat block in different columns if spread in multiple columnIndexes // .SelectMany(b => b.GetComponent<Block>().GetColumnIndexes().Select((columnIndex, i) => new KeyValuePair<int, GameObject>(columnIndex, b))) // .OrderBy(item => item.Key) // .Select(kv => kv.Value); // }) // .Select(grp => grp.ToList()) // .ToList()); BlocksUtil.LogRows(this.rows); print("*********"); }
private List <List <GameObject> > DoFindBlocksForUnion(int rowStart, int rowEnd) { print("=============================FindBlocksForUnion"); List <List <GameObject> > rows = blockManager.GetRows(); List <List <GameObject> > groups = new List <List <GameObject> >(); List <GameObject> selectedBlocks = new List <GameObject>(); var iR = rowStart; var iC = 0; while (iR <= rowEnd && iC < rows[0].Count) { print("=============iR iC:" + iR + " " + iC); GameObject currentBlock = rows[iR][iC]; if (currentBlock != null) { print(currentBlock.GetComponent <Block>().color); bool isBlockAlreadySelected = selectedBlocks.IndexOf(currentBlock) > 0; bool isBlockVisible = currentBlock.GetComponent <BlockPlayable>().isVisible; if (isBlockAlreadySelected == false && isBlockVisible) { // union to the right and top print("iR iC ok:" + iR + "," + iC); List <List <GameObject> > groupRight = new List <List <GameObject> >(); groupRight = this.UnionWithRight(rows, new List <List <GameObject> >(), iR, iC, 2, selectedBlocks); print("groupRight1"); BlocksUtil.LogRows(groupRight); groupRight = this.UnionWithTop(rows, groupRight, iR + 2, iC, groupRight.Count > 0 ? groupRight[0].Count : 0, selectedBlocks); print("groupRight2"); BlocksUtil.LogRows(groupRight); List <GameObject> flattenGroupRight = groupRight.SelectMany(i => i).ToList <GameObject>(); // union to the top and right List <List <GameObject> > groupTop = new List <List <GameObject> >(); groupTop = this.UnionWithTop(rows, new List <List <GameObject> >(), iR, iC, 2, selectedBlocks); print("groupTop1"); BlocksUtil.LogRows(groupTop); groupTop = this.UnionWithRight(rows, groupTop, iR, iC + 2, groupTop.Count, selectedBlocks); print("groupTop2"); BlocksUtil.LogRows(groupTop); List <GameObject> flattenGroupTop = groupTop.SelectMany(i => i).ToList <GameObject>(); List <GameObject> selectedGroup; if (flattenGroupRight.Count >= 4 || flattenGroupTop.Count >= 4) { List <Vector2> groupRightBounds = this.GetBoundsFromGroup(groupRight, iR, iC); List <Vector2> groupTopBounds = this.GetBoundsFromGroup(groupTop, iR, iC); bool isGroupRightValid = this.IsGroupValid(flattenGroupRight, groupRightBounds); bool isGroupTopValid = this.IsGroupValid(flattenGroupTop, groupTopBounds); print("VALID right: " + isGroupRightValid); print("VALID top: " + isGroupTopValid); //Is any of the groups valid ? if (isGroupRightValid || isGroupTopValid) { //if right not valid, just reset if (isGroupRightValid == false) { flattenGroupRight = new List <GameObject>(); groupRight = new List <List <GameObject> >(); } //if top not valid, just reset if (isGroupTopValid == false) { flattenGroupTop = new List <GameObject>(); groupTop = new List <List <GameObject> >(); } print(iR + " " + iC + " found"); if (flattenGroupRight.Count >= flattenGroupTop.Count) { selectedGroup = flattenGroupRight; iC += groupRight[0].Count; } else { selectedGroup = flattenGroupTop; iC += groupTop[0].Count; } print(iR + " " + iC + " " + selectedGroup[0].GetComponent <Block>().color); groups.Add(selectedGroup); selectedBlocks.InsertRange(selectedBlocks.Count, selectedGroup); } else { //otherwise go to the new column iC++; } } else { iC++; } } else { iC++; } } else { iC++; } //boundaries if (iC > rows[0].Count - 2) { iR++; iC = 0; } } for (var iG = 0; iG < groups.Count; iG++) { this.blockManager.UnionBlocks(groups[iG]); } print("groups.Count " + groups.Count); return(groups); }
private List <List <GameObject> > UnionWithRight(List <List <GameObject> > rows, List <List <GameObject> > group, int row, int column, int length, List <GameObject> selectedBlocks) { if (column < rows[0].Count && length >= 2) { GameObject block = rows[row][column]; if (block != null) { BlockColor color = group.Count > 0 ? group[0][0].GetComponent <Block>().color: block.GetComponent <Block>().color; List <GameObject> blocks = new List <GameObject>(); bool sameColor = true; bool isOneOfBlocksNull = false; bool isOneOfBlocksAlreadySelected = false; bool isBlockWithDifferentSize = false; for (var iB = 0; iB < length; iB++) { GameObject currentBlock = rows[row + iB][column]; if (currentBlock != null) { blocks.Add(currentBlock); // console.log(currentBlock.color); if (currentBlock.GetComponent <Block>().color != color) { sameColor = false; } if (selectedBlocks.IndexOf(currentBlock) >= 0) { isOneOfBlocksAlreadySelected = true; } //// To manage this case //// Here, the length is 2 but the next block to check is a block2x3 which can not be added to the group //// //// ->o o O O //// o o O O //// O O //// //if (currentBlock.GetComponent<Block>().GetYIndexes().Count != length) //{ // isBlockWithDifferentSize = true; // print("isBlockWithDifferentSize Right:" + isBlockWithDifferentSize); //} } else { isOneOfBlocksNull = true; } } print("sameColor:" + sameColor); print("isOneOfBlocksAlreadySelected:" + isOneOfBlocksAlreadySelected); print("isOneOfBlocksNull:" + isOneOfBlocksNull); if (sameColor && isOneOfBlocksAlreadySelected == false && isOneOfBlocksNull == false)//&& isBlockWithDifferentSize == false) { //add each block to the correct row for (var iB = 0; iB < blocks.Count; iB++) { if (group.Count > iB) { group[iB].Add(blocks[iB]); } else { group.Add(new List <GameObject>() { blocks[iB] }); } } BlocksUtil.LogRows(group); group = this.UnionWithRight(rows, group, row, column + 1, length, selectedBlocks); } } } return(group); }