Add difficulty menu to UI (not yet functional)
This commit is contained in:
parent
ef655f99cd
commit
60fabb0214
4 changed files with 110 additions and 8 deletions
|
@ -27,7 +27,11 @@ function addLogInfo(existingLog: React.JSX.Element[], newItem: React.JSX.Element
|
|||
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(() => {
|
||||
return props.wasm.get_board_cell_types();
|
||||
|
|
81
ui/src/Menu.tsx
Normal file
81
ui/src/Menu.tsx
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ import init, {GameWasm} from '../node_modules/word_grid/word_grid.js';
|
|||
import {Game} from "./Game";
|
||||
import {createRoot} from "react-dom/client";
|
||||
import * as React from "react";
|
||||
import {Menu} from "./Menu";
|
||||
|
||||
// @ts-ignore
|
||||
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"));
|
||||
root.render(<Game wasm={game} settings={{trayLength: 7}} />);
|
||||
root.render(<Menu dictionary_text={dictionary_text} settings={{trayLength: 7}}/>);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -169,6 +169,28 @@ dialog {
|
|||
border-radius: 10px;
|
||||
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 {
|
||||
display: flex;
|
||||
|
|
Loading…
Reference in a new issue