Add difficulty menu to UI (not yet functional)

This commit is contained in:
Joel Therrien 2023-09-08 23:32:44 -07:00
parent ef655f99cd
commit 60fabb0214
4 changed files with 110 additions and 8 deletions

View file

@ -27,7 +27,11 @@ function addLogInfo(existingLog: React.JSX.Element[], newItem: React.JSX.Element
return existingLog.slice(); return existingLog.slice();
} }
export function Game(props: {wasm: GameWasm, settings: Settings}) { export function Game(props: {
wasm: GameWasm,
settings: Settings,
end_game_fn: () => void,
}) {
const cellTypes = useMemo(() => { const cellTypes = useMemo(() => {
return props.wasm.get_board_cell_types(); return props.wasm.get_board_cell_types();

81
ui/src/Menu.tsx Normal file
View file

@ -0,0 +1,81 @@
import * as React from "react";
import {useState} from "react";
import {GameWasm} from 'word_grid';
import {Settings} from "./utils";
import {Game} from "./Game";
export function Menu(props: {settings: Settings, dictionary_text: string}) {
const [aiRandomness, setAIRandomness] = useState<number>(6);
const [proportionDictionary, setProportionDictionary] = useState<number>(7);
const [game, setGame] = useState<React.JSX.Element>(null);
// Can change log scale to control shape of curve using following equation:
// aiRandomness = log(1 + x*(n-1))/log(n) when x, the user input, ranges between 0 and 1
const logBase: number = 10000;
const processedAIRandomness = Math.log(1 + (logBase - 1)*aiRandomness/100) / Math.log(logBase);
if (game == null) {
return <dialog open>
<div className="new-game">
<div className="grid">
<label htmlFor="proportion-dictionary">AI's proportion of dictionary:</label>
<input type="number"
name="proportion-dictionary"
value={proportionDictionary}
onInput={(e) => {
setProportionDictionary(parseInt(e.currentTarget.value));
}}
min={1}
max={100}/>
<label htmlFor="randomness">Level of randomness in AI:</label>
<input type="number"
name="randomness"
value={aiRandomness}
onInput={(e) => {
setAIRandomness(parseInt(e.currentTarget.value));
}}
min={0}
max={100}/>
</div>
<details>
<ul>
<li>
"AI's proportion of dictionary" controls what percent of the total AI dictionary
the AI can form words with. At 100%, it has access to its entire dictionary -
although this dictionary is still less than what the player has access to.</li>
<li>
<div>
"Level of randomness in AI" controls the degree to which the AI picks the optimal move
for each of its turns. At 0, it always picks the highest scoring move it can do using the
dictionary it has access to. At 1, it picks from its available moves at random.
</div>
<div>
Note that "Level of randomness in AI" is now mapped on a log scale.
Your current setting is equivalent to {(100*processedAIRandomness).toFixed(1)}% on the previous scale.
</div>
</li>
</ul>
</details>
<div className="selection-buttons">
<button onClick={() => {
const seed = new Date().getTime();
const game_wasm = new GameWasm(BigInt(seed), props.dictionary_text);
const game = <Game settings={props.settings} wasm={game_wasm} key={seed} end_game_fn={() => setGame(null)}/>
setGame(game);
}}>New Game</button>
</div>
</div>
</dialog>
} else {
return game;
}
}

View file

@ -2,6 +2,7 @@ import init, {GameWasm} from '../node_modules/word_grid/word_grid.js';
import {Game} from "./Game"; import {Game} from "./Game";
import {createRoot} from "react-dom/client"; import {createRoot} from "react-dom/client";
import * as React from "react"; import * as React from "react";
import {Menu} from "./Menu";
// @ts-ignore // @ts-ignore
const dictionary_url = new URL("../../resources/dictionary.csv", import.meta.url); const dictionary_url = new URL("../../resources/dictionary.csv", import.meta.url);
@ -45,15 +46,9 @@ async function run() {
}) })
} }
let game = new GameWasm(BigInt(1234), dictionary_text);
const cellTypes = game.get_board_cell_types();
console.log({cellTypes});
const root = createRoot(document.getElementById("root")); const root = createRoot(document.getElementById("root"));
root.render(<Game wasm={game} settings={{trayLength: 7}} />); root.render(<Menu dictionary_text={dictionary_text} settings={{trayLength: 7}}/>);
} }

View file

@ -169,6 +169,28 @@ dialog {
border-radius: 10px; border-radius: 10px;
z-index: 1; z-index: 1;
.new-game {
width: 50em;
.grid {
display: grid;
grid-template-columns: 3fr 2fr;
grid-column-gap: 1em;
grid-row-gap: 0.5em;
}
.selection-buttons {
display: grid;
grid-template-columns: 1fr 1fr;
justify-items: center;
padding-top: 1em;
button {
width: 40%;
}
}
}
.close-button-div { .close-button-div {
display: flex; display: flex;