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 ( +
+ + + + + + + {/* Colspan of 3 for the scenario grouping */} + {/* Colspan of 3 for the scenario grouping */} + {/* Colspan of 3 for the scenario grouping */} + + + {scenarios.map((scenario) => ( + + + + + + ))} + + + + {hands.map((hand) => ( + + + {scenarios.map((scenario) => ( + + ))} + + ))} + +
HandNo calls or raises1 or more calls1 or more raises
CallRaiseFold
{hand}
+
+ ); +}; + +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