想不通这个决策树的bug

问题描述 投票:0回答:0

我正在制作顶级王牌类型的纸牌游戏 - 但我在其中一个控件上遇到了麻烦。在这个问题上我一直在用头撞墙——这很奇怪,因为它似乎是最简单的解决方法

这是一个基本的决策树,只有 3 个步骤,但由于某些原因它不起作用。

handleAction
renderActionButtons
renderSlotButtons
之间的东西坏了:(


上下文

轮到任何玩家都可以采取两种行动:[将牌添加到牌组][攻击]

[将卡添加到牌组] - 这将打开一个选项列表,用于将卡添加到牌组中的位置 - 点击该选项将执行操作。 这很好用/

[攻击] - 这应该打开三个连续的选项集。

  1. 首先是一组控件,询问您要攻击对手的哪个插槽[攻击 [x] - [x] 是插槽名称]
  2. 那你们想用哪张牌来攻击[从[y]攻击-[y]是我选择的攻击牌]
  3. 然后我想用哪个属性攻击 - [用 [z] 攻击 - [z] 是我想使用的属性]

(注意 XYZ 不在代码中 - 仅用于说明目的)

但实际上它显示我(粗体表示选择)

  1. [添加卡片到牌组][攻击]
  2. [攻击 [x]1] [攻击 [x]2] [...]
  3. [攻击 [x]1] [攻击 [x]2] [...] + [攻击 [Z]1] [攻击 [Z]2] [...]

问题

1.[Attack from [Y]] 从来没有真正渲染过:它显示了我 [Attack [x]] 两次 2.第 3 步向我展示了决策树的两个步骤 - 应该一次只向我展示一个

---代码

// Controls.Js - this is the logic for rendering the controls

import React, { useState } from 'react';
import './Controls.css';
import { slotNames } from '../constants';

const Controls = ({ onAction, currentPlayer }) => {
  const [currentAction, setCurrentAction] = useState(null);
  const [selectedSlot, setSelectedSlot] = useState(null);

  const handleActionChoice = (action) => {
    setCurrentAction(action);
  };

  const handleSlotChoice = (slot) => {
    if (currentAction === 'addCard') {
      onAction({ type: 'ADD_CARD_TO_BATTLE_DECK', payload: { playerId: currentPlayer, slot } });
      setCurrentAction(null);
    } else {
      setSelectedSlot(slot);
    }
  };

  const handleAttributeChoice = (attribute) => {
    onAction({
      type: 'ATTACK',
      payload: { playerId: currentPlayer, attackerSlot: selectedSlot, defenderSlot: selectedSlot, attribute },
    });
    setCurrentAction(null);
    setSelectedSlot(null);
  };

  const renderActionButtons = () => {
    if (!currentAction) {
      return (
        <>
          <button onClick={() => handleActionChoice('addCard')}>Add Card to Deck</button>
          <button onClick={() => handleActionChoice('attack')}>Attack</button>
        </>
      );
    }
  };

  const renderSlotButtons = () => {
    if (currentAction) {
      return (
        <>
          <button className="back-button" onClick={() => setCurrentAction(null)}>{`←`}</button>



          {slotNames.map((slotName, index) => (
            <button key={`slot-${index}`} onClick={() => handleSlotChoice(index + 1)}>
              {currentAction === 'attack' ? 'Attack ' : 'Add Card to '}
              {slotName}
            </button>
          ))}
        </>
      );
    }
  };

  const renderAttributeButtons = () => {
    if (currentAction === 'attack' && selectedSlot) {
      return (
        <>
          <button onClick={() => setSelectedSlot(null)}>{`←`}</button>
          {['force', 'magic', 'stealth', 'luck'].map((attribute) => (
            <button key={`attribute-${attribute}`} onClick={() => handleAttributeChoice(attribute)}>
              Attack with {attribute}
            </button>
          ))}
        </>
      );
    }
  };

  return (
    <div className={`controls controls-player${currentPlayer}`}>
      {renderActionButtons()}
      {renderSlotButtons()}
      {renderAttributeButtons()}
    </div>
  );
};


export default Controls;


//Handle action - contained in GameContainer.js - to handle game state

const handleAction = useCallback((action) => {
  // Verify active player
  if (action.payload.playerId !== currentPlayer) {
    return;
  }

  // Clone gameState and get player states
  const newGameState = { ...gameState };
  const currentPlayerState = newGameState[`player${action.payload.playerId}`];
  const opponentPlayerState = newGameState[`player${action.payload.playerId === 1 ? 2 : 1}`];

  // Process actions based on type
  switch (action.type) {
    case 'ADD_CARD_TO_BATTLE_DECK':
      // Remove card from reserveDeck
      const cardToAdd = currentPlayerState.reserveDeck.shift();
      // Add card to battleDeck
      currentPlayerState.battleDeck[action.payload.slot - 1].push(cardToAdd);
      // Notify user
      showNotification('Card added to deck');
      break;
    case 'ATTACK':
      // Get attacker and defender slots
      const attackerSlot = currentPlayerState.battleDeck[action.payload.attackerSlot - 1];
      const defenderSlot = opponentPlayerState.battleDeck[action.payload.defenderSlot - 1];
      // Get top cards from slots
      const attackerCard = attackerSlot[attackerSlot.length - 1];
      const defenderCard = defenderSlot[defenderSlot.length - 1];
      // Get attribute for comparison
      const attribute = action.payload.attribute;

      // Compare cards and update graveyard
      if (attackerCard && defenderCard && attackerCard[attribute] > defenderCard[attribute]) {
        opponentPlayerState.graveyard.push(defenderCard);
        defenderSlot.pop();
        showNotification(`Player ${action.payload.playerId} victorious`);
      } else if (attackerCard && defenderCard && attackerCard[attribute] < defenderCard[attribute]) {
        currentPlayerState.graveyard.push(attackerCard);
        attackerSlot.pop();
        showNotification(`Attack was parried`);
      } else {
        showNotification(`Player ${action.payload.playerId} turn`);
      }

      // Check for game win condition
      if (opponentPlayerState.graveyard.length === 24) {
        showNotification(`Player ${action.payload.playerId} wins the game!`);
      }

      break;
    default:
      break;
  }

  // Update gameState with new state
  setGameState(newGameState);

我尝试多次重写 RenderslotCards 和 HandleAction,但它最终破坏了一个东西,然后又破坏了另一个

实际上可能是显示了正确的选项,但标记错误(但仍然一次显示 2

node.js reactjs logic game-development decision-tree
© www.soinside.com 2019 - 2024. All rights reserved.