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- ഒരുപക്ഷേ സഹായകരമാണ്: ഉമിക്കോയുടെ അധിക സ്ക്രീൻഷോട്ട് "അത് ആയിരുന്നു ഒരേ പ്രവർത്തനത്തെ വിളിക്കുന്നു വീണ്ടും വീണ്ടും ", ഇത് കോഡിൽ കാണിച്ചേക്കില്ല.
- ഓ! എനിക്കത് അറിയില്ലായിരുന്നു! Watch ഞാൻ കണ്ട സൈഡ് "അനന്ത ലൂപ്പ്"
- Og ലോഗൻ ഞാൻ ശരിക്കും സമ്മതിക്കുന്നില്ല. ഒരു ആനിമേഷനിൽ നിന്ന് സംഭവിച്ച ചില സോഴ്സ് കോഡിനെക്കുറിച്ച് ഒപിക്ക് ഒരു ചോദ്യമുണ്ടെന്നത് മാത്രമല്ല; ഒപിയുടെ ചോദ്യം ഒരു പ്രത്യേക പ്രസ്താവനയെക്കുറിച്ചാണ് കുറിച്ച് ആനിമിലെ ഒരു പ്രതീകത്തിന്റെ സോഴ്സ് കോഡ്, ഒപ്പം ആനിമേഷനുമായി ബന്ധപ്പെട്ട ഒരു ഉത്തരമുണ്ട്, അതായത് "ക്രഞ്ചൈറോൾ വിഡ് go ിത്തവും വരി തെറ്റായി വിവർത്തനം ചെയ്തു".
- @ സെൻഷിൻ യഥാർത്ഥത്തിൽ ചോദിക്കുന്നതിനേക്കാൾ നിങ്ങൾ എന്തായിരിക്കണമെന്ന് നിങ്ങൾ ആഗ്രഹിക്കുന്നുവെന്ന് ഞാൻ കരുതുന്നു. ചോദ്യം ചില സോഴ്സ് കോഡ് നൽകുകയും അത് യഥാർത്ഥ ജീവിത സി ++ കോഡായി അനന്തമായ ലൂപ്പ് സൃഷ്ടിക്കുന്നുണ്ടോ എന്ന് ചോദിക്കുകയും ചെയ്യുന്നു. പുതിയ ഗെയിം! ഒരു സാങ്കൽപ്പിക കൃതിയാണ്; യഥാർത്ഥ ജീവിത നിലവാരങ്ങളുമായി പൊരുത്തപ്പെടുന്നതിന് കോഡ് അവതരിപ്പിക്കേണ്ട ആവശ്യമില്ല. ഏത് സി ++ മാനദണ്ഡങ്ങളേക്കാളും കംപൈലറുകളേക്കാളും ആധികാരികമാണ് കോഡിനെക്കുറിച്ച് യുമിക്കോ പറയുന്നത്. മുകളിലുള്ള (സ്വീകരിച്ച) ഉത്തരത്തിന് പ്രപഞ്ചത്തിലെ ഏതെങ്കിലും വിവരങ്ങളെക്കുറിച്ച് പരാമർശമില്ല. ഒരു നല്ല ഉത്തരം ഉപയോഗിച്ച് വിഷയത്തിൽ ഒരു ചോദ്യം ചോദിക്കാമെന്ന് ഞാൻ കരുതുന്നു, പക്ഷേ പദാവലി പോലെ ഇത് അങ്ങനെയല്ല.
കോഡ് അനന്തമായ ലൂപ്പല്ല, പക്ഷേ ഇത് ഒരു ബഗ് ആണ്.
രണ്ട് (ഒരുപക്ഷേ മൂന്ന്) പ്രശ്നങ്ങളുണ്ട്:
- ഡീബഫുകളൊന്നും ഇല്ലെങ്കിൽ കേടുപാടുകൾ ഒന്നും ബാധകമല്ല
- 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 എച്ച്പിക്ക് മുകളിൽ പോയില്ലെങ്കിൽ 4 ഫ്ലോട്ടുകൾ ആരോഗ്യത്തിന് മികച്ചതാണ്. നിങ്ങൾക്ക് ആക്രമിക്കാൻ കഴിയുന്ന ഒരു ശത്രുവിനെ സൃഷ്ടിക്കാൻ നിങ്ങൾക്ക് ആരോഗ്യം അനന്തമായി സജ്ജമാക്കാം, പക്ഷേ മരിക്കില്ല, കൂടാതെ അനന്തമായ കേടുപാടുകൾ ഉപയോഗിച്ച് ഒറ്റത്തവണ ആക്രമണം നടത്തുകയും അത് അനന്തമായ എച്ച്പി പ്രതീകത്തെ കൊല്ലുകയുമില്ല (ഐഎൻഎഫ്-ഐഎൻഎഫിന്റെ ഫലം NaN ആണ്) മറ്റെല്ലാം നശിപ്പിക്കും. അതിനാൽ ഇത് വളരെ ഉപയോഗപ്രദമാണ്.
- 1 atcat പല കോഡിംഗ് മാനദണ്ഡങ്ങളിലും കൺവെൻഷൻ പ്രകാരം
m_
പ്രിഫിക്സ് എന്നാൽ ഇത് ഒരു അംഗ വേരിയബിൾ എന്നാണ്. ഈ സാഹചര്യത്തിൽ ഒരു അംഗ വേരിയബിൾDestructibleActor
. - 2 ot ഹോട്ടൽ കാലിഫോർണിയ ഒരു ചെറിയ അവസരമുണ്ടെന്ന് ഞാൻ സമ്മതിക്കുന്നു
ApplyToDamage
പ്രതീക്ഷിച്ചപോലെ പ്രവർത്തിക്കുന്നില്ല, പക്ഷേ നിങ്ങൾ നൽകുന്ന ഉദാഹരണത്തിൽ ഞാൻ പറയുംApplyToDamage
കൂടാതെ യഥാർത്ഥമായത് കൈമാറുന്നതിനായി പുനർനിർമ്മിക്കേണ്ടതുണ്ട്sourceDamage
അതുപോലെ തന്നെ അത്തരം സന്ദർഭങ്ങളിൽ ഡീബഫ് ശരിയായി കണക്കാക്കാനും കഴിയും. ഒരു കേവല പെഡന്റാകാൻ: ഈ സമയത്ത് ഡിഎംജി വിവരങ്ങൾ യഥാർത്ഥ ഡിഎംജി, നിലവിലെ ഡിഎംജി, കേടുപാടുകളുടെ സ്വഭാവം എന്നിവ ഉൾക്കൊള്ളുന്ന ഒരു ഘടനയായിരിക്കണം, കൂടാതെ ഡീബഫുകൾക്ക് "തീപിടുത്തത്തിനുള്ള സാധ്യത" പോലുള്ള കാര്യങ്ങളുണ്ടെങ്കിൽ. അനുഭവത്തിൽ നിന്ന് ഡീബഫുകളുള്ള ഏതെങ്കിലും ഗെയിം ഡിസൈൻ ഇവ ആവശ്യപ്പെടുന്നതിന് വളരെ മുമ്പല്ല. - 1 te സ്റ്റെഫാൻ ഹോക്കൺഹൾ നന്നായി പറഞ്ഞു!
കോഡ് അനന്തമായ ലൂപ്പ് സൃഷ്ടിക്കുന്നതായി തോന്നുന്നില്ല.
ലൂപ്പ് അനന്തമായിരിക്കും
debuf.ApplyToDamage(resolvedDamage);
അഥവാ
DestroyMe();
എന്നതിലേക്ക് പുതിയ ഇനങ്ങൾ ചേർക്കേണ്ടതായിരുന്നു m_debufs
കണ്ടെയ്നർ.
ഇത് സാധ്യതയില്ലെന്ന് തോന്നുന്നു. അങ്ങനെയാണെങ്കിൽ, ആവർത്തനം ചെയ്യുമ്പോൾ കണ്ടെയ്നർ മാറ്റുന്നതിനാൽ പ്രോഗ്രാം തകരാറിലാകും.
കോൾ കാരണം പ്രോഗ്രാം മിക്കവാറും തകരാറിലാകും DestroyMe();
ഇത് നിലവിൽ ലൂപ്പ് പ്രവർത്തിപ്പിക്കുന്ന നിലവിലെ ഒബ്ജക്റ്റിനെ നശിപ്പിക്കുന്നു.
'മോശം വ്യക്തി' ഒരു ശാഖയെ 'നല്ല മനുഷ്യൻ' വീഴ്ത്താൻ ആഗ്രഹിക്കുന്ന കാർട്ടൂണായി നമുക്ക് ഇതിനെ കണക്കാക്കാം, പക്ഷേ അയാൾ കട്ടിന്റെ തെറ്റായ ഭാഗത്താണെന്ന് വളരെ വൈകി മനസ്സിലാക്കുന്നു. അല്ലെങ്കിൽ മിഡ്ഗാർഡ് പാമ്പ് സ്വന്തം വാൽ കഴിക്കുന്നു.
അനന്തമായ ലൂപ്പിന്റെ ഏറ്റവും സാധാരണമായ ലക്ഷണം അത് പ്രോഗ്രാം മരവിപ്പിക്കുകയോ പ്രതികരിക്കാതിരിക്കുകയോ ചെയ്യുന്നുവെന്നതും ഞാൻ ചേർക്കണം. മെമ്മറി ആവർത്തിച്ച് അനുവദിക്കുകയോ അല്ലെങ്കിൽ പൂജ്യം അല്ലെങ്കിൽ ലൈക്കുകൾ കൊണ്ട് വിഭജിക്കുന്ന എന്തെങ്കിലും ചെയ്യുകയോ ചെയ്താൽ അത് പ്രോഗ്രാം തകരാറിലാകും.
അക്കി തനകയുടെ അഭിപ്രായത്തെ അടിസ്ഥാനമാക്കി,
ഒരുപക്ഷേ സഹായകരമാണ്: കോഡിൽ കാണിക്കാനിടയില്ലാത്ത "ഒരേ പ്രവർത്തനത്തെ ഇത് വീണ്ടും വീണ്ടും വിളിക്കുന്നു" എന്ന് ഉമിക്കോയുടെ അധിക സ്ക്രീൻഷോട്ട്.
"ഇത് ഒരേ പ്രവർത്തനത്തെ വീണ്ടും വീണ്ടും വിളിക്കുന്നു" ഇത് കൂടുതൽ സാധ്യതയുണ്ട്.
അത് അനുമാനിക്കുന്നു DestroyMe();
ഒന്നിലധികം തവണ വിളിക്കാൻ രൂപകൽപ്പന ചെയ്തിട്ടില്ല, ഇത് ഒരു ക്രാഷിന് കാരണമാകാൻ സാധ്യതയുണ്ട്.
ഈ പ്രശ്നം പരിഹരിക്കാനുള്ള ഒരു മാർഗം മാറ്റുക എന്നതാണ് if
ഇതുപോലുള്ള ഒന്നിനായി:
if (m_currentHealth <= 0.f) { m_currentHealth = 0.f; DestroyMe(); break; }
ഡിസ്ട്രക്റ്റബിൾ ആക്റ്റർ നശിപ്പിക്കുമ്പോൾ ഇത് ലൂപ്പിൽ നിന്ന് പുറത്തുകടക്കും, ഇത് 1) ദി DestroyMe
രീതിയെ ഒരുതവണ മാത്രമേ വിളിക്കൂ, 2) ഒബ്ജക്റ്റ് ഇതിനകം മരിച്ചതായി കണക്കാക്കിയാൽ ഉപയോഗശൂന്യമായി ബഫുകൾ പ്രയോഗിക്കരുത്.
- ആരോഗ്യം പരിശോധിക്കുമ്പോൾ ലൂപ്പിനുശേഷം കാത്തിരിക്കുന്നത് എന്നതിനേക്കാൾ മികച്ച പരിഹാരമാണ് <= 0.
- ഞാൻ കരുതുന്നു
break
ലൂപ്പിന് പുറത്ത്, ഒപ്പം തുടർന്ന് വിളിDestroyMe()
, സുരക്ഷിതമായിരിക്കാൻ
കോഡിൽ നിരവധി പ്രശ്നങ്ങളുണ്ട്:
- ഡീബഫുകൾ ഇല്ലെങ്കിൽ, നാശനഷ്ടങ്ങൾ ഉണ്ടാകില്ല.
DestroyMe()
പ്രവർത്തന നാമം അപകടകരമാണെന്ന് തോന്നുന്നു. ഇത് എങ്ങനെ നടപ്പാക്കി എന്നതിനെ ആശ്രയിച്ച്, ഇത് ഒരു പ്രശ്നമാകാം അല്ലെങ്കിൽ ഉണ്ടാകില്ല. ഇത് ഒരു ഫംഗ്ഷനിൽ പൊതിഞ്ഞ നിലവിലെ ഒബ്ജക്റ്റിന്റെ ഡിസ്ട്രക്റ്ററിലേക്കുള്ള ഒരു കോൾ മാത്രമാണെങ്കിൽ, ഒരു പ്രശ്നമുണ്ട്, കാരണം കോഡ് എക്സിക്യൂട്ട് ചെയ്യുന്നതിനിടയിൽ ഒബ്ജക്റ്റ് നശിപ്പിക്കപ്പെടും. നിലവിലെ ഒബ്ജക്റ്റിന്റെ ഇല്ലാതാക്കൽ ഇവന്റിനെ ക്യൂ ചെയ്യുന്ന ഒരു ഫംഗ്ഷനിലേക്കുള്ള കോൾ ആണെങ്കിൽ, ഒരു പ്രശ്നവുമില്ല, കാരണം അതിന്റെ എക്സിക്യൂഷൻ പൂർത്തിയാക്കി ഇവന്റ് ലൂപ്പ് ആരംഭിക്കുമ്പോൾ അത് നശിപ്പിക്കപ്പെടും.- ആനിമേഷനിൽ പരാമർശിച്ചതായി തോന്നുന്ന യഥാർത്ഥ പ്രശ്നം, "ഇത് ഒരേ പ്രവർത്തനത്തെ വീണ്ടും വീണ്ടും വിളിക്കുന്നു" - ഇത് വിളിക്കും
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 - ഞാൻ മുമ്പ് മെമ്മറി അലോക്കേറ്ററുകൾ എഴുതിയതുപോലെ, അതേ മെമ്മറി ഇല്ലാതാക്കുന്നത് ഒരു പ്രശ്നമല്ലെന്ന് ഞാൻ ചൂണ്ടിക്കാണിക്കണം. ഇത് അനാവശ്യവും ആകാം. ഇതെല്ലാം അലോക്കേറ്ററുടെ പെരുമാറ്റത്തെ ആശ്രയിച്ചിരിക്കുന്നു. എന്റേത് ഒരു താഴ്ന്ന നിലയിലുള്ള ലിങ്കുചെയ്ത ലിസ്റ്റ് പോലെ പ്രവർത്തിച്ചതിനാൽ ഇല്ലാതാക്കിയ ഡാറ്റയ്ക്കായുള്ള "നോഡ്" ഒന്നുകിൽ നിരവധി തവണ സ set ജന്യമായി സജ്ജീകരിക്കുകയോ അല്ലെങ്കിൽ നിരവധി തവണ പുനർനിർമ്മിക്കുകയോ ചെയ്യുന്നു (ഇത് അനാവശ്യ പോയിന്റർ റീഡയറക്ഷനുകളുമായി പൊരുത്തപ്പെടും). നല്ല ക്യാച്ച് ആണെങ്കിലും.
- ഇരട്ട-രഹിതം ഒരു ബഗ് ആണ്, ഇത് സാധാരണയായി നിർവചിക്കപ്പെടാത്ത സ്വഭാവത്തിലേക്കും ക്രാഷുകളിലേക്കും നയിക്കുന്നു. ഒരേ മെമ്മറി വിലാസത്തിന്റെ പുനരുപയോഗം എങ്ങനെയെങ്കിലും അനുവദിക്കാത്ത ഒരു ഇച്ഛാനുസൃത അലോക്കേറ്റർ നിങ്ങളുടെ പക്കലുണ്ടെങ്കിൽപ്പോലും, ഇരട്ട രഹിതം ഒരു ദുർഗന്ധമുള്ള കോഡാണ്, കാരണം ഇത് അർത്ഥമാക്കുന്നില്ല, മാത്രമല്ല സ്റ്റാറ്റിക് കോഡ് അനലൈസറുകൾ നിങ്ങളെ അലട്ടുകയും ചെയ്യും.
- തീർച്ചയായും! അതിനായി ഞാൻ ഇത് രൂപകൽപ്പന ചെയ്തിട്ടില്ല. സവിശേഷതകളുടെ അഭാവം കാരണം ചില ഭാഷകൾക്ക് ഒരു അലോക്കേറ്റർ ആവശ്യമാണ്. ഇല്ല ഇല്ല ഇല്ല. ഒരു ക്രാഷ് ഉറപ്പില്ലെന്ന് ഞാൻ പറയുകയായിരുന്നു. ചില ഡിസൈൻ ക്ലാസിഫിക്കേഷനുകൾ എല്ലായ്പ്പോഴും തകരാറിലാകില്ല.