Assignment - DNA Mixing

Create breed function by using the _mixDna function that mixes DNA of cat’s parents.

1 Like

DNA Mixing Assignment Code

breed
function breed(uint256 _dadId, uint256 _momId) public returns(uint256){
        require(_owns(msg.sender, _dadId) && _owns(msg.sender, _momId), "You must own both bears to breed them!");
        
        //get newDna from _mixDna
        uint256 newGenes = _mixDna(bears[_dadId].genes, bears[_momId].genes); 

        //Generation determination
        uint256 newGen;
        if(bears[_momId].generation == bears[_dadId].generation){
            newGen = bears[_momId].generation++;
        }
        else if (bears[_momId].generation < bears[_dadId].generation)
        {
            newGen = bears[_momId].generation++;
        }
        else{
            newGen = (bears[_momId].generation + bears[_dadId].generation) / 2;
        }

        //Create new bear and transfer to msg.sender
        _createBear(_momId, _dadId, newGen, newGenes, msg.sender);


    }
mixDNA

    function _mixDna(uint256 _dadDna, uint256 _momDna) internal pure returns(uint256){
        uint256 dadHalf = _dadDna / 100000000;
        uint256 momHalf = _momDna % 100000000;
        uint256 newDna = (dadHalf * 100000000) + momHalf;
        return newDna;
    }
1 Like
function breed(uint256 _dadId, uint256 _mumId) public returns(uint256){
    //check ownership
    //check you got the dna
    //figure out the generation
    //create a new cat with new properties, give it to msg.sender
    require(owns(msg.sender, _dadId) && owns(msg.sender, _mumId), "You must own both cats in order to breed");
    uint256 newCatDna = mixDna(_dadId, _mumId);
    
    uint256 newGen; 
    uint256 mumGen = cats[_mumId].generation;
    uint256 dadGen = cats[_dadId].generation;

    if(dadGen == mumGen){
        newGeneration = mumGen++;
    }else if(dadGen < mumGen){
        newGeneration = dadGen++;
    }else{
        newGeneration = (dadGen + mumGen) / 2;
    }
    
    _createCat(newCatDna, _mumId, _dadId, newGeneration, msg.sender);
    return newCatDna;
}

function mixDna(uint256 _dadDNA, uint256 _mumDNA) internal returns(uint256){
    uint256 dadSide = _dadDNA / 100000000;
    uint256 mumSide = _mumDNA % 100000000;
    uint256 newDna = (dadSide*100000000)+ mumSide;
    return newDNA;
}
1 Like

here we go:

function breed(uint256 _dadId, uint256 _mumId) public returns (uint256){
        // Check Ownership
        require(_owns(msg.sender,_dadId) && _owns(msg.sender, _mumId), "Must own parents to breed");
        
        Kitty storage dad = kitties[_dadId];
        Kitty storage mum = kitties[_mumId];
        
        // Figure out generation
        uint16 newGen = (dad.generation + mum.generation)/2+1;
        
        // Create a new cat with new properties and give it to msg.sender
        uint256 newDna = _mixDna(dad.genes,mum.genes);

        return _createKitty(_mumId, _dadId, newGen, newDna, msg.sender);

    }
1 Like

Here’s my code

breed (Doracontract.sol)

function breed(uint256 _dadId, uint256 _mumId) public returns (uint256){
  require(_owns(msg.sender, _dadId) && _owns(msg.sender, _mumId), "You are not the owner of this token");
  Doraemon storage dad = allTokens[_dadId];
  Doraemon storage mum = allTokens[_mumId];
  uint256 newDna = _mixDna(dad.genes, mum.genes);
  uint256 newGen = (dad.generation + mum.generation) / 2 + 1;
  return _createDoraemon(_dadId, _mumId, newGen, newDna, msg.sender);
}
1 Like

My code

 function breed(uint256 _dadId, uint256 _mumId) public  {
        require(_dadId < kitties.length &&_mumId < kitties.length);
        require(ownershipTokenID[_dadId]==  msg.sender && ownershipTokenID[_mumId]== msg.sender); // check ownership 
        uint256 dadDna = kitties[_dadId].genes; // you got the DNA 
        uint256 mumDna = kitties[_mumId].genes;
        uint256 newGen = kitties[_dadId].generation + kitties[_mumId].generation;  // figure out the generation
        if (newGen == kitties[_dadId].generation || newGen == kitties[_mumId].generation){
            newGen += 1;
        }
        uint256 newDna= _mixDna(dadDna, mumDna);
        _createKitty(_mumId, _dadId, newGen,newDna, msg.sender); // create a new cat with te new properties, give it to the msg.sender
        
    }
    function _mixDna(uint256 _dadDna, uint256 _mumDna) internal pure returns (uint256){
        uint256 firstHalf = _dadDna / 100000000;
        uint256 secondHalf = _mumDna % 100000000; 
        uint256 newDna = firstHalf * 100000000;
        newDna = newDna + secondHalf; 
        return newDna; 
    }
