ডেটা চালিত নকশা
আমি সম্প্রতি কোড রিভিউতে এই প্রশ্নের মতো কিছু জমা দিয়েছি ।
কিছু পরামর্শ এবং উন্নতির পরে, ফলাফলটি একটি সহজ কোড যা কোনও অভিধান (বা জেএসএন) এর উপর ভিত্তি করে অস্ত্র তৈরিতে কিছু আপেক্ষিক নমনীয়তার অনুমতি দেয়। ডেটা রানটাইম-এ ব্যাখ্যা করা হয় এবং Weapon
একটি সম্পূর্ণ স্ক্রিপ্ট অনুবাদকারীর উপর নির্ভর করার প্রয়োজন না করে সহজ যাচাই ক্লাস নিজেই করে থাকে।
পাইথন একটি দোহিত ভাষা হওয়া সত্ত্বেও ডেটা-চালিত ডিজাইন (উত্স এবং ডেটা ফাইল উভয়ই তাদের পুনরায় সংকলনের প্রয়োজন ছাড়াই সম্পাদনা করা যেতে পারে), যেমন আপনি উপস্থাপন করেছেন তেমন ক্ষেত্রে সঠিক কাজ করার মতো মনে হচ্ছে। এই প্রশ্নটি ধারণা সম্পর্কে আরও বিশদগুলিতে যায়, এর উপকারিতা এবং বিপরীতে। এটি সম্পর্কে কর্নেল বিশ্ববিদ্যালয়ের একটি দুর্দান্ত উপস্থাপনাও রয়েছে res
অন্যান্য ভাষার সাথে তুলনা করা, যেমন সি ++, সম্ভবত ডেটা এক্স ইঞ্জিনের ইন্টারঅ্যাকশন এবং স্ক্রিপ্টিং পরিচালনা করতে কোনও স্ক্রিপ্টিং ভাষা (যেমন এলইউএ) এবং ডেটা সংরক্ষণের জন্য একটি নির্দিষ্ট ডেটা ফর্ম্যাট (এক্সএমএলের মতো) ব্যবহার করতে পারে, পাইথন আসলেই করতে পারে এটি সমস্ত নিজস্বভাবে (মানকটি বিবেচনা করে dict
তবে এটির weakref
পরে বিশেষত সম্পদ লোডিং এবং ক্যাশিংয়ের জন্য)।
একটি স্বাধীন বিকাশকারী, তবে, এই নিবন্ধে প্রস্তাবিত হিসাবে ডেটা চালিত পদ্ধতির চূড়ান্ত করতে না পারে :
আমি ডেটা-চালিত নকশা সম্পর্কে কত? আমি মনে করি না কোনও গেম ইঞ্জিনে গেম-নির্দিষ্ট কোডের একক লাইন থাকা উচিত। একটি না. কোনও হার্ডকোডযুক্ত অস্ত্রের ধরণ নেই। কোনও হার্ডকোডযুক্ত এইচইউডি বিন্যাস নেই। কোনও হার্ডকোডযুক্ত ইউনিট নয় AI নাদা। জিপ। Zilch।
পাইথনের সাহায্যে, উত্পাদনশীলতা এবং এক্সটেনসিবিলিটি উভয়ের লক্ষ্য রেখেই বস্তু-ভিত্তিক এবং ডেটা-চালিত উভয় পদ্ধতির মধ্যেই সেরা উপকার পেতে পারে।
সাধারণ নমুনা প্রক্রিয়াকরণ
কোড পর্যালোচনায় আলোচিত নির্দিষ্ট ক্ষেত্রে, একটি অভিধান "স্থিতিক বৈশিষ্ট্য" এবং ব্যাখ্যা করার জন্য যুক্তি উভয়ই সংরক্ষণ করে - যদি অস্ত্রটির কোনও শর্তযুক্ত আচরণ করা উচিত।
নীচের উদাহরণে একটি তরোয়ালটিতে 'অ্যান্টিপ্যালাদিন' শ্রেণীর চরিত্রের হাতে কিছু ক্ষমতা এবং পরিসংখ্যান থাকা উচিত এবং অন্যান্য চরিত্রের দ্বারা ব্যবহৃত যখন নিম্নতর পরিসংখ্যানের সাথে কোনও প্রভাব নেই):
WEAPONS = {
"bastard's sting": {
# magic enhancement, weight, value, dmg, and other attributes would go here.
"magic": 2,
# Those lists would contain the name of effects the weapon provides by default.
# They are empty because, in this example, the effects are only available in a
# specific condition.
"on_turn_actions": [],
"on_hit_actions": [],
"on_equip": [
{
"type": "check",
"condition": {
'object': 'owner',
'attribute': 'char_class',
'value': "antipaladin"
},
True: [
{
"type": "action",
"action": "add_to",
"args": {
"category": "on_hit",
"actions": ["unholy"]
}
},
{
"type": "action",
"action": "add_to",
"args": {
"category": "on_turn",
"actions": ["unholy aurea"]
}
},
{
"type": "action",
"action": "set_attribute",
"args": {
"field": "magic",
"value": 5
}
}
],
False: [
{
"type": "action",
"action": "set_attribute",
"args": {
"field": "magic",
"value": 2
}
}
]
}
],
"on_unequip": [
{
"type": "action",
"action": "remove_from",
"args": {
"category": "on_hit",
"actions": ["unholy"]
},
},
{
"type": "action",
"action": "remove_from",
"args": {
"category": "on_turn",
"actions": ["unholy aurea"]
},
},
{
"type": "action",
"action": "set_attribute",
"args": ["magic", 2]
}
]
}
}
পরীক্ষার উদ্দেশ্যে, আমি সহজ Player
এবং Weapon
ক্লাস তৈরি করেছি : প্রথমে অস্ত্রটি ধরে রাখা / সজ্জিত করা (সুতরাং এটির শর্তসাপেক্ষে on_equip সেটিং বলা হয়) এবং পরবর্তীকৃত হিসাবে একক শ্রেণি হিসাবে অভিধান থেকে ডেটা পুনরুদ্ধার করতে পারে, আইটেমের নাম হিসাবে পাস করা হয়েছে Weapon
আরম্ভের সময় যুক্তি । এগুলি সঠিক গেম ক্লাসের নকশা প্রতিফলিত করে না তবে তথ্যের পরীক্ষার জন্য এখনও কার্যকর হতে পারে:
class Player:
"""Represent the player character."""
inventory = []
def __init__(self, char_class):
"""For this example, we just store the class on the instance."""
self.char_class = char_class
def pick_up(self, item):
"""Pick an object, put in inventory, set its owner."""
self.inventory.append(item)
item.owner = self
class Weapon:
"""A type of item that can be equipped/used to attack."""
equipped = False
action_lists = {
"on_hit": "on_hit_actions",
"on_turn": "on_turn_actions",
}
def __init__(self, template):
"""Set the parameters based on a template."""
self.__dict__.update(WEAPONS[template])
def toggle_equip(self):
"""Set item status and call its equip/unequip functions."""
if self.equipped:
self.equipped = False
actions = self.on_unequip
else:
self.equipped = True
actions = self.on_equip
for action in actions:
if action['type'] == "check":
self.check(action)
elif action['type'] == "action":
self.action(action)
def check(self, dic):
"""Check a condition and call an action according to it."""
obj = getattr(self, dic['condition']['object'])
compared_att = getattr(obj, dic['condition']['attribute'])
value = dic['condition']['value']
result = compared_att == value
self.action(*dic[result])
def action(self, *dicts):
"""Perform action with args, both specified on dicts."""
for dic in dicts:
act = getattr(self, dic['action'])
args = dic['args']
if isinstance(args, list):
act(*args)
elif isinstance(args, dict):
act(**args)
def set_attribute(self, field, value):
"""Set the specified field with the given value."""
setattr(self, field, value)
def add_to(self, category, actions):
"""Add one or more actions to the category's list."""
action_list = getattr(self, self.action_lists[category])
for action in actions:
if action not in action_list:
action_list.append(action)
def remove_from(self, category, actions):
"""Remove one or more actions from the category's list."""
action_list = getattr(self, self.action_lists[category])
for action in actions:
if action in action_list:
action_list.remove(action)
ভবিষ্যতের কিছু উন্নতির সাথে আমি আশা করি যে এটি আমার একদিন পুরো অস্ত্রের পরিবর্তে অস্ত্র উপাদানগুলি প্রক্রিয়াজাতকরণ, গতিশীল কারুকার্যকরণ সিস্টেমটিও চালিয়ে যাবে ...
পরীক্ষা
- অক্ষর একটি অস্ত্র বাছাই করে, এটি সজ্জিত করুন (আমরা এর পরিসংখ্যানগুলি মুদ্রণ করি), তারপরে এটি ফেলে দিন;
- চরিত্র বি একই অস্ত্রটিকে বেছে নিয়েছে, এটি সজ্জিত করে (এবং আমরা তার পরিসংখ্যানগুলি কীভাবে আলাদা তা দেখানোর জন্য এটি আবার মুদ্রণ করি)।
এটার মত:
def test():
"""A simple test.
Item features should be printed differently for each player.
"""
weapon = Weapon("bastard's sting")
player1 = Player("bard")
player1.pick_up(weapon)
weapon.toggle_equip()
print("Enhancement: {}, Hit effects: {}, Other effects: {}".format(
weapon.magic, weapon.on_hit_actions, weapon.on_turn_actions))
weapon.toggle_equip()
player2 = Player("antipaladin")
player2.pick_up(weapon)
weapon.toggle_equip()
print("Enhancement: {}, Hit effects: {}, Other effects: {}".format(
weapon.magic, weapon.on_hit_actions, weapon.on_turn_actions))
if __name__ == '__main__':
test()
এটি মুদ্রণ করা উচিত:
একটি বার্ডের জন্য
বৃদ্ধি: 2, হিট প্রভাব: [], অন্যান্য প্রভাব: []
একটি অ্যান্টিপালাদিনের জন্য
বর্ধন: 5, হিট প্রভাব: ['অপরিষ্কার'], অন্যান্য প্রভাব: ['অপরিষ্কার অরিয়া']