private void CalculateEquity(List <EquityPlayer> players, Street street, BoardCards boardCards, HandHistories.Objects.Cards.Card[] dead, GeneralGameTypeEnum gameType, int potIndex) { var equitySolverParams = new EquitySolverParams { PlayersCards = players.Select(x => x.HoleCards).ToArray(), BoardCards = boardCards.ToArray(), Dead = dead, GameType = gameType }; var equity = CalculateEquity(equitySolverParams); for (var i = 0; i < players.Count; i++) { players[i].Equity[potIndex] = (decimal)equity[i].Equity; } }
public EquitySolverResult[] CalculateEquity(EquitySolverParams equitySolverParams) { var cardsDelimeter = " "; var gameTypeArg = equitySolverParams.GameType == GeneralGameTypeEnum.Holdem ? "-h" : (equitySolverParams.GameType == GeneralGameTypeEnum.OmahaHiLo ? "-o8" : "-o"); var playerCardsArgs = string.Join(" - ", equitySolverParams.PlayersCards.Select(x => x.ToString(cardsDelimeter)).ToArray()); var boardCardsArgs = string.Join(cardsDelimeter, equitySolverParams.BoardCards.Select(x => x.ToString())); var deadCardsArgs = string.Join(cardsDelimeter, equitySolverParams.Dead.Select(x => x.ToString()).ToArray()); // use monte-carlo simulation for omaha w/o board var prefix = equitySolverParams.GameType != GeneralGameTypeEnum.Holdem && string.IsNullOrEmpty(boardCardsArgs) ? "p -mc 10000" : "p"; var argsLine = $"{prefix} {gameTypeArg} {playerCardsArgs}"; if (!string.IsNullOrEmpty(boardCardsArgs)) { argsLine += $" -- {boardCardsArgs}"; } if (!string.IsNullOrEmpty(deadCardsArgs)) { argsLine += $" / {deadCardsArgs}"; } var argv = argsLine.Split(' '); CalculateEquity(argv.Length, argv, out CalculationResult result); var equitySolverResults = new EquitySolverResult[equitySolverParams.PlayersCards.Length]; unsafe { for (var i = 0; i < equitySolverParams.PlayersCards.Length; i++) { equitySolverResults[i] = new EquitySolverResult { Equity = result.ev[i], Wins = result.nwinhi[i] + result.nwinlo[i], Loses = result.nlosehi[i] + result.nloselo[i], Ties = result.ntiehi[i] + result.ntielo[i] }; } } if (!equitySolverParams.CalculatePct) { return(equitySolverResults); } var sortedEquitySolverResults = equitySolverResults.OrderBy(x => x.Ties).ToList(); var totalCombinations = 0L; var tempsTies = sortedEquitySolverResults.Select(x => x.Ties).ToArray(); var resultIndex = 0; while (sortedEquitySolverResults.Count > 0) { var equitySolverResult = sortedEquitySolverResults.FirstOrDefault(); if (totalCombinations == 0) { totalCombinations = equitySolverResult.Loses + equitySolverResult.Ties + equitySolverResult.Wins; } tempsTies[resultIndex] = tempsTies[resultIndex] / sortedEquitySolverResults.Count; equitySolverResult.TiesPct = totalCombinations != 0 ? (double)tempsTies[resultIndex] / totalCombinations : 0; equitySolverResult.WinPct = totalCombinations != 0 ? (double)equitySolverResult.Wins / totalCombinations : 0; sortedEquitySolverResults.Remove(equitySolverResult); for (var i = resultIndex + 1; i < tempsTies.Length; i++) { tempsTies[i] -= tempsTies[resultIndex]; } resultIndex++; } return(equitySolverResults); }