2 Likes

Assigment code

  function breed(uint256 _dadId, uint256 _mumId) public returns (uint256) {
        // Check Ownership
        require(
            _owns(msg.sender, _dadId) && _owns(msg.sender, _mumId),
            "Must own [0] parents to breed"
        );

        Kitty storage dad = kitties[_dadId];
        Kitty storage mum = kitties[_mumId];

        // Figure out generation
        uint16 newGen = 0;
        if ((dad.generation + mum.generation) > 0) {
            newGen = (dad.generation + mum.generation) / 2 + 1;
        } else {
            newGen = 1;
        }

        // Create a new cat with new properties and give it to msg.sender
        uint256 newDna = _mixDna(dad.genes, mum.genes);

        return _createKitty(_mumId, _dadId, newGen, newDna, msg.sender);
    }

    // Ddna:11 22 33 44 55 66 77 88
    //Mdna:88 77 66 55 44 33 22 11

    function _mixDna(uint256 _dadDna, uint256 _mumDna)
        internal
        view
        returns (uint256)
    {
        uint256 dadPart = _dadDna / 100000000;
        uint256 mumPart = _mumDna % 100000000;

        uint256 newDna = (dadPart * 100000000) + mumPart;

        // Make animation completely Random I have implemented 1-7 types so I'll limit to that

        uint8 random = uint8(block.timestamp % 7) + 1;

        uint256 removeBit = newDna % 100;

        newDna = (newDna - removeBit) + (random * 10) + 1;

        return newDna;
    }
2 Likes

Hi, devs :wave:
Is there a way to round up numbers in Solidity like Math.ceil() on Javascript?
I can’t find one so I just assigned the generation of the new Kitty to be: the higher generation between mom and dad, + 1

breedKitty
    function breedKitty(uint256 _dadId, uint256 _mumId) public returns (uint256) {
        //Check ownership
        require(msg.sender != address(0), "ERC721: balance query for the zero address");
        require(_ownedBy(msg.sender, _dadId) && _ownedBy(msg.sender, _mumId), "ERC721: breeder is not owner of both cats");

        //DNA is here
        uint256 kittyDna = _mixDna(kitties[_dadId].genes, kitties[_mumId].genes);

        //Figure out the generation
        uint16 dadGen = kitties[_dadId].generation;
        uint16 mumGen = kitties[_mumId].generation;
        uint16 kittyGen = 0;
        if(dadGen == 0 && mumGen == 0) {
            kittyGen = 1;
        } else if(dadGen == mumGen) {
            kittyGen = dadGen++;
        } else if(dadGen < mumGen) {
            kittyGen = mumGen++;
        } else {
            kittyGen = dadGen++;
        }

        //Create a new kitty with the new properties, give it to msg.sender
        return _createKitty(_mumId, _dadId, kittyGen, kittyDna, msg.sender);
    }
_mixDna
    function _mixDna(uint256 _dadDna, uint256 _mumDna) internal pure returns (uint256) {
        uint256 fromDad = _dadDna / 100000000;
        uint256 fromMum = _mumDna % 100000000;

        uint256 kittyDna = (fromDad * 100000000) + fromMum;
        return kittyDna;
    }

Most of this JS functions are not available in solidity but you can create your own custom one, but is a bit tricky. My advice is to make it simple than rounding. You can add + 1 to the higher generation and thats it. Because if we mix a gen 1 with a gen 3 for example, makes sense to have a gen 4. Not lower and not equal since generations are always increassing.

1 Like

Mixing assignment:

    function breed(uint256 _dadId, uint256 _mumId) public returns(uint256 _newKitten){
        require(_owns(msg.sender, _dadId) && _owns(msg.sender, _mumId), "The user doesn't own the token"); //check ownership.
        //you got the dna.
        _KittyGeneration(_newKitten);//figure out the generation.
        //create new cat with the new properties, give it to the msg.sender
        uint256 newDna = _mixDna(_dadId, _mumId);
        _createKitty(_mumId, _dadId, _newKitten, newDna, msg.sender);
    }

    function _KittyGeneration(uint256 _id) internal view returns (uint256 generation){
        Kitty storage kitty = kitties[_id];    
        generation = uint256(kitty.generation);
        return generation;
    }

