function roll(uint8 _number)
        public
        payable
        returns (bool _success)
    {
        
        if (!_validateBetOrRefund(_number)) return;

        
        User memory _prevUser = users[msg.sender];
        if (_prevUser.r_block == uint32(block.number)){
            _errorAndRefund("Only one bet per block allowed.", msg.value, _number);
            return false;
        }

        
        Stats memory _stats = stats;
        User memory _newUser = User({
            id: _prevUser.id == 0 ? _stats.numUsers + 1 : _prevUser.id,
            r_id: _stats.numRolls + 1,
            r_block: uint32(block.number),
            r_number: _number,
            r_payout: computePayout(msg.value, _number)
        });
        users[msg.sender] = _newUser;

        
        
        if (_prevUser.r_block != 0) _finalizePreviousRoll(_prevUser, _stats);

        
        _stats.numUsers = _prevUser.id == 0 ? _stats.numUsers + 1 : _stats.numUsers;
        _stats.numRolls = stats.numRolls + 1;
        _stats.totalWagered = stats.totalWagered + uint96(msg.value);
        stats = _stats;

        
        emit RollWagered(now, _newUser.r_id, msg.sender, msg.value, _newUser.r_number, _newUser.r_payout);
        return true;
    }