Пример #1
0
		private bool AddBroken( AnalizeData result, int rate = 1 ){
			result.Score += BrokenScore * 1;
			result.BrokenCount++;
			if( result.BrokenCount > BrokenLimit ) return true;
			return false;
		}
Пример #2
0
		//
		//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;
		}
Пример #3
0
		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);
		}
Пример #4
0
		private bool AddBrokenBlock( AnalizeData result, ModelBlock b ){
			if( b.Broken ) 	return false;
			b.GroundNG = b.Broken 	 = true;
			return AddBroken(result);
		}
Пример #5
0
		//連鎖の一部の数字チェック
		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;
		}
Пример #6
0
		//連鎖の進行度計算
		public void CalcScore( Game game, AnalizeData result ){
			AnalizeCounter++;
			Changed = false;
				
			//空領域を確認
			foreach( ModelBlock b in MustBlocks )
				if( b.MustNumber == b.Number){
					if( b.End && b.Number != 0 ) 	AddBrokenBlock( result, b );
					else{
						result.Score += BingoScore * b.ScoreRate * 8;
						result.BingoCount++;
					}
				}else{
					if( b.Number != 0 ){
						if( b.Number > Sum )	AddBrokenBlock( result, b );
						else{
							result.Score 	+= GroundNGScore;
							b.GroundNG 		 = true;
						}
					}
					b.Number = b.MustNumber;
				}
			
			
			foreach( ModelBlock b in CeilBlocks )
				if( b.Number != 0 )
					if(b.Number > Sum)	result.Score += CeilScore * 4;
					else				result.Score += CeilScore;
			
			
			foreach( ModelBlock b in GroundBlocks )
				if( b.Number > Sum ){	
					result.Score += GroundScore * b.ScoreRate;
					result.Score += (Height - b.Y) * GroundHScore;
				}else if(b.Number != 0){
					result.Score += GroundNGScore;
					b.GroundNG = true;
				}else{
					b.Number = Sum + 1;
				}
			
			SegCount = 0;
			var first = true;
			int count = 0;
			
			do{
				Changed = false;
				for(int i = 0, l = ChainGroups.Count; i < l; i++){
					if( CheckChainGroup( result, ChainGroups[i], i, first ) )	return;
					if( first && !SegAdded && SegCount > 0 ){
						result.ChainSegs.Add( SegCount );
						SegCount = 0;
					}
				}
				
				for( int i = 0, il = RootSolidGroups.Count; i < il; i++ )
					if( CheckSolidGroup( result, RootSolidGroups[i], first, 0, 0 ) ) 	return;
				
				first = false;
			}while( Changed || count++ < 2 );
			
			
			//間違ったブロックの上に邪魔ブロックを置かない
			for( int i = 0; i < Width; i++ ){
				double c = 0;
				var row = Model[i];
				for( int j = Bottom; j < Height; j++ ){
					var b = row[j];
					if( c > 0 ){
						var n = game.Field[i][j];
						if( n > Sum ){
							result.Score += BrokenScore * c;
						}else{
							result.Score += GroundNGScore * c;
						}
					}
					if( b.GroundNG ) 	c += b.ScoreRate;
				}
			}
			
			
		}
Пример #7
0
		//連鎖の状態を分析する。
		public AnalizeData Analize( Game game, bool outon = false ){
			AnalizeData			result			= new AnalizeData();
			Reset( game );
			CalcScore( game, result );
			//SimulateChain( game, result, outon );
			
			result.Score += result.MaxChain 	* MaxChainScore;
			
			foreach( int c in result.ChainSegs )
				result.Score += (c - 1) * ChainScore;
			
			return result;
		}