This commit is contained in:
Maciej Caderek
2022-04-01 20:52:15 +02:00
parent a003ab6089
commit 2a252b6c69
8 changed files with 136 additions and 44 deletions

View File

@@ -3,6 +3,7 @@ import Board from "../board/Board";
import Game from "../game/Game";
import { setState, state } from "../state";
import sfx from "./sfx";
import Speech, { sanToText } from "./speach";
const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
@@ -11,11 +12,14 @@ class Player {
private game: Game = new Game();
private ply: number = 0;
private callback: (playing: boolean, ply: number) => void = () => {};
private speech: Speech;
public playing: boolean = false;
private firstRender: Promise<void>;
constructor(private board: Board, private config: GameConfig) {
this.speech = new Speech();
this.firstRender = this.board
.frame(this.game.getPosition(0), this.game.header)
.then((_) => this.board.render());
@@ -109,6 +113,10 @@ class Player {
await this.board.frame(position, this.game.header);
this.board.render();
if (state.boardConfig.speech) {
this.speech.say(sanToText(position.move?.san as string));
}
if (this.ply > 0 && state.boardConfig.sounds) {
if (position.mate) {
sfx.snap.play();

66
src/player/speach.ts Normal file
View File

@@ -0,0 +1,66 @@
const words: { [key: string]: string } = {
x: " takes ",
"+": " check!",
"#": " mate!",
"=": " promotes to a ",
P: "pawn ",
R: "rook ",
B: "bishop ",
N: "knight ",
Q: "queen ",
K: "king ",
"O-O": "short castle",
"O-O-O": "long castle",
};
const config = {
volume: 50,
rate: 2,
lang: "en-US",
};
const sanToText = (move: string) => {
if (move === "O-O" || move === "O-O-O") {
move = words[move];
} else {
// Handles special cases like R2a6 ore Nbd2
const special = move.match(/[a-h1-8][a-h][1-8]/);
if (special) {
move = move.replace(
special[0],
`${special[0][0]} ${special[0][1]}${special[0][2]}`
);
}
move = move
.split("")
.map((x) => words[x] ?? x)
.join("")
.replace(/\s{2,}/g, " ");
}
return move;
};
class Speach {
private voice: SpeechSynthesisVoice | undefined;
constructor() {
const voices = speechSynthesis.getVoices();
this.voice = voices.find((voice) => voice.lang === config.lang);
}
say(text: string) {
const info = new SpeechSynthesisUtterance(text);
info.volume = config.volume / 100;
info.lang = config.lang;
if (this.voice) {
info.voice = this.voice;
}
info.rate = 1 + config.rate / 10;
speechSynthesis.speak(info);
}
}
export { sanToText };
export default Speach;