Reputation: 135377
This is my first redux project. I'm trying to make a flashcard game that teaches you hiragana/katakana. I'm getting stuck on some of the state flow...
Game state visualization
{
// the current displayed card
currentCard: null | {q: 'き', a: 'ki'},
// time the game was started
timestamp: millisecondTimestamp,
// submitted answers
answers: [
{
card: {q: 'か', a: 'ka'},
answer: 'ka'
},
{
card: {q: 'な', a: 'na'},
answer: 'na'
},
...
],
// remaining cards in the deck
deck: [
{q: 'く', a: 'ku'},
{q: 'け', a: 'ke'},
{q: 'こ', a: 'ko'}
...
]
}
stores/game.js
import {BEGIN_GAME, NEXT_CARD, SUBMIT_ANSWER} from '../actions/';
import {isEmpty, first, rest} from '../utilities/';
const gameReducer = (state=null, action) => {
switch (action.type) {
case BEGIN_GAME:
return Object.assign({}, state, {deck: action.deck});
case NEXT_CARD:
return isEmpty(state.deck)
? Object.assign({}, state, {
currentCard: null
})
: Object.assign({}, state, {
currentCard: first(state.deck),
deck: rest(state.deck)
})
;
case SUBMIT_ANSWER:
return Object.assign({}, state, {
currentCard: null,
answers: state.answers.concat({
card: state.currentCard,
answer: action.answer
})
});
default:
return state;
}
};
export default gameReducer;
actions/index.js
import {shuffle} from '../utilities/';
export const BEGIN_GAME = 'BEGIN_GAME';
export const NEXT_CARD = 'NEXT_CARD';
export const SUBMIT_ANSWER = 'SUBMIT_ANSWER';
export const beginGame = deck => ({
type: BEGIN_GAME,
deck: shuffle(deck)
});
export const nextCard = () => ({
type: NEXT_CARD
});
export const submitAnswer = answer => ({
type: SUBMIT_ANSWER,
answer
});
I'm thinking the game loop will work something like this:
state
is null
, wait for user to press Begin game button which dispatches BEGIN_GAME
actionCHECK_END_GAME
to determine if any cards remain in the deckNEXT_CARD
to display the next card on the deckSUBMIT_ANSWER
actionCHECK_END_GAME
, followed by NEXT_CARD
, followed by waiting for SUBMIT_ANSWER
, etcCHECK_END_GAME
should trigger a DISPLAY_RESULTS
action... ??See, I'm getting a little lost here... With redux, I don't think I can (or should) dispatch another action from within a store. But then how do I decompose these actions or state checks ?
My brain is currently thinking with a model like this:
BEGIN_GAME(deck)
LOOP(
CHECK_END_GAME()->NEXT_CARD()->SUBMIT_ANSWER(answer)->
)
DISPLAY_RESULTS()
The problem is, I don't know how to chain actions like this, or if it's even advised. I'm open to designing the actions/store in a completely different way. I'm a noob here, so just tell me if I'm doing something wrong.
Any nudge in the proper direction will be helpful. Thanks !
Upvotes: 2
Views: 941
Reputation: 345
One way to code the application is to model (or to organize) the game logic in terms of Petri Net Elements and based on this organization write the code (Chionglo, 2014). The following is an example of a game logic (based on a Flashcard game) organized in terms of Petri Nets (“How to Design”, 2016). In this game there are nine cards. One card is shown at a time then the player guesses the card. The number of correct guesses and the number of incorrect guesses are recorded and play continues until there are no more cards to display.
Figure 1 (for the PDF version of this reply) is an interactive, dynamic diagram of the game logic; it includes “graphic notations” of cards with standard Petri Net notations and some high-level notations of Petri Net elements. The demonstration mode of the game logic randomly selects a card from the deck then randomly guesses the card.
Chionglo, J. F. (2016). A Reply to "How to design a state flow for a react/redux flashcard game?" at Stack Overflow. Stack Overflow. https://www.academia.edu/34059934/A_Reply_to_How_to_design_a_state_flow_for_a_react_redux_flashcard_game_at_Stack_Overflow.
Chionglo, J. F. (2014). Net Elements and Annotations for Computer Programming: Computations and Interactions in PDF. https://www.academia.edu/26906314/Net_Elements_and_Annotations_for_Computer_Programming_Computations_and_Interactions_in_PDF.
“How to design a state flow for a react/redux flashcard game?” (2016). Stack Exchange. Retrieved on Feb. 7, 2016 at http://stackoverflow.com/questions/35220169/how-to-design-a-state-flow-for-a-react-redux-flashcard-game.
Upvotes: 4
Reputation: 11585
Disclaimer: this answer will be a little rushed, I have a train to catch
Currently, I only "chain" async actions but I guess the same principle could apply.
I don't really understand this game :P, But suspect you should be thinking about it a little more like this:
BEGIN_GAME(deck)
DISPLAY_STATE
{if END_GAME()}
Its over!
{else}
<button onclick=dispatch( drawCardAndModifyStateAction )/>
In your parent reducer you might compose (as opposed to chain) your reducers:
const gameReducer = (state=null, action) => {
switch (action.type) {
NEXT_CARD: state.nextCard = nextCard(state);
}
state.checkEndGame = checkEndGame(state);
return state;
}
Your nextCard
"sub" reducer does some stuff...
const nextCard = (state=null, action) => {
switch (action.type) {
case NEXT_CARD:
return Object.assign({}, state, {
currentCard: first(state.deck),
isEmpty: isEmpty(state.deck),
deck: rest(state.deck)
})
}
return state;
}
Followed by checkEndGame
const checkEndGame = (state=null, action) => {
switch (action.type) {
default:
return Object.assign({}, state, {
message: ...,
winner: ...,
})
}
}
You might also look into middleware like redux saga, redux thunk.
Upvotes: 1