//targetがchildになりうるか調べて、 //childになれるなら追加してtrue。 //ならないなら何もせずfalse。 public bool ScanAsChild( BlockGroup target ){ var bs = target.Blocks; for(int i = 0, l = Blocks.Count; i < l; i++) if( bs.IndexOf( Blocks[i] ) == -1 ) return false; for(int i = 0, l = Blocks.Count; i < l; i++){ var index = bs.IndexOf( Blocks[i] ); var b = bs[index]; bs[ index ] = bs[ i ]; bs[ i ] = b; } if( Children == null ) Children = new List<BlockGroup>(); Children.Add( target ); return true; }
private bool AddBrokenGroup( AnalizeData result, BlockGroup g ){ if( g.Broken ) return false; g.Broken = true; foreach( var b in g.Blocks ) b.GroundNG = true; return AddBroken(result); }
// //Trueを返した場合、中断して十分に低いスコアを返す private bool CheckSolidGroup( AnalizeData result, BlockGroup g, bool first, int pos, int sum, ModelBlock empty = null, int emptyCount = 0 ){ if( g.Counter != AnalizeCounter ){ g.Reset(); g.Counter = AnalizeCounter; }else if( g.Broken || g.Success ) return false; var blocks = g.Blocks; for( int l = blocks.Count, max = l + 1; pos < l; pos++ ){ var b = blocks[pos]; if( b.Number > 0 ) sum += b.Number; else if( emptyCount++ == 0 ) empty = b; } if( sum > Sum - emptyCount ){ g.Success = true; //if( first ) result.Score += SolidScore * g.FamilyNum; return false; }else{ if( emptyCount == 0 ){ if( sum == Sum ){ if( AddBrokenGroup( result, g ) ) return true; return false; }else if( sum > Sum ){ g.Success = true; return false; //if( first ) result.Score += SolidScore * g.FamilyNum; } }else if( emptyCount == 1 ){ int bc = empty.LifeNum; int c = empty.KillAt( Sum - sum ); if( bc != c ){ if( c == 0 ){ if( AddBrokenBlock( result, empty ) ) return true; return false; }else{ Changed = true; if( c == 1 ){ empty.Number = Array.IndexOf( empty.DeadList, false ) + 1; sum += empty.Number; empty = null; emptyCount--; if( sum > Sum ){ g.Success = true; return false; } } } } } } var children = g.Children; if( children != null ) for( int i = 0, l = children.Count; i < l; i++ ) if( CheckSolidGroup( result, children[i], first, pos, sum, empty, emptyCount ) ) return true; return false; }
//連鎖の一部の数字チェック private bool CheckChainGroup( AnalizeData result, BlockGroup g, int num, bool first ){ if( g.Broken || g.Success ) return false; List<ModelBlock> emptys = new List<ModelBlock>(); var emptyCount = 0; int sum = 0; SegAdded = false; for( int j = g.Blocks.Count - 1; j >= 0; j-- ){ var b = g.Blocks[j]; if( b.Number > 0 ){ int bn = b.Number; sum += bn; if( bn > Sum ) if( AddBrokenBlock( result, b ) ) return true; if( sum + j + emptyCount > Sum ){ if( AddBrokenGroup( result, g ) ) return true; return false; } }else{ emptyCount++; emptys.Add( b ); } } if( emptyCount == 0 ){ if( sum == Sum ){ g.Success = true; if( first ){ int d = 4 + num; if( d > 40 ) d = 40; result.Score += BingoScore * g.Blocks[0].ScoreRate * 40 / d; result.BingoCount++; SegCount++; SegAdded = true; } }else{ if( AddBrokenGroup( result, g ) ) return true; } }else{ if( first ){ int d = 4 + num; if( d > 40 ) d = 40; result.Score += (g.Blocks.Count - emptyCount) * LizhiScore * g.Blocks[0].ScoreRate * 40 / d; } if( emptyCount == 1 ){ emptys[0].Number = Sum - sum; g.Success = true; }else if( emptyCount == 2 && !first ){ //片方の候補の消去を、もう片方に反映。 int max = Sum - sum - 1; if(emptys[0].LifeNum < max || emptys[1].LifeNum < max){ var e0 = emptys[0]; var e1 = emptys[1]; var d0 = e0.DeadList; var d1 = e1.DeadList; for( int i = 0; i < max; i++ ){ if( d0[i] == true ) e1.KillAt( max - i ); if( d1[i] == true ) e0.KillAt( max - i ); } int c = e0.LifeNum; if( c == 0 ){ if( AddBrokenBlock( result, e0 ) ) return true; if( AddBrokenBlock( result, e1 ) ) return true; g.Broken = true; }else if( c == 1 ){ e0.Number = Array.IndexOf( e0.DeadList, false ) + 1; e1.Number = Array.IndexOf( e1.DeadList, false ) + 1; g.Success = true; } } } } return false; }