zoukankan      html  css  js  c++  java
  • [Javascript] Broadcaster + Operator + Listener pattern -- 17. Building a Word Matching Game

    It's common for a user to enter values that you want to check against your pre-defined values. Let's make a demo of a word game to demonstrate one approach to solving that use case.

    Try consolidating map(hangmanLogic) even further into a stand-alone hangmanLogic operator so that there's no mapping, just the hangmanLogic operator

    import { addListener, done, forOf } from "./broadcasters";
    import { targetValue } from "./operators";
    
    const log = console.log;
    
    let inputInput = addListener("#input", "input");
    let inputValue = targetValue(inputInput);
    
    let word = forOf("honeycomb");
    
    inputValue((value) => {
      let result = "";
      word((letter) => {
        if (letter === done) {
          console.log(result);
          return
        }
        if (value.includes(letter)) {
          result += letter;
        } else {
          result += "*";
        }
      });
    });
    
    /*
    h**e***** 
    honeycomb 
    */

    We have outside 'inputValue' to provde value and inside 'word' providing innerValue.

    1. Model the behavior for tow broadcasters: "inputValue" & "word".

    The logic is "inputValue", inside, it doesn't mapping to a transform function but to another broadcaster: word.

    So create a operator called mapBroadcaster:

    let mapBroadcaster = createBroadcaster => broadcaster => listener => {
      broadcaster(value => {
        let newBroadcaster = createBroadcaster(value)
        newBroadcaster(listener)
      })
    }
    
    mapBroadcaster(value => word)(inputValue)(log)

    2. Apply logic to inner broadcaster 'word':

    logic we want to apply:

        if (value.includes(letter)) {
          result += letter;
        } else {
          result += "*";
        }

    then:

    let mapBroadcaster = (createBroadcaster) => (broadcaster) => (listener) => {
      broadcaster((value) => {
        let newBroadcaster = createBroadcaster(value);
        newBroadcaster(listener);
      });
    };
    
    mapBroadcaster((value) => {
      return map((letter) => (value.includes(letter) ? letter : "*"))(word);
    })(inputValue)(log);

    Equals to:

    mapBroadcaster((value) => {
      return mapBroadcaster((operator) => operator(word))(
        map((value) => {
          return map((letter) => (value.includes(letter) ? letter : "*"));
        })(inputValue)
      );
    })(log);

    Pattern to catch: 

    inputValue(value => logicFn)(listener)
    
    // equals to 
    
    map(value => logicFn)(inputValue)(listener)

    Refect again:

    let hangmanLogic = (value) => {
      return map((letter) => (value.includes(letter) ? letter : "*"));
    };
    
    mapBroadcaster((value) => {
      return mapBroadcaster((operator) => operator(word))(
        map(hangmanLogic)(inputValue)
      );
    })(log);

    3. Add helper function 'applyBroadcaster':

    Catching this pattern:

    mapBroadcaster((operator) => operator(word))

    so:

    let mapBroadcaster = (createBroadcaster) => (broadcaster) => (listener) => {
      broadcaster((value) => {
        let newBroadcaster = createBroadcaster(value);
        newBroadcaster(listener);
      });
    };
    
    let hangmanLogic = (value) => {
      return map((letter) => (value.includes(letter) ? letter : "*"));
    };
    
    let applyOperator = broadcaster => mapBroadcaster(operator => operator(broadcaster))
    
    applyOperator(word)(
        map(hangmanLogic)(inputValue)
      )(log);

    4. Apply "pipe":

    let mapBroadcaster = (createBroadcaster) => (broadcaster) => (listener) => {
      broadcaster((value) => {
        let newBroadcaster = createBroadcaster(value);
        newBroadcaster(listener);
      });
    };
    
    let hangmanLogic = (value) => {
      return map((letter) => (value.includes(letter) ? letter : "*"));
    };
    
    let applyOperator = (broadcaster) =>
      mapBroadcaster((operator) => operator(broadcaster));
    
    let hangman = pipe(map(hangmanLogic), applyOperator(word));
    hangman(inputValue)(log);

    5. Applying the rest of logic:

    let mapBroadcaster = (createBroadcaster) => (broadcaster) => (listener) => {
      broadcaster((value) => {
        let newBroadcaster = createBroadcaster(value);
        newBroadcaster(listener);
      });
    };
    
    let hangmanLogic = (value) => {
      return map((letter) => (value.includes(letter) ? letter : "*"));
    };
    
    let applyOperator = (broadcaster) =>
      mapBroadcaster((operator) => operator(broadcaster));
    
    let stringConcat = (broadcaster) => (listener) => {
      let result = "";
      broadcaster((value) => {
        if (value === done) {
          listener(result);
          result = "";
          return;
        }
        result += value;
      });
    };
    
    let hangman = pipe(map(hangmanLogic), applyOperator(word), stringConcat);
    hangman(inputValue)(log);


    Full code:

    import { addListener, done, forOf } from "./broadcasters";
    import { targetValue, map } from "./operators";
    import { pipe } from "lodash/fp";
    const log = console.log;
    
    let inputInput = addListener("#input", "input");
    let inputValue = targetValue(inputInput);
    
    let word = forOf("honeycomb");
    
    inputValue((value) => {});
    
    let mapBroadcaster = (createBroadcaster) => (broadcaster) => (listener) => {
      broadcaster((value) => {
        let newBroadcaster = createBroadcaster(value);
        newBroadcaster(listener);
      });
    };
    
    let hangmanLogic = (value) => {
      return map((letter) => (value.includes(letter) ? letter : "*"));
    };
    
    let applyOperator = (broadcaster) =>
      mapBroadcaster((operator) => operator(broadcaster));
    
    let stringConcat = (broadcaster) => (listener) => {
      let result = "";
      broadcaster((value) => {
        if (value === done) {
          listener(result);
          result = "";
          return;
        }
        result += value;
      });
    };
    
    let hangman = pipe(map(hangmanLogic), applyOperator(word), stringConcat);
    hangman(inputValue)(log);
  • 相关阅读:
    ActiveMQ_Linux安装(一)
    Jenkins_多项目构建(二):使用Maven聚集关系
    Shell命令_for
    C# 读取Excel
    [ORACLE错误]ORA-00001: unique constraint (...) violated并不一定是数据冲突
    [ORACLE错误]ORA-00054:resource busy and acquire with nowait specified解决方法
    [ORACLE错误]oracle 不能更新 PL/SQL 点击“edit data”报“ these query results are not updateable”
    只有 DBA 才能导入由其他 DBA 导出的文件
    Windows系统安装Oracle 11g客户端
    Windows系统安装Oracle 11g数据库
  • 原文地址:https://www.cnblogs.com/Answer1215/p/13964352.html
Copyright © 2011-2022 走看看