private bool DropRound(PriorityQueue<Cell> emptyCells, Dictionary<uint, DropInfo> dropMap, int turn) { var nextCells = new List<Cell>(); // 向两侧掉落 var slidings = new PriorityQueue<Cell>(new CellComparer()); //var slidings = new HashSet<Coord2>(); var waitings = new List<Cell>(); var hasDrop = false; //var hopeless = false; while(emptyCells.Count > 0) { // process line,只处理直线掉落 while(emptyCells.Count > 0) { var cell = emptyCells.Pop(); var co = cell.coord; DropMode mode; var top = mPortol.GetTop(co); if(!cell.IsEmpty) { continue; } if(cell.drop == turn) { // 说明处理过了 mode = DropMode.WAIT; } else if(mCreator.CanDropElement(co)) { mode = DropMode.GENERATE; } else { mode = GetDropMode(top, turn); } switch(mode) { case DropMode.GENERATE: // 直接生成 hasDrop = true; DropOne(dropMap, turn, true, cell, cell); break; case DropMode.DROP: // 持续向上找掉落 hasDrop = true; DropLine(emptyCells, dropMap, turn, cell, top); break; case DropMode.STUCK: case DropMode.WAIT: // 等待尝试两边滑落 for (var i = 0; i < 2; i++) { var coord = cell.coord + (SIDE_DIR[i] | Direction.TOP); mode = GetDropMode(coord, turn); if(mode == DropMode.DROP) { slidings.Push(GetCell(coord)); //slidings.Add(coord); } } waitings.Add(cell); break; //case DropMode.STUCK: // // 尝试两侧滑落,记录并延迟计算 // var stuck = 0; // for (var i = 0; i < 2; i++) { // var coord = cell.coord + (SIDE_DIR[i] | Direction.TOP); // mode = GetDropMode(coord, turn); // if(mode == DropMode.DROP) { // slidings.Add(coord); // //sidings[coord] |= SIDE_DIR[i]; // } else if(mode == DropMode.STUCK) { // // 记录两侧 // stuck++; // } // } // // 记录hopelsess // if(stuck == 2) { // // 回溯最大范围的标记hopeless?? // if(cell.SetHopeless()) { // hopeless = true; // } // } else { // // 等待slide // waitings.Add(cell); // } // break; //case DropMode.WAIT: //// 等待下次尝试 //nextCells.Add(cell); //break; } } // 处理两侧掉落 while(slidings.Count > 0) { var cell = slidings.Pop(); if (cell.IsHopeless) { continue; } // 非空位置,不能掉落 if (cell.IsEmpty) { continue; } // 已经掉落过了 if (cell.drop == turn) { continue; } // 优先尝试预定方向,每次交换一个方向 for (var i = 0; i < 2; i++) { var idx = (i + cell.bias) % 2; var testCoord = cell.coord + (SIDE_DIR[idx] | Direction.BOTTOM); if (!IsInside(testCoord)) { continue; } var testCell = GetCell(testCoord); // 校验目标,TODO:gen if (testCell == null || !testCell.IsEmpty) { continue; } // 可以滑落 DropOne(dropMap, turn, false, cell, testCell); hasDrop = true; // swap bias cell.bias = (idx + 1) % 2; // 产生新的空格子,尝试竖着掉落 var top = mPortol.GetTop(cell.coord); var mode = GetDropMode(top, turn); if(mode == DropMode.DROP) { DropLine(emptyCells, dropMap, turn, cell, top); } else { emptyCells.Push(cell); } //emptyCells.Push(cell); break; } } //foreach(var coord in slidings) { // var cell = GetCell(coord); // if(cell.IsHopeless) { // continue; // } // // 非空位置,不能掉落 // if(cell.IsEmpty) { // continue; // } // // 已经掉落过了 // if(cell.drop == turn) { // continue; // } // // 优先尝试预定方向,每次交换一个方向 // for (var i = 0; i < 2; i++) { // var idx = (i + cell.bias) % 2; // var testCoord = coord + (SIDE_DIR[idx] | Direction.BOTTOM); // if(!IsInside(testCoord)) { // continue; // } // var testCell = GetCell(testCoord); // // 校验目标,TODO:gen // if(!testCell.IsEmpty) { // continue; // } // // 可以滑落 // DropOne(dropMap, turn, false, cell, testCell); // hasDrop = true; // // swap bias // cell.bias = (idx + 1) % 2; // // 产生新的空格子,竖着掉落 // //emptyCells.Push(cell); // break; // } //} // 没有滑落成功的,等待下一次掉落 foreach(var cell in waitings) { if(!cell.IsHopeless && cell.IsEmpty) { nextCells.Add(cell); } } slidings.Clear(); waitings.Clear(); // 需要重新计算一次 //if(emptyCells.Count == 0 && hopeless) { // hopeless = false; // foreach (var c in nextCells) { // emptyCells.Push(c); // } // nextCells.Clear(); //} } foreach(var c in nextCells) { emptyCells.Push(c); } return hasDrop; }