Table Selection API

# Table Selection API

Design for a table selection module that interacts with poker platform lobbies to find optimal tables for bot deployment.

---

## Overview

The table selection module sits between the poker platform and the bot framework:

```
Poker Platform Lobby ←→ Table Selector ←→ Bot Framework
   (scraping/API)        (scoring)         (strategy bot)
```

---

## Selection Criteria

| Criterion | Source | Weight |
|-----------|--------|--------|
| Average pot size | Lobby stats | High — bigger pots = more profit |
| Player skill level | Observed stats / notes | High — weaker opponents preferred |
| Table fullness | Lobby stats | Medium — avoid nearly-full tables |
| Blind level | Lobby stats | Filter — must match bot config |
| Game type (NL/FL/PL) | Lobby stats | Filter — must match bot strategy |
| Average VPIP of seated players | Tracked statistics | Medium — high VPIP = loose players |

---

## Architecture

```rust
struct TableSelector {
    platform: Box<dyn PokerPlatformAPI>,
}

trait PokerPlatformAPI {
    fn fetch_tables(&self) -> Vec<Table>;
    fn join_table(&self, table_id: &TableId) -> Result<()>;
    fn leave_table(&self, table_id: &TableId) -> Result<()>;
}

struct TableCriteria {
    game_type: GameType,          // NL, FL, PL
    table_size: Range<usize>,     // e.g., 6..=10
    blind_range: Range<f64>,      // BB range
    min_avg_pot: Option<f64>,
    max_skill_level: Option<f64>,
}

struct Table {
    id: TableId,
    name: String,
    game_type: GameType,
    num_seats: usize,
    num_players: usize,
    big_blind: f64,
    average_pot: f64,
    players: Vec<PlayerInfo>,
}
```

### Table Scoring

```rust
impl TableSelector {
    fn select_table(&self, criteria: &TableCriteria) -> Option<Table> {
        self.platform.fetch_tables()
            .into_iter()
            .filter(|t| self.matches(t, criteria))
            .max_by_key(|t| self.score(t, criteria))
    }

    fn score(&self, table: &Table, criteria: &TableCriteria) -> f64 {
        let mut score = 0.0;
        score += table.average_pot * 0.4;           // Favor big pots
        score += self.avg_opponent_weakness(table) * 0.4;  // Favor weak opponents
        score += (table.num_seats - table.num_players) as f64 * 0.2; // Favor open seats
        score
    }
}
```

---

## Platform Adapters

Each poker platform gets its own adapter implementing `PokerPlatformAPI`:

- **Scraping adapter** — reads screen/DOM elements from browser poker client
- **Protocol adapter** — intercepts and parses network protocol messages
- **API adapter** — uses official platform API if available

The extension (see "Browser Extension" note) provides the scraping/protocol layer. The table selector consumes it.

---

## Integration with Bot Framework

1. Table selector identifies optimal table via `select_table()`
2. Platform adapter joins the table
3. Bot framework receives `GameInfo` events from the table
4. Strategy bot produces actions
5. Platform adapter executes actions on the table

---

## Future Enhancements

- **Multi-table coordination** — manage multiple tables simultaneously
- **Dynamic table switching** — leave tables when conditions deteriorate
- **Bankroll-aware selection** — avoid tables above sustainable stake level
- **Time-based patterns** — track when fish tend to play (evenings, weekends)

id: df17fb33c80046ee8826ce5ecca785f6
parent_id: 2c8da247905946c3aa19eb4936e16323
created_time: 2025-02-13T05:34:13.336Z
updated_time: 2026-05-31T11:00:24.257Z
is_conflict: 0
latitude: 48.20817430
longitude: 16.37381890
altitude: 0.0000
author: 
source_url: 
is_todo: 0
todo_due: 0
todo_completed: 0
source: joplin-desktop
source_application: net.cozic.joplin-desktop
application_data: 
order: 0
user_created_time: 2025-02-13T05:34:13.336Z
user_updated_time: 2026-05-31T11:00:24.257Z
encryption_cipher_text: 
encryption_applied: 0
markup_language: 1
is_shared: 0
share_id: 
conflict_original_id: 
master_key_id: 
user_data: 
deleted_time: 0
type_: 1