Как заменить подчеркивание буквой React Hook - PullRequest
0 голосов
/ 30 сентября 2019

Я пытался создать игру «Висячий человек», и для того, чтобы сделать эту игру, слово было заменено подчеркиванием, например, (hello) ==> _ _ _ _ _. Поэтому каждый раз, когда игрок нажимает на кнопку с ключом, он должен заменять подчеркивание соответствующей буквой.

Но важно помнить, что он не должен заменять подчеркивание, например, когда пользователь нажимает e --> _ e _ _ _, а затем нажимает l --> _ _ l l _. Вы видите, что буква e, которая соответствует, заменялась подчеркиванием, как в моем коде. Волшебство происходит в функции showMatchedLetter

import React, { useState, useEffect } from 'react';
import { fetchButton } from '../actions';
import axios from 'axios';
import 'babel-polyfill';

const App = () => {
    const [word, setWord] = useState([]);
    const [underscore, setUnderscore] = useState([]);
    const [data, setData] = useState([]);

    useEffect(() => {
        const runEffect = async () => {
            const result = await axios('src/api/api.js');
            setData(result.data)
        }
        runEffect();
    }, []);

    const randomWord = () => {
        const chosenWord = data[Math.floor(Math.random() * data.length)];
        replaceLetter(chosenWord.word);
    }

    const replaceLetter = (string) => {
      
        let getString = string;
        setWord(getString);
        let stringToUnderScore = getString.replace(/[a-z]/gi, '_');
        setUnderscore(stringToUnderScore);
    }

    useEffect(() => {
        const checkLetter = (event) => {
            if(event.keyCode >= 65 && event.keyCode <= 90) {
                checkMatchLetter(word, String.fromCharCode(event.keyCode).toLowerCase());
            }
        };

        document.addEventListener('keydown', checkLetter);
        return () => {
            document.removeEventListener('keydown', checkLetter);
        }
    }, [word]);

    const checkMatchLetter = (word, keyButton) => {
        if(word == undefined) {
            return;
        } else {
            for(let i = 0; i < word.length; i++) {
                if(word[i] == keyButton) {
                    let index = i;
                    showMatchedLetter(word[i], index);
                }
            }
        }
    }

    const showMatchedLetter = (letter, index) => {
        console.log(letter, index);
        let string = word;
        string = setCharAt(string, index, letter);
        console.log(string)
    }

    const setCharAt = (string, index, letter) => {
        if(index > string.length - 1) return string;
        console.log(string)
        return underscore.substr(0, index) + letter + underscore.substr(index + 1); 
        
    }

    return (
        <div>
            <p>{word}</p>
            <p>{underscore}</p>
            <button onClick={randomWord}></button>
        </div>
    )
}

export default App;

1 Ответ

1 голос
/ 01 октября 2019

Способ подойти к этому - просто сохранить текущий список букв, которые уже были угаданы.

Затем просто замените любую букву, которая не была угадана, подчеркиванием, чтобы получать «скрытое» слово каждый раз, когда угадывается новая буква.

Функцию revealOnly, приведенную ниже, можно реализовать вВ любом случае, но важно то, что для его замены требуется полная строка слова и список букв, а затем возвращается новая строка, в которой пропущены любые не угаданные буквы.

const phrase = 'Hello World'

function revealOnly(str, guessed=[]){
  const regExpr = new RegExp(`[^${guessed.join("")}\\s]`, 'ig')
  return str.replace(regExpr, '_')
}

console.log(revealOnly(phrase, [])) // no letters guessed

console.log(revealOnly(phrase, ['e', 'l'])) // some letters guessed

Ниже приведена рабочая демонстрационная программа, демонстрирующая, как вы можете использовать это:

const { useState } = React

const App = () => {
  const [phrase, setPhrase] = useState('Hello World')
  const [guessed, setGuessed] = useState([])

  function onGuessLetter(letter){
    if(guessed.includes(letter)) return
    // add letter to guessed array
    setGuessed(prev => [...prev, letter])
  }

  function revealOnly(str, guessed=[]){
    const regExpr = new RegExp(`[^${guessed.join("")}\\s]`, 'ig')
    return str.replace(regExpr, '_')
  }

  return (
    <div>
      <div> {revealOnly(phrase, guessed)} </div>
      <LetterPicker onPick={onGuessLetter} />
    </div>
  )
}

const LetterPicker = (props)=>{
  const letters = []
  for(let i = 0; i < 26; i++){
    letters.push(String.fromCharCode(97+i))
  }
  return (
   <div className={'letter-picker'}>
    {letters.map(l => <div onClick={()=>props.onPick(l)}>{l}</div>)}
   </div>
  )
}

ReactDOM.render(<App/>, document.querySelector("#root"))
.letter-picker > div {
 display : inline-block;
 cursor : pointer;
 padding : 3px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Ведение текущего списка угаданных букв также может быть полезно для проверки того, было ли слово полностью раскрыто (хотя вы можете просто проверить его существование). любого _, а также). Точно так же в традиционной манере палача вы можете также показать ранее где-то буквы.

РЕДАКТИРОВАТЬ:

Как проверить, угадано ли все слово.

Просто проверьте, соответствует ли найденное слово оригинальной фразе.

const curr = revealOnly(phrase, ['h','e','l','w','o','r', 'd']
const isGuessed = curr === phrase

const { useState } = React

const App = () => {
  const [phrase, setPhrase] = useState('Hello World')
  const [guessed, setGuessed] = useState([])

  function onGuessLetter(letter){
    if(guessed.includes(letter)) return
    // add letter to guessed array
    setGuessed(prev => [...prev, letter])
  }

  function revealOnly(str, guessed=[]){
    const regExpr = new RegExp(`[^${guessed.join("")}\\s]`, 'ig')
    return str.replace(regExpr, '_')
  }
  
  const curr = revealOnly(phrase, guessed)
  const isGuessed = curr === phrase

  return (
    <div>
      <div> {curr} </div>
      <div>Gussed: {isGuessed.toString()} </div>
      <LetterPicker onPick={onGuessLetter} />
    </div>
  )
}

const LetterPicker = (props)=>{
  const letters = []
  for(let i = 0; i < 26; i++){
    letters.push(String.fromCharCode(97+i))
  }
  return (
   <div className={'letter-picker'}>
    {letters.map(l => <div onClick={()=>props.onPick(l)}>{l}</div>)}
   </div>
  )
}

ReactDOM.render(<App/>, document.querySelector("#root"))
.letter-picker > div {
 display : inline-block;
 cursor : pointer;
 padding : 3px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...