/// <summary>
 ///
 /// </summary>
 /// <param name="devalgo"></param>
 /// <param name="s"></param>
 public SearchPlan(DevelopmentAlgorithm devalgo, Station s)
 {
     target = s;
     dev    = devalgo;
     phase  = Phase.Start;
     Update();
 }
        /// <summary>
        ///
        /// </summary>
        public void Process()
        {
            if (vie <= 0)
            {
                return;
            }
            vie--;
            switch (phase)
            {
            case Phase.Start:
            {
                if (strength <= 0)
                {
                    break;
                }
                Clock c = WorldDefinition.World.Clock;
                if (c.hour < vie)
                {
                    scaning = pickPlace(4);
                }
                if (scaning != Location.Unplaced && WorldDefinition.World.IsInsideWorld(scaning))
                {
                    phase++;
                }
                else
                {
                    strength += strength * (1 - F_StrDiffuse) / 7;
                }
            }
            break;

            case Phase.SelectStruct1:
            {
                Debug.Assert(WorldDefinition.World.IsInsideWorld(scaning));
                int minVal = (int)(WorldDefinition.World.LandValue[scaning] * F_LandPriceScale);
                int maxVal = Math.Max(minVal + 15, (int)(minVal * 1.2));
                //maxVal = Math.Max(maxVal,(int)Math.Pow(strength,F_MaxPricePower));
                Debug.WriteLine(string.Format("target price: {0} to {1}", minVal, maxVal), "devalgo");
                work[0] = DevelopmentAlgorithm.FindFirstIndexOf(DevelopmentAlgorithm.structs, minVal);
                work[1] = DevelopmentAlgorithm.FindLastIndexOf(DevelopmentAlgorithm.structs, maxVal);
                work[2] = DevelopmentAlgorithm.FindFirstIndexOf(DevelopmentAlgorithm.vhStructs, minVal);
                work[3] = DevelopmentAlgorithm.FindLastIndexOf(DevelopmentAlgorithm.vhStructs, maxVal);
                phase++;
            }
            break;

            case Phase.SelectStruct2:
            {
                int n1 = work[1] - work[0];
                int n2 = work[3] - work[2];
                int n  = n1 + n2;
                if (n <= 0)
                {
                    phase = Phase.End;
                    return;
                }
                int r;
                do
                {
                    r = rnd.Next(n);
                } while (r == n);
                IEntityBuilder entity;
                if (r < n1)
                {
                    entity = DevelopmentAlgorithm.structs[work[0] + r] as IEntityBuilder;
                }
                else if (r - n1 < work[3])         //check upper bounds
                {
                    entity = DevelopmentAlgorithm.vhStructs[work[2] + r - n1] as IEntityBuilder;
                }
                else
                {
                    break;         //retry
                }
                plan = GetPlan(entity);
                if (plan != null)
                {
                    phase++;
                }
                else
                {
                    phase = Phase.End;
                }
            }
            break;

            case Phase.FitPlace:
            {
                //bool OK = true;

                if (WorldDefinition.World.IsOutsideWorld(plan.cube) || !plan.cube.IsOnGround)
                {
                    phase = Phase.Start;
                    break;
                }
                IEntity[] es = plan.cube.GetEntities();
                foreach (IEntity e in es)
                {
                    if (!IsReplaceable(e, WorldDefinition.World.LandValue[scaning]))
                    {
                        strength += (int)Math.Pow(plan.value, 1.0 / F_MaxPricePower);
                        phase     = Phase.Start;
                        return;
                    }
                }
                foreach (IEntity e in es)
                {
                    e.remove();
                }
                phase++;
                // 用地確保と建設の間があくと、入れ違いで他のプランが建設される可能性あり
                //				}
                //					break;
                //				case Phase.Build:{
                plan.build();
                Debug.Write("building reduces strength " + strength);
                double p = Math.Pow((double)finalPrice, 1.0 / F_MaxPricePower);
                strength -= Math.Min(p, strength);
                Debug.WriteLine("-> " + strength);
                phase++;
            }
            break;

            case Phase.End:
            {
                phase = Phase.Start;
            }
            break;
            }
        }