public bool callButtonVisible(Image <Bgr, byte> img) { //Using optical character recognition VirtualMouse1 vr = new VirtualMouse1(); Rectangle[] buttons = vr.getButtonsRectangles(); Rectangle callButton = buttons[1]; PointF center = new PointF(callButton.X + callButton.Width / 2, callButton.Y + callButton.Height / 2); SizeF size = new SizeF(callButton.Width, callButton.Height); Image <Bgr, byte> image = cropImage(img, new MCvBox2D(center, size, 0)); if (image != null) { image = image.Resize(3.0, INTER.CV_INTER_CUBIC); string[] recong = OCR(image); image.Dispose(); if (recong[0].Contains("Pago") || recong[0].Contains("Passo")) { return(true); } } //If it does not work, using template matching Image <Bgr, Byte> region; double[] min1, max1; Point[] pointMin1, pointMax1; MCvBox2D box = new MCvBox2D(new PointF(653, 646), new SizeF(311, 106), 0); region = cropImage(img, box); if (region != null) { Image <Bgr, Byte> buttonTemplate1 = new Image <Bgr, Byte>("ButtonsTemplate/call.png"); Image <Bgr, Byte> buttonTemplate2 = new Image <Bgr, Byte>("ButtonsTemplate/call2.png"); //Template match the template with the region containing the comunitary cards Image <Gray, float> comparationImage1 = region.MatchTemplate(buttonTemplate1, Emgu.CV.CvEnum.TM_TYPE.CV_TM_CCOEFF_NORMED); Image <Gray, float> comparationImage2 = region.MatchTemplate(buttonTemplate2, Emgu.CV.CvEnum.TM_TYPE.CV_TM_CCOEFF_NORMED); comparationImage1.MinMax(out min1, out max1, out pointMin1, out pointMax1); //If the max correlation exceds some minimum value comparationImage1.Dispose(); if (max1[0] > MIN_TMPLT_MATCHING_DEALER) { return(true); } double[] min2, max2; Point[] pointMin2, pointMax2; comparationImage2.MinMax(out min2, out max2, out pointMin2, out pointMax2); //If the max correlation exceds some minimum value comparationImage2.Dispose(); if (max2[0] > MIN_TMPLT_MATCHING_DEALER) { return(true); } } return(false); }
//Do not change the signature of this function!!! public void AgentEventHandler(PokerAPI.CardDetector cd, PokerAPI.Player[] players, double probabilities, bool myTurn, IntPtr hWnd, Image <Bgr, byte> img) { //Perform the action only when is my turn to play if (myTurn) { List <PokerAPI.Card> holeCards = cd.getHoleCards(), boardCards = cd.getComunitaryCards(); int myStack = players[0].getStack(); //Setting the PokerAPI to automatically add chips when we run out of money cd.autoAddChips = true; //Associating a virtual mouse object to the pokerstars game window VirtualMouse1 vr = new VirtualMouse1(hWnd); //cd.printComunitaryCards(); //Deffinig our AI strategy if (myStack >= 100) { if (probabilities > 0.85) { vr.allIn(); } else if (probabilities > 0.6) { vr.raise(); } else if (probabilities >= 0.4) { //The call button is not allways visible if (cd.callButtonVisible(img)) { vr.call(); } else { vr.fold(); } } else { vr.fold(); } } else { if (probabilities > 0.9) { vr.allIn(); } else if (probabilities >= 0.8) { vr.raise(); } if (probabilities >= 0.7) { //The call button is not allways visible if (cd.callButtonVisible(img)) { vr.call(); } else { vr.fold(); } } } //moving the mouse to other place after performing the move vr.moveToRamdomPlace(); } }
/// <summary> /// Method for the agent Thread /// </summary> public void RunThread() { agent = new Agent.Agent("Poker genius!!!"); List <PokerAPI.Card> holeCards = cd.getHoleCards(); List <PokerAPI.Card> boardCards = cd.getComunitaryCards(); Evt += agent.AgentEventHandler; int startValue = 0, endValue = 0; //Importante!!!!!! Inicializar o random apenas uma vez em toda a aplicação!!! random = new Random(); bool myTurn = false, first = true, newGame = false; int dealer = -1, secondCount = 0, estado = -1, lastPlayerToMove = 0; Game game = new Game(); MatchState matchState = new MatchState(new State(0, game), 0); //See if changes ocurred in the players stacks bool changes = false, runningAgent = false; while (agentRunning) { //Capturing the image Image <Bgr, byte> img = captureImage(); //If is the first image if (first) { //Detect the comunitary cards cd.detectTableCards(img); estado = printState(cd.getComunitaryCards().Count); cd.printComunitaryCards(); myTurn = cd.buttonsVisible(img); dealer = cd.findDealer(img); } //Read the player stacks cd.readPlayerStacks(img); for (int i = 0; i < players.Length; i++) { //Setting the player stacks in the player objects players[i].setStack(cd.playerStacks[i]); } endValue = players[0].getStack(); if (first) { startValue = endValue; } printPlayerStacks(cd.playerStacks); //If it's not the first image if (!first) { //For all players for (int i = 0; i < players.Length; i++) { //If changes ocurred in is stack if (players[i].getStack() != oldValues[i]) { changes = true; if (oldValues[i] > players[i].getStack()) { //A raise ocurred int raise = oldValues[i] - players[i].getStack(); //PARA JÁ if (runningAgent) { int j = lastPlayerToMove; while (j != i) { //A fazer call dos possiveis jogadores que fizeram call ou fold... ver isto... try { matchState.state.doAction(game, new LIACC.Poker.Action(ActionType.Call, 0)); } catch (IndexOutOfRangeException e) { } j++; if (j == 10) { j = 0; } } lastPlayerToMove = i; try { matchState.state.doAction(game, new LIACC.Poker.Action(ActionType.Raise, raise)); } catch (IndexOutOfRangeException e) { } } Console.WriteLine("Player: " + i + " raised " + raise); appendTextBox("\nPlayer: " + i + " raised " + raise); } Console.WriteLine("Player: " + i + " has now " + players[i].getStack()); appendTextBox("\nPlayer: " + i + " has now " + players[i].getStack()); } } } //If any change ocurred in the a player stack if (changes) { int newdealer = cd.findDealer(img); //Locate the dealer position if (newdealer != -1) { if (newdealer == dealer) { //if the dealer is the same, then it's not a new game newGame = false; } else { dealer = newdealer; //if the dealer changed then it's a new game newGame = true; } Console.WriteLine("Dealer: " + dealer); appendTextBox("\nDealer: " + dealer); } //Detect the comunitary cards cd.detectTableCards(img); if (runningAgent) { holeCards = cd.getHoleCards(); bool holeCardsConhecidas = (holeCards.Count == 2); //deves preencher informação sobre as cartas assim que as detetares: //exemplo, as cartas do jogador 2 são Ás de ouros e Reis de Paus byte[] fullHand; byte[] holeCards1, boardCards1; if (holeCardsConhecidas) { matchState.state.HoleCards[0, 0] = LIACC.Poker.Cards.Card.MakeCard(holeCards.ElementAt(0).toStringShort()); matchState.state.HoleCards[0, 1] = LIACC.Poker.Cards.Card.MakeCard(holeCards.ElementAt(1).toStringShort()); fullHand = new byte[] { matchState.state.HoleCards[0, 0], matchState.state.HoleCards[0, 1] }; holeCards1 = new byte[] { fullHand[0], fullHand[1] }; boardCards1 = new byte[] { }; boardCards = cd.getComunitaryCards(); if (boardCards.Count >= 3 && holeCardsConhecidas) { matchState.state.BoardCards[0] = LIACC.Poker.Cards.Card.MakeCard(boardCards[0].toStringShort()); matchState.state.BoardCards[1] = LIACC.Poker.Cards.Card.MakeCard(boardCards[1].toStringShort()); matchState.state.BoardCards[2] = LIACC.Poker.Cards.Card.MakeCard(boardCards[2].toStringShort()); fullHand = new byte[] { matchState.state.HoleCards[0, 0], matchState.state.HoleCards[0, 1], matchState.state.BoardCards[0], matchState.state.BoardCards[1], matchState.state.BoardCards[2] }; holeCards1 = new byte[] { fullHand[0], fullHand[1] }; boardCards1 = new byte[] { fullHand[2], fullHand[3], fullHand[4] }; if (boardCards.Count == 4 || boardCards.Count == 5) { matchState.state.BoardCards[3] = LIACC.Poker.Cards.Card.MakeCard(boardCards[3].toStringShort()); fullHand = new byte[] { matchState.state.HoleCards[0, 0], matchState.state.HoleCards[0, 1], matchState.state.BoardCards[0], matchState.state.BoardCards[1], matchState.state.BoardCards[2], matchState.state.BoardCards[3] }; boardCards1 = new byte[] { fullHand[2], fullHand[3], fullHand[4], fullHand[5] }; if (boardCards.Count == 5) { matchState.state.BoardCards[4] = LIACC.Poker.Cards.Card.MakeCard(boardCards[4].toStringShort()); fullHand = new byte[] { matchState.state.HoleCards[0, 0], matchState.state.HoleCards[0, 1], matchState.state.BoardCards[0], matchState.state.BoardCards[1], matchState.state.BoardCards[2], matchState.state.BoardCards[3], matchState.state.BoardCards[4] }; boardCards1 = new byte[] { fullHand[2], fullHand[3], fullHand[4], fullHand[5], fullHand[6] }; } } } Console.WriteLine("Probabilidade da mão: "); Hand.PrintHand(fullHand); var prob = Hand.Equity(holeCards1, boardCards1, 1, game, random); probabilties = prob; Console.WriteLine(" é " + prob); } } int state = printState(cd.getComunitaryCards().Count); if (state == 0 && estado != state) { //If the actual state is pre-flop and the previous is different than pre-flop, then it's a new game newGame = true; estado = state; } cd.printComunitaryCards(); //Detect if it is my turn to play myTurn = cd.buttonsVisible(img); } if (newGame) { Console.WriteLine("?????: " + players[0].getStack()); //Adding chips (not working) if (players[0].getStack() <= 0) { Console.WriteLine("A adicionar fichas"); VirtualMouse1 vr = new VirtualMouse1(hWnd); Thread.Sleep(500); vr.addChips(true); } if (startValue >= 0) { if (endValue < 0) { endValue = 0; } database.GameStats gs = new database.GameStats(DateTime.Now.ToString(), startValue, endValue, endValue - startValue, 0); database.SQLiteDatabase.InsertGame(gs); } startValue = endValue; Console.WriteLine("New Game started"); appendTextBox("New Game Started"); //Criar um objeto do tipo Game, no inicio de cada jogo, com as regras do jogo atual. game = new Game(); //escolher tipo de jogo: limit ou nolimit game.BettingType = BettingType.NoLimit; //número de cartas de mesa que são adicionadas em cada ronda. no limit é sempre: game.NumBoardCards = new byte[] { 0, 3, 1, 1 }; //mesmo para cartas do jogador game.NumHoleCards = 2; //número máximo de raises em cada ronda. no no-limit texas hold'em não há limite... vamos colocar o máximo possível game.MaxRaises = new byte[] { 255, 255, 255, 255 }; //tamanho dos raises em cada ronda. não interessa para o no-limit poker game.RaiseSize = new int[] { }; //configurar o baralho. sempre igual game.NumRanks = 13; game.NumSuits = 4; //número de rondas game.NumRounds = 4; ///////////////////////// //// NOTA: Até aqui a configuração das regras é fixa! A partir das instruções abaixo, depende //// das condições iniciais do jogo específico!! //////////////////////// //indicar o numero de joadores //os jogadores são numerados de 0 a N-1 //não deves considerar os seats vazios! game.NumPlayers = 9; //escolher a estrutura de blinds por assento. //neste exemplo os jogadores na posicao 1 e na posicao 2 pagaram respetivamente 10 e 20. //nota que os valores sao sempre inteiros (considera a representacao em centimos de dolar) int[] blinds = cd.detectSmallAndBigBlind(hWnd); Console.WriteLine("SmallBlind: " + blinds[0] + " BigBlind: " + blinds[1]); game.Blind[1] = blinds[0]; game.Blind[2] = blinds[1]; //indicar qual dos jogadores é o primeiro a jogar em cada ronda. //fiz uma função para auxiliar a atribuição para o no limit poker. //neste caso o primeiro jogador seria o que está na posição 2. game.FirstPlayer = GetFirstPlayerNoLimit(2, game.NumPlayers); //preencher os valores iniciais de dinheiro de cada jogador. preencher em centimos //jogador 0 tem 10 euros, jogador 1 tem 15 euros, jogador 2 tem 5 euros, jogador 3 tem 9.50 e jogador 4 tem 2 euros game.Stack = new[] { players[0].getStack(), players[1].getStack(), players[2].getStack(), players[3].getStack(), players[4].getStack(), players[5].getStack(), players[6].getStack(), players[7].getStack(), players[8].getStack() }; //Inicar um state para o jogo. O argumento handid (1337) é só um identificador para o estado, podes colocar o que quiseres //o argumento viewingPlayer (2) indica a posição na mesa do teu bot matchState = new MatchState(new State(1337, game), 0); //para modificar o estado do jogo é necessário ocorrer ações //as acções são executadas sequencialmente, e o estado do jogo é automáticamente modificado //não é necessário indicar quem realizou a ação newGame = false; runningAgent = true; } //Sleep for one second Thread.Sleep(1000); secondCount++; //To ensure that it does not take long to detect again the table cards if (secondCount == 3) { secondCount = 0; changes = true; } else { changes = false; } //Displaying the image //ibOriginal.Image = img; first = false; //Setting the stack old values for (int i = 0; i < cd.playerStacks.Length; i++) { oldValues[i] = cd.playerStacks[i]; } //Sending the event to the agent if (Evt != null) { Evt(cd, players, probabilties, myTurn, hWnd, img); } //Dipose the image img.Dispose(); } }