আমার কোড জুড়ে এক-অফ পতাকা এবং চেক এড়াতে আমি কী করতে পারি?


18

হার্টস্টোন জাতীয় কার্ড কার্ড বিবেচনা করুন ।

এমন শত শত কার্ড রয়েছে যা বিভিন্ন ধরণের কাজ করে, যার কয়েকটি একক কার্ডের জন্যও অনন্য! উদাহরণস্বরূপ, একটি কার্ড রয়েছে (নামডোজডর্মু) যা প্লেয়ারকে কেবল 15 সেকেন্ডে পরিণত করে!

আপনার যখন এ জাতীয় বিভিন্ন ধরণের সম্ভাব্য প্রভাব রয়েছে, আপনি কীভাবে আপনার সমস্ত কোডে ম্যাজিক নম্বর এবং এক-অফ চেকগুলি এড়িয়ে যাবেন? প্লেয়ার টার্নটাইম ক্লাসে "চেক_নজডর্মু_ইন_প্লে" পদ্ধতিটি কীভাবে এড়ানো যায়? এবং কীভাবে কেউ কোডটি এমনভাবে সংগঠিত করতে পারে যে আপনি যখন আরও বেশি প্রভাব যুক্ত করেন তখন আপনার আগে কখনও সমর্থন করা হয়নি এমন স্টাফ সমর্থন করার জন্য আপনার কোর সিস্টেমগুলি রিফ্যাক্টরের প্রয়োজন হবে না?


এটি কি আসলেই পারফরম্যান্সের সমস্যা? মানে, আপনি প্রায় কোনও সময়ের মধ্যে আধুনিক সিপিইউগুলির সাথে
ক্রেজিট

11
পারফরম্যান্স সমস্যা সম্পর্কে কে কিছু বলেছেন? আমি যে প্রধান সমস্যাটি দেখতে পাব তা হল প্রতিটি সময় আপনি নতুন কার্ড তৈরি করার সময় আপনার সমস্ত কোড সামঞ্জস্য করতে হবে।

2
সুতরাং একটি স্ক্রিপ্টিং ভাষা যুক্ত করুন এবং প্রতিটি কার্ড স্ক্রিপ্ট করুন।
জারি কম্প্পা 3'15

1
যথাযথ উত্তর দেওয়ার সময় নেই, তবে খেলোয়াড় ঘুরিয়ে দেয় এমন "প্লেয়ারটর্নটাইম" শ্রেণীর কোডের মধ্যে যেমন Nozdormu চেক এবং 15 সেকেন্ড সামঞ্জস্য থাকার পরিবর্তে, আপনি "প্লেয়ারটর্মটাইম" ক্লাসে একটি কল করতে পারেন [শ্রেণি-, আপনি চাইলে ] নির্দিষ্ট পয়েন্টে বাইরে থেকে সরবরাহ করা ফাংশন। তারপরে Nozdormu কার্ড কোড (এবং অন্যান্য সমস্ত কার্ড যা একই প্ল্যান্সকে প্রভাবিত করতে পারে) সেই সমন্বয়টির জন্য একটি ফাংশন বাস্তবায়ন করতে পারে এবং যখন প্রয়োজন হয় তখন প্লেয়ারটাইমটাইম ক্লাসে সেই ফাংশনটি ইনজেক্ট করতে পারে। ক্লাসিক ডিজাইন প্যাটার্নস বই থেকে
প্যাটারিস

2
কিছু সময় আমি ভাবতে পারি যে কোডের প্রাসঙ্গিক বিটগুলিতে অ্যাড-হক চেক যুক্ত করা সহজ সমাধান কিনা
ব্যবহারকারী 253751

উত্তর:


12

আপনি কি সত্তা উপাদান সিস্টেম এবং ইভেন্ট মেসেজিং কৌশলগুলি সন্ধান করেছেন?

