Пример #1
0
		//パターンを配置
		public void SetPattern( ModelBlock[][] model, Pattern pattern, int chain, int x, int y, int dir ){
			object[,] data = pattern.Data;
			for( int i = 0; i < pattern.Width; i++ ){
				for( int j = 0; j < pattern.Height; j++ ){
					object cell 	= data[j,i];
					int mx		= x + i * dir;
					int my		= y + pattern.Height - j - 1;
					
					if( cell is int ){
						int num = chain + (int)cell;
						model[mx][my] = new ModelBlock(IDCount++, mx, my, num, num, false, pattern.ScoreRate);
					}else if( cell == ChainConfig.E ){
						model[mx][my] = new ModelBlock(IDCount++, mx, my, -1, int.MaxValue, true, 1, 0 );
					}else if( cell is int[] ){
						int[] nums = cell as int[];
						model[mx][my] = new ModelBlock(IDCount++, mx, my, nums[0], nums[2], false, 1, nums[1]);
					}else{
						if( model[mx][my] == null ){
							model[mx][my] = new ModelBlock(IDCount++, mx, my, -1, int.MaxValue, false, pattern.ScoreRate);
						}else{
							if( model[mx][my].ScoreRate < pattern.ScoreRate ) 
								model[mx][my].ScoreRate = pattern.ScoreRate;
						}
					}
				}
			}
		}
Пример #2
0
		//足場の保存期間を指定、ブロックの空きを埋める。
		public void SetupModel( ModelBlock[][] model, Game game, int bottom ){
			for( int i = 0, w = model.Length; i < w; i++ ){
				int min = int.MaxValue;
				for( int j = model[i].Length - 1; j >= 0; j--){
					if( model[i][j] == null ){
						if( j < bottom && game.Field[i][j] > Game.Sum )	
							model[i][j] = new ModelBlock(IDCount++, i, j, -1, min, false, 1, game.Field[i][j] );
						else								
							model[i][j] = new ModelBlock(IDCount++, i, j, -1, min);
					
						continue;
					}
					var block = model[i][j];
					if( block.Chain >= 0 )				if( min > block.Chain ) min = block.Chain;
					if( block.Ground == int.MaxValue ) 	block.Ground = min;
				}
			}
		}
Пример #3
0
		public ChainModel( Game game, ChainFactory factory, int chainLimit, bool haiteiMode, ModelSetting setting ){
			setting.Setup( this );
			
			Width 			= Game.Width;
			Height 			= Game.Height + Game.Size;
			Sum				= Game.Sum;
			ChainLimit		= chainLimit;
			HaiteiMode		= haiteiMode;
			
			AllBlocks 			= new List<ModelBlock>();
			ChainGroups		= new List<BlockGroup>();
			SolidGroups		= new List<BlockGroup>[Sum - 1];
			for(int i = 0; i < (Sum - 1); i++) 	SolidGroups[i] = new List<BlockGroup>();
			
			Model = new ModelBlock[Width][];
			for(int i = 0; i < Width; i++)
				Model[i] = new ModelBlock[Height];
			
			factory.Make( this, game, ChainLimit );
			
			for(int i = 0; i < ChainLimit; i++) ChainGroups.Add( new BlockGroup( new List<ModelBlock>() ) );
			
			SetupGroup( game );
			Reset( game );
		}
