Anonim

আইআইএমবিট ২.০

নিউ গেম 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
  • সম্ভবত সহায়ক: উমিকো অতিরিক্ত স্ক্রিনশটটি বলে যে "এটি ছিল একই অপারেশন কল বার বার ", যা কোডে প্রদর্শিত নাও হতে পারে।
  • উহু! আমি জানতাম না! আকি তনাকা যে সাবটি আমি দেখেছি তা "অসীম লুপ" বলে
  • @ লোগানএম আমি সত্যিই তাতে একমত নই এটি কেবল এটি নয় যে কোনও এনিমে থেকে আসা কোনও উত্স কোড সম্পর্কে ওপির একটি প্রশ্ন রয়েছে; ওপির প্রশ্নটি একটি নির্দিষ্ট বিবৃতি দেওয়া সম্পর্কে সম্পর্কিত এনিমে একটি চরিত্র দ্বারা উত্স কোড, এবং একটি এনিমে সম্পর্কিত উত্তর আছে, যথা "ক্রঞ্চাইরোল সম্পন্ন গোফড এবং লাইনটি ভুলভাবে অনুবাদ করা"।
  • @ এসেনশিন আমার মনে হয় আপনি আসলে যা জিজ্ঞাসা করা হয়েছে তার চেয়ে আপনি যা চান প্রশ্নটি পড়তে চান। প্রশ্নটি কিছু উত্স কোড সরবরাহ করে এবং জিজ্ঞাসা করে যে এটি বাস্তব জীবনের সি ++ কোড হিসাবে অসীম লুপ তৈরি করে। নতুন খেলা! একটি কাল্পনিক কাজ; বাস্তব জীবনের মান মেনে চলার জন্য এতে কোডের উপস্থাপনের দরকার নেই। কোড সম্পর্কে উমিকো কী বলেন তা কোনও সি ++ স্ট্যান্ডার্ড বা সংকলকগুলির চেয়ে বেশি অনুমোদিত। শীর্ষ (স্বীকৃত) উত্তরে মহাবিশ্বের কোনও তথ্যের উল্লেখ নেই। আমি মনে করি একটি ভাল উত্তর দিয়ে এই বিষয়ে একটি বিষয়ে প্রশ্ন করা যেতে পারে, তবে বাক্যযুক্ত হিসাবে এটি এটি নয়।

কোডটি অসীম লুপ নয় তবে এটি একটি বাগ।

দুটি (সম্ভবত তিনটি) সমস্যা রয়েছে:

  • কোনও ডেবুফ উপস্থিত না থাকলে কোনও ক্ষয়ই একেবারেই প্রয়োগ করা হবে না
  • 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 পাশাপাশি এটি যাতে ডাবুফকে সঠিকভাবে গণনা করতে পারে। নিখুঁত পেডেন্ট হতে: এই মুহুর্তে ডিএমজি তথ্য একটি কাঠামোযুক্ত হওয়া উচিত যাতে এতে মূল ডিএমজি, বর্তমান ডিএমজি এবং ক্ষতির প্রকৃতি এবং সেইসাথে যদি ডেবুফগুলিতে "আগুনের দুর্বলতা" এর মতো জিনিস থাকে। অভিজ্ঞতা থেকে ডেবিফগুলির সাথে কোনও গেম ডিজাইন দাবি করার আগে এটি দীর্ঘ নয়।
  • ১ @ স্টিফেন হকেনহুল ভাল বলেছেন!

কোডটি অসীম লুপ তৈরি করে বলে মনে হচ্ছে না।

লুপ অসীম একমাত্র উপায় যদি হত

debuf.ApplyToDamage(resolvedDamage); 

বা

DestroyMe(); 

নতুন আইটেম যুক্ত ছিল m_debufs ধারক

এটি অসম্ভব বলে মনে হচ্ছে। এবং যদি এটি হয় তবে প্রোগ্রামটি পুনরায় করা হওয়ার সময় ধারক পরিবর্তন করার কারণে ক্রাশ হতে পারে।

কল করার কারণে প্রোগ্রামটি সম্ভবত ক্রাশ হবে DestroyMe(); যা সম্ভবত বর্তমান লুপটি চালাচ্ছে এমন বর্তমান অবজেক্টটিকে ধ্বংস করে।

