当前位置: 首页>>代码示例>>C++>>正文


C++ CvCity::plot方法代码示例

本文整理汇总了C++中CvCity::plot方法的典型用法代码示例。如果您正苦于以下问题:C++ CvCity::plot方法的具体用法?C++ CvCity::plot怎么用?C++ CvCity::plot使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在CvCity的用法示例。


在下文中一共展示了CvCity::plot方法的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: BuildEnemyUnitList

// Find all our enemies (combat units)
void CvTacticalAnalysisMap::BuildEnemyUnitList()
{
	m_EnemyUnits.clear();
	m_EnemyCities.clear();

	TeamTypes ourTeam = GET_PLAYER(m_ePlayer).getTeam();
	for(int iPlayer = 0; iPlayer < MAX_PLAYERS; iPlayer++)
	{
		const PlayerTypes ePlayer = (PlayerTypes)iPlayer;
		CvPlayer& kPlayer = GET_PLAYER(ePlayer);
		const TeamTypes eTeam = kPlayer.getTeam();

		// for each opposing civ
		if(kPlayer.isAlive() && GET_TEAM(eTeam).isAtWar(ourTeam))
		{
			int iLoop;
			CvUnit* pLoopUnit = NULL;
			CvCity* pLoopCity;

			for(pLoopCity = kPlayer.firstCity(&iLoop); pLoopCity != NULL; pLoopCity = kPlayer.nextCity(&iLoop))
				if (pLoopCity->plot()->isRevealed(ourTeam))
					m_EnemyCities.push_back(pLoopCity->GetIDInfo());

			for(pLoopUnit = kPlayer.firstUnit(&iLoop); pLoopUnit != NULL; pLoopUnit = kPlayer.nextUnit(&iLoop))
				if(pLoopUnit->IsCanAttack() && pLoopUnit->plot()->isVisible(ourTeam))
					m_EnemyUnits.push_back(pLoopUnit->GetIDInfo());
		}
	}
}
开发者ID:kawyua,项目名称:Community-Patch-DLL,代码行数:30,代码来源:CvTacticalAnalysisMap.cpp

示例2: Update

/// Updates the lookup table
void CvDistanceMapTurns::Update()
{
	//performance optimization, reduce pathfinding range
	int iMaxTurns = GC.getGame().getElapsedGameTurns() == 0 ? 7 : 12;
	int iVeryFar = iMaxTurns * 6;

	const CvMap& map = GC.getMap();
	int nPlots = map.numPlots();

	m_vDistance = std::vector<int>(nPlots, iVeryFar);
	m_vClosestFeature = std::vector<int>(nPlots,0);
	m_bArrayAllocated = true;
		
	for (int i = 0; i < MAX_PLAYERS; i++)
	{
		//if we have a set player, ignore all others
		if (m_ePlayer!=NO_PLAYER && m_ePlayer!=i)
			continue;

		// for each city
		CvPlayer& thisPlayer = GET_PLAYER((PlayerTypes)i);
		int iCityIndex = 0;
		for(CvCity* pLoopCity = thisPlayer.firstCity(&iCityIndex); pLoopCity != NULL; pLoopCity = thisPlayer.nextCity(&iCityIndex))
		{
			//slow update only for plots close to the city
			ReachablePlots turnsFromCity;
			SPathFinderUserData data(m_ePlayer, PT_GENERIC_REACHABLE_PLOTS, -1, iMaxTurns);
			turnsFromCity = GC.GetStepFinder().GetPlotsInReach(pLoopCity->plot(), data);

			for (ReachablePlots::iterator it = turnsFromCity.begin(); it != turnsFromCity.end(); ++it)
			{
				int iTurns = it->iTurns;
				bool bUpdate = (iTurns < m_vDistance[it->iPlotIndex]);
					
				//in case of equal distance, take care not to prefer the player with the lower ID
				if (iTurns == m_vDistance[it->iPlotIndex])
				{
					PlayerTypes currentOwner = (PlayerTypes)UNPACK_OWNER(m_vClosestFeature[it->iPlotIndex]);
					CvCity* pCurrentCity = GET_PLAYER(currentOwner).getCity(UNPACK_ID(m_vClosestFeature[it->iPlotIndex]));
					//it can happen that there is no current city if the plot has never been updated because it's very remote
					bUpdate = (pCurrentCity==NULL) || (pCurrentCity->getGameTurnFounded() > pLoopCity->getGameTurnFounded());
				}

				if (bUpdate)
				{
					m_vDistance[it->iPlotIndex] = iTurns;
					m_vClosestFeature[it->iPlotIndex] = PACK(pLoopCity->getOwner(), pLoopCity->GetID());
				}
			}
		}
	}

	m_bDirty = false;
}
开发者ID:kawyua,项目名称:Community-Patch-DLL,代码行数:55,代码来源:CvDistanceMap.cpp