স্থিতির প্রভাবগুলি এমন কোনও ধরণের উপাদান হওয়া উচিত যা একটি অনক্রিয়েট () পদ্ধতিতে তাদের অবিরাম প্রভাব প্রয়োগ করতে পারে, ওনারআমোভড ()-এ তাদের প্রভাবের মেয়াদ শেষ করতে পারে এবং গেম ইভেন্টের বার্তাগুলিতে সাবস্ক্রাইব করতে পারে যা কোনও ঘটনার প্রতিক্রিয়া হিসাবে ঘটে এমন প্রভাব প্রয়োগ করে।

যদি প্রভাবটি অবিরামভাবে শর্তযুক্ত হয় (এক্স টার্নগুলির জন্য স্থায়ী হয় তবে কেবলমাত্র কিছু নির্দিষ্ট পরিস্থিতিতে প্রযোজ্য) আপনাকে বিভিন্ন পর্যায়ে এই শর্তগুলি পরীক্ষা করতে হবে।

তারপরে, আপনি কেবল নিশ্চিত হয়ে নিন যে আপনার গেমের কোনও ডিফল্ট ম্যাজিক সংখ্যাও নেই। যে কোনও ব্যতিক্রমের জন্য ব্যবহৃত ভেরিয়েবলের সাথে হার্ড কোডিং ডিফল্ট পরিবর্তে ডেটা চালিত ভেরিয়েবলের পরিবর্তিত সমস্ত কিছু নিশ্চিত করুন।

এইভাবে, আপনি কখনই অনুমান করবেন না যে মোড়ের দৈর্ঘ্য কত হবে। এটি সর্বদা একটি নিয়মিত পরীক্ষিত ভেরিয়েবল যা কোনও প্রভাব দ্বারা পরিবর্তিত হতে পারে এবং প্রভাবের পরে এটি শেষ হয়ে গেলে সম্ভবত পূর্বাবস্থায় ফিরে আসতে পারে। আপনার যাদু নম্বরটিতে ডিফল্ট হওয়ার আগে আপনি কখনই ব্যতিক্রমগুলির জন্য যাচাই করেন না।


2
"নিশ্চিত হয়ে নিন যে কোনও কিছু ব্যতিক্রমের জন্য ব্যবহৃত ভেরিয়েবলের সাথে হার্ড কোডিং ডিফল্ট পরিবর্তে ডেটা চালিত ভেরিয়েবলের পরিবর্তিত সমস্ত কিছু is" - ওহ, আমি বরং এটি পছন্দ করি। এটি অনেক সাহায্য করে, আমি মনে করি!
সাবলীল ড্রিমার

আপনি "তাদের অবিচ্ছিন্ন প্রভাব প্রয়োগ করুন" এর বিস্তারিত ব্যাখ্যা করতে পারেন? টার্নস্টার্টে সাবস্ক্রাইব করা এবং তারপরে দৈর্ঘ্যের মান পরিবর্তন করা কোডটিকে অনিবার্য এবং আরও খারাপের সাথে অসঙ্গতিপূর্ণ ফলাফল তৈরি করতে পারে (যখন একই রকম প্রভাবের মধ্যে ইন্টারঅ্যাক্ট করার সময়)?
আশ্চর্যজনকভাবে

কেবলমাত্র সেই গ্রাহকদের জন্য যে কোনও নির্দিষ্ট সময়কাল অনুমান করবে। আপনি সাবধানে মডেল করতে হবে। প্লেয়ার টার্ন টাইম থেকে বর্তমান টার্নের সময় আলাদা হওয়া ভাল হতে পারে। নতুন টার্ন তৈরি করতে পিটিটি পরীক্ষা করা হবে। কার্ড দ্বারা সিটিটি পরীক্ষা করা যায়। যদি কোনও প্রভাব বর্তমান সময়ের বৃদ্ধি করতে পারে তবে টাইমার ইউআই প্রাকৃতিকভাবে তা রাষ্ট্রবিহীন অবস্থায় অনুসরণ করা উচিত।
রবস্টোন

