Advertisement

← poker-tutor

Sources/pokerlab/main.swift

5.3 KB Download file
import Foundation
import PokerCore
import PokerAI
import PokerCoach
import PokerTests
import PokerSession

/// Command-line driver for the poker engine. `pokerlab test` runs the suites;
/// `pokerlab tournament` plays one out so the engine can be watched working.

let args = Array(CommandLine.arguments.dropFirst())
let command = args.first ?? "test"

func flag(_ name: String) -> Bool { args.contains("--\(name)") }

func value(_ name: String) -> String? {
    guard let i = args.firstIndex(of: "--\(name)"), i + 1 < args.count else { return nil }
    return args[i + 1]
}

/// `--format cash` sits the session at a cash table (`--structure fixedLimit|potLimit|noLimit`,
/// `--stakes 50/100`); anything else is the tournament the commands always played.
let labFormat: AppVariant.Format = value("format") == "cash" ? .cash : .tournament
let labStructure: BettingStructure = BettingStructure(rawValue: value("structure") ?? "noLimit") ?? .noLimit
let labSetup: CashSetup = {
    var setup = CashSetup.standard
    setup.structure = labStructure
    if let stakes = value("stakes")?.split(separator: "/").compactMap({ Int($0) }), stakes.count == 2 {
        setup.stakes = BlindLevel(smallBlind: stakes[0], bigBlind: stakes[1])
    }
    return setup
}()

switch command {

case "test":
    let ok = runAllTests(verbose: flag("verbose"), filter: value("filter"))
    exit(ok ? 0 : 1)

case "tournament":
    let players = Int(value("players") ?? "9") ?? 9
    let seed = UInt64(value("seed") ?? "1") ?? 1
    let verbose = flag("verbose")
    runTournament(players: players, seed: seed, verbose: verbose)

case "seat-sweep":
    runSeatSweep(playerName: value("player") ?? "control",
                 hands: Int(value("hands") ?? "6000") ?? 6000,
                 seedCount: Int(value("seeds") ?? "4") ?? 4,
                 firstSeed: UInt64(value("seed") ?? "11") ?? 11,
                 rung: Int(value("rung") ?? "0") ?? 0)

case "shootout":
    runShootout(hands: Int(value("hands") ?? "3000") ?? 3000, seed: UInt64(value("seed") ?? "1") ?? 1,
                stack: Int(value("stack") ?? "10000") ?? 10000, structure: labStructure)

case "coach":
    if labFormat == .cash { AppVariant.use(.pokerTutorCash) }
    let coachHands = Int(value("hands") ?? "320") ?? 320
    let coachSeed = UInt64(value("seed") ?? "4242") ?? 4242
    let coachSamples = Int(value("samples") ?? "4") ?? 4
    let coachRung = Int(value("rung") ?? "0") ?? 0
    runCoach(hands: coachHands, seed: coachSeed, playerName: value("player") ?? "control",
             samples: coachSamples, showProfile: flag("profile"),
             format: labFormat, setup: labSetup, rung: coachRung,
             keepEveryReview: flag("all"), breakdown: flag("breakdown"))

case "sweep":
    runSweep(playerName: value("player") ?? "control", againstName: value("against"),
             hands: Int(value("hands") ?? "4000") ?? 4000,
             seedCount: Int(value("seeds") ?? "12") ?? 12,
             firstSeed: UInt64(value("seed") ?? "4242") ?? 4242,
             format: labFormat, setup: labSetup, rung: Int(value("rung") ?? "0") ?? 0)

case "calibrate":
    runCalibration(hands: Int(value("hands") ?? "1200") ?? 1200,
                   seedCount: Int(value("seeds") ?? "6") ?? 6,
                   firstSeed: UInt64(value("seed") ?? "11") ?? 11,
                   format: labFormat, setup: labSetup)

case "demo-history":
    runDemoHistory(playerName: value("player") ?? "loose",
                   seed: UInt64(value("seed") ?? "9") ?? 9,
                   hands: Int(value("hands") ?? "320") ?? 320,
                   out: value("out") ?? "demo-hands.jsonl",
                   format: labFormat, setup: labSetup)

case "assess":
    if labFormat == .cash { AppVariant.use(.pokerTutorCash) }
    runAssessment(playerName: value("player") ?? "control",
                  seed: UInt64(value("seed") ?? "11") ?? 11,
                  hands: Int(value("hands") ?? "40") ?? 40,
                  setupID: value("setup"),
                  cash: labFormat == .cash ? labSetup : nil)

case "ablate":
    let styleName = value("style") ?? "solidRegular"
    let style = Personality.allCases.first { $0.rawValue.lowercased() == styleName.lowercased() } ?? .solidRegular
    runAblation(hands: Int(value("hands") ?? "400") ?? 400, seed: UInt64(value("seed") ?? "57") ?? 57,
                personality: style, seats: Int(value("seats") ?? "6") ?? 6)

case "diagnose":
    runDiagnose(hands: Int(value("hands") ?? "800") ?? 800, seed: UInt64(value("seed") ?? "57") ?? 57,
                stack: Int(value("stack") ?? "4000") ?? 4000, samples: Int(value("samples") ?? "0") ?? 0)

case "gen-preflop":
    generatePreflopTable(trials: Int(value("trials") ?? "20000") ?? 20000)

case "hand":
    runSingleHand(seed: UInt64(value("seed") ?? "1") ?? 1, players: Int(value("players") ?? "6") ?? 6)

default:
    print("""
    pokerlab — poker engine driver

      pokerlab test [--verbose] [--filter <text>]
      pokerlab tournament [--players N] [--seed N] [--verbose]
      pokerlab hand [--players N] [--seed N]
      pokerlab assess [--player <flaw>] [--seed N] [--hands N]
      any command that sits a session: --format cash [--structure fixedLimit|potLimit|noLimit] [--stakes 50/100]
      pokerlab shootout --structure fixedLimit
    """)
    exit(1)
}