Пример #4
0
		/*
		private void SimulateChain(Game game, AnalizeData result, bool outon){
			Output = "";
			
			//ChainBlocksの位置にあるブロックを後ろから消していき、
			//発生した連鎖数を数える。
			for(int i = ChainLimit - 1; i >= 0; ){
				if( outon ) { Output += ModelOutput(Model,game); }
				i = DeleteChain( game, result, i );
			}
			
			//result.Score += result.Chain 		* ChainScore;
		}
		
		
		
		//ゲーム状態の変化に連鎖モデルの変化を同期させる。
		private int DeleteChain( Game game, AnalizeData result, int headNum ){
			List<ModelBlock> delete = ChainGroups[headNum].Blocks;
			var Field 			= game.Field;
			var HeightList 		= game.HeightList;
			
			//消去位置をマーク
			int count = 0, l = delete.Count, sum = 0;
			for(int i = 0; i < l; i++){
				ModelBlock b = delete[i];
				if( b == null || b.Dead ){ continue; }
				var val = Field[b.X][b.Y];
				if( val == 0 ) continue;
				
				sum += val;
				Field[b.X][b.Y] 	|= 0x800000;	
				game.Marked[b.X] 	= true;
			}
			
			if( sum != Game.Sum ){
				for(int i = 0; i < l; i++){
					ModelBlock b = delete[i];
					sum += Field[b.X][b.Y];
				}
			}
			
			bool 	perfect = true;
			int 	chain 	= 0;
			int 	num 	= headNum;
			int		next 	= headNum - 1;
			
			Output += "start:" + headNum + "\n";
			
			game.ChangedLeft 	= 0;
			game.ChangedRight	= Game.Width;
			game.ChangedBottom	= 0;
			game.ChangedTop 	= Game.Height + Game.Size;
			
			//連鎖を見る
			do{
				Output += "count:" + count + "\n";
			
				chain++;
				int hitNum	= 0;
				
				//目印を付けた部分を削除
				for(int i = 0, il = Width; i < il; i++){
					if(! game.Marked[i] ){ 
						game.Marked[i] = false;
						continue;
					}
					
					var row 	= Field[i];
					var mr		= Model[i];
					int h 		= HeightList[i];
					int k 		= 0;
					
					for(int j = 0; j < h; j++ ){
						int	val = row[j];
						if( j != k ){
							row[k] = val;
							var b = mr[k] = mr[j];
							if( b != null ){ b.Y = k; }
						}
						if( (val & 0x800000) == 0 ) k++;
						else{
							var b = mr[j];
							if( b != null ){
								b.Dead = true;
								if( b.Chain == num ){ hitNum++; }
							}
						}
					}
					
					for(; k < Height; k++){
						row[k] 	= 0; mr[k] 	= null;
					}
				}
				
				Output += "num:" + num + "\n";
				
				if( perfect && num != headNum && num >= 0 ){
					if( hitNum != ChainGroups[num].Blocks.Count ){
						perfect = false;
						next = num - 1;
						if( headNum - num > 1 ){
							result.ChainSegs.Add( headNum - num - 1 );
						}
					}
				}
				
				num--;
				
				//新しい消去フラグを探す。
				count = game.Mark();
			}while( count > 0 );
			
			if( perfect ){
				next = num;
				if( headNum - num > 1 )	result.ChainSegs.Add( headNum - num - 1 );
				if( num < 0 ) 			result.Chain = headNum;
			}
			
			return next;
		}
		*/
		
		//
		public string ModelOutput( ModelBlock[][] model, Game game ){
			string result = "";
			for(int i = Height - 1; i >= 0; i--){
				for(int j = 0; j < Width; j++){
					var b = game.Field[j][i];
					result +=( " " + b.ToString( "D2" ) );
				}
				result +=( "\n" );
			}
			result +=( "\n" );
			
			for(int i = Height - 1; i >= 0; i--){
				for(int j = 0; j < Width; j++){
					var b = model[j][i];
					if( b == null )					result +=( " Nul" );
					else if( b.Chain >= 0 )			result +=( " C" + b.Chain.ToString( "D2" ) );
					else if( b.MustNumber >= 0 )	result +=( " M" + b.MustNumber.ToString( "D2" ) );
					else if( b.Ground != int.MaxValue )	
													result +=( " G" + b.Ground.ToString( "D2" ) );
					else						result +=( " Xxx" );
				}
				result +=( "\n" );
			}
			return result + "\n";
		}
Пример #5
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;
		}
Пример #6
0
		private bool AddBrokenBlock( AnalizeData result, ModelBlock b ){
			if( b.Broken ) 	return false;
			b.GroundNG = b.Broken 	 = true;
			return AddBroken(result);
		}
Пример #7
0
		//海底用に発火ブロックの数字をそろえる
		public void SetHeadNumber( Game game, ModelBlock fire, ModelBlock fired ){
			int max = 0;
			var block = Game.DefaultBlocks[ Game.StepNum - 1 ];
			for( int x = 0; x < Game.Size; x++ ){
				for( int y = 0; y < Game.Size; y++ ){
					var d = block.Data[x,y];
					if( d > max && d < Sum ) max = d;
				}
			}
			
			if( max > 0 ){
				fire.MustNumber		= max;
				fired.MustNumber 	= Sum - max;
				MustBlocks.Add( fired );
			}
		}