প্রশ্নের উত্তরের জন্য। আর কিছুই কিছুই টার্ন টাইম বা এর বাইরে থাকা কিছু সঞ্চয় করে না। সর্বদা এটির জন্য পরীক্ষা করুন।
রবস্টোন

11

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

প্রতিটি কার্ডের সাথে এটির সংক্রমণের একটি সেট থাকা উচিত, এটি এমনভাবে সংজ্ঞায়িত করা হয় যাতে এটি প্রভাবটি কী তা চিহ্নিত করতে পারে, এটি কী লক্ষ্যবস্তু করে, কীভাবে এবং কতক্ষণ ধরে। উদাহরণস্বরূপ, "প্রতিপক্ষের ক্ষতি" প্রভাবটি এর মতো দেখতে পারে;

Effect type: deal damage (enumeration, string, what-have-you)
Effect amount: 20
Source: my weapon
Target: opponent
Effect Cost: 20
Cost Type: Mana

তারপরে, যখন প্রভাবটি আগুন লাগে, তখন জেনেরিক রুটিনে প্রভাবটির প্রক্রিয়াকরণটি পরিচালনা করতে হবে। একজন নির্বোধের মতো, আমি একটি বিশাল কেস / স্যুইচ স্টেটমেন্ট ব্যবহার করেছি:

switch (effect_type)
{
     case DAMAGE:

     break;
}

তবে এটি করার একটি আরও ভাল এবং আরও মডিউলার উপায় হ'ল পলিমারফিজমের মাধ্যমে। একটি প্রভাব ক্লাস তৈরি করুন যা এই সমস্ত ডেটা মোড়ানো করে, প্রতিটি প্রকারের প্রভাবের জন্য একটি উপশ্রেণী তৈরি করে এবং তারপরে সেই শ্রেণিটি শ্রেণীর জন্য নির্দিষ্ট একটি অনেক্সট () পদ্ধতিকে ওভাররাইড করে।

class Effect
{
    Object source;
    int amount;

    public void onExecute(Object target)
    {
          // Do nothing
    }
}

class DamageEffect extends Effect
{
    public void onExecute(Object target)
    {
          target.health -= amount;
    }
}

সুতরাং আমাদের একটি বেসিক এফেক্ট ক্লাস, তারপরে অন্যাক্সিউট () পদ্ধতি সহ একটি ড্যামেজএফেক্ট শ্রেণি রয়েছে, সুতরাং আমাদের প্রসেসিং কোডে আমরা কেবল যেতে চাই;

Effect effect = card.getActiveEffect();

effect.onExecute();

খেলতে কী রয়েছে তা জানার উপায় হল একটি ভেক্টর / অ্যারে / লিঙ্কযুক্ত তালিকা / ইত্যাদি তৈরি করা। সক্রিয় প্রভাবগুলির (টাইপ এফেক্টের, বেস ক্লাসের) কোনও বস্তুর সাথে জড়িত (প্লেফিল্ড / "গেম" সহ), যাতে কোনও নির্দিষ্ট প্রভাব খেলছে কিনা তা পরীক্ষা না করে, আপনি কেবলমাত্র সংযুক্ত সমস্ত প্রভাবের মধ্য দিয়ে লুপ করুন অবজেক্ট (গুলি) এবং তাদের কার্যকর করতে দিন। যদি কোনও প্রভাব কোনও বস্তুর সাথে সংযুক্ত না হয়, তবে এটি খেলবে না।

Effect effect;

for (int o = 0; o < objects.length; o++)
{
    for (int e = 0; e < objects[o].effects.length; e++)
    {
         effect = objects[o].effects[e];

         effect.onExecute();
    }
}

