-
Notifications
You must be signed in to change notification settings - Fork 0
/
useGamePlay.ts
79 lines (67 loc) · 2.09 KB
/
useGamePlay.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import { useContext, useEffect, useMemo, useState } from 'react';
import GameContext from '../context/GameContext';
import { getPlayerType } from '../controllers/playerController';
import useWord from './useWord';
import usePlayer from './usePlayer';
import { TGamePlay } from '../utils/types';
/**
* A React hook that communicate {@link useWord} and {@link usePlayer} hooks with each other.
* Also evaluates the responses coming from them.
*
* @function useGamePlay
* @memberOf React
* @return {TGamePlay} - Returns {@link lostMessage} that contains game over message, {@link addWord} that waits for a response from players
* and {@link currentPlayerType} that contains type of current player.
*/
const useGamePlay = (): TGamePlay => {
const { state, dispatch } = useContext(GameContext);
const [lostMessage, setLostMessage] = useState<string>('');
const { saveWord, wordResponse } = useWord();
const { player, addWord, lastAction } = usePlayer();
/**
* Step #1
* Triggers 'play' function of 'usePlayer' for a new game as soon as 'currentPlayer' changes.
* After triggers, a new word is expected from players.
*
* @inner
*/
useEffect(() => {
player.play();
}, [state.currentPlayer]);
/**
* Step #2
* Listens the 'lastAction' of 'usePlayer' and saves the last action which contains new spoken word if players played.
*
* @inner
*/
useEffect(() => {
if (lastAction?.played) {
saveWord(lastAction);
}
}, [lastAction]);
/**
* Step #3
* Listens word saving response and switch player if response is valid.
* Deactivates timer if the response is invalid.
*
* @inner
*/
useEffect(() => {
if (wordResponse?.valid) {
player.nextPlayer();
}
if (wordResponse?.invalid) {
setLostMessage(wordResponse.result);
dispatch({ type: 'timer', payload: { active: false } });
}
}, [wordResponse]);
const currentPlayerType = useMemo(() => getPlayerType(state.currentPlayer, state.players), [
state,
]);
return {
lostMessage,
addWord,
currentPlayerType,
};
};
export default useGamePlay;