public BotResponse GetResponse(TimeSpan time)
		{
			if (TableCount != Table.Count)
			{
				Own.Odds = null;
				TableCount = Table.Count;
			}
			if (!Own.Odds.HasValue)
			{
				Own.Odds = PokerHandEvaluator.GetOdds(Hand, Table);
			}

			var state = new ActorState()
			{
				Round = Current.Round,
				SubRound = Current.SubRound,
				Step = 1 + Own.Actions.Count,
				BigBlind = Matches.Current.BigBlind,
				Odds = Own.Odds.Value,
				OwnStack = Own.Stack,
				OwnPot = Own.Pot,
				OtherStack = Other.Stack,
				OtherPot = Other.Pot,
			};

			var option = Actor.GetOption(state);

			var response = new BotResponse()
			{
				Action = option.Action,
				Log = GetLog(state, option),
			};
			return response;
		}
		public ActionOption GetOption(ActorState state)
		{
			if (state.AmountToCall == state.SmallBlind && state.Odds > 0.52)
			{
				return new ActionOption(GameAction.Call, state.AmountToCall * (state.Odds - 0.5));
			}

			var options = new ActionOptions();

			if (state.NoAmountToCall)
			{
				options.Add(new ActionOption(GameAction.Check, state.Odds * state.Pot, 1));
			}
			else
			{
				options.Add(GameAction.Call);
			}
			if (state.AmountToCall != state.SmallBlind)
			{
				var step = 1 + ((state.MaximumRaise - state.BigBlind) >> 4);

				for (var raise = state.BigBlind; raise <= state.MaximumRaise; raise += step)
				{
					options.Add(GameAction.Raise(raise));
				}
			}
			// Only add a fold if we have to call, and there is a change that we 
			// can play a next round.
			if (!state.NoAmountToCall && state.OtherPot >= state.BigBlind)
			{
				options.Add(GameAction.Fold);
			}

			Node test = state.ToNode();
			options.Sort(test, Nodes);

			var best = SelectOption(options);

			if (best.Action != GameAction.Fold)
			{
				if (best.Action != GameAction.Check)
				{
					test.Profit = (short)state.OwnPot;
					test.Action = best.Action;
					test.IsNew = true;
					Buffer.Add(test);
				}
			}
			else if(options.Count > 1)
			{
				best = new ActionOption(GameAction.Fold, options[1].Profit, options[1].Weight);
			}
			return best;
		}
		private string GetLog(ActorState state, ActionOption best)
		{
			var log = new StringBuilder();
			
			log.AppendFormat("{0:00}.{1,-5}", Current.Round, Current.SubRound)
				.Append(' ').Append(Hand);
			
			if (Current.SubRound != SubRoundType.Pre)
			{
				log.AppendFormat(", {0}", Table);
			}
			
			log.AppendFormat(", {0:0.0%}", state.Odds)
				.Append(", ")
				.Append(best.Action)
				.Append(" ")
				.Append(best.Profit > 0 ? "+" : "")
				.Append(best.Profit.ToString("#,##0.0"));

			return log.ToString();
		}
		private static void TestSelect(IEnumerable<double> odds, ActorState state)
		{
			var sw = Stopwatch.StartNew();

			foreach (var odd in odds)
			{
				var st = new ActorState()
				{
					BigBlind = state.BigBlind,
					Odds = odd,
					OwnPot = state.OwnPot,
					OtherPot = state.OtherPot,
					OwnStack = state.OwnStack,
					OtherStack = state.OtherStack,
					Round = state.Round,
					Step = state.Step,
					SubRound = state.SubRound,
				};

				var option = Act.GetOption(st);
				Console.WriteLine("{0:00.0%} {1}", odd, option);
			}
			Console.WriteLine(sw.Elapsed);
		}