Advertisement
Guest User

Untitled

a guest
Mar 21st, 2018
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 26.75 KB | None | 0 0
  1. using System;
  2. using System.Diagnostics;
  3. using PioViewer.Util.Debug;
  4.  
  5. namespace PioViewer.Solver.SolverObjects
  6. {
  7. public class Game
  8. {
  9. public int Dead;
  10. public int[] Invested = new int[2];
  11. public int ToAct;
  12. public bool AtLeastOneRaiseHasHappened;
  13. public int NumberOfBetsThisStreet;
  14.  
  15. private int _round;
  16. public int Round
  17. {
  18. get
  19. {
  20. return _round;
  21. }
  22. set
  23. {
  24. if (value < 3 || value > 6)
  25. {
  26. throw new DebugException("Board nedds to have 3 to 5 cards. Was " + value);
  27. }
  28. _round = value;
  29. }
  30. }
  31.  
  32. /// <summary>
  33. /// Starting effective stacks
  34. /// </summary>
  35. public int EffectiveStacks { get; set; }
  36.  
  37. private int _maxInvestedPreflop;
  38.  
  39. public int PostflopEffectiveStacks => EffectiveStacks - _maxInvestedPreflop;
  40.  
  41. public int PostflopCurrentInvested
  42. {
  43. get
  44. {
  45. var investedPreflop = EffectiveStacks - PostflopEffectiveStacks;
  46. return CurrentInvested - investedPreflop;
  47. }
  48. }
  49.  
  50. //Who was the last aggressor on the given street. The indexes for 0,1,2 are useless :)
  51. //We set the aggressor for all the rounds before the game started to IP player
  52. //so that the first bet of the tree can be treated as a donk-bet
  53. public int[] StreetAggressor = new int[6];
  54.  
  55. public void Start(SolverPlayer previousStreetAggressor)
  56. {
  57. StreetAggressor = new[] { -1, -1, -1, -1, -1, -1 };
  58. for (int i = 0; i < Round; i++)
  59. {
  60. StreetAggressor[i] = previousStreetAggressor?.Index ?? -1;
  61. }
  62. }
  63.  
  64. /// <summary>
  65. /// This is deepness after call if there is something to call.
  66. /// </summary>
  67. public float Deepness
  68. {
  69. get
  70. {
  71. var pot = Dead + 2 * CurrentInvested;
  72. var stack = EffectiveStacks - CurrentInvested;
  73. return stack * 1.0f / pot;
  74. }
  75. }
  76.  
  77. public int CurrentInvested
  78. {
  79. get
  80. {
  81. int max = Math.Max(Invested[0], Invested[1]);
  82. int other = Invested[1 - ToAct];
  83. if (max != other)
  84. {
  85. throw new DebugException("Incorrect money invested values.");
  86. }
  87. return max;
  88. }
  89. }
  90.  
  91. public Game Copy()
  92. {
  93. Game result = (Game)this.MemberwiseClone();
  94. result.Invested = new[] { this.Invested[0], this.Invested[1] };
  95. result.StreetAggressor = new[] { -1, -1, -1, this.StreetAggressor[3], this.StreetAggressor[4], this.StreetAggressor[5] };
  96. return result;
  97. }
  98.  
  99. public Game CheckCall()
  100. {
  101. if (!CanAct)
  102. {
  103. throw new DebugException("Betting forbidden after showdown");
  104. }
  105. var g = this.Copy();
  106. g.SetInvested(ToAct, g.Invested[1 - ToAct]);
  107.  
  108. if (ToAct != 0 || Invested[0] != Invested[1]) //unless OOP and first check - new round
  109. {
  110. g.NumberOfBetsThisStreet = 0;
  111. g.Round++;
  112. g.ToAct = 0;
  113. }
  114. else
  115. {
  116. g.ToAct = 1 - g.ToAct;
  117. }
  118. return g;
  119. }
  120.  
  121. /// <summary>
  122. /// Returns information on how big (in terms of the potsize) would an allin be
  123. /// </summary>
  124. public float GetAllinSizeInPercent()
  125. {
  126. int invested = Invested[1 - ToAct];
  127. int totalPotAfterCall = Dead + 2 * invested;
  128. int effectiveStack = EffectiveStacks - invested;
  129. return effectiveStack * 100f / totalPotAfterCall;
  130. }
  131.  
  132. public bool CanAct => Round != 6;
  133.  
  134. public Game Raise(string actionString)
  135. {
  136. if (!CanAct)
  137. {
  138. throw new TooLongLineException("Betting forbidden after showdown");
  139. }
  140. int invested = Invested[1 - ToAct];
  141. int totalPotAfterCall = Dead + 2 * invested;
  142. int effectiveStack = EffectiveStacks - invested;
  143. int betSize;
  144.  
  145. if (actionString.Contains("a"))
  146. {
  147. betSize = EffectiveStacks;
  148. }
  149. else if (actionString.EndsWith("c"))
  150. {
  151. if (!int.TryParse(actionString.Substring(0, actionString.Length - 1), out int cappedSize))
  152. {
  153. throw new UserException("Incorrect betting expression '" + actionString + "'.");
  154. }
  155. betSize = cappedSize + invested;
  156. }
  157. else if (actionString.EndsWith("x"))
  158. {
  159. if (!float.TryParse(actionString.Substring(0, actionString.Length - 1), out float multiplier))
  160. {
  161. throw new UserException("Incorrect betting expression '" + actionString + "'.");
  162. }
  163. if (multiplier <= 1)
  164. {
  165. throw new UserException("Raise has to be bigger than 1x. Incorrect expression " + actionString);
  166. }
  167. if (this.Invested[0] == this.Invested[1])
  168. {
  169. throw new UserException(actionString + " only allowed for raises - not bets");
  170. }
  171. int difference = this.Invested[1 - ToAct] - this.Invested[ToAct];
  172. Debug.Assert(difference > 0);
  173. betSize = invested + (int)Math.Round(difference * (multiplier - 1));
  174. }
  175. else if (actionString.Contains("e"))
  176. {
  177. if (!int.TryParse(actionString.Substring(0, actionString.Length - 1), out int numberOfBets))
  178. {
  179. throw new UserException("Incorrect betting expression '" + actionString + "'.");
  180. }
  181. double multiplier = EvenBets(totalPotAfterCall, effectiveStack, numberOfBets);
  182. betSize = invested + (int)(totalPotAfterCall * multiplier);
  183. }
  184. else
  185. {
  186. if (!float.TryParse(actionString, out float percent))
  187. {
  188. throw new UserException("Incorrect betting expression '" + actionString + "'.");
  189. }
  190. betSize = invested + (int)Math.Round(totalPotAfterCall * percent / 100);
  191. }
  192. return Raise(betSize);
  193. }
  194.  
  195. public Game Raise(int betSize)
  196. {
  197. if (!CanAct)
  198. {
  199. throw new TooLongLineException("Betting forbidden after showdown");
  200. }
  201. var g = this.Copy();
  202. g.StreetAggressor[g.Round] = g.ToAct;
  203.  
  204. var minraise = 1;
  205.  
  206. if (this.Invested[0] != this.Invested[1])
  207. {
  208. g.AtLeastOneRaiseHasHappened = true;
  209. minraise = Math.Abs(this.Invested[0] - this.Invested[1]);
  210. }
  211.  
  212. g.NumberOfBetsThisStreet += 1;
  213.  
  214. if (betSize >= EffectiveStacks)
  215. {
  216. g.Round = 6;
  217. betSize = EffectiveStacks;
  218. }
  219. else if (betSize < g.Invested[1 - ToAct] + minraise)
  220. {
  221. betSize = Math.Min(g.Invested[1 - ToAct] + minraise, EffectiveStacks);
  222. }
  223.  
  224. g.SetInvested(ToAct, betSize);
  225. g.ToAct = 1 - g.ToAct;
  226. return g;
  227. }
  228.  
  229. private void SetInvested(int toAct, int investment)
  230. {
  231. this.Invested[toAct] = investment;
  232. if (Round == 0)
  233. {
  234. _maxInvestedPreflop = Math.Max(_maxInvestedPreflop, investment);
  235. }
  236. }
  237.  
  238. private static double EvenBets(int pot, int stack, int number_of_bets)
  239. {
  240. double depth = (2.0 * stack + pot) / pot;
  241. double mult = Math.Pow(depth, 1.0 / number_of_bets);
  242. return (mult - 1) / 2;
  243. }
  244. }
  245.  
  246. public class TooLongLineException : UserException
  247. {
  248. public TooLongLineException(string message)
  249. : base(message)
  250. {
  251. }
  252. }
  253. }
  254.  
  255. using System;
  256. using System.Collections.Generic;
  257. using System.Linq;
  258. using PioViewer.Solver.SolverObjects;
  259. using PioViewer.Util.Debug;
  260. using PioViewer.Util.TreeBuilding;
  261.  
  262. namespace PioViewer.Browser.TreeBuilding.V2
  263. {
  264. public class ActionBuildingUtilV2
  265. {
  266. private TreeBuildingDataV2LinesGenerationPart TreeData { get; set; }
  267.  
  268. private List<ActionLine> _lines = new List<ActionLine>();
  269. private HashSet<ActionLine> _removeLines = new HashSet<ActionLine>();
  270. private List<ActionLine> _forceLines = new List<ActionLine>();
  271.  
  272. private Game StartingGame { get; set; }
  273.  
  274. public static TreeGenerationLines GenerateLinesForPreflop(TreeBuildingDataV2LinesGenerationPart treeData, int[] pot,
  275. int effectiveStacks, SolverPlayer preflopAggressor)
  276. {
  277. Game g = new Game()
  278. {
  279. Dead = pot[2],
  280. Invested = new[] { pot[0], pot[1] },
  281. EffectiveStacks = effectiveStacks,
  282. Round = 3,
  283. };
  284. return GenerateLines(treeData, g, preflopAggressor);
  285. }
  286.  
  287. public static TreeGenerationLines GenerateLines(TreeBuildingDataV2LinesGenerationPart treeData)
  288. {
  289. Game g = new Game()
  290. {
  291. Dead = treeData.Pot,
  292. EffectiveStacks = treeData.EffectiveStacks,
  293. Round = treeData.Board.Length,
  294. };
  295. return GenerateLines(treeData, g, null);
  296. }
  297.  
  298. private static TreeGenerationLines GenerateLines(TreeBuildingDataV2LinesGenerationPart treeData, Game g,
  299. SolverPlayer preflopAggressor)
  300. {
  301. if (treeData == null)
  302. {
  303. return new TreeGenerationLines()
  304. {
  305. AddLines = new List<ActionLine>(),
  306. RemoveLines = new List<ActionLine>(),
  307. ForceLines = new List<ActionLine>()
  308. };
  309. }
  310.  
  311. var util = new ActionBuildingUtilV2()
  312. {
  313. TreeData = treeData
  314. };
  315. g.Start(preflopAggressor);
  316. util.StartingGame = g;
  317. util.GenerateLines(ActionLine.CreateRoot(g.CurrentInvested), g);
  318. util.GenerateForcingBet();
  319. util.AddExtraLines();
  320. util.RemoveLinesProvidedByUser();
  321.  
  322. util.AssertActionsMakeSense();
  323.  
  324. util.ClearDuplicatedLines();
  325.  
  326. return new TreeGenerationLines()
  327. {
  328. AddLines = util._lines,
  329. RemoveLines = util._removeLines.ToList(),
  330. ForceLines = util._forceLines
  331. };
  332. }
  333.  
  334. private void ClearDuplicatedLines()
  335. {
  336. var lines = _lines.ToArray();
  337. _lines = null;
  338. Array.Sort(lines);
  339. var result = new List<ActionLine>();
  340. for (int i = 0; i < lines.Length - 1; i++)
  341. {
  342. if (lines[i + 1].StartsWith(lines[i]))
  343. {
  344. //nothing
  345. }
  346. else
  347. {
  348. result.Add(lines[i]);
  349. }
  350. }
  351. result.Add(lines[lines.Length - 1]);
  352. _lines = result;
  353. }
  354.  
  355. private void AssertActionsMakeSense()
  356. {
  357. if (TreeData.ForceOOPBet && TreeData.ForceIPBet)
  358. {
  359. throw new UserException("Cannot force both IP and OOP bets.");
  360. }
  361. if (_lines.Count == 0)
  362. {
  363. if (TreeData.ForceOOPBet)
  364. {
  365. throw new UserException(
  366. "Specified tree would be empty. You might have selected 'force OOP bet', but there are no bets for OOP.");
  367. }
  368. if (TreeData.ForceIPBet)
  369. {
  370. throw new UserException(
  371. "Specified tree would be empty. You might have selected 'force IP bet', but there are no bets for IP.");
  372. }
  373. throw new UserException("Specified tree would be empty.");
  374. }
  375. }
  376.  
  377. private void GenerateForcingBet()
  378. {
  379. if (StartingGame.Invested[0] != StartingGame.Invested[1])
  380. {
  381. throw new UserException("This only works if both players have some money in the pot to begin with.");
  382. }
  383.  
  384. var oopCheck = ActionLine.Create(ActionLine.CreateRoot(StartingGame.Invested[0]), StartingGame.Invested[0], "CheckCall");
  385. ActionLine removedLine;
  386. if (TreeData.ForceOOPBet)
  387. {
  388. removedLine = oopCheck;
  389. }
  390. else if (TreeData.ForceIPBet)
  391. {
  392. _forceLines.Add(oopCheck);
  393. _lines.RemoveAll(a => !a.StartsWith(oopCheck));
  394. //oop check, ip check
  395. removedLine = ActionLine.Create(oopCheck, StartingGame.Invested[1], "CheckCall");
  396. }
  397. else
  398. {
  399. return;
  400. }
  401. _removeLines.Add(removedLine);
  402. _lines.RemoveAll(a => a.StartsWith(removedLine));
  403. }
  404.  
  405.  
  406. public void RemoveLinesProvidedByUser()
  407. {
  408. var parsedLines = new List<RemoveLineByUser>();
  409. if (TreeData.RemovedLines == null) return;
  410.  
  411. foreach (var r in TreeData.RemovedLines)
  412. {
  413. if (!string.IsNullOrWhiteSpace(r))
  414. {
  415. parsedLines.Add(RemoveLineByUser.Parse(r));
  416. }
  417. }
  418.  
  419. foreach (var parsedLine in parsedLines.OrderBy(pl => pl.Expressions.Count))
  420. {
  421. var linesToBeRemovedFromAllLines = new List<ActionLine>();
  422. var linesToBeAdded = new List<ActionLine>();
  423. foreach (var line in _lines)
  424. {
  425. var result = parsedLine.ShouldRemove(line);
  426. if (result != null)
  427. {
  428. if (result.RemoveThisLine)
  429. {
  430. linesToBeRemovedFromAllLines.Add(line);
  431. }
  432. if (result.AdditionalLineToRemove != null)
  433. {
  434. result = parsedLine.ShouldRemove(line);
  435. _removeLines.Add(result.AdditionalLineToRemove);
  436. }
  437. if (result.ParentLineToStay != null)
  438. {
  439. linesToBeAdded.Add(result.ParentLineToStay);
  440. }
  441. }
  442. }
  443. foreach (var line in linesToBeAdded)
  444. {
  445. _lines.Add(line);
  446. }
  447. foreach (var line in linesToBeRemovedFromAllLines)
  448. {
  449. _lines.Remove(line);
  450. }
  451. }
  452. }
  453.  
  454. private void AddExtraLinesHelper(ActionLine path, string[] actions, int actionIndex, Game g)
  455. {
  456. if (actions.Length == actionIndex || g.CurrentInvested >= g.EffectiveStacks)
  457. {
  458. GenerateLines(path, g);
  459. return;
  460. }
  461.  
  462. Action<Game, string> next =
  463. (newGame, actionNames) =>
  464. {
  465. AddExtraLinesHelper(ActionLine.Create(path, newGame.CurrentInvested, actionNames), actions, actionIndex + 1,
  466. newGame);
  467. };
  468.  
  469.  
  470. Action<Game, string[]> nextMany =
  471. (newGame, actionNames) =>
  472. {
  473. AddExtraLinesHelper(ActionLine.Create(path, newGame.CurrentInvested, actionNames), actions, actionIndex + 1,
  474. newGame);
  475. };
  476. {
  477. var action = actions[actionIndex];
  478. var items = action.ToLower().Trim().Split();
  479. if (string.IsNullOrWhiteSpace(items[0]))
  480. {
  481. return;
  482. }
  483. if (items[0].StartsWith("c")) //check, call
  484. {
  485. if (items.Length != 1)
  486. {
  487. throw new UserException("Invalid action expression: " + action);
  488. }
  489. next(g.CheckCall(), "CheckCall");
  490. }
  491. else if (items[0].StartsWith("f"))
  492. {
  493. throw new UserException("Can't add extra lines with explicit fold");
  494. }
  495. else if (items[0].StartsWith("b") || items[0].StartsWith("r")) //bet or raise
  496. {
  497. if (items.Length == 1)
  498. {
  499. //find all sizes already used in the tree
  500. var knownBetsizes = new Dictionary<int, HashSet<string>>();
  501. foreach (var line in this._lines)
  502. {
  503. if (line.StartsWith(path))
  504. {
  505. var potentialBet = line.FirstActionAfter(path);
  506. var currentBetsize = path == null ? 0 : path.Bet;
  507. if (potentialBet != null && potentialBet.Bet > currentBetsize)
  508. {
  509. if (!knownBetsizes.ContainsKey(potentialBet.Bet))
  510. {
  511. knownBetsizes[potentialBet.Bet] = new HashSet<string>();
  512. }
  513. knownBetsizes[potentialBet.Bet].UnionWith(potentialBet.BettingExpressions);
  514. }
  515. }
  516. }
  517.  
  518. foreach (var kvp in knownBetsizes)
  519. {
  520. int raiseSize = kvp.Key;
  521. var expressions = kvp.Value.ToArray();
  522. if (g.CanAct)
  523. {
  524. nextMany(g.Raise(raiseSize), expressions);
  525. }
  526. }
  527. }
  528. else
  529. {
  530. if (g.CanAct)
  531. {
  532. next(g.Raise(items[1]), items[1]);
  533. }
  534. }
  535. }
  536. else if (items[0].StartsWith("a"))
  537. {
  538. if (items.Length != 1)
  539. {
  540. throw new UserException("Invalid action expression: " + action);
  541. }
  542. next(g.Raise("allin"), "Allin");
  543. }
  544. else
  545. {
  546. throw new UserException("Invalid expression: " + action);
  547. }
  548. }
  549. }
  550.  
  551. private void AddExtraLines()
  552. {
  553. if (TreeData.ExtraLines == null) return;
  554. foreach (var extraLine in TreeData.ExtraLines)
  555. {
  556. if (string.IsNullOrWhiteSpace(extraLine)) continue;
  557.  
  558. var actions = extraLine.Split(',');
  559. try
  560. {
  561. AddExtraLinesHelper(ActionLine.CreateRoot(this.StartingGame.Invested.Min()), actions, 0,
  562. this.StartingGame);
  563. }
  564. catch (TooLongLineException)
  565. {
  566. throw new UserException($"Couldn't add extra line \"{extraLine}\" to the tree. Line is too long.");
  567. }
  568. catch (Exception x)
  569. {
  570. Console.WriteLine(x);
  571. throw new UserException($"Couldn't add extra line \"{extraLine}\" to the tree.\n{x.Message}");
  572. }
  573. }
  574. }
  575.  
  576. /// <summary>
  577. /// returns a validation string - true if all bet action eventually lead to allin
  578. /// </summary>
  579. /// <param name="path"></param>
  580. /// <param name="g"></param>
  581. /// <returns></returns>
  582. private bool GenerateLines(ActionLine path, Game g)
  583. {
  584. var atLeastOneLineToAllin = false;
  585.  
  586. if (g.CurrentInvested >= g.EffectiveStacks)
  587. {
  588. _lines.Add(path);
  589. return true;
  590. }
  591.  
  592. if (g.Round == 6) return false;
  593.  
  594. if (GenerateLines(ActionLine.Create(path, g.CurrentInvested, "CheckCall"), g.CheckCall()))
  595. {
  596. atLeastOneLineToAllin = true;
  597. }
  598. var appliedBetsizes = new Dictionary<int, Game>();
  599. var appliedFormulas = new Dictionary<int, List<string>>();
  600.  
  601. Action<int, Game, string> apply = (betsize, game, formula) =>
  602. {
  603. appliedBetsizes[betsize] = game;
  604. if (!appliedFormulas.ContainsKey(betsize))
  605. {
  606. appliedFormulas[betsize] = new List<string>();
  607. }
  608. appliedFormulas[betsize].Add(formula);
  609. };
  610.  
  611. //below I calculate the size of the bet and create a new game object.
  612. //If it is null, than it means the bet/raise should not be made
  613.  
  614. var streetConfig = TreeData.StreetConfigForRoundAndPosition(g.Round, g.ToAct);
  615. var betSizes = BetBetSizesFromConfig(g, streetConfig);
  616.  
  617. //only if betsizes are not null - so betting / raising is allowed
  618. if (!string.IsNullOrWhiteSpace(betSizes))
  619. {
  620. bool canBetAtAll = true;
  621. bool canUseBetsizesOtherThanAllin = true;
  622.  
  623. bool useCap = TreeData.CapEnabled && TreeData.Cap != 0;
  624. if (useCap)
  625. {
  626. switch (TreeData.CapMode)
  627. {
  628. case CapStyle.NoLimit:
  629. //allin
  630. if (TreeData.Cap == g.NumberOfBetsThisStreet + 1)
  631. {
  632. var gAllin = g.Raise("allin");
  633. apply(gAllin.Invested[g.ToAct], gAllin, "allin");
  634. canUseBetsizesOtherThanAllin = false;
  635. }
  636. break;
  637. case CapStyle.Limit:
  638. if (TreeData.Cap == g.NumberOfBetsThisStreet)
  639. {
  640. canBetAtAll = false;
  641. }
  642. break;
  643. //nothing to do
  644. }
  645. }
  646.  
  647. //don't allow 3bet IP if don't 3bet selected
  648. if (g.NumberOfBetsThisStreet == 2 && g.ToAct == 1 && ((IPStreetConfig)streetConfig).Dont3bet)
  649. {
  650. canBetAtAll = false;
  651. }
  652.  
  653. if (canUseBetsizesOtherThanAllin && canBetAtAll)
  654. {
  655. foreach (var betSize in betSizes.Split(',', ';', ' '))
  656. {
  657. if (!string.IsNullOrWhiteSpace(betSize))
  658. {
  659. string b = betSize.Trim();
  660. var ng = g.Raise(b);
  661.  
  662. int raiseDifference = ng.Invested[g.ToAct] - ng.Invested[1 - g.ToAct];
  663.  
  664. if (raiseDifference < TreeData.MinimumBetsize)
  665. {
  666. ng = g.Raise(ng.Invested[1 - g.ToAct] + TreeData.MinimumBetsize);
  667. }
  668.  
  669. if (ng.PostflopCurrentInvested > (TreeData.AllinThreshold / 100) * ng.PostflopEffectiveStacks)
  670. {
  671. ng = g.Raise("allin");
  672. }
  673.  
  674. apply(ng.Invested[g.ToAct], ng, b);
  675. }
  676. }
  677. }
  678.  
  679. if (canBetAtAll)
  680. {
  681. if (streetConfig.AddAllin)
  682. {
  683. float allin = g.GetAllinSizeInPercent();
  684. if (allin < TreeData.AddAllinOnlyIfLessThanThisTimesThePot)
  685. {
  686. var gAllin = g.Raise("allin");
  687. apply(gAllin.Invested[g.ToAct], gAllin, "allin");
  688. }
  689. }
  690.  
  691. foreach (var kvp in appliedBetsizes.OrderBy(kvp => kvp.Key))
  692. {
  693. var actionLine = ActionLine.Create(path, kvp.Key, string.Join("|", appliedFormulas[kvp.Key]));
  694. if (!GenerateLines(actionLine, kvp.Value))
  695. {
  696. _lines.Add(actionLine);
  697. }
  698. atLeastOneLineToAllin = true;
  699. }
  700. }
  701. }
  702. return atLeastOneLineToAllin;
  703. }
  704.  
  705. private string BetBetSizesFromConfig(Game g, StreetConfig streetConfig)
  706. {
  707. string betSizes = null;
  708.  
  709. if (g.Invested[0] == g.Invested[1])
  710. {
  711. //bet
  712.  
  713. var isDonk = g.ToAct == 0 && g.StreetAggressor[g.Round - 1] == 1;
  714. if (isDonk)
  715. {
  716. var oopData = (OOPStreetConfig)streetConfig;
  717. betSizes = oopData.DonkBetSize;
  718. }
  719. else
  720. {
  721. betSizes = streetConfig.BetSize;
  722. if (TreeData.UseUnifiedBetAfterRaise && g.AtLeastOneRaiseHasHappened)
  723. {
  724. betSizes = TreeData.UnifiedBetAfterRaise;
  725. }
  726. }
  727. }
  728. else
  729. {
  730. //raise
  731. betSizes = streetConfig.RaiseSize;
  732. if (TreeData.UseUnifiedRaiseAfterRaise && g.AtLeastOneRaiseHasHappened)
  733. {
  734. betSizes = TreeData.UnifiedRaiseAfterRaise;
  735. }
  736. }
  737. return betSizes;
  738. }
  739. }
  740. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement