Anonim

AIMBOT 2.0

న్యూ గేమ్ 2 యొక్క ఎపిసోడ్ 1 లో, 9:40 చుట్టూ, నేనే వ్రాసిన కోడ్ యొక్క షాట్ ఉంది:

అనువదించిన వ్యాఖ్యలతో ఇది టెక్స్ట్ రూపంలో ఉంది:

// the calculation of damage when attacked void DestructibleActor::ReceiveDamage(float sourceDamage) { // apply debuffs auto resolvedDamage = sourceDamage; for (const auto& debuf:m_debufs) { resolvedDamage = debuf.ApplyToDamage(resolvedDamage); m_currentHealth -= resolvedDamage if (m_currentHealth <= 0.f) { m_currentHealth = 0.f; DestroyMe(); } } } 

షాట్ తరువాత, ఉమికో, ఫర్ లూప్ వైపు చూపిస్తూ, కోడ్ క్రాష్ కావడానికి కారణం అనంతమైన లూప్ ఉందని అన్నారు.

నాకు నిజంగా సి ++ తెలియదు కాబట్టి ఆమె చెప్పేది నిజమో కాదో నాకు తెలియదు.

నేను చూడగలిగిన దాని నుండి, ఫోర్ లూప్ ప్రస్తుతం నటుడు కలిగి ఉన్న డీబఫ్‌ల ద్వారా మళ్ళిస్తుంది. నటుడికి అనంతమైన డీబఫ్‌లు ఉంటే తప్ప, అది అనంతమైన లూప్‌గా మారవచ్చని నేను అనుకోను.

కానీ నాకు ఖచ్చితంగా తెలియదు ఎందుకంటే కోడ్ యొక్క షాట్ ఉన్న ఏకైక కారణం వారు ఇక్కడ ఈస్టర్ గుడ్డు పెట్టాలని కోరుకున్నారు, సరియైనదా? మేము ల్యాప్‌టాప్ వెనుక భాగంలో ఒక షాట్ సంపాదించి, ఉమికో "ఓహ్ మీకు అక్కడ అనంతమైన లూప్ వచ్చింది" అని చెప్పడం విన్నాము. వారు వాస్తవానికి కొన్ని కోడ్‌ను చూపించారనే వాస్తవం ఏదో ఒకవిధంగా ఈస్టర్ ఒక రకమైన ఈస్టర్ గుడ్డు అని నేను అనుకుంటున్నాను.

కోడ్ వాస్తవానికి అనంతమైన లూప్‌ను సృష్టిస్తుందా?

8
  • బహుశా సహాయకారిగా ఉంటుంది: ఉమికో యొక్క అదనపు స్క్రీన్ షాట్ "ఇది అదే ఆపరేషన్ను పిలుస్తుంది పదే పదే ", ఇది కోడ్‌లో చూపబడకపోవచ్చు.
  • ఓహ్! అది నాకు తెలియదు! K నేను చూసిన ఉప అకిటనాకా "అనంతమైన లూప్"
  • Og లోగాన్ నేను నిజంగా అంగీకరించను. అనిమే నుండి వచ్చిన కొన్ని సోర్స్ కోడ్ గురించి OP కి ప్రశ్న ఉందని మాత్రమే కాదు; OP యొక్క ప్రశ్న ఒక నిర్దిష్ట ప్రకటన గురించి గురించి అనిమేలోని ఒక అక్షరం ద్వారా సోర్స్ కోడ్, మరియు అనిమే-సంబంధిత సమాధానం ఉంది, అవి "క్రంచైరోల్ గూఫ్డ్ మరియు లైన్‌ను తప్పుగా అనువదించింది".
  • ennsnshin వాస్తవానికి అడిగిన దాని కంటే, మీరు ప్రశ్న గురించి ఏమి కోరుకుంటున్నారో చదువుతున్నారని నేను అనుకుంటున్నాను. ప్రశ్న కొన్ని సోర్స్ కోడ్‌ను అందిస్తుంది మరియు ఇది నిజ జీవిత C ++ కోడ్‌గా అనంతమైన లూప్‌ను ఉత్పత్తి చేస్తుందా అని అడుగుతుంది. కొత్త గేమ్! ఒక కల్పిత పని; నిజ జీవిత ప్రమాణాలకు అనుగుణంగా దానిలో సమర్పించబడిన కోడ్ అవసరం లేదు. కోడ్ గురించి ఉమికో చెప్పేది ఏ C ++ ప్రమాణాలు లేదా కంపైలర్లకన్నా ఎక్కువ అధికారం. ఎగువ (అంగీకరించబడిన) సమాధానంలో విశ్వంలో ఏ సమాచారం గురించి ప్రస్తావించబడలేదు. మంచి జవాబుతో దీనిపై ఆన్-టాపిక్ ప్రశ్న అడగవచ్చని నేను అనుకుంటున్నాను, కాని పదజాలం ప్రకారం ఇది కాదు.

