检查玩家是否尚未在 RPS 中下棋

Checking that a player hasn't played a move already in RPS

对于这行代码:

// check that the player hasnt played the move already 
require(choices[msg.sender] == 0); 

作为以下内容的一部分:

   // SPDX-License-Identifier: GPL-3.0
        
        pragma solidity >=0.7.0 <0.9.0;
        
        /**
         * @title Storage
         * @dev Store & retrieve value in a variable
         */
        contract Game {
        
            uint8 constant ROCK = 0;
            uint8 constant PAPER = 1;
            uint8 constant SCISSORS = 2;
            address[] public players;
        
            // the public keyword will create a function with the same name as the mapping which will allow us to lookup the key outside the contract
            // no data is ever hidden in a smart contract deployed on a public chain and using `private` will not hide data in any way.
            mapping(address => uint8) public choices;
            
            
            function enroll() public payable {
                require(msg.value > .01 ether);
        
                players.push(msg.sender);
            }
        
            function play(uint8 choice) external {
                // check that the move is valid
                require(choice == ROCK || choice == PAPER || choice == SCISSORS);
                // check that the player hasnt played the move already
                require(choices[msg.sender] == 0);
                // set the choice for the players address
                choices[msg.sender] = choice;
            }
        
          function evaluate(address alice, address bob)
                public
                view
                returns (address add)
            {
                // if the choices are the same, the game is a draw, therefore returning 0x0000000000000000000000000000000000000000 as the winner
                if (choices[alice] == choices[bob]) {
                    return address(0);
                }
        
                // paper beats rock bob/alice
                if (choices[alice] == ROCK && choices[bob] == PAPER) {
                    return bob;
                    // paper still beats rock (played in opposite alice/bob)
                } else if (choices[bob] == ROCK && choices[alice] == PAPER) {
                    return alice;
                } else if (choices[alice] == SCISSORS && choices[bob] == PAPER) {
                    return alice;
                } else if (choices[bob] == SCISSORS && choices[alice] == PAPER) {
                    return bob;
                } else if (choices[alice] == ROCK && choices[bob] == SCISSORS) {
                    return alice;
                } else if (choices[bob] == ROCK && choices[alice] == SCISSORS) {
                    return bob;
                }
        
            
            function pickWinner(address bob, address alice) public payable {
                if (evaluate(alice, bob) == bob) {
                    bob.transfer(address(this).balance);
                }
                if (evaluate(alice, bob) == alice) {
                    alice.transfer(address(this).balance);
                }
                players = new address[](0);
            }
            }        
        
                
                
            
           
        }

我不明白为什么它会检查玩家还没有下棋?在我看来,对于 R、P 或 S,选择可以是 0、1 或 2,那么为什么通过要求映射值为 0 来证明它是一个新的着法?

数组值默认为 0。因此,如果您未分配任何值,则它们必须为 0。

ROCK的代码也是0。因此,如果用户还没有选择任何东西,或者选择了 ROCK,则 require evaluation 将为真。显然,这是一个错误,您可以通过将 ROCK 的代码更改为不是 0 的代码来修复此错误。例如,使用 [1, 2, 3] 而不是 [0, 1, 2]。