示例3: Update

/// Updates the danger plots values to reflect threats across the map
void CvDistanceMap::Update()
{
	const CvMap& map = GC.getMap();
	int nPlots = map.numPlots();

	m_vDistance = std::vector<int>(nPlots,INT_MAX);
	m_vClosestFeature = std::vector<int>(nPlots,0);
	m_bArrayAllocated = true;
		
	// since we know there are very few cities compared to the number of plots,
	// we don't need to do the full distance transform

	for (int i = 0; i < MAX_PLAYERS; i++)
	{
		if (m_ePlayer!=NO_PLAYER && m_ePlayer!=i)
			continue;

		// for each city
		CvPlayer& thisPlayer = GET_PLAYER((PlayerTypes)i);
		int iCityIndex = 0;
		for(CvCity* pLoopCity = thisPlayer.firstCity(&iCityIndex); pLoopCity != NULL; pLoopCity = thisPlayer.nextCity(&iCityIndex))
		{
			CvPlot* pCityPlot = pLoopCity->plot();

			for (int iPlotIndex=0; iPlotIndex<nPlots; iPlotIndex++)
			{
				CvPlot* pPlot = map.plotByIndexUnchecked(iPlotIndex);
				if (pPlot)
				{
					int iDistance = plotDistance( pCityPlot->getX(),pCityPlot->getY(),pPlot->getX(),pPlot->getY() );

					bool bUpdate = (iDistance < m_vDistance[iPlotIndex]);
					
					//in case of equal distance, take care not to prefer the player with the lower ID
					if (iDistance == m_vDistance[iPlotIndex]) 
					{
						PlayerTypes currentOwner = (PlayerTypes) UNPACK_OWNER(m_vClosestFeature[iPlotIndex]);
						CvCity* pCurrentCity = GET_PLAYER(currentOwner).getCity( UNPACK_ID(m_vClosestFeature[iPlotIndex]) );
						bUpdate = (pCurrentCity->getGameTurnFounded() > pLoopCity->getGameTurnFounded());
					}

					if (bUpdate)
					{
						m_vDistance[iPlotIndex] = iDistance;
						m_vClosestFeature[iPlotIndex] = PACK(pLoopCity->getOwner(), pLoopCity->GetID());
					}
				}
			}
		}
	}

	m_bDirty = false;
}
开发者ID:DivineYuri,项目名称:Community-Patch-DLL,代码行数:54,代码来源:CvDistanceMap.cpp

示例4: CheckTargetReached

CvPlot* CvArmyAI::CheckTargetReached(PlayerTypes eEnemy, bool bNavalOp, int iMaxDistance)
{
	//check if we're at the target
	CvPlot *pTargetPlot = GetGoalPlot();
	CvPlot *pCenterOfMass = GetCenterOfMass(NO_DOMAIN);
	if(pCenterOfMass && pTargetPlot && plotDistance(*pCenterOfMass,*pTargetPlot) <= iMaxDistance)
		return pTargetPlot;

	//check early termination if we ran into the enemy
	if(GetArmyAIState() == ARMYAISTATE_MOVING_TO_DESTINATION)
	{
		CvPlot*	pEnemyPlot = DetectNearbyEnemy(eEnemy, bNavalOp);
		if(pEnemyPlot != NULL)
		{
			CvCity* pCity = pEnemyPlot->getWorkingCity();
			if(pCity != NULL)
			{
				if (bNavalOp && pCity->isCoastal() && pCity->waterArea()==pTargetPlot->area())
					pEnemyPlot = pCity->plot();

				if (!bNavalOp && pCity->area()==pTargetPlot->area())
					pEnemyPlot = pCity->plot();

				if (pEnemyPlot!=GetGoalPlot())
				{
					if(GC.getLogging() && GC.getAILogging())
					{
						CvString strMsg;
						strMsg.Format("Switching target from %d,%d to closest city at %d,%d", GetGoalX(), GetGoalY(), pEnemyPlot->getX(), pEnemyPlot->getY() );
						GET_PLAYER(m_eOwner).getAIOperation(m_iOperationID)->LogOperationSpecialMessage(strMsg);
					}
				}

				return pEnemyPlot;
			}
		}
	}

	return NULL;
}
开发者ID:steemroller,项目名称:Community-Patch-DLL,代码行数:40,代码来源:CvArmyAI.cpp

