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
  • कदाचित उपयुक्तः "तो होता असं म्हणत उमिकोचा अतिरिक्त स्क्रीनशॉट समान ऑपरेशन कॉल पुन्हा पुन्हा ", जे कदाचित कोडमध्ये दर्शविले जाऊ शकत नाही.
  • अरे! मला ते माहित नव्हते! @AkTanaka मी पाहिलेला सब "अनंत लूप" म्हणतो
  • @LoganM यांना प्रत्युत्तर देत आहे हे केवळ असे नाही की OPनिममधून आलेल्या काही स्त्रोत कोडबद्दल ओपीचा प्रश्न आहे; ओपीचा प्रश्न एका विशिष्ट विधानाबद्दल आहे बद्दल अ‍ॅनिमामधील एका वर्णाद्वारे स्त्रोत कोड आणि तेथे imeनीमाशी संबंधित उत्तर आहे, "क्रंचयरोल डू गोफ्ड एंड द लाइन अयोग्यरचना".
  • @senshin मला असे वाटते की आपण जे विचारू इच्छित आहात त्याऐवजी आपण काय प्रश्न विचारू इच्छित आहात. प्रश्न काही स्त्रोत कोड प्रदान करतो आणि विचारतो की हे रिअल-लाइफ सी ++ कोड म्हणून असीम लूप व्युत्पन्न करते की नाही. नवीन खेळ! एक काल्पनिक काम आहे; वास्तविक जीवनातील मानकांच्या अनुरुप त्यामध्ये कोड सादर करण्याची आवश्यकता नाही. कोडबद्दल उमिको काय म्हणतात हे कोणत्याही सी ++ मानक किंवा कंपाईलरपेक्षा अधिक अधिकृत आहे. वरच्या (स्वीकृत) उत्तरामध्ये विश्वातील कोणत्याही माहितीचा उल्लेख नाही. मला असे वाटते की या विषयावर योग्य उत्तरासह एक प्रश्न विचारला जाऊ शकतो, परंतु शब्दबद्ध केल्यानुसार हे असे नाही.

कोड एक असीम लूप नाही परंतु तो एक बग आहे.

तेथे दोन (शक्यतो तीन) समस्या आहेतः

  • कोणतेही डीबफ उपस्थित नसल्यास कोणतेही नुकसान अजिबात लागू होणार नाही
  • 1 पेक्षा अधिक डेब्यू असल्यास जास्त नुकसान लागू होईल
  • जर डिस्ट्रॉयमे () त्वरित ऑब्जेक्ट डिलिट करतो आणि प्रक्रिया करण्यासाठी अद्याप 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
  • 15 आम्ही कोड पुनरावलोकनावर आहोत? : डी
  • आपण 16777216 एचपीपेक्षा वर न गेल्यास आरोग्यासाठी 4 फ्लोट्स उत्कृष्ट आहेत. आपण मारू शकता असा शत्रू तयार करण्यासाठी आपण आरोग्य अनंतवर सेट देखील करू शकता परंतु मरणार नाही, आणि अनंत एचपी कॅरेक्टरला मारणार नाही अशा अनंत नुकसानीचा वापर करून एक-प्राणघातक हल्ला कराल (आयएनएफ-आयएनएफचा परिणाम एनएएन आहे) परंतु इतर सर्वकाही ठार करील. तर ते खूप उपयुक्त आहे.
  • 1 @ कॅट अनेक कोडिंग मानकांमध्ये संमेलनाद्वारे m_ प्रत्यय म्हणजे तो सदस्य व्हेरिएबल आहे. या प्रकरणात एक सदस्य व्हेरिएबल DestructibleActor.
  • 2 यांना प्रत्युत्तर देत आहे ApplyToDamage अपेक्षेप्रमाणे कार्य करत नाही परंतु आपण देऊ त्या उदाहरणात मी म्हणावे ApplyToDamage देखील मूळ पास करणे आवश्यक आहे यासाठी पुन्हा काम करणे आवश्यक आहे sourceDamage तसेच जेणेकरून त्या प्रकरणात डेबफची योग्य गणना करता येईल. परिपूर्ण पेडंट होण्यासाठी: याक्षणी डीएमजी माहिती एक रचना असावी ज्यात मूळ डीएमजी, चालू डीएमजी आणि नुकसानीचे स्वरूप तसेच डेबफमध्ये "आग लागण्याची असुरक्षा" यासारख्या गोष्टी असतील. अनुभवावरून डेब्यूजसह कोणत्याही गेम डिझाइनची मागणी होण्यापूर्वी हे फार काळ नाही.
  • १ @StephaneHockenhull यांना प्रत्युत्तर देत आहे

कोड अनंत पळवाट तयार करत असल्यासारखे दिसत नाही.

लूप अनंत असण्याचा एकमेव मार्ग असेल तर

debuf.ApplyToDamage(resolvedDamage); 

किंवा

DestroyMe(); 

नवीन आयटम जोडा होते m_debufs कंटेनर

हे संभव नाही असे दिसते. आणि जर तसे झाले असेल तर, पुनरावृत्ती होत असताना कंटेनर बदलल्यामुळे प्रोग्राम क्रॅश होऊ शकतो.

कॉल केल्यामुळे बहुधा प्रोग्राम क्रॅश होईल DestroyMe(); जे सध्या लूप चालू असलेल्या वर्तमान ऑब्जेक्टचा नष्ट करते.