కోడ్ అనంతమైన లూప్ కాదు కానీ అది బగ్.

రెండు (బహుశా మూడు) సమస్యలు ఉన్నాయి:

  • డీబఫ్‌లు లేనట్లయితే ఎటువంటి నష్టం వర్తించదు
  • 1 కంటే ఎక్కువ డీబఫ్ ఉంటే అధిక నష్టం వర్తించబడుతుంది
  • DestroyMe () వెంటనే ఆబ్జెక్ట్‌ను తొలగిస్తే మరియు ప్రాసెస్ చేయాల్సిన m_debufs ఇంకా ఉంటే, లూప్ తొలగించబడిన వస్తువు మరియు ట్రాష్ మెమరీపై అమలు అవుతుంది. చాలా గేమ్ ఇంజన్లు దీని చుట్టూ పనిచేయడానికి నాశనం క్యూను కలిగి ఉంటాయి మరియు అందువల్ల సమస్య ఉండకపోవచ్చు.

నష్టం యొక్క అప్లికేషన్ లూప్ వెలుపల ఉండాలి.

సరిదిద్దబడిన ఫంక్షన్ ఇక్కడ ఉంది:

// the calculation of damage when attacked void DestructibleActor::ReceiveDamage(float sourceDamage) { // apply debuffs auto resolvedDamage = sourceDamage; for (const auto& debuf:m_debufs) { resolvedDamage = debuf.ApplyToDamage(resolvedDamage); } m_currentHealth -= resolvedDamage if (m_currentHealth <= 0.f) { m_currentHealth = 0.f; DestroyMe(); } } 
12
  • మేము కోడ్ సమీక్షలో ఉన్నారా? : డి
  • మీరు 16777216 HP పైన వెళ్ళకపోతే 4 ఫ్లోట్లు ఆరోగ్యానికి గొప్పవి. మీరు కొట్టగలిగే శత్రువును సృష్టించడానికి మీరు ఆరోగ్యాన్ని కూడా అనంతంగా సెట్ చేయవచ్చు మరియు అనంతమైన నష్టాన్ని ఉపయోగించి ఒక-చంపే దాడి కలిగి ఉంటారు, అది అనంతమైన HP అక్షరాన్ని చంపదు (INF-INF యొక్క ఫలితం NaN) కానీ మిగతావన్నీ చంపుతుంది. కనుక ఇది చాలా ఉపయోగకరంగా ఉంటుంది.
  • 1 at క్యాట్ అనేక కోడింగ్ ప్రమాణాలలో సమావేశం ద్వారా m_ ఉపసర్గ అంటే ఇది సభ్యుల వేరియబుల్. ఈ సందర్భంలో సభ్యుల వేరియబుల్ DestructibleActor.
  • 2 -హోటెల్కాలిఫోర్నియా ఒక చిన్న అవకాశం ఉందని నేను అంగీకరిస్తున్నాను ApplyToDamage expected హించిన విధంగా పనిచేయదు కాని మీరు ఇచ్చిన ఉదాహరణ సందర్భంలో నేను చెబుతాను ApplyToDamage కూడా దానిని అసలైనదిగా పంపించాల్సిన అవసరం ఉంది sourceDamage అలాగే అది ఆ సందర్భాలలో డీబఫ్‌ను సరిగ్గా లెక్కించగలదు. సంపూర్ణ పెడెంట్‌గా ఉండటానికి: ఈ సమయంలో dmg సమాచారం అసలు dmg, ప్రస్తుత dmg మరియు నష్టం (ల) యొక్క స్వభావాన్ని కలిగి ఉన్న ఒక స్ట్రక్ట్‌గా ఉండాలి, అలాగే డీబఫ్‌లు "అగ్ని ప్రమాదం" వంటి వాటిని కలిగి ఉంటే. అనుభవం నుండి డీబఫ్స్‌తో ఏదైనా గేమ్ డిజైన్ వీటిని డిమాండ్ చేయడానికి చాలా కాలం ముందు కాదు.
  • 1 te స్టెఫేన్ హాకెన్‌హల్ బాగా చెప్పారు!

