Esempio n. 1
0
		private void FixedAttack(){
			var data = Model.Analize( Target.Clone() );
			
			Output += Target.CurrentStep + ":\n" + data.BrokenCount;
			Output += "\n" + data.Score;
			
			Output += "\n" + data.MaxChain;
			Output += "\n" + data.Chain;
			Output += "\n" + string.Join(",", data.ChainSegs.Select(s => s.ToString()).ToArray());
			Output += "\n" + data.BingoCount +"/"+ Model.BingoMax;
			
			if( 
			   	(Game.DefaultBlocks.Length - Target.CurrentStep < FixedLimit && data.BingoCount == Model.BingoMax && !HaiteiMode) || 
			   	Game.DefaultBlocks.Length - Target.CurrentStep < 25
			   		){
				FixedMode = false;
				FinishFix = Target.Clone();
				Attack();
				return;
			}
			
			var futures	= new List<Future>();
			Block 	b 		= Game.DefaultBlocks[ Target.CurrentStep ];
			int 	w 		= Game.Width - Game.Size + 1;
			int		rest 	= Game.DefaultBlocks.Length - Target.CurrentStep - 1;
			int		depth 	= FixedDepth < rest ? FixedDepth : rest;
			
			for(int i = 0; i < Game.ROTATE_NUM; i++){
				for(int j = -b.Left[i], jl = w + b.Right[i]; j < jl; j++){
					Game clone = Target.Clone();
					clone.Next(j,i);
					if( clone.GameOver ) continue;
					data = Model.Analize( clone.Clone() );
					var move = new Move(j, i);
					futures.Add( new Future( move, clone, data.Score ) );
				}
			}
			
			futures = FixedReadFutures( futures, depth );
			
			if( futures.Count == 0 ){
				FixedMode = false;
				FinishFix = Target.Clone();
				Attack();
			}else{
				futures.Sort();
				var move = futures[0].Root;
				Output += "\n" + futures[0].Potaintial;
				Drop( move.Position, move.Rotate );
			}
		}
Esempio n. 2
0
		public Future( Move root, Game target, double potaintial ){
			Root = root; Target = target; Potaintial = potaintial;
		}
Esempio n. 3
0
		//評点
		private double CalcPotaintial( Game game, Move move, int depth ){
			double 	max = double.MinValue;
			Block 	b = Game.DefaultBlocks[ game.CurrentStep ];
			int 	w = Game.Width - Game.Size + 1;
			
			//次のブロックを落下させてみる。
			for(int i = 0; i < Game.ROTATE_NUM; i++ ){
				for(int j = -b.Left[i], jl = w + b.Right[i]; j < jl; j++){
					Game clone 			=  game.Clone();
					clone.Next(j,i);
					
					if( clone.GameOver ) continue;
					double score = clone.Score - game.Score;
					if( max < score ){ max = score; }
				}
			}
			
			if( ChainMaxScore <= max ){ 
				ChainMaxScore 	= max;
				ChainMove 		= move;
			}
			
			if( depth <= 1 ) return max;
			
			int h0 = 0, h1 = 0, h2 = game.HeightList[0];
			var cl = CheckList[ game.CurrentStep ];
			int end = (Game.Sum-1);
			
			//連鎖テスト用のブロックを落下させてみる。
			for( int x = 0; x < Game.Width; x++ ){
				h0 = h1; h1 = h2;
				if( x + 1 < Game.Width )	h2 = game.HeightList[ x + 1 ];
				else						h2 = 0;
				
				for( int i = 0; i < CheckHeight; i++ ){
					if( h0 <= h1 + i * HeightSpan && h2 <= h1 + i * HeightSpan ) break;
					
					for( int j = 0; j < end; j++ ){
						if(! cl[ j ] ) continue;
						Game clone = game.Clone();
						clone.Drop( CheckBlocks[i,j], x, 1, 0 );
						clone.Kill();
						
						if( clone.GameOver || clone.LastChain == 0 ) continue;
						double score = (clone.Score - game.Score);
						if( max < score ) max = score;
					}
				}
			}
			return max;
		}
Esempio n. 4
0
		//先読みする手を足切り点付きで枝刈り、残りの手が1種類になったら、True。
		protected static bool Prune( List<Future> futures, Move currentMove, int width, double minScore ){
			futures.Sort();
			
			int l = futures.Count;
			
			if( l > width ){
				futures.RemoveRange( width, l - width );
				l = width;
			}
			
			for( int i = 0; i < l; i++ )
				if( futures[i].Potaintial < minScore ){
					futures.RemoveRange(i, l - i);
					l = i;
					break;
				}
			
			for( int i = 0; i < l; i++ )
				if( currentMove != futures[i].Root ) return false;
				
			return true;
		}
Esempio n. 5
0
		//不定型連鎖を組む。
		public void Attack(){
			var 	futures		= new List<Future>();
			Block 	b 			= Game.DefaultBlocks[ Target.CurrentStep ];
			int 	w 			= Game.Width - Game.Size + 1;
			int		rest 		= Game.DefaultBlocks.Length 	- Target.CurrentStep - 1;
			int		depth 		= Depth < rest ? Depth : rest;
			double	baseScore	= Target.Score;
			FireMax = ChainMaxScore = double.MinValue;
			
			for(int i = 0; i < Game.ROTATE_NUM; i++)
				for(int j = -b.Left[i], jl = w + b.Right[i]; j < jl; j++){
					Game clone = Target.Clone();
					clone.Next(j,i);
					if(! clone.GameOver ){
						double score 	= clone.Score - baseScore;
						var move 	= new Move( j, i, score );
						
						if( FireMax <= score ){
							FireMax		= score;
							FireMove 	= move;
						}
						
						if( depth > 0 ) futures.Add( new Future( move, clone, CalcPotaintial(clone, move, depth) ) );
					}
				}
			
			if( futures.Count == 0 ){
				Fire();
				return;
			}
			ReadFuture( futures, depth - 1 );
			
			if( FireMax * FireRate > ChainMaxScore )	Fire();
			else										ChainUp();
		}