আমি এটি ঠিক এভাবেই করেছি। এখানকার সৌন্দর্যটি হ'ল আপনার কাছে ডেটা-চালিত সিস্টেম রয়েছে এবং আপনি প্রতি-প্রভাবের ভিত্তিতে যুক্তিটি সহজেই সামঞ্জস্য করতে পারেন। সাধারণত আপনাকে এফেক্টের এক্সিকিউশন লজিকটিতে কিছু শর্ত পরীক্ষা করতে হবে, তবে এই চেকগুলি কেবল প্রশ্নে প্রভাবিত হওয়ার কারণে এটি আরও অনেক সুসংগত।
manabreak

1

আমি কয়েক মুদ্রণ প্রস্তাব দেব। তাদের মধ্যে কিছু একে অপরের বিরোধিতা করে। তবে সম্ভবত কিছু দরকারী।

পতাকা বনাম তালিকা বিবেচনা করুন

আপনি বিশ্বজুড়ে পুনরাবৃত্তি করতে পারেন এবং পতাকা-জিনিসটি করবেন কি না তা সিদ্ধান্ত নিতে প্রতিটি আইটেমের একটি পতাকা চেক করতে পারেন। অথবা আপনি কেবল সেই আইটেমের একটি তালিকা রাখতে পারেন যা পতাকা-জিনিসটি করা উচিত।

তালিকা এবং গণনা বিবেচনা করুন

আপনি আপনার আইটেম শ্রেণিতে বুলিয়ান ক্ষেত্রগুলি যুক্ত করতে পারেন, এটি এবং ইসাথ। অথবা আপনার কাছে স্ট্রিং বা এনাম উপাদানগুলির একটি তালিকা থাকতে পারে, যেমন {"ইসাথস", "ইসাথ্যাট"} বা {আইএস_এ_টিআইএস, আইএস_এ_থ্যাট}} এই ক্ষেত্রটি যুক্ত না করে আপনি গণনায় নতুন (বা স্ট্রিং কনসেট) যুক্ত করতে পারেন। ক্ষেত্রগুলি যুক্ত করার সাথে সত্যিই কিছু ভুল নেই ...

ফাংশন পয়েন্টার বিবেচনা করুন

পতাকা বা এনামগুলির তালিকার পরিবর্তে বিভিন্ন আইটেমের জন্য বিভিন্ন আইটেমটির জন্য কার্যকর করার ক্রিয়াগুলির একটি তালিকা থাকতে পারে। (সত্তা পর ...)

বস্তু বিবেচনা করুন

কিছু লোক ডেটাচালিত, বা স্ক্রিপ্টড বা উপাদান উপাদান সত্তার পদ্ধতির পছন্দ করে। তবে পুরানো ফ্যাশনযুক্ত অবজেক্টের শ্রেণিবিন্যাসগুলিও বিবেচনার জন্য। বেস ক্লাসটির ক্রিয়াগুলি গ্রহণ করা দরকার, যেমন "টার্ন-ফেজ বিয়ের জন্য এই কার্ডটি খেলুন" বা যাই হোক না কেন। তারপরে প্রতিটি ধরণের কার্ড ওভাররাইড এবং যথাযথ প্রতিক্রিয়া জানাতে পারে। সম্ভবত কোনও প্লেয়ার অবজেক্ট এবং গেমের অবজেক্টও রয়েছে, সুতরাং গেমটি এমন কিছু করতে পারে, যদি (প্লেয়ার-> isAowedToPlay ()) the খেলাটি করুন ...}}

ডিবাগ-ক্ষমতা বিবেচনা করুন

পতাকা ক্ষেত্রগুলির গাদা সম্পর্কে একবার দুর্দান্ত জিনিসটি হ'ল আপনি প্রতিটি আইটেমের অবস্থা একইভাবে পরীক্ষা করতে এবং মুদ্রণ করতে পারবেন। যদি রাষ্ট্রটি বিভিন্ন ধরণের, বা উপাদানগুলির ব্যাগ, বা ফাংশন পয়েন্টারগুলি দ্বারা প্রতিনিধিত্ব করা হয় বা বিভিন্ন তালিকায় থাকে তবে কেবলমাত্র আইটেমের ক্ষেত্রগুলি দেখার জন্য এটি যথেষ্ট নাও হতে পারে। এটা সব বাণিজ্য।

