function giveBirth(uint256 _matronId) payable
        external
        whenNotPaused
        returns(uint256)
    {
        
        Puppy storage matron = puppies[_matronId];

        
        require(matron.birthTime != 0);

        
        require(_isReadyToGiveBirth(matron));

        
        uint256 sireId = matron.siringWithId;
        Puppy storage sire = puppies[sireId];

        
        uint16 parentGen = matron.generation;
        if (sire.generation > matron.generation) {
            parentGen = sire.generation;
        }

        
        
        uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1);

        
        address owner = PuppyIndexToOwner[_matronId];
        
        uint16 strength = uint16(random(_matronId));
        uint16 agility = uint16(random(strength));
        uint16 intelligence = uint16(random(agility));
        uint16 speed = uint16(random(intelligence));

        uint256 puppyId = _createPuppy(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner, strength, agility, intelligence, speed);

        
        
        delete matron.siringWithId;

        
        pregnantpuppies--;

        
        msg.sender.send(autoBirthFee);

        
        return puppyId;
    }