కోడ్ అనంతమైన లూప్‌ను సృష్టించినట్లు లేదు.

ఒకవేళ లూప్ అనంతంగా ఉంటుంది

debuf.ApplyToDamage(resolvedDamage); 

లేదా

DestroyMe(); 

క్రొత్త అంశాలను జోడించాలి m_debufs కంటైనర్.

ఇది అసంభవం. ఒకవేళ అది జరిగితే, కంటైనర్‌ను మళ్ళించేటప్పుడు ప్రోగ్రామ్ క్రాష్ కావచ్చు.

కాల్ కారణంగా ప్రోగ్రామ్ చాలావరకు క్రాష్ అవుతుంది DestroyMe(); ఇది ప్రస్తుతం లూప్‌ను నడుపుతున్న ప్రస్తుత వస్తువును నాశనం చేస్తుంది.

'మంచి వ్యక్తి' దానితో పడిపోయేలా 'చెడ్డ వ్యక్తి' ఒక శాఖను చూసే కార్టూన్‌గా మనం భావించవచ్చు, కాని అతను కట్ యొక్క తప్పు వైపు ఉన్నాడని చాలా ఆలస్యంగా తెలుసుకుంటాడు. లేదా మిడ్‌గార్డ్ స్నేక్ తినడం దాని స్వంత తోక.


అనంతమైన లూప్ యొక్క సాధారణ లక్షణం ఏమిటంటే అది ప్రోగ్రామ్‌ను స్తంభింపజేస్తుంది లేదా ప్రతిస్పందించనిలా చేస్తుంది. ఇది పదేపదే మెమరీని కేటాయించినట్లయితే లేదా ప్రోగ్రామ్ సున్నా లేదా ఇష్టాలతో విభజించబడితే అది క్రాష్ అవుతుంది.


అకీ తనకా వ్యాఖ్య ఆధారంగా,

బహుశా సహాయకారిగా ఉంటుంది: "ఇది ఒకే ఆపరేషన్‌ను పదే పదే పిలుస్తోంది" అని ఉమికో యొక్క అదనపు స్క్రీన్ షాట్, ఇది కోడ్‌లో చూపబడకపోవచ్చు.

"ఇది ఒకే ఆపరేషన్ను పదే పదే పిలుస్తోంది" ఇది ఎక్కువ.

అని uming హిస్తూ DestroyMe(); ఒకటి కంటే ఎక్కువసార్లు పిలవబడేలా రూపొందించబడలేదు, ఇది క్రాష్‌కు కారణం కావచ్చు.

ఈ సమస్యను పరిష్కరించడానికి ఒక మార్గం మార్చడం if ఇలాంటి వాటి కోసం:

 if (m_currentHealth <= 0.f) { m_currentHealth = 0.f; DestroyMe(); break; } 

డిస్ట్రక్టిబుల్ యాక్టర్ నాశనం అయినప్పుడు ఇది లూప్ నుండి నిష్క్రమిస్తుంది, 1) ది DestroyMe పద్ధతి ఒక్కసారి మాత్రమే పిలువబడుతుంది మరియు 2) వస్తువు ఇప్పటికే చనిపోయినట్లు భావించిన తర్వాత బఫ్స్‌ను పనికిరాని విధంగా వర్తించవద్దు.

2
  • ఆరోగ్యం ఉన్నప్పుడు లూప్ నుండి బయటపడటం <= 0 ఖచ్చితంగా ఆరోగ్యాన్ని తనిఖీ చేయడానికి లూప్ తర్వాత వేచి ఉండటం కంటే మంచి పరిష్కారం.
  • నేను బహుశా అనుకుంటున్నాను break లూప్ నుండి, మరియు అప్పుడు కాల్ DestroyMe(), సురక్షితంగా ఉండటానికి

