public byte GetMove(Field field, TimeSpan min, TimeSpan max)
		{
			byte ply = (byte)(field.Count + 1);
			if (depth <= ply) { depth = (byte)(ply + 1); }
			var redToMove = (ply & 1) == 1;

			if (depth > MaximumDepth) { depth = MaximumDepth; }

			Sw.Restart();
			Logger.Clear();
			Max = max;

			var candidates = new MoveCandidates(redToMove);
			candidates.Add(field, ply, this);
			var move = candidates.GetMove();
			
			Root = GetNode(field, ply);
			Root.Add(candidates);

			for (/**/; depth <= MaximumDepth; depth++)
			{
				Root.Apply(depth, this, Scores.InitialAlpha, Scores.InitialBeta);

				move = candidates.GetMove();

				var log = new PlyLog(ply, move, Root.Score, depth, Sw.Elapsed);
				Logger.Append(log).AppendLine();

				// Don't spoil time.
				if (Sw.Elapsed > min || !TimeLeft) { break; }
			}
			return move;
		}
		public override void Add(MoveCandidates candidates)
		{
			// Just set.
			Children = new ISearchTreeNode[7];
			foreach(var candidate in candidates)
			{
				Children[Count++]=candidate.Node;
			}
		}
		public void Add(MoveCandidates candidates) { throw new NotImplementedException(); }
		public abstract void Add(MoveCandidates candidates);