fix infinite check bug
[rofl0r-oopoker.git] / ai_human.cpp
blobf0888e8c454bda63ed726c843a37f7b1d55b3256
1 /*
2 OOPoker
4 Copyright (c) 2010 Lode Vandevenne
5 All rights reserved.
7 This file is part of OOPoker.
9 OOPoker is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 OOPoker is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with OOPoker. If not, see <http://www.gnu.org/licenses/>.
23 #include "ai_human.h"
24 #include "host_terminal.h"
25 #include "io_terminal.h"
26 #include "pokermath.h"
27 #include "util.h"
28 #include "info.h"
30 struct Options
32 int sleepMS; //how much milliseconds to sleep per player (to have effect of AI's thinking)
34 bool offerBoastCards;
36 bool autoAnalytics;
38 Options();
42 Options options;
44 Options::Options()
45 : sleepMS(500)
46 , offerBoastCards(false)
47 , autoAnalytics(false)
51 void editOptions(Options& options)
53 std::cout << "Enter value to change option:\n\
54 0: set speed to fast\n\
55 1: set speed to medium\n\
56 2: set speed to slow\n\
57 3: set speed to slowest\n\
58 4: toggle offer boast cards\n\
59 5: toggle auto analytics\n\
60 6: toggle unicode card symbols\n" << std::endl;
62 std::string s = getLine();
64 if(s == "0") options.sleepMS = 0;
65 else if(s == "1") options.sleepMS = 500;
66 else if(s == "2") options.sleepMS = 1000;
67 else if(s == "3") options.sleepMS = 2000;
68 else if(s == "4") options.offerBoastCards = !options.offerBoastCards;
69 else if(s == "5") options.autoAnalytics = !options.autoAnalytics;
70 #if defined(_WIN32)
71 else if(s == "6") CARDPRINTMODE = CARDPRINTMODE ? 0 : 1;
72 #else
73 else if(s == "6") CARDPRINTMODE = CARDPRINTMODE ? 0 : 2;
74 #endif
77 void editOptions()
79 editOptions(options);
82 AIHuman::AIHuman(HostTerminal* host)
83 : host(host)
85 host->setHasHumanPlayer(true);
88 static std::string getHarringtonZone(double mratio)
90 if(mratio >= 20) return "Green";
91 else if(mratio >= 10) return "Yellow";
92 else if(mratio >= 6) return "Orange";
93 else if(mratio >= 1) return "Red";
94 else return "Dead";
97 static void showAnalytics(const Info& info)
99 std::cout << std::endl;
100 std::cout << " * Analytics * " << std::endl;
101 Combination combo;
102 getCombo(combo, info.getHandTableVector());
103 std::cout << "> Hand: " << combo.getNameWithAllCardsPrintable() << std::endl;
104 if(!info.boardCards.empty()) {
105 getCombo(combo, info.boardCards);
106 std::cout << "> Table only: " << combo.getNameWithAllCardsPrintable() << std::endl;
108 if(info.round == R_PRE_FLOP)
110 std::cout << "> Group: " << getSklanskyMalmuthGroup(info.getHoleCards()[0], info.getHoleCards()[1]) << std::endl;
112 else
114 std::cout << "> Pot Equity: " << info.getPotEquity() << std::endl;
116 std::cout << "> Pot Odds: " << info.getPotOdds() << std::endl;
117 std::cout << "> M Ratio: " << info.getMRatio() << " (" << getHarringtonZone(info.getMRatio()) << ")" << std::endl;
120 Action AIHuman::doTurn(const Info& info)
122 int call = info.getCallAmount();
124 drawTable(info);
126 int amount = 0;
127 for(;;)
129 if(options.autoAnalytics) showAnalytics(info);
131 std::cout << std::endl;
132 std::cout << "Enter chip amount to move to the table, or letter for special action" << std::endl;
133 //(" << call << " to call, min " << (info.minRaiseAmount + call) << " to raise, q to quit, o for options): ";
134 std::cout << "Options: q = quit, a = analytics, o = options, number = wager chips" << std::endl;
135 if (call == 0) std::cout << "Enter amount (" << call << " to call, min " << info.getMinChipsToRaise() << " to raise): " << std::endl;
136 else std::cout << "Enter amount (" << call << " to call, min " << info.getMinChipsToRaise() << " to raise, 0 to fold): " << std::endl;
137 std::string s = getLine();
138 if(s == "q" || s == "Q")
140 host->setQuitSignalFromHumanPlayer();
141 return Action(A_FOLD);
143 else if(s == "o" || s == "O")
145 editOptions();
147 else if(s == "a" || s == "A")
149 showAnalytics(info);
151 else
153 amount = strtoval<int>(s);
154 break;
158 std::cout << "you entered: " << amount << std::endl;
159 return info.amountToAction(amount);
162 void AIHuman::onEvent(const Event& event)
164 if(event.type == E_POT_DIVISION)
166 std::cout << std::endl << "$$$$$$$$$$" << std::endl << std::endl;
169 std::cout << "> " << eventToStringVerbose(event) << std::endl;
171 std::vector<Card> cards;
172 if(event.type == E_RECEIVE_CARDS)
174 cards.push_back(event.card1); cards.push_back(event.card2);
176 else if(event.type == E_FLOP)
178 cards.push_back(event.card1); cards.push_back(event.card2); cards.push_back(event.card3);
180 else if(event.type == E_TURN)
182 cards.push_back(event.card1); cards.push_back(event.card2); cards.push_back(event.card3); cards.push_back(event.card4);
184 else if(event.type == E_RIVER)
186 cards.push_back(event.card1); cards.push_back(event.card2); cards.push_back(event.card3); cards.push_back(event.card4); cards.push_back(event.card5);
188 if(!cards.empty()) std::cout << cardsToAsciiArt(cards) << std::endl;
190 bool no_wait = false;
191 if(event.type == E_JOIN) no_wait = true;
192 if(event.type == E_PLAYER_SHOWDOWN) no_wait = true;
193 if(event.type == E_SMALL_BLIND) no_wait = true;
194 if(event.type == E_BIG_BLIND) no_wait = true;
195 if(event.type == E_ANTE) no_wait = true;
196 if(event.type == E_TOURNAMENT_RANK) no_wait = true;
197 if(event.type == E_REVEAL_AI) no_wait = true;
199 if(!no_wait) sleepMS(options.sleepMS);
202 bool AIHuman::boastCards(const Info& info)
204 if(options.offerBoastCards)
206 drawTable(info);
208 std::cout << "boast cards? (y/n)" << std::endl;
209 char c = getChar();
210 return c == 'y' || c == 'Y';
212 else return false;
215 std::string AIHuman::getAIName()
217 return "Human";