కోడ్‌తో అనేక సమస్యలు ఉన్నాయి:

  1. డీబఫ్‌లు లేకపోతే, ఎటువంటి నష్టం జరగదు.
  2. DestroyMe() ఫంక్షన్ పేరు ప్రమాదకరమైనదిగా అనిపిస్తుంది. ఇది ఎలా అమలు చేయబడిందనే దానిపై ఆధారపడి, ఇది సమస్య కావచ్చు లేదా కాకపోవచ్చు. ఇది ఒక ఫంక్షన్‌లో చుట్టబడిన ప్రస్తుత వస్తువు యొక్క డిస్ట్రక్టర్‌కు కేవలం కాల్ అయితే, ఒక సమస్య ఉంది, ఎందుకంటే ఆ వస్తువు కోడ్‌ను అమలు చేసే మధ్యలో ఆ వస్తువు నాశనం అవుతుంది. ప్రస్తుత వస్తువు యొక్క తొలగింపు సంఘటనను క్యూ చేసే ఫంక్షన్‌కు ఇది కాల్ అయితే, సమస్య లేదు, ఎందుకంటే వస్తువు దాని అమలు పూర్తయిన తర్వాత నాశనం అవుతుంది మరియు ఈవెంట్ లూప్ ప్రారంభమవుతుంది.
  3. అనిమేలో ప్రస్తావించబడినట్లు కనిపించే అసలు సమస్య, "ఇది ఒకే ఆపరేషన్‌ను పదే పదే పిలుస్తోంది" - ఇది పిలుస్తుంది DestroyMe() ఉన్నంత కాలం m_currentHealth <= 0.f మరియు మళ్ళించడానికి మరిన్ని డీబఫ్‌లు మిగిలి ఉన్నాయి, దీని ఫలితంగా సంభవించవచ్చు DestroyMe() పదే పదే పిలుస్తారు. మొదటి తర్వాత లూప్ ఆగిపోవాలి DestroyMe() కాల్ చేయండి, ఎందుకంటే ఒక వస్తువును ఒకటి కంటే ఎక్కువసార్లు తొలగించడం వల్ల మెమరీ అవినీతి జరుగుతుంది, ఇది దీర్ఘకాలంలో క్రాష్‌కు దారితీస్తుంది.

ప్రతి డీబఫ్ ఆరోగ్యాన్ని ఎందుకు తీసివేస్తుందో నాకు ఖచ్చితంగా తెలియదు, ఆరోగ్యం ఒక్కసారి మాత్రమే తీసివేయబడుతుంది, అన్ని డీబఫ్‌ల యొక్క ప్రభావాలను ప్రారంభ నష్టంపై వర్తింపజేయబడింది, కాని ఇది సరైన ఆట తర్కం అని నేను అనుకుంటాను.

సరైన కోడ్ ఉంటుంది

// the calculation of damage when attacked void DestructibleActor::ReceiveDamage(float sourceDamage) { // apply debuffs auto resolvedDamage = sourceDamage; for (const auto& debuf:m_debufs) { resolvedDamage = debuf.ApplyToDamage(resolvedDamage); m_currentHealth -= resolvedDamage if (m_currentHealth <= 0.f) { m_currentHealth = 0.f; DestroyMe(); break; } } } 
3
  • నేను గతంలో మెమరీ కేటాయింపులను వ్రాసినట్లుగా, అదే మెమరీని తొలగించడం సమస్య కాదని నేను ఎత్తి చూపాలి. ఇది కూడా అనవసరంగా ఉంటుంది. ఇదంతా కేటాయింపుదారుడి ప్రవర్తనపై ఆధారపడి ఉంటుంది. మైన్ తక్కువ స్థాయి లింక్డ్ జాబితా వలె పనిచేసింది, కాబట్టి తొలగించబడిన డేటా కోసం "నోడ్" చాలాసార్లు ఉచితంగా సెట్ చేయబడుతుంది లేదా చాలాసార్లు రీడిలేట్ అవుతుంది (ఇది పునరావృత పాయింటర్ దారి మళ్లింపులకు అనుగుణంగా ఉంటుంది). మంచి క్యాచ్ అయితే.
  • డబుల్ ఫ్రీ అనేది బగ్, మరియు సాధారణంగా నిర్వచించబడని ప్రవర్తన మరియు క్రాష్‌లకు దారితీస్తుంది. మీరు ఒకే మెమరీ చిరునామాను తిరిగి ఉపయోగించడాన్ని అనుమతించని కస్టమ్ కేటాయింపుదారుని కలిగి ఉన్నప్పటికీ, డబుల్ ఫ్రీ అనేది స్మెల్లీ కోడ్, ఎందుకంటే ఇది అర్థం కాదు మరియు మీరు స్టాటిక్ కోడ్ ఎనలైజర్ల ద్వారా అరుస్తారు.
  • వాస్తవానికి! నేను ఆ ప్రయోజనం కోసం దీనిని రూపొందించలేదు. కొన్ని భాషలకు లక్షణాలు లేకపోవడం వల్ల కేటాయింపు అవసరం. లేదు లేదు లేదు. క్రాష్ హామీ ఇవ్వలేదని నేను పేర్కొన్నాను. కొన్ని డిజైన్ వర్గీకరణలు ఎల్లప్పుడూ క్రాష్ కావు.