diff --git a/.github/workflows/release win.yml b/.github/workflows/release win.yml
index 0cd1e67e..20de7d07 100644
--- a/.github/workflows/release win.yml
+++ b/.github/workflows/release win.yml
@@ -1,6 +1,7 @@
name: Binary Release Windows
-on: [push, pull_request]
+on:
+ workflow_dispatch:
jobs:
build:
diff --git a/poker/tools/mongo_manager.py b/poker/tools/mongo_manager.py
index e2244d64..a493f0cf 100644
--- a/poker/tools/mongo_manager.py
+++ b/poker/tools/mongo_manager.py
@@ -7,10 +7,10 @@
import requests
from PIL import Image
from fastapi.encoders import jsonable_encoder
+from requests.exceptions import JSONDecodeError
from poker.tools.helper import COMPUTER_NAME, get_config, get_dir
from poker.tools.singleton import Singleton
-from requests.exceptions import JSONDecodeError
TABLES_COLLECTION = 'tables'
@@ -78,11 +78,11 @@ def update_tensorflow_model(self, table_name: str, hdf5_file: bytes, model_str:
def load_table_nn_weights(self, table_name: str):
log.info("Downloading neural network weights for card recognition with tolerance...")
- weights_str = requests.post(URL + "get_tensorflow_weights", params={'table_name': table_name}).json()
try:
+ weights_str = requests.post(URL + "get_tensorflow_weights", params={'table_name': table_name}).json()
weights = base64.b64decode(weights_str)
- except TypeError:
- log.error("No Trained Neural Network found. The cards need to be trained first.")
+ except Exception as e:
+ log.error(f"No Trained Neural Network found. The cards need to be trained first. {e}")
return
with open(get_dir('codebase') + '/loaded_model.h5', 'wb') as fh:
diff --git a/website/src/App.css b/website/src/App.css
index ca47b388..0c7e432c 100644
--- a/website/src/App.css
+++ b/website/src/App.css
@@ -113,4 +113,8 @@
align-items: center;
justify-content: center;
padding: 2em;
-}
\ No newline at end of file
+}
+
+.main-content {
+ margin-top: 90px; /* Adjust this value based on your navbar's height */
+}
diff --git a/website/src/App.tsx b/website/src/App.tsx
index a3e32490..1bcbf357 100644
--- a/website/src/App.tsx
+++ b/website/src/App.tsx
@@ -1,17 +1,14 @@
-import ReactGA from 'react-ga'
-import { BrowserRouter } from "react-router-dom"
-import './App.css'
-import NavBar from './routes/NavBar'
-import Routing from "./routes/Routing"
-import { useEffect } from 'react'
-
+import ReactGA from "react-ga";
+import { BrowserRouter } from "react-router-dom";
+import "./App.css";
+import NavBar from "./routes/NavBar";
+import Routing from "./routes/Routing";
+import { useEffect } from "react";
const TRACKING_ID = "UA-7794836-7"; // OUR_TRACKING_ID
ReactGA.initialize(TRACKING_ID);
-
function App() {
-
useEffect(() => {
ReactGA.pageview(window.location.pathname + window.location.search);
}, []);
@@ -20,10 +17,12 @@ function App() {
<>
-
+
+
+
>
- )
+ );
}
-export default App
+export default App;
diff --git a/website/src/components/strategy_editor/PreFlopStrategy.tsx b/website/src/components/strategy_editor/PreFlopStrategy.tsx
new file mode 100644
index 00000000..3f419f2a
--- /dev/null
+++ b/website/src/components/strategy_editor/PreFlopStrategy.tsx
@@ -0,0 +1,248 @@
+import axios from "axios";
+import React, { useEffect, useState } from "react";
+import { API_URL } from "../../views/config";
+
+// Subcomponent for each hand scenario row
+const HandScenarioRow = ({
+ hand,
+ scenario,
+ position,
+ strategies,
+ onStrategyChange,
+}) => {
+ const [call, setCall] = useState(0);
+ const [raise, setRaise] = useState(0);
+
+ // Update call and raise when strategies or position changes
+ useEffect(() => {
+ const posStrategy = strategies[position]?.[hand]?.[scenario];
+ setCall(posStrategy?.call || 0);
+ setRaise(posStrategy?.raise || 0);
+ }, [hand, scenario, position, strategies]);
+
+ const handleCallChange = (e) => {
+ const newCall = Math.max(
+ 0,
+ Math.min(100, parseInt(e.target.value, 10) || 0)
+ );
+ onStrategyChange(hand, scenario, newCall, raise);
+ };
+
+ const handleRaiseChange = (e) => {
+ const newRaise = Math.max(
+ 0,
+ Math.min(100, parseInt(e.target.value, 10) || 0)
+ );
+ onStrategyChange(hand, scenario, call, newRaise);
+ };
+
+ const fold = 100 - call - raise;
+
+ return (
+ <>
+
+
+ %
+ |
+
+
+ %
+ |
+ {`${fold}%`} |
+ >
+ );
+};
+
+// Main component
+const PreFlopStrategyEditor = () => {
+ const [position, setPosition] = useState("0");
+ const [strategies, setStrategies] = useState({});
+
+ useEffect(() => {
+ const fetchPreflopValues = async () => {
+ try {
+ const response = await axios.get(
+ `${API_URL}/get_preflop_values/default`
+ );
+ setStrategies(response.data.preflop_values || {});
+ } catch (error) {
+ console.error("Error fetching preflop values:", error);
+ // Handle the error
+ }
+ };
+
+ fetchPreflopValues();
+ }, []);
+
+ const handleStrategyChange = (hand, scenario, call, raise) => {
+ setStrategies((prevStrategies) => ({
+ ...prevStrategies,
+ [position]: {
+ ...prevStrategies[position],
+ [hand]: {
+ ...prevStrategies[position]?.[hand],
+ [scenario]: { call, raise },
+ },
+ },
+ }));
+ };
+
+ const handlePositionChange = (e) => {
+ setPosition(e.target.value);
+ };
+
+ // Function to save all strategies for all positions
+ const saveStrategy = async () => {
+ try {
+ const response = await axios.post(`${API_URL}/save_preflop_values`, {
+ table_name: "default", // This could be a dynamic name based on your application logic
+ preflop_values: strategies, // Sending the entire strategies object
+ });
+
+ if (response.data.message) {
+ console.log(response.data.message);
+ // Optionally, display a success message to the user
+ }
+ } catch (error) {
+ console.error("Error saving preflop values:", error);
+ // Optionally, display an error message to the user
+ }
+ };
+
+ const scenarios = ["noCalls", "previousCalls", "previousRaises"];
+ const hands = [
+ "AA",
+ "KK",
+ "QQ",
+ "JJ",
+ "TT",
+ "99",
+ "88",
+ "77",
+ "66",
+ "55",
+ "44",
+ "33",
+ "22",
+ "AKs",
+ "AQs",
+ "AJs",
+ "ATs",
+ "A9s",
+ "A8s",
+ "A7s",
+ "A6s",
+ "A5s",
+ "A4s",
+ "A3s",
+ "A2s",
+ "KQs",
+ "KJs",
+ "KTs",
+ "K9s",
+ "K8s",
+ "K7s",
+ "K6s",
+ "K5s",
+ "K4s",
+ "K3s",
+ "QJs",
+ "QTs",
+ "Q9s",
+ "JTs",
+ "J9s",
+ "J8s",
+ "T9s",
+ "T8s",
+ "T7s",
+ "98s",
+ "97s",
+ "96s",
+ "87s",
+ "86s",
+ "85s",
+ "76s",
+ "75s",
+ "74s",
+ "65s",
+ "64s",
+ "63s",
+ "54s",
+ "53s",
+ "52s",
+ "43s",
+ "42s",
+ "AKo",
+ "AJo",
+ "ATo",
+ "KQo",
+ "KJo",
+ "QJo",
+ ];
+
+ return (
+
+
+
+
+
+
+ Hand |
+ No calls or raises | {/* Colspan of 3 for the scenario grouping */}
+ 1 or more calls | {/* Colspan of 3 for the scenario grouping */}
+ 1 or more raises | {/* Colspan of 3 for the scenario grouping */}
+
+
+ {scenarios.map((scenario) => (
+
+ Call |
+ Raise |
+ Fold |
+
+ ))}
+
+
+
+ {hands.map((hand) => (
+
+ {hand} |
+ {scenarios.map((scenario) => (
+
+ ))}
+
+ ))}
+
+
+
+ );
+};
+
+export default PreFlopStrategyEditor;
diff --git a/website/src/routes/NavBar.tsx b/website/src/routes/NavBar.tsx
index 2edcf580..d44b1a6a 100644
--- a/website/src/routes/NavBar.tsx
+++ b/website/src/routes/NavBar.tsx
@@ -1,77 +1,81 @@
-import "bootstrap/dist/css/bootstrap.css";
-import { Link } from "react-router-dom";
-import { useDlLink } from "../views/config";
+import React, { useState } from 'react';
+import 'bootstrap/dist/css/bootstrap.css';
+import { Link } from 'react-router-dom';
+import { useDlLink } from '../views/config';
function NavBar() {
+ // State to manage the toggle status of the navbar
+ const [isOpen, setIsOpen] = useState(false);
const dlLink = useDlLink();
- return (
-
- );
+
+
+
+ );
}
export default NavBar;
diff --git a/website/src/routes/Routing.tsx b/website/src/routes/Routing.tsx
index e50751bb..3d8f069f 100644
--- a/website/src/routes/Routing.tsx
+++ b/website/src/routes/Routing.tsx
@@ -5,6 +5,7 @@ import PaymentCards from "../views/Purchase"
import TableAnalyzer from "../views/TableAnalyzer"
import StrategyAnalyzer from "../views/StrategyAnalyzer"
import TableMapper from "../views/TableMapper"
+import StrategyEditor from "../views/StrategyEditor"
function Routing() {
return (
@@ -15,6 +16,7 @@ function Routing() {
} />
} />
} />
+ } />
)
diff --git a/website/src/views/StrategyEditor.tsx b/website/src/views/StrategyEditor.tsx
new file mode 100644
index 00000000..3715f4fd
--- /dev/null
+++ b/website/src/views/StrategyEditor.tsx
@@ -0,0 +1,11 @@
+import PreFlopStrategyEditor from '../components/strategy_editor/PreFlopStrategy'
+
+function StrategyEditor() {
+ return (
+
+ )
+}
+
+export default StrategyEditor
\ No newline at end of file