आम्ही या कार्टूनच्या रूपात विचार करू शकतो ज्यात 'वाईट माणूस' त्याच्याबरोबर 'चांगले माणूस' पडण्यासाठी एक शाखा पाहतो, परंतु तो बराच उशीर करतो की तो कटच्या चुकीच्या बाजूने आहे. किंवा मिडगार्ड साप स्वतःची शेपूट खात आहे.


मी हे देखील जोडले पाहिजे की अनंत पळवाट येण्याचे सर्वात सामान्य लक्षण म्हणजे ते प्रोग्राम गोठवते किंवा त्यास प्रतिसाद देत नाही. हे प्रोग्रामला वारंवार मेमरीचे वाटप करत असल्यास किंवा शून्य किंवा पसंतींनी विभाजित होणारे असे काहीतरी करत असल्यास प्रोग्राम क्रॅश होईल.


अकी तानाका यांच्या टिप्पणीवर आधारित,

कदाचित उपयुक्तः "समान ऑपरेशनला पुन्हा पुन्हा कॉल करीत आहे" असे म्हणत उमिकोचा अतिरिक्त स्क्रीनशॉट, जो कोडमध्ये दर्शविला जाऊ शकत नाही.

"हे पुन्हा पुन्हा त्याच ऑपरेशनला कॉल करीत आहे" हे अधिक शक्यता आहे.

ते गृहीत धरून DestroyMe(); एकापेक्षा जास्त वेळा कॉल करण्यासाठी डिझाइन केलेले नाही, यामुळे क्रॅश होण्याची शक्यता असते.

ही समस्या सोडवण्याचा एक मार्ग म्हणजे तो बदलणे if अशा कशासाठी:

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

डिस्ट्रिक्टिबलएक्टर नष्ट झाल्यावर हे लूपमधून बाहेर पडाल हे सुनिश्चित करून 1) द DestroyMe केवळ एकदाच मेथड म्हटले जाते आणि २) ऑब्जेक्ट आधीच मृत समजला की निरुपयोगीपणे बफ्स लावू नका.

2
  • 1 जेव्हा आरोग्य <= 0 असते तेव्हा वळण सोडणे निश्चितच आरोग्याची तपासणी करण्यासाठी पळवाट होईपर्यंत प्रतीक्षा करण्यापेक्षा चांगले निराकरण आहे.
  • मला वाटतं मी बहुधा break पळवाट बाहेर, आणि मग कॉल करा DestroyMe(), फक्त सुरक्षित रहाण्यासाठी

कोडसह अनेक समस्या आहेत:

  1. जर कोणतेही डीबफ नाहीत तर नुकसान केले जाणार नाही.
  2. DestroyMe() फंक्शनचे नाव धोकादायक वाटते. ते कसे अंमलात आणले यावर अवलंबून, ही समस्या असू शकते किंवा असू शकत नाही. जर हे एखाद्या फंक्शनमध्ये लपेटलेल्या वर्तमान ऑब्जेक्टच्या डिस्ट्रक्टरकडे फक्त कॉल असेल तर तेथे एक समस्या आहे कारण ऑब्जेक्ट कोडच्या अंमलबजावणीच्या मध्यभागी नष्ट होईल. जर सध्याच्या ऑब्जेक्टच्या हटविण्याच्या घटकास रांगा लावलेल्या एखाद्या फंक्शनला हा कॉल असेल तर मग त्यातून काही हरकत नाही कारण ऑब्जेक्टची अंमलबजावणी पूर्ण झाल्यावर नष्ट होईल आणि इव्हेंट लूप आत जाईल.
  3. Issueनीमेमध्ये उल्लेख केल्यासारखे दिसत असलेल्या वास्तविक समस्येवर, "हे समान ऑपरेशन पुन्हा पुन्हा कॉल करीत आहे" - ते कॉल करेल 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
  • मी हे सांगायला हवे की यापूर्वी मी मेमरी अ‍ॅलोकटर लिहिले आहेत, त्याच मेमरी हटविणे ही समस्या ठरणार नाही. हे निरर्थक देखील असू शकते. हे सर्व वाटप करणार्‍याच्या वागण्यावर अवलंबून असते. माईनने फक्त निम्न स्तरीय दुवा साधलेल्या यादीसारखे काम केले आहे म्हणून हटवलेल्या डेटासाठी "नोड" एकतर बर्‍याच वेळा विनामूल्य सेट केला जाईल किंवा बर्‍याच वेळा पुनर्विकृत केला जाईल (जे फक्त रिडंडंट पॉइंटर रीडायरेक्शन्सशी संबंधित असेल). चांगले पकडले तरी.
  • डबल-फ्री हा एक दोष आहे आणि सामान्यत: अपरिभाषित वर्तन आणि क्रॅश होते. जरी आपल्याकडे सानुकूल वाटप करणारा असा आहे की तरीही त्याच मेमरी पत्त्याचा पुनर्वापर करण्यास अनुमती नाही, डबल-फ्री हा एक गोंधळ कोड आहे कारण त्याचा काहीच अर्थ नाही आणि आपणास स्थिर कोड विश्लेषकांकडून हे कळेल.
  • नक्कीच! मी त्या हेतूने डिझाइन केलेले नाही. वैशिष्ट्यांच्या अभावामुळे काही भाषांमध्ये फक्त वाटप करणे आवश्यक असते. नाही नाही नाही. मी फक्त असे म्हणत होतो की क्रॅशची हमी नाही. विशिष्ट डिझाइनचे वर्गीकरण नेहमीच क्रॅश होत नाही.