can someone maybe confirm that this could work? I will implement the next video into my code but was playing around with the code in my head and tried to work something out I see that everyone else in here got different code that’s why I’m wondering. Have a nice day!

1 Like

Hey! @jelle_van_der_meer you have to test to know if its work. If you have some errors please send screen shoot hre.

DNA mixing assignment
function breed(uint256 _dadId, uint256 _mumId) public returns(uint256){
        require(_dadId<kitties.length && _mumId<kitties.length, "Invalid Ids");
        require(_owns(msg.sender, _dadId)&&_owns(msg.sender, _mumId), "Not the owner");
        uint256 newGen = (kitties[_dadId].generation + kitties[_mumId].generation)/2+1;
        uint256 newDna = _mixDna(dadDna, mumDna);
        uint256 newKitty = _createKitty(newDna, _dadId, _mumId, _newGen, msg.sender);
    }

function _mixDna(uint256 _dadDna, uint256 _momDna) internal returns(uint256){
        uint256 firstHalf =_dadDna / 100000000;
        uint256 secondHalf = _momDna % 100000000;
        return firstHalf *100000000 + secondHalf;
    }

see my code below:

function breed(uint256 _dadId, uint256 _mumId) public onlyOwner returns (uint256) {
        uint newDna = _mixDna(_dadId, _mumId);

        uint16 _mumGeneration = kitties[_mumId].generation;
        uint16 _dadGeneration = kitties[_dadId].generation;

        uint newGeneration = _mixGeneration(_mumGeneration, _dadGeneration);

        return _createKitty(_mumId, _dadId, newGeneration, newDna, msg.sender);
    }

function _mixGeneration(uint16 _mumGeneration, uint16 _dadGeneration) internal returns (uint16) {
        uint16 newGeneration = _mumGeneration + _dadGeneration;
        newGeneration = newGeneration/2;

        if(_mumGeneration > _dadGeneration){
            newGeneration = newGeneration;
        }
        else if (_mumGeneration < _dadGeneration) {
            newGeneration = newGeneration + 1;
        }
        else{
            newGeneration = _mumGeneration;
        }
        return newGeneration;
    }
    //breed 2 cats to product new kittens
   function breed(uint256 _dadId, uint256 _mumId) public returns (uint256) {
       
       //check ownership
       require(ownerOf(_dadId) == msg.sender && ownerOf(_mumId) == msg.sender);
       
       //get mum and dad DNA and create DNA for new kitty
        uint256 mumDna = kitties[_mumId].genes;
        uint256 dadDna = kitties[_dadId].genes;
        uint256 newDna = _mixDNA(dadDna,mumDna);

       //figure out generation
       uint256 new_generation = (kitties[_mumId].generation > kitties[_dadId].generation) ? kitties[_mumId].generation:kitties[_dadId].generation; 
       new_generation++; //taking oldest generation and increasing by 1;
       
       //create new cat and give to msg.sender and returning new kittenId
       return _createKitty(_mumId,_dadId,new_generation,newDna,msg.sender);
   }
  // Breads a new kitty from two other kitties
  function breed(uint256 mumId, uint256 dadId) public {
    // '_isApprovedOrOwner' includes check whether token exists
    require(
      _isApprovedOrOwner(msg.sender, mumId) &&
        _isApprovedOrOwner(msg.sender, dadId),
      "Unauthorized"
    );

    Kitty storage mum = _kitties[mumId];
    Kitty storage dad = _kitties[dadId];
    uint256 newGenes = _mixGenes(mum.genes, dad.genes);
    uint16 newGeneration = _mixGeneration(mum.generation, dad.generation);

    _createKitty(mumId, dadId, newGeneration, newGenes, ownerOf(mumId));
  }

  function _mixGeneration(uint16 generation1, uint16 generation2)
    internal
    pure
    returns (uint16)
  {
    return (generation1 + generation2) / 2 + 1;
  }

  function _mixGenes(uint256 genes1, uint256 genes2)
    internal
    pure
    returns (uint256)
  {
    // Example DNA: 20 20 300 | 1 0 0 35 1 1 (20203001003511)
    uint256 genes1Part1 = genes1 / 10000000;
    uint256 genes2Part2 = genes2 % 10000000;
    return genes1Part1 * 10000000 + genes2Part2;
  }