示例5: UpdateDanger

/// Updates the danger plots values to reflect threats across the map
void CvDangerPlots::UpdateDanger (bool bPretendWarWithAllCivs, bool bIgnoreVisibility)
{
	// danger plots have not been initialized yet, so no need to update
	if (!m_bArrayAllocated)
	{
		return;
	}

	// wipe out values
	int iGridSize = GC.getMap().numPlots();
	CvAssertMsg(iGridSize == m_DangerPlots.size(), "iGridSize does not match number of DangerPlots");
	for (int i = 0; i < iGridSize; i++)
	{
		m_DangerPlots[i] = 0;
	}

	CvPlayer& thisPlayer = GET_PLAYER(m_ePlayer);
	TeamTypes thisTeam = thisPlayer.getTeam();

	// for each opposing civ
	for (int iPlayer = 0; iPlayer < MAX_PLAYERS; iPlayer++)
	{
		PlayerTypes ePlayer = (PlayerTypes)iPlayer;
		CvPlayer& loopPlayer = GET_PLAYER(ePlayer);
		TeamTypes eTeam = loopPlayer.getTeam();

		if (!loopPlayer.isAlive())
		{
			continue;
		}

		if (eTeam == thisTeam)
		{
			continue;
		}

		if (ShouldIgnorePlayer(ePlayer) && !bPretendWarWithAllCivs)
		{
			continue;
		}

		//for each unit
		int iLoop;
		CvUnit* pLoopUnit = NULL;
		for (pLoopUnit = loopPlayer.firstUnit(&iLoop); pLoopUnit != NULL; pLoopUnit = loopPlayer.nextUnit(&iLoop))
		{
			if (ShouldIgnoreUnit(pLoopUnit, bIgnoreVisibility))
			{
				continue;
			}

			int iRange = pLoopUnit->baseMoves();
			if (pLoopUnit->canRangeStrike())
			{
				iRange += pLoopUnit->GetRange();
			}

			CvPlot* pUnitPlot = pLoopUnit->plot();
			AssignUnitDangerValue(pLoopUnit, pUnitPlot);
			CvPlot* pLoopPlot = NULL;

			for (int iDX = -(iRange); iDX <= iRange; iDX++)
			{
				for (int iDY = -(iRange); iDY <= iRange; iDY++)
				{
					pLoopPlot = plotXYWithRangeCheck(pUnitPlot->getX(), pUnitPlot->getY(), iDX, iDY, iRange);
					if (!pLoopPlot || pLoopPlot == pUnitPlot)
					{
						continue;
					}

					if (!pLoopUnit->canMoveOrAttackInto(*pLoopPlot) && !pLoopUnit->canRangeStrikeAt(pLoopPlot->getX(),pLoopPlot->getY()))
					{
						continue;
					}

					AssignUnitDangerValue(pLoopUnit, pLoopPlot);
				}
			}
		}

		// for each city
		CvCity* pLoopCity;
		for (pLoopCity = loopPlayer.firstCity(&iLoop); pLoopCity != NULL; pLoopCity = loopPlayer.nextCity(&iLoop))
		{
			if (ShouldIgnoreCity(pLoopCity, bIgnoreVisibility))
			{
				continue;
			}

			int iRange = GC.getCITY_ATTACK_RANGE();
			CvPlot* pCityPlot = pLoopCity->plot();
			AssignCityDangerValue(pLoopCity, pCityPlot);
			CvPlot* pLoopPlot = NULL;

			for (int iDX = -(iRange); iDX <= iRange; iDX++)
			{
				for (int iDY = -(iRange); iDY <= iRange; iDY++)
				{
//.........这里部分代码省略.........
开发者ID:Be1eriand,项目名称:Battle-Royale,代码行数:101,代码来源:CvDangerPlots.cpp

示例6: findTraderCity

CvCity* CvMap::findTraderCity(int iX, int iY, PlayerTypes eOwner, TeamTypes eTeam, bool bSameArea, bool bCoastalOnly, bool bNative, YieldTypes eNativeYield, int iMinAttitude, CvUnit* pUnit, bool bRandom)
{
	int iBestValue = MAX_INT;
	CvCity* pBestCity = NULL;
	CvCity* pHomeCity = NULL;
	if (pUnit != NULL)
    {
        pHomeCity = pUnit->getHomeCity();
        if (pHomeCity == NULL)
        {
            return NULL;
        }
    }
    std::vector<CvCity*> aCitys;
	for (int iI = 0; iI < MAX_PLAYERS; iI++)
	{
		if (GET_PLAYER((PlayerTypes)iI).isAlive() && (!bNative || GET_PLAYER((PlayerTypes)iI).isNative()))
		{
			if ((eOwner == NO_PLAYER) || (eOwner != NO_PLAYER && (GET_PLAYER(eOwner).isNative() != GET_PLAYER((PlayerTypes)iI).isNative())))
			{
				if ((eTeam == NO_TEAM) || GET_TEAM(GET_PLAYER((PlayerTypes)iI).getTeam()).isOpenBorders(eTeam))
				{
					int iLoop;
					for (CvCity* pLoopCity = GET_PLAYER((PlayerTypes)iI).firstCity(&iLoop); pLoopCity != NULL; pLoopCity = GET_PLAYER((PlayerTypes)iI).nextCity(&iLoop))
					{
					    int iNativeCityPathTurns;
					    if (pUnit == NULL || pUnit->generatePath(pLoopCity->plot(), 0, true, &iNativeCityPathTurns))
					    {
                            if (!bSameArea || (pLoopCity->area() == plotINLINE(iX, iY)->area()) || (bCoastalOnly && (pLoopCity->waterArea() == plotINLINE(iX, iY)->area())))
                            {
                                if (!bCoastalOnly || pLoopCity->isCoastal(GC.getMIN_WATER_SIZE_FOR_OCEAN()))
                                {
                                    //if(!bNative || pLoopCity->isNative())
                                   //{
                                        if (eNativeYield == NO_YIELD || (iMinAttitude <= 0 && pLoopCity->AI_getDesiredYield() == eNativeYield) || (pLoopCity->isHuman() && pLoopCity->isImport(eNativeYield)))
                                        {
                                            int iValue = plotDistance(iX, iY, pLoopCity->getX_INLINE(), pLoopCity->getY_INLINE());
                                            if ((iValue <= iMinAttitude) || iMinAttitude <= 0)
                                            {

                                                if (!bRandom)
                                                {

                                                    if (iValue < iBestValue)
                                                    {
                                                        iBestValue = iValue;
                                                        pBestCity = pLoopCity;
                                                    }
                                                }
                                                else
                                                {
                                                    aCitys.push_back(pLoopCity);
                                                }
                                            }
                                        }
                                    //}
                                }
                            }
					    }
					}
				}
			}
		}
	}
    if (bRandom)
    {
        int iRandom = aCitys.size();

        if (iRandom >= 1)
        {
            iRandom = GC.getGameINLINE().getSorenRandNum(iRandom, "Random Find City");
            return aCitys[iRandom];
        }
        else
        {
            return NULL;
        }

    }

    return pBestCity;
}
开发者ID:Nightinggale,项目名称:Medieval_Tech,代码行数:82,代码来源:CvMap.cpp

示例7: UpdateDanger

/// Updates the danger plots values to reflect threats across the map
void CvDangerPlots::UpdateDanger(bool bPretendWarWithAllCivs, bool bIgnoreVisibility)
{
	// danger plots have not been initialized yet, so no need to update
	if(!m_bArrayAllocated)
		return;

	// wipe out values
	int iGridSize = GC.getMap().numPlots();
	CvAssertMsg(iGridSize == m_DangerPlots.size(), "iGridSize does not match number of DangerPlots");
	for(int i = 0; i < iGridSize; i++)
	{
		m_DangerPlots[i].clear();
	}

	//units we know from last turn
	UnitSet previousKnownUnits = m_knownUnits;
	m_knownUnits.clear();

	CvPlayer& thisPlayer = GET_PLAYER(m_ePlayer);
	TeamTypes thisTeam = thisPlayer.getTeam();

	// for each opposing civ
	for(int iPlayer = 0; iPlayer < MAX_PLAYERS; iPlayer++)
	{
		PlayerTypes ePlayer = (PlayerTypes)iPlayer;
		CvPlayer& loopPlayer = GET_PLAYER(ePlayer);
		TeamTypes eTeam = loopPlayer.getTeam();

		if(!loopPlayer.isAlive())
			continue;

		if(eTeam == thisTeam)
			continue;

		if(ShouldIgnorePlayer(ePlayer) && !bPretendWarWithAllCivs)
			continue;

		//for each unit
		int iLoop;
		CvUnit* pLoopUnit = NULL;
		for(pLoopUnit = loopPlayer.firstUnit(&iLoop); pLoopUnit != NULL; pLoopUnit = loopPlayer.nextUnit(&iLoop))
		{
			UpdateDangerSingleUnit(pLoopUnit, bIgnoreVisibility, true);
		}

		// for each city
		CvCity* pLoopCity;
		for(pLoopCity = loopPlayer.firstCity(&iLoop); pLoopCity != NULL; pLoopCity = loopPlayer.nextCity(&iLoop))
		{
			if(ShouldIgnoreCity(pLoopCity, bIgnoreVisibility))
				continue;

#if defined(MOD_EVENTS_CITY_BOMBARD)
			bool bIndirectFireAllowed = false;
			int iRange = pLoopCity->getBombardRange(bIndirectFireAllowed);
#else
			int iRange = GC.getCITY_ATTACK_RANGE();
#endif
			CvPlot* pCityPlot = pLoopCity->plot();
			CvPlot* pLoopPlot = NULL;
			for(int iDX = -(iRange); iDX <= iRange; iDX++)
			{
				for(int iDY = -(iRange); iDY <= iRange; iDY++)
				{
					pLoopPlot = plotXYWithRangeCheck(pCityPlot->getX(), pCityPlot->getY(), iDX, iDY, iRange);
					if(!pLoopPlot || pLoopPlot == pCityPlot)
						continue;

#if defined(MOD_EVENTS_CITY_BOMBARD)
					if (!bIndirectFireAllowed && !pCityPlot->canSeePlot(pLoopPlot, NO_TEAM, iRange, NO_DIRECTION))
						continue;
#endif
					AssignCityDangerValue(pLoopCity, pLoopPlot);
				}
			}
		}
	}

	// now compare the new known units with the previous known units
	for (UnitSet::iterator it = previousKnownUnits.begin(); it != previousKnownUnits.end(); ++it)
	{
		//might have made peace ...
		if (ShouldIgnorePlayer(it->first))
			continue;

		if (m_knownUnits.find(*it) == m_knownUnits.end())
		{
			CvUnit* pVanishedUnit = GET_PLAYER(it->first).getUnit(it->second);

			//it's still there, but moved out of sight - nevertheless count is, a human would do that as well
			//do not add it to the known units though, so next turn we will have forgotten about it
			if (pVanishedUnit)
				UpdateDangerSingleUnit(pVanishedUnit, true, false);
		}
	}

	int iPlotLoop;
	CvPlot* pPlot, *pAdjacentPlot;
	for(iPlotLoop = 0; iPlotLoop < GC.getMap().numPlots(); iPlotLoop++)
//.........这里部分代码省略.........
开发者ID:JFDaly,项目名称:Community-Patch-DLL,代码行数:101,代码来源:CvDangerPlots.cpp

示例8: AI_tradeRoutes

bool CvSelectionGroupAI::AI_tradeRoutes()
{
	PROFILE_FUNC();

	const IDInfo kEurope(getOwnerINLINE(), CvTradeRoute::EUROPE_CITY_ID);

	CvCity* pPlotCity = plot()->getPlotCity();
	CvPlayerAI& kOwner = GET_PLAYER(getOwnerINLINE());
	std::set<int>::iterator it;

	std::map<IDInfo, int> cityValues;

	std::vector<CvTradeRoute*> routes;
	std::vector<int> routeValues;

	std::vector<bool> yieldsDelivered(NUM_YIELD_TYPES, false);
	std::vector<bool> yieldsToUnload(NUM_YIELD_TYPES, false);
	std::vector<int> yieldsOnBoard(NUM_YIELD_TYPES, false);

	if (!isHuman() || (getAutomateType() == AUTOMATE_TRANSPORT_FULL))
	{
		std::vector<CvTradeRoute*> aiRoutes;
		kOwner.getTradeRoutes(aiRoutes);
		for (uint i = 0; i < aiRoutes.size(); ++i)
		{
			CvTradeRoute* pRoute = aiRoutes[i];

			// transport feeder - start - Nightinggale
			CvCity* pDestinationCity = ::getCity(pRoute->getDestinationCity());
			if (pDestinationCity != NULL && pDestinationCity->isAutoImportStopped(pRoute->getYield()))
			{
				// ignore trade routes where destination is using feeder service and is full
				continue;
			}
			// transport feeder - end - Nightinggale

			// traderoute fix - start - Nightinggale
			if (isHuman() && pRoute->getDestinationCity().eOwner != getOwnerINLINE())
			{
				// humans can't transport to allied cities with fully automated transports
				continue;
			}
			// traderoute fix - end - Nightinggale

			CvCity* pSourceCity = ::getCity(pRoute->getSourceCity());
			CvArea* pSourceWaterArea = pSourceCity->waterArea();
			if ((pSourceCity != NULL) && ((getDomainType() != DOMAIN_SEA) || (pSourceWaterArea != NULL)))
			{
				int iSourceArea = (getDomainType() == DOMAIN_SEA) ? pSourceWaterArea->getID() : pSourceCity->getArea();
				if (getDomainType() == DOMAIN_SEA ? plot()->isAdjacentToArea(iSourceArea) : (iSourceArea == getArea()))
				{
					if ((getDomainType() == DOMAIN_SEA) || (pRoute->getDestinationCity() != kEurope))
					{
						routes.push_back(pRoute);
						routeValues.push_back(0);

						yieldsDelivered[pRoute->getYield()] = true;

						if (pPlotCity != NULL && ::getCity(pRoute->getDestinationCity()) == pPlotCity)
						{
							yieldsToUnload[pRoute->getYield()] = true;
						}


						cityValues[pRoute->getSourceCity()] = 0;
						cityValues[pRoute->getDestinationCity()] = 0;
					}
				}
			}
		}
	}
	else
	{
		for (it = m_aTradeRoutes.begin(); it != m_aTradeRoutes.end(); ++it)
		{
			CvTradeRoute* pRoute = kOwner.getTradeRoute(*it);
			CvCity* pSourceCity = ::getCity(pRoute->getSourceCity());
			if (pSourceCity != NULL)
			{
				CvArea* pSourceWaterArea = pSourceCity->waterArea();
				if (getDomainType() != DOMAIN_SEA || pSourceWaterArea != NULL)
				{
					int iSourceArea = (getDomainType() == DOMAIN_SEA) ? pSourceWaterArea->getID() : pSourceCity->getArea();
					if (getDomainType() == DOMAIN_SEA ? plot()->isAdjacentToArea(iSourceArea) : (iSourceArea == getArea()))
					{
						if ((getDomainType() == DOMAIN_SEA) || (pRoute->getDestinationCity() != kEurope))
						{
							routes.push_back(pRoute);
							routeValues.push_back(0);

							yieldsDelivered[pRoute->getYield()] = true;

							if (pPlotCity != NULL && ::getCity(pRoute->getDestinationCity()) == pPlotCity)
							{
								yieldsToUnload[pRoute->getYield()] = true;
							}


							cityValues[pRoute->getSourceCity()] = 0;
							cityValues[pRoute->getDestinationCity()] = 0;
//.........这里部分代码省略.........
开发者ID:Nightinggale,项目名称:Medieval_Tech,代码行数:101,代码来源:CvSelectionGroupAI.cpp


注:本文中的CvCity::plot方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。