简体   繁体   English

如何为React / Redux抽认卡游戏设计状态流?

[英]How to design a state flow for a react/redux flashcard game?

This is my first redux project. 这是我的第一个redux项目。 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 商店/ 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 动作/ 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: 我认为游戏循环会像这样工作:

  • when state is null , wait for user to press Begin game button which dispatches BEGIN_GAME action statenull ,等待用户按下开始游戏按钮,该按钮将调度BEGIN_GAME动作
  • At this point, begin the main game loop 此时,开始主游戏循环
  • Dispatch CHECK_END_GAME to determine if any cards remain in the deck 派送CHECK_END_GAME以确定卡牌中是否还剩下任何纸牌
  • Dispatch NEXT_CARD to display the next card on the deck 派发NEXT_CARD以显示卡组中的下一张卡
  • Wait for an answer to be clicked, then dispatch a SUBMIT_ANSWER action 等待单击答案,然后调度SUBMIT_ANSWER操作
  • After the answer is recorded, repeat the loop, starting with CHECK_END_GAME , followed by NEXT_CARD , followed by waiting for SUBMIT_ANSWER , etc 记录答案后,从CHECK_END_GAME开始,然后是NEXT_CARD ,然后等待SUBMIT_ANSWER等,重复循环。
  • At some point CHECK_END_GAME should trigger a DISPLAY_RESULTS action... ?? 在某个时候, CHECK_END_GAME应该触发DISPLAY_RESULTS操作... ??

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. 瞧,我在这里有点迷路了...使用redux,我不认为我可以(或应该)从商店内部调度另一个动作。 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 ! 谢谢 !

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). 编写应用程序代码的一种方法是根据Petri Net Elements建模(或组织)游戏逻辑,并基于该组织编写代码(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). 以下是根据Petri Nets组织的游戏逻辑(基于Flashcard游戏)的示例(“ 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; 图1( 此回复的PDF版本 )是游戏逻辑的交互式动态图; it includes “graphic notations” of cards with standard Petri Net notations and some high-level notations of Petri Net elements. 它包括具有标准Petri Net表示法的卡片的“图形表示​​法”和一些Petri Net元素的高级表示法。 The demonstration mode of the game logic randomly selects a card from the deck then randomly guesses the card. 游戏逻辑的演示模式从卡组中随机选择一张牌,然后随机猜测该牌。

Petri网元素的标签和描述

Petri网游戏模型

References 参考

Chionglo, JF (2016). J.Chionglo(2016)。 A Reply to "How to design a state flow for a react/redux flashcard game?" 对“如何为React / Redux抽认卡游戏设计状态流?”的回复 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 . https://www.academia.edu/34059934/A_Reply_to_How_to_design_a_state_flow_for_a_react_redux_flashcard_game_at_Stack_Overflow

Chionglo, JF (2014). Chionglo,JF(2014)。 Net Elements and Annotations for Computer Programming: Computations and Interactions in PDF. 用于计算机编程的网络元素和注释:PDF中的计算和交互。 https://www.academia.edu/26906314/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). “如何为react / redux抽认卡游戏设计状态流?”(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 . 于2016年2月7日在http://stackoverflow.com/questions/35220169/how-to-design-a-state-flow-for-a-react-redux-flashcard-game检索。

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: 我不太了解这个游戏:P,但是怀疑您应该像这样多考虑一下:

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... 您的nextCard “子”减速器做了一些工作...

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 其次是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 . 您可能还会研究redux sagaredux thunk等中间件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM