Skip to content

Commit

Permalink
T: OH: new symbol isrush
Browse files Browse the repository at this point in the history
  • Loading branch information
TheHighFish committed Apr 26, 2015
1 parent 83c6fbc commit ca9636e
Show file tree
Hide file tree
Showing 9 changed files with 195 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ NEW STUFF:
Thanks to BadHabit for the patch,
Termitapalahermita an Relhby for help and advice.
[THF]
- New symbol isrush, especially meant to control flexible
heartbeat delays between fold and new game.
[THF]

MAINTENANCE:
- Renaming many PT stats. Please see:
Expand Down
4 changes: 4 additions & 0 deletions OpenHoldem/CEngineContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "CSymbolEngineICM.h"
#include "CSymbolEngineIniFunctions.h"
#include "CSymbolEngineIsOmaha.h"
#include "CSymbolEngineIsRush.h"
#include "CSymbolEngineIsTournament.h"
#include "CSymbolEngineMemorySymbols.h"
#include "CSymbolEngineMTTInfo.h"
Expand Down Expand Up @@ -201,6 +202,9 @@ void CEngineContainer::CreateSymbolEngines() {
// CSymbolEngineMTTInfo"
p_symbol_engine_mtt_info = new CSymbolEngineMTTInfo;
AddSymbolEngine(p_symbol_engine_mtt_info);
// CSymbolEngineIsRush
p_symbol_engine_isrush = new CSymbolEngineIsRush;
AddSymbolEngine(p_symbol_engine_isrush);
// CSymbolEngineIniFunctions
// "depends" on all other engines,
// as it can only be called after all symbols have been initialized.
Expand Down
7 changes: 6 additions & 1 deletion OpenHoldem/CHeartbeatThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "CStableFramesCounter.h"
#include "CSessionCounter.h"
#include "CSymbolEngineAutoplayer.h"
#include "CSymbolEngineIsRush.h"
#include "CSymbolEngineUserchair.h"
#include "..\CTablemap\CTablemap.h"
#include "CTableMapLoader.h"
Expand Down Expand Up @@ -98,7 +99,11 @@ void CHeartbeatThread::FlexibleHeartbeatSleeping() {
scrape_delay *= 2;
} else if (!p_table_state->User()->HasKnownCards()) {
// Folded
if (p_symbol_engine_active_dealt_playing->nopponentsplaying() >= 3) {
if (p_symbol_engine_isrush->isrush()) {
// New hand starts soon
// Don't change delay
}
else if (p_symbol_engine_active_dealt_playing->nopponentsplaying() >= 3) {
// Multiway, not participating.
// Hand will continue for some time.
scrape_delay *= 2;
Expand Down
45 changes: 45 additions & 0 deletions OpenHoldem/CSymbolEngineIsRush.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//*******************************************************************************
//
// This file is part of the OpenHoldem project
// Download page: http://code.google.com/p/openholdembot/
// Forums: http://www.maxinmontreal.com/forums/index.php
// Licensed under GPL v3: http://www.gnu.org/licenses/gpl.html
//
//*******************************************************************************
//
// Purpose: Detecting if we plaz rush / zoom / ...
// depending on the time since our last action on handreset.
//
//*******************************************************************************

#ifndef INC_CSYMBOLENGINEISRUSH_H
#define INC_CSYMBOLENGINEISRUSH_H

#include "CVirtualSymbolEngine.h"

class CSymbolEngineIsRush: public CVirtualSymbolEngine {
public:
CSymbolEngineIsRush();
~CSymbolEngineIsRush();
public:
// Mandatory reset-functions
void InitOnStartup();
void ResetOnConnection();
void ResetOnHandreset();
void ResetOnNewRound();
void ResetOnMyTurn();
void ResetOnHeartbeat();
public:
// Public accessors
bool EvaluateSymbol(const char *name, double *result, bool log = false);
CString SymbolsProvided();
public:
bool isrush();
private:
double sum_of_handreset_durations;
int handresets;
};

extern CSymbolEngineIsRush *p_symbol_engine_isrush;

#endif INC_CSYMBOLENGINEUSERCHAIR_H
103 changes: 103 additions & 0 deletions OpenHoldem/CSymbolengineIsRush.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
//*******************************************************************************
//
// This file is part of the OpenHoldem project
// Download page: http://code.google.com/p/openholdembot/
// Forums: http://www.maxinmontreal.com/forums/index.php
// Licensed under GPL v3: http://www.gnu.org/licenses/gpl.html
//
//*******************************************************************************
//
// Purpose: Detecting if we plaz rush / zoom / ...
// depending on the time since our last action on handreset.
//
//*******************************************************************************

#include "stdafx.h"
#include "CSymbolEngineIsRush.h"

#include "CPreferences.h"
#include "CScraper.h"
#include "CSymbolEngineIsTournament.h"
#include "CSymbolEngineTime.h"
#include "CTableState.h"
#include "MagicNumbers.h"

CSymbolEngineIsRush *p_symbol_engine_isrush = NULL;

// Maximum average time between last action and handreset
// if the game should be considered rush / zoom.
// Ploease note: detecting hand-resets can take several heartbeats (2..4)
// so this value might need some fine-tuning.
const int kMaxAverageDurationOfHandreset = 4;

CSymbolEngineIsRush::CSymbolEngineIsRush() {
// The values of some symbol-engines depend on other engines.
// As the engines get later called in the order of initialization
// we assure correct ordering by checking if they are initialized.
assert(p_symbol_engine_time != NULL);
assert(p_symbol_engine_istournament != NULL);
}

CSymbolEngineIsRush::~CSymbolEngineIsRush() {
}

void CSymbolEngineIsRush::InitOnStartup() {
ResetOnConnection();
}

void CSymbolEngineIsRush::ResetOnConnection() {
sum_of_handreset_durations = 0.0;
// Init to 1 to avoid division by zero
handresets = 1;
}

void CSymbolEngineIsRush::ResetOnHandreset() {
if (p_symbol_engine_time->elapsedauto() > 60) {
// Unreliable value, we might have been sitting out
return;
}
sum_of_handreset_durations += p_symbol_engine_time->elapsedauto();
++handresets;
}

void CSymbolEngineIsRush::ResetOnNewRound() {
}

void CSymbolEngineIsRush::ResetOnMyTurn() {
}

void CSymbolEngineIsRush::ResetOnHeartbeat() {
}

bool CSymbolEngineIsRush::isrush() {
if (p_symbol_engine_istournament->istournament()) {
// Not a cash-game, therefore not rush
write_log(preferences.debug_symbolengine(),
"[CSymbolEngineIsRush] Tournament, therefore not rush / zoom\n");
return false;
}
assert(handresets > 0);
write_log(preferences.debug_symbolengine(),
"[CSymbolEngineIsRush] Average duration of hand-reset: %.2f\n",
sum_of_handreset_durations / handresets);
if (sum_of_handreset_durations / handresets > kMaxAverageDurationOfHandreset) {
// Too long duration
return false;
}
return true;
}

bool CSymbolEngineIsRush::EvaluateSymbol(const char *name, double *result, bool log /* = false */) {
FAST_EXIT_ON_OPENPPL_SYMBOLS(name);
if (memcmp(name, "isrush", 6)==0) {
*result = isrush();
return true;
}
// Symbol of a different symbol-engine
return false;
}

CString CSymbolEngineIsRush::SymbolsProvided() {
return "isrush ";
}

71 changes: 25 additions & 46 deletions OpenHoldem/CTablePositioner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,21 @@ CTablePositioner::~CTablePositioner()
{}

// To be called once after connection
void CTablePositioner::PositionMyWindow()
{
void CTablePositioner::PositionMyWindow() {
// Build list of poker tables (child windows)
// Use the shared memory (auto-connector) for that.
HWNDs_of_child_windows = p_sharedmem->GetDenseListOfConnectedPokerWindows();
_number_of_tables = p_sharedmem->SizeOfDenseListOfAttachedPokerWindows();

if (_number_of_tables <= 0)
{
if (_number_of_tables <= 0) {
// Do nothing if there are 0 tables connected.
// Actually an empty list of tables consists of only NULLs,
// but if MicroSofts table-arranging functions see a NULL
// they will arrange all windows at the desktop.
// That's not what we want.
MessageBox(0, "No tables", "blocker", 0);
return;
}
if (preferences.table_positioner_options() == k_position_tables_tiled)
{
if (preferences.table_positioner_options() == k_position_tables_tiled) {
write_log(preferences.debug_table_positioner(), "[CTablePositioner] PositionMyWindow() Going to tile %d windows...\n", _number_of_tables);
PositionMyWindow(HWNDs_of_child_windows);
// Tiling windows: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633554(v=vs.85).aspx
Expand All @@ -66,9 +62,7 @@ void CTablePositioner::PositionMyWindow()
_number_of_tables,
HWNDs_of_child_windows);
*/
}
else if (preferences.table_positioner_options() == k_position_tables_cascaded)
{
} else if (preferences.table_positioner_options() == k_position_tables_cascaded) {
write_log(preferences.debug_table_positioner(), "[CTablePositioner] PositionMyWindow() Going to cascade %d windows...\n", _number_of_tables);
// Cascading windows: http://msdn.microsoft.com/en-us/library/windows/desktop/ms632674(v=vs.85).aspx
CascadeWindows(
Expand All @@ -77,19 +71,15 @@ void CTablePositioner::PositionMyWindow()
NULL, // Target area; NULL = parent window, here desktop
_number_of_tables,
HWNDs_of_child_windows);
}
else
{
} else {
// preferences.table_positioner_options() == k_position_tables_never
write_log(preferences.debug_table_positioner(), "[CTablePositioner] PositionMyWindow() Not doing anything because of preferences.\n");
}
}

void CTablePositioner::PositionMyWindow(HWND *list_of_tables)
{
void CTablePositioner::PositionMyWindow(HWND *list_of_tables) {
assert(p_autoconnector != NULL);
if (!p_autoconnector->IsConnected())
{
if (!p_autoconnector->IsConnected()) {
// This should not happen, as this function gets only called after connection
// But it does not hurt to avoid trouble with p_autoconnector->attached_hwnd()
return;
Expand All @@ -106,8 +96,7 @@ void CTablePositioner::PositionMyWindow(HWND *list_of_tables)
write_log(preferences.debug_table_positioner(), "[CTablePositioner] PositionMyWindow() Connected to window %i\n", p_autoconnector->attached_hwnd());
write_log(preferences.debug_table_positioner(), "[CTablePositioner] PositionMyWindow() Table size: %ix%i\n", _table_size_x, _table_size_y);
write_log(preferences.debug_table_positioner(), "[CTablePositioner] PositionMyWindow() Desktop size: %ix%i\n", _desktop_rectangle.right, _desktop_rectangle.bottom);
if (_number_of_tables == 1)
{
if (_number_of_tables == 1) {
// No other tables at the moment,
// so we don't really have to care about overlaps.
// Moving this table to the top-left (0, 0) however,
Expand All @@ -122,20 +111,16 @@ void CTablePositioner::PositionMyWindow(HWND *list_of_tables)
// and then try to dock at the left or top of known windows.
// Main advantage: we have to search in 2 direction only
// if the desktop gets empty again.
if (TryBottomRightPosition())
{
if (TryBottomRightPosition()) {
return;
}
for (int i=0; i<_number_of_tables; i++)
{
for (int i=0; i<_number_of_tables; i++) {
HWND HWND_of_potential_neighbour_table = list_of_tables[i];
write_log(preferences.debug_table_positioner(), "[CTablePositioner] PositionMyWindow() Trying neighbour-table %i\n", HWND_of_potential_neighbour_table);
if (TryLeftSideOfTable(HWND_of_potential_neighbour_table))
{
if (TryLeftSideOfTable(HWND_of_potential_neighbour_table)) {
return;
}
if (TryTopSideOfTable(HWND_of_potential_neighbour_table))
{
if (TryTopSideOfTable(HWND_of_potential_neighbour_table)) {
return;
}
}
Expand All @@ -145,8 +130,7 @@ void CTablePositioner::PositionMyWindow(HWND *list_of_tables)
MoveToTopLeft();
}

bool CTablePositioner::TryLeftSideOfTable(HWND HWND_of_potential_neighbour_table)
{
bool CTablePositioner::TryLeftSideOfTable(HWND HWND_of_potential_neighbour_table) {
RECT position_of_potential_neigbour_table;
GetWindowRect(HWND_of_potential_neighbour_table, &position_of_potential_neigbour_table);
write_log(preferences.debug_table_positioner(), "[CTablePositioner] TryLeftSideOfTable() Neighbours position: %i, %i, %i, %i\n",
Expand All @@ -158,18 +142,16 @@ bool CTablePositioner::TryLeftSideOfTable(HWND HWND_of_potential_neighbour_table
return TryPosition(my_left_x, my_top_y);
}

bool CTablePositioner::TryTopSideOfTable(HWND HWND_of_potential_neighbour_table)
{
bool CTablePositioner::TryTopSideOfTable(HWND HWND_of_potential_neighbour_table) {
RECT position_of_potential_neigbour_table;
GetWindowRect(HWND_of_potential_neighbour_table, &position_of_potential_neigbour_table);
write_log(preferences.debug_table_positioner(), "[CTablePositioner] TryTopSideOfTable() Trying bottom side of neighbour\n");
write_log(preferences.debug_table_positioner(), "[CTablePositioner] TryTopSideOfTable() Trying top side of neighbour\n");
int my_left_x = position_of_potential_neigbour_table.left;
int my_top_y = position_of_potential_neigbour_table.bottom - _table_size_y;
int my_top_y = position_of_potential_neigbour_table.top - _table_size_y;
return TryPosition(my_left_x, my_top_y);
}

bool CTablePositioner::TryBottomRightPosition()
{
bool CTablePositioner::TryBottomRightPosition() {
int left_x = _desktop_rectangle.right - _table_size_x + 1;
int top_y = _desktop_rectangle.bottom - _table_size_y + 1;
write_log(preferences.debug_table_positioner(), "[CTablePositioner] TryBottomRightPosition()\n");
Expand Down Expand Up @@ -207,18 +189,17 @@ bool CTablePositioner::TryPosition(int left_x, int top_y)
return true;
}

bool CTablePositioner::PotentialNewPositionOverlapsTable(int left_x,
int top_y, HWND table_to_check_for_overlapping)
{
bool CTablePositioner::PotentialNewPositionOverlapsTable(
int left_x,
int top_y,
HWND table_to_check_for_overlapping) {
// Sanity check for real tables in the list
if (!IsWindow(table_to_check_for_overlapping))
{
if (!IsWindow(table_to_check_for_overlapping)) {
write_log(preferences.debug_table_positioner(), "[CTablePositioner] PotentialNewPositionOverlapsTable() Not a window, therefore no overlap\n");
return false;
}
// Make sure, we don't exceed the desktop
if ((left_x < 0) || (top_y < 0))
{
if ((left_x < 0) || (top_y < 0)) {
// No good position
// Treat it as overlap
write_log(preferences.debug_table_positioner(), "[CTablePositioner] PotentialNewPositionOverlapsTable() Out of desktop. No valid position\n");
Expand All @@ -238,17 +219,15 @@ bool CTablePositioner::PotentialNewPositionOverlapsTable(int left_x,
GetWindowRect(table_to_check_for_overlapping,
&position_of_table_to_check_for_overlapping);
if ((left_x > position_of_table_to_check_for_overlapping.right)
|| (top_y > position_of_table_to_check_for_overlapping.bottom))
{
|| (top_y > position_of_table_to_check_for_overlapping.bottom)) {
write_log(preferences.debug_table_positioner(), "[CTablePositioner] PotentialNewPositionOverlapsTable() No overlap. Potential good position\n");
// No overlap
return false;
}
// No overlap so far
// Continue with right_x and bottom_y
if ((right_x < position_of_table_to_check_for_overlapping.left)
|| (bottom_y < position_of_table_to_check_for_overlapping.top))
{
|| (bottom_y < position_of_table_to_check_for_overlapping.top)) {
write_log(preferences.debug_table_positioner(), "[CTablePositioner] PotentialNewPositionOverlapsTable() No overlap. Potential good position\n");
// No overlap
return false;
Expand Down
1 change: 1 addition & 0 deletions OpenHoldem/DialogFormulaScintilla.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1999,6 +1999,7 @@ void CDlgFormulaScintilla::PopulateSymbols()
AddSymbol(parent, "ismtt", "true if a multi-table tournament is detected");
AddSymbol(parent, "issng", "true if a single-table tournament is detected");
AddSymbol(parent, "isfinaltable", "true if you are playing the finaltable of an MTT and the tables can be visually distinguished.");
AddSymbol(parent, "isrush", "true if the game is rush / zoom.");

mainParent = parent = AddSymbolTitle("MTT Info", NULL, hCatItem);
AddSymbol(parent, "mtt_number_entrants", "number of entrants in the tournament");
Expand Down
Loading

0 comments on commit ca9636e

Please sign in to comment.