public static void Main(string[] args) { Console.WriteLine("Loading opponents..."); var seats = new Seat[6]; seats[0] = new Seat(1, "TeeJayorTJ5", 1000, new WekaPlayer(CLASSIFIER_DIR + "preflop.model",CLASSIFIER_DIR + "flop.model",CLASSIFIER_DIR + "turn.model",CLASSIFIER_DIR + "river.model")); seats[1] = new Seat(2, "Dave_Wilkes", 1000, new WekaPlayer(CLASSIFIER_DIR + "preflop.model",CLASSIFIER_DIR + "flop.model",CLASSIFIER_DIR + "turn.model",CLASSIFIER_DIR + "river.model")); seats[2] = new Seat(3, "Some_Killa", 1000, new WekaPlayer(CLASSIFIER_DIR + "preflop.model",CLASSIFIER_DIR + "flop.model",CLASSIFIER_DIR + "turn.model",CLASSIFIER_DIR + "river.model")); seats[3] = new Seat(4, "Better_Boy", 1000, new WekaPlayer(CLASSIFIER_DIR + "preflop.model",CLASSIFIER_DIR + "flop.model",CLASSIFIER_DIR + "turn.model",CLASSIFIER_DIR + "river.model")); seats[4] = new Seat(5, "Kiddo1973", 1000, new WekaPlayer(CLASSIFIER_DIR + "preflop.model",CLASSIFIER_DIR + "flop.model",CLASSIFIER_DIR + "turn.model",CLASSIFIER_DIR + "river.model")); seats[5] = new Seat(6, "Human", 1000, new ConsolePlayer()); var blinds = new double[] { 10, 20 }; uint handNumber = 0; Console.WriteLine("Starting simulation"); HandEngine engine = new HandEngine(); while(true) { HandHistory results = new HandHistory(seats, handNumber, handNumber % (uint)seats.Length + 1, blinds, 0, BettingStructure.Limit); //engine.PlayHand(results, cachedHands[(int)handNumber]); engine.PlayHand(results); Console.WriteLine(results.ToString(true)); Thread.Sleep(2000); foreach(var seat in seats) if(seat.Chips == 0) { Console.WriteLine("{0} rebuys for $1000", seat.Name); seat.Chips = 1000; } handNumber++; } }
private void LogHand(Settings settings, HandHistory history, bool append) { lock (LogLock) using (TextWriter writer = new StreamWriter(settings.LogFile + Generation + ".txt", append)) { writer.WriteLine(history.ToString()); writer.WriteLine(); } }
private void LogHand(Settings settings, HandHistory history, bool append) { lock(LogLock) using (TextWriter writer = new StreamWriter(settings.LogFile + Generation + ".txt", append)) { writer.WriteLine(history.ToString()); writer.WriteLine(); } }
private List <double> playRound(List <IPlayer> players, double[] stacks) { List <double> roi = new List <double>(); for (int i = 0; i < players.Count; i++) { roi.Add(0); } HandEngine engine = new HandEngine() { AnalyzeHands = false }; //bool[] stillIn = new bool[stacks.Length]; //for (int i = 0; i < stillIn.Length; i++) // stillIn[i] = true; //Play one hand in every position for (int i = 0; i < players.Count; i++) { var seats = getSeats(players, stacks); //for (int j = seats.Count() - 1; j >= 0; j--) // if (!stillIn[j]) // seats.RemoveAt(j); //Have the players play a single hand. HandHistory history = new HandHistory(seats.ToArray(), GamesPlayed, (uint)seats[i].SeatNumber, new double[] { SmallBlind, BigBlind }, 0, BettingStructure.Limit); engine.PlayHand(history); GamesPlayed++; if (GamesPlayed % 100000 == 0) { using (TextWriter writer = new StreamWriter(LogFilename, GamesPlayed > 1)) { writer.WriteLine(history.ToString()); writer.WriteLine(); } for (int j = 0; j < stacks.Length; j++) { Console.WriteLine("Reward {0}: {1}", seats[j].Name, seats[j].Chips - stacks[j]); } } for (int j = 0; j < stacks.Length; j++) { roi[j] += seats[j].Chips - stacks[j]; } } return(roi); }
private void debugPrint(HandHistory history, double[] inputs) { Console.WriteLine(); Console.WriteLine(history.ToString()); Console.WriteLine(); Console.WriteLine("HoleCards: {0}", HoldemHand.Hand.MaskToString(history.HoleCards[history.Hero])); Console.WriteLine("INPUTS:"); for (var i = 0; i < inputs.Length; i++) Console.WriteLine("{0}: {1}", i, inputs[i]); Console.WriteLine(); }
private void debugPrint(HandHistory history, double[] inputs) { Console.WriteLine(); Console.WriteLine(history.ToString()); Console.WriteLine(); Console.WriteLine("HoleCards: {0}", HoldemHand.Hand.MaskToString(history.HoleCards[history.Hero])); Console.WriteLine("INPUTS:"); for (var i = 0; i < inputs.Length; i++) { Console.WriteLine("{0}: {1}", i, inputs[i]); } Console.WriteLine(); }
public HandTreeNode(HandHistory h) : base(h.ToString()) { hand = h; TreeNode gameNode = Nodes.Add("Game"); gameNode.Nodes.Add("Game type: " + GameTypeUtils.GetDisplayName(hand.GameDescription.GameType)); gameNode.Nodes.Add("Game format: " + PokerFormatUtils.GetDisplayName(hand.GameDescription.PokerFormat)); TreeNode players = Nodes.Add("Players"); foreach (Player player in hand.Players) { TreeNode playerNode = players.Nodes.Add(player.PlayerName); playerNode.Nodes.Add("Seat: " + player.SeatNumber); if (!player.IsSittingOut) { playerNode.Nodes.Add("Starting stack: $" + player.StartingStack); if (player.hasHoleCards) { playerNode.Nodes.Add("Hole Cards: " + player.HoleCards); } } else { playerNode.Nodes.Add("Sitting out"); } } TreeNode actions = Nodes.Add("Actions"); foreach (HandAction action in hand.HandActions) { actions.Nodes.Add(action.ToString()); } Nodes.Add("Date (Utc): " + hand.DateOfHandUtc.ToString()); Nodes.Add("Date: " + hand.DateOfHandUtc.ToLocalTime().ToString()); Nodes.Add("Community cards: " + (hand.ComumnityCards.Count == 0 ? "None" : string.Join(" ", hand.ComumnityCards.Select(c => c.ToString())))); Nodes.Add("Active players: " + hand.NumPlayersActive); Nodes.Add("Total pot: " + hand.TotalPot + " BB"); }
public void EvaluatePopulation(Population pop, EvolutionAlgorithm ea) { var count = pop.GenomeList.Count; #region Reset the genomes for (var i = 0; i < count; i++) { pop.GenomeList[i].TotalFitness = EvolutionAlgorithm.MIN_GENOME_FITNESS; pop.GenomeList[i].EvaluationCount = 0; pop.GenomeList[i].Fitness = EvolutionAlgorithm.MIN_GENOME_FITNESS; } #endregion //TODO: Parallelize/Distribute this loop //Ideally we should have a distributed method which returns an array of //doubles to add to the genome fitnesses of each individual. for (var i = 0; i < count; i++) { Console.WriteLine("Individual #{0}", i + 1); var g = pop.GenomeList[i]; var network = g.Decode(ActivationFunction); if (network == null) { // Future genomes may not decode - handle the possibility. g.Fitness = EvolutionAlgorithm.MIN_GENOME_FITNESS; g.TotalFitness = g.Fitness; g.EvaluationCount = 1; continue; } HandEngine engine = new HandEngine(); //Run multiple hands per individual for (var curGame = 0; curGame < GamesPerEvaluation; curGame++) { #region Setup the players for this game var field = new List <Seat>(); var stacks = GetStacks(PlayersPerGame); var networks = new int[PlayersPerGame]; networks[0] = i; IPlayer hero = null;//new NeuralNetworkPlayer(InputGenerator, OutputInterpreter, // network, Rand); field.Add(new Seat(1, "Net_" + i, stacks[0], hero)); for (var curPlayer = 1; curPlayer < PlayersPerGame; curPlayer++) { INetwork nextNetwork = null; var next = 0; while (nextNetwork == null) { next = Rand.Next(0, count); nextNetwork = pop.GenomeList[next].Decode(ActivationFunction); } networks[curPlayer] = next; //"NeuralNet" + next, stacks[curPlayer], IPlayer villain = null; // new NeuralNetworkPlayer(InputGenerator, // OutputInterpreter, nextNetwork, Rand); field.Add(new Seat(curPlayer + 1, "Net" + next + "_Seat+ " + (curPlayer + 1), stacks[curPlayer], villain)); } #endregion //Have the players play a single hand. HandHistory history = new HandHistory(field.ToArray(), (ulong)curGame + 1, (uint)(curGame % PlayersPerGame + 1), new double[] { 1, 2 }, 0, BettingType); CachedHand hand = CachedHands[Rand.Next(CachedHands.Count)]; engine.PlayHand(history); #region Add the results to the players' fitness scores //We'll use the profit as the fitness function. //Alternatively, we could in the future experiment with using profit //as a percentage of the original stacks. Or we could use the square //of the profit (multiplying by -1 if the player lost money). for (var curResult = 0; curResult < PlayersPerGame; curResult++) { var curGenome = pop.GenomeList[networks[curResult]]; curGenome.TotalFitness += field[curResult].Chips - stacks[curResult]; curGenome.EvaluationCount++; } #endregion if (GamesPlayed % 10000 == 0) { using (TextWriter writer = new StreamWriter("game_" + GamesPlayed + ".txt")) writer.WriteLine(history.ToString()); } //increment the game counter GamesPlayed++; } } //Normalize the fitness scores to use the win-rate for (var i = 0; i < count; i++) { pop.GenomeList[i].Fitness = Math.Max(pop.GenomeList[i].Fitness, EvolutionAlgorithm.MIN_GENOME_FITNESS); pop.GenomeList[i].TotalFitness = Math.Max(pop.GenomeList[i].Fitness, EvolutionAlgorithm.MIN_GENOME_FITNESS); } }
private List <double> playSemiTourney(List <IPlayer> players, double[] stacks) { List <double> roi = new List <double>(); for (int i = 0; i < players.Count; i++) { roi.Add(0); } HandEngine engine = new HandEngine() { AnalyzeHands = false }; var seats = getSeats(players, stacks); for (int i = 0, handsThisTourney = 0; seats.Count > 3 && handsThisTourney < MaxHandsPerTourney; i = (i + 1) % seats.Count, GamesPlayed++, handsThisTourney++) { HandHistory history = new HandHistory(seats.ToArray(), GamesPlayed, (uint)seats[i].SeatNumber, new double[] { SmallBlind, BigBlind }, 0, BettingStructure.Limit); try { if (AnalyzeHands) { engine.PlayHand(history, cachedHands[random.Next(cachedHands.Count)]); } else { engine.PlayHand(history); } } catch (Exception e) { Console.WriteLine(e.StackTrace); using (TextWriter writer = new StreamWriter("error_log.txt", true)) { writer.WriteLine(e.StackTrace); writer.WriteLine(); } } if (GamesPlayed % 100000 == 0) { using (TextWriter writer = new StreamWriter(LogFilename, GamesPlayed > 1)) { writer.WriteLine(history.ToString()); writer.WriteLine(); } } //remove broke players for (var j = seats.Count - 1; j >= 0; j--) { if (seats[j].Chips < 24 * BigBlind) { seats.RemoveAt(j); } } } seats.Sort((a, b) => b.Chips.CompareTo(a.Chips)); for (var i = 0; i < players.Count; i++) { for (var j = 0; j < seats.Count; j++) { if (seats[j].Brain == players[i]) { if (j == 0) { roi[i] = 10; } else if (j == 1) { roi[i] = 7; } else if (j == 2) { roi[i] = 5; } else if (j == 3) { roi[i] = 3; } else if (j == 4) { roi[i] = 2; } break; //if you made it this far, you don't lose more than 20 big blinds //if you did really well though, you can win as much as you can take //roi[i] = Math.Max(-20 * BigBlind, seats[j].Chips - stacks[i]); } } } return(roi); }
public void GetAction(HandHistory history, out holdem_engine.Action.ActionTypes action, out double amount) { Console.WriteLine(history.ToString()); action = getAction(); amount = 0; }
public void EvaluatePopulation(Population pop, EvolutionAlgorithm ea) { var count = pop.GenomeList.Count; #region Reset the genomes for (var i = 0; i < count; i++) { pop.GenomeList[i].TotalFitness = EvolutionAlgorithm.MIN_GENOME_FITNESS; pop.GenomeList[i].EvaluationCount = 0; pop.GenomeList[i].Fitness = EvolutionAlgorithm.MIN_GENOME_FITNESS; } #endregion //TODO: Parallelize/Distribute this loop //Ideally we should have a distributed method which returns an array of //doubles to add to the genome fitnesses of each individual. for (var i = 0; i < count; i++) { Console.WriteLine("Individual #{0}", i + 1); var g = pop.GenomeList[i]; var network = g.Decode(ActivationFunction); if (network == null) { // Future genomes may not decode - handle the possibility. g.Fitness = EvolutionAlgorithm.MIN_GENOME_FITNESS; g.TotalFitness = g.Fitness; g.EvaluationCount = 1; continue; } HandEngine engine = new HandEngine(); //Run multiple hands per individual for (var curGame = 0; curGame < GamesPerEvaluation; curGame++) { #region Setup the players for this game var field = new List<Seat>(); var stacks = GetStacks(PlayersPerGame); var networks = new int[PlayersPerGame]; networks[0] = i; IPlayer hero = null;//new NeuralNetworkPlayer(InputGenerator, OutputInterpreter, // network, Rand); field.Add(new Seat(1, "Net_" + i, stacks[0], hero)); for (var curPlayer = 1; curPlayer < PlayersPerGame; curPlayer++) { INetwork nextNetwork = null; var next = 0; while (nextNetwork == null) { next = Rand.Next(0, count); nextNetwork = pop.GenomeList[next].Decode(ActivationFunction); } networks[curPlayer] = next; //"NeuralNet" + next, stacks[curPlayer], IPlayer villain = null;// new NeuralNetworkPlayer(InputGenerator, // OutputInterpreter, nextNetwork, Rand); field.Add(new Seat(curPlayer + 1, "Net" + next + "_Seat+ " + (curPlayer+1), stacks[curPlayer], villain)); } #endregion //Have the players play a single hand. HandHistory history = new HandHistory(field.ToArray(), (ulong)curGame+1, (uint)(curGame % PlayersPerGame + 1), new double[] { 1, 2 }, 0, BettingType); CachedHand hand = CachedHands[Rand.Next(CachedHands.Count)]; engine.PlayHand(history); #region Add the results to the players' fitness scores //We'll use the profit as the fitness function. //Alternatively, we could in the future experiment with using profit //as a percentage of the original stacks. Or we could use the square //of the profit (multiplying by -1 if the player lost money). for (var curResult = 0; curResult < PlayersPerGame; curResult++) { var curGenome = pop.GenomeList[networks[curResult]]; curGenome.TotalFitness += field[curResult].Chips - stacks[curResult]; curGenome.EvaluationCount++; } #endregion if (GamesPlayed % 10000 == 0) using (TextWriter writer = new StreamWriter("game_" + GamesPlayed + ".txt")) writer.WriteLine(history.ToString()); //increment the game counter GamesPlayed++; } } //Normalize the fitness scores to use the win-rate for (var i = 0; i < count; i++) { pop.GenomeList[i].Fitness = Math.Max(pop.GenomeList[i].Fitness, EvolutionAlgorithm.MIN_GENOME_FITNESS); pop.GenomeList[i].TotalFitness = Math.Max(pop.GenomeList[i].Fitness, EvolutionAlgorithm.MIN_GENOME_FITNESS); } }