শেষ পর্যন্ত, রিফ্যাক্টরিং: ইউনিট পরীক্ষা বিবেচনা করুন

আপনি আপনার আর্কিটেকচারকে কতটা সাধারণীকরণ করুন না কেন, আপনি এমন বিষয়গুলি কল্পনা করতে সক্ষম হবেন যা এটি আবৃত করে না। তারপরে আপনাকে রিফ্যাক্টর করতে হবে। হয়তো কিছুটা, হয়তো অনেক কিছু।

এই নিরাপদ করার একটি উপায় বডি ইউনিট পরীক্ষার সাথে। এই ভাবে আপনি আত্মবিশ্বাসী হতে পারেন যে আপনি নীচে জিনিসগুলি পুনরায় সাজিয়ে নিলেও (সম্ভবত অনেক কিছু!) বিদ্যমান কার্যকারিতা এখনও কাজ করে। প্রতিটি ইউনিট পরীক্ষা সাধারণত দেখতে লাগে:

void test1()
{
   Game game;
   game.addThis();
   game.setupThat(); // use primary or backdoor API to get game to known state

   game.playCard(something something).

   int x = game.getSomeInternalState;
   assertEquals(“did it do what we wanted?”, x, 23); // fail if x isn’t 23
}

আপনি দেখতে পাচ্ছেন, গেমের (বা প্লেয়ার, কার্ড, এবং সি) স্থিতিশীল API শীর্ষস্থানীয় এপিআই কলগুলি ইউনিট পরীক্ষার কৌশলটির মূল চাবিকাঠি।


0

প্রতিটি কার্ড স্বতন্ত্রভাবে চিন্তা করার পরিবর্তে, প্রভাবের বিভাগগুলির ক্ষেত্রে চিন্তাভাবনা শুরু করুন এবং কার্ডগুলিতে এর মধ্যে এক বা একাধিক বিভাগ রয়েছে। উদাহরণস্বরূপ, ঘুরেফিরে সময়ের পরিমাণ গণনা করতে আপনি খেলতে থাকা সমস্ত কার্ডের মধ্য দিয়ে লুপ করতে পারেন এবং প্রতিটি কার্ডের "ম্যানিপুলেট টার্ন পিরিয়ড" বিভাগটি অন্তর্ভুক্ত রাখতে পারেন। প্রতিটি কার্ড তারপরে আপনার সিদ্ধান্ত নেওয়া নিয়মের ভিত্তিতে টার্নের সময়কালকে বাড়িয়ে দেয় বা ওভাররাইট করে।

এটি মূলত একটি মিনি-উপাদান সিস্টেম, যেখানে প্রতিটি "কার্ড" অবজেক্ট কেবল কার্যকর উপাদানগুলির গুচ্ছের জন্য একটি ধারক।


যেহেতু কার্ডগুলি - এবং ভবিষ্যতের কার্ডগুলিও - যে কোনও কিছু করতে পারে, তাই আমি প্রতিটি কার্ডের একটি স্ক্রিপ্ট বহন করবো বলে আশা করি। তবুও আমি নিশ্চিত যে এটি প্রকৃত পারফরম্যান্স সমস্যা নয় ..
জারি কম্প্পা

4
মূল মতামত অনুসারে: পারফরম্যান্স সমস্যা সম্পর্কে কেউ (আপনি ব্যতীত) কিছু বলেনি। বিকল্প হিসাবে সম্পূর্ণ স্ক্রিপ্টিং হিসাবে, একটি উত্তরে এটি বিস্তারিত।
ঝক্কিচ্ছিল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.