function buy(address _referral) public payable disableContract
    {
      require(init == true);
      require(games[round].ended == false);
      require(msg.sender != _referral);

      if (games[round].endTime <= now) endRound();
      Game storage g   = games[round];

      uint256 keyPrice       = SafeMath.mul(g.keyLevel, KEY_PRICE_DEFAULT);
      uint256 repay          = SafeMath.sub(msg.value, keyPrice); 
      
      uint256 _referralBonus = SafeMath.div(SafeMath.mul(keyPrice, REFERRAL), 100);
      uint256 _profitTHT     = SafeMath.div(SafeMath.mul(keyPrice, THT_TOKEN_OWNERS), 100);
      uint256 _dividends     = SafeMath.div(SafeMath.mul(keyPrice, KEY_HOLDERS_DIVIDEND), 100);
      uint256 _marketingFee  = SafeMath.div(SafeMath.mul(keyPrice, MARKETING), 100);
      uint256 _finalPot      = SafeMath.div(SafeMath.mul(keyPrice, FINAL_POT), 100); 
      uint256 _nextPot       = keyPrice - (_referralBonus + _profitTHT + _dividends + _marketingFee + _finalPot);
      if (msg.value < keyPrice) revert();
      if (repay > 0) msg.sender.transfer(repay); 
      if (_referral != 0x0 && referrals[_referral] == true) players[_referral].referrals += _referralBonus;
      else owner.transfer(_referralBonus);

      uint256 _fee = _dividends * MAGINITUDE;
      nextPot = SafeMath.add(nextPot, _nextPot);
      profitTHT = SafeMath.add(profitTHT, _profitTHT);

      if (g.keyLevel > 1) {            
        g.profitPerShare += (_dividends * MAGINITUDE / g.keyLevel);
        _fee = _fee - (_fee - (1 * (_dividends * MAGINITUDE / g.keyLevel)));
      }
      int256 _updatedPayouts = (int256) (g.profitPerShare * 1 - _fee);
      updatePlayer(msg.sender, _updatedPayouts);
      
      updateGame(_finalPot);

      sendToTeamMaketing(_marketingFee);

      sendProfitTTH();
      
      emit Buy(round, msg.sender, keyPrice, games[round].keyLevel);
    }