আমরা এটিকে কার্টুন হিসাবে ভাবতে পারি যেখানে 'খারাপ লোক' এর সাথে 'ভাল লোক' পড়ার জন্য একটি শাখা দেখেছিল, তবে বুঝতে পেরেছিল যে সে কাটার ভুল দিকে রয়েছে। বা মিডগার্ড সাপটি নিজের লেজ খাচ্ছে।


আমার আরও যোগ করা উচিত যে অসীম লুপের সর্বাধিক সাধারণ লক্ষণ হ'ল এটি প্রোগ্রামটি স্থির করে দেয় বা এটিকে প্রতিক্রিয়াশীল করে না not এটি প্রোগ্রাম ক্রাশ করবে যদি এটি বারবার মেমরি বরাদ্দ করে, বা এমন কিছু করে যা শূন্য দ্বারা ভাগ করে শেষ করে বা পছন্দগুলি করে।


আকী তানাকার মন্তব্যের ভিত্তিতে,

সম্ভবত সহায়ক: উমিকোর অতিরিক্ত স্ক্রিনশটটি বলেছিল যে "এটি একই ক্রিয়াকলাপটি বারবার কল করছিল", যা কোডটিতে প্রদর্শিত নাও হতে পারে।

"এটি একই অপারেশনটিকে বারবার আহ্বান জানিয়েছিল" এটি সম্ভবত বেশি।

ধরে নিচ্ছি যে DestroyMe(); একাধিকবার কল করার জন্য ডিজাইন করা হয়নি, এটি ক্রাশ হওয়ার সম্ভাবনা বেশি।

এই সমস্যাটি সমাধান করার একটি উপায় হ'ল পরিবর্তন করা if এই জাতীয় কিছু জন্য:

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

ধ্বংসাত্মক অ্যাক্টরটি ধ্বংস হয়ে যাওয়ার পরে এটি লুপটি প্রস্থান করবে, তা নিশ্চিত করে 1) DestroyMe পদ্ধতিটিকে কেবল একবার বলা হয় এবং 2) বস্তুটি ইতিমধ্যে মৃত হিসাবে বিবেচিত হলে অযথা বাছুর প্রয়োগ করবেন না।

2
  • 1 যখন স্বাস্থ্য <= 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
  • আমার উল্লেখ করা উচিত যে আমি অতীতে মেমরির বরাদ্দকারীদের যেমন লিখেছি, একই মেমরি মুছে ফেলার বিষয়টি হওয়ার দরকার নেই। এটি অতিরিক্ত কাজ হতে পারে। এটি সব বরাদ্দকারীর আচরণের উপর নির্ভর করে। খনি কেবলমাত্র একটি নিম্ন স্তরের লিঙ্কযুক্ত তালিকার মতো কাজ করেছিল তাই মুছে ফেলা তথ্যের জন্য "নোড" হয় বেশ কয়েকবার বিনামূল্যে সেট হয়ে যায় বা বেশ কয়েকবার পুনরায় বিভক্ত হয় (যা কেবলমাত্র অপ্রয়োজনীয় পয়েন্টার পুনঃনির্দেশের সাথে সামঞ্জস্য করে)। ভাল ধরা যদিও।
  • ডাবল-ফ্রি হ'ল একটি বাগ এবং এটি সাধারণত অনির্ধারিত আচরণ এবং ক্র্যাশের দিকে পরিচালিত করে। এমনকি যদি আপনার কাছে এমন কাস্টম বরাদ্দকারী থাকে যা কোনওভাবে একই মেমরি ঠিকানার পুনরায় ব্যবহার নিষিদ্ধ করে, ডাবল-ফ্রি একটি গন্ধযুক্ত কোড যা এর কোনও অর্থ দেয় না এবং আপনি স্থির কোড বিশ্লেষক দ্বারা চিৎকার করতে পারবেন।
  • অবশ্যই! আমি সে উদ্দেশ্যে এটি নকশা করি নি। কিছু ভাষার বৈশিষ্ট্যগুলির অভাবের কারণে কেবল একটি বরাদ্দকারী প্রয়োজন require না না না. আমি কেবল বলছিলাম যে ক্র্যাশের নিশ্চয়তা নেই। কিছু নির্দিষ্ট নকশার শ্রেণিবিন্যাস সর্বদা ক্রাশ হয় না।