क्या दुनिया के इतिहास को संसाधित करने का एक तरीका है?


28

मैं कुछ चित्र का रहस्य हूँ पाया यहाँ एक काल्पनिक दुनिया कुछ पुरुष बनाई में सांस्कृतिक इतिहास के 1800 साल का प्रतिनिधित्व।

यहाँ छवि विवरण दर्ज करें

इस तरह की बात खेल के विकास के लिए मजबूत अनुप्रयोगों के लिए प्रतीत होती है, विश्व डिजाइन के रूप में इनफोर।

ऐसा लग रहा है कि उसने हाथ से यह चित्र बनाया है। अगर मुझे इसमें दिलचस्पी है तो देखिए कि क्या इस तरह का डायग्राम प्रोग्राम बनाने का कोई तरीका है।

यदि आपको यादृच्छिक मूल्यों से ऊपर की शैली में आरेख बनाने का काम सौंपा गया था, तो आप इसके बारे में कैसे जाएंगे? क्या कोई विशेष डेटा संरचना या एल्गोरिदम हैं जिन पर आप विचार करेंगे?


5
बौना किले पर एक नज़र डालने पर विचार करें । स्रोत अनुपलब्ध है और विश्व पीढ़ी की प्रक्रिया अविभाजित है (जो मुझे पता है कि मैं इसका जवाब क्यों नहीं दे रहा हूं) लेकिन आप वास्तव में गेम खेलने के लिए सीखने के बिना उत्पन्न विश्व इतिहास की जांच कर सकते हैं और यह आपको एक तरह का विचार दे सकता है। आप कर सकते हैं चीजों की।
जोश

एक और संसाधन, और इस पर एक जवाब नहीं मिल सकता है: www-cs-students.stanford.edu/~amitp/game-programming/… यह एक वातावरण बनाने के लिए एक लेख है, लेकिन यह पर्यावरण कैसे हो सकता है संसाधनों (जैसे पानी, रहने योग्य भूमि, आदि) के आधार पर राज्यों के लिए क्षेत्रीय सीमाओं को परिभाषित करने के लिए उपयोग किया जाता है, जो कि जब और जहां या जैसे लोगों के लिए युद्ध में जाते हैं, तो मिश्रण में फेंक दिया जा सकता है। फिर से, सिर्फ एक संसाधन, एक जवाब नहीं।
जेम्स

1
यह आरेख सभ्यता 3 में बिजली के ग्राफ के समान दिखता है। आप कुछ विचारों के लिए उस श्रृंखला की जांच करना चाह सकते हैं।
WildWeazel

जवाबों:


15

आप कितना सही होना चाहते हैं? एक अच्छा लेकिन जटिल विकल्प उस सभी इतिहास का अनुकरण करेगा:

  1. इन क्षेत्रों के बीच एक यादृच्छिक क्षेत्र सूची और आसन्न उत्पन्न करें।
  2. जनसंख्या, जुझारूपन, तकनीक ... जैसी विशेषताओं के साथ यादृच्छिक सभ्यताएँ बनाएँ और क्षेत्रों को आबाद करें।
  3. सभ्यता के लक्षणों के आधार पर परिणामों का निर्धारण करते हुए, इतिहास के कई वर्षों तक का अनुकरण करें।

उदाहरण: दो आसन्न जुझारू सभ्यताओं में एक दूसरे पर युद्ध शुरू करने की संभावना अधिक है, जो समय के साथ कम आबादी की ओर ले जाती है। व्यापारी सभ्यताओं के पास उच्च संसाधन हैं, लेकिन आक्रमणों के लिए एक महान लक्ष्य हैं। अत्यधिक आबादी वाले तेजी से बढ़ेंगे लेकिन भूख की संभावना भी अधिक होगी। सांस्कृतिक रूप से विषम civs में आंतरिक युद्ध (जिससे ब्रेकअप हो सकता है) की संभावना कम होती है ... और इसी तरह ... नतीजों से सभ्यता की विशेषताओं में भी बदलाव आएगा: उच्च प्रौद्योगिकी से बेहतर व्यापार, मजबूत हथियार आदि बनते हैं।

यह कुछ प्रक्रियात्मक कहानी कहने के लिए भी अनुमति देता है: आप न केवल एक क्षेत्र आरेख का उत्पादन कर सकते हैं, बल्कि समय के माध्यम से इतिहास के पाठ्य विवरण भी। आप इस प्रणाली को जितना चाहें उतना जटिल बना सकते हैं।


EDIT: यहां चुनौती एक तकनीकी नहीं है, लेकिन यथार्थवादी और दिलचस्प इतिहास पीढ़ी के लिए विशेषताओं को समायोजित करना है। करीब से देखें और 3 उपरोक्त बिंदुओं के बारे में सोचें ... यह आपकी तकनीकी व्याख्या है! इसे एक लूप में अनुवाद करें (प्रत्येक पुनरावृत्ति जितना चाहें उतना समय का प्रतिनिधित्व कर सकता है, 1 वर्ष, आधा वर्ष, 1 महीना ...) और यही वह है। आपको इनवर्टर (डेटा संरचनाएं, आंकड़े) पर काम करना होगा और इसे अपनी विशिष्ट समस्या और आवश्यकताओं के अनुकूल बनाना होगा। यह कठिन हिस्सा है यहां और कोई भी आपकी मदद नहीं कर सकता, क्योंकि यह कल्पना, परीक्षण और त्रुटि के बारे में है।

इस समस्या के लिए कोई भी आम डेटा संरचना नहीं हैं इसके अलावा आप लगभग किसी भी समस्या के लिए उपयोग करेंगे: सूचियां, कतारें, पेड़ ... और ये आपके विशिष्ट कार्यान्वयन के लिए बंधे होंगे (क्या मुझे एक वंशावली वृक्ष की आवश्यकता है? सभ्यताओं की सूची? युद्ध में? प्रत्येक नागरिक के लिए कार्यों की एक कतार?) बेशक आपको सभ्यताओं की एक सूची भी चाहिए। विकल्प स्पष्ट और बहुत सामान्य ज्ञान हैं।

सिमुलेशन मौका / संभावना का मामला है और आप इसे यादृच्छिक संख्याओं के साथ एक हजार अलग-अलग तरीके से बना सकते हैं। किसी भी अन्य खेल के बारे में सोचें जहां सिमुलेशन फुटबॉल प्रबंधकों, आरपीजी (सब के बाद, हिटप्वाइंट्स / आँकड़े सिर्फ मुकाबला सिमुलेशन है ), रणनीति के खेल की तरह शामिल है ... यह सिर्फ विशेषताओं है (इसलिए आपको सभ्यता विशेषताओं और डेटा को संग्रहीत करने के लिए एक तरीके की आवश्यकता होगी) और यादृच्छिक परिणाम सांख्यिकीय रूप से उन पर आधारित होते हैं (इसलिए आपको इन विशेषताओं के आधार पर सिमुलेशन स्थिति को यादृच्छिक रूप से बदलना होगा।)

यह आपके एल्गोरिथ्म का सार है: उत्तराधिकारियों को समायोजित करने के लिए कठिन: प्रत्येक सभ्यता के लिए सिमुलेशन की शुरुआत में विशेषताओं को कैसे वितरित किया जाए और उनके आधार पर सिमुलेशन राज्य को सांख्यिकीय रूप से कैसे बदला जाए।

संक्षेप में: आपका एल्गोरिथ्म सिर्फ एक लूप है जिसमें किसी भी वांछित वृद्धि के साथ नकली समय है। कम वेतन वृद्धि ऐतिहासिक ऐतिहासिक सिमुलेशन को जन्म देती है, लेकिन स्पष्ट रूप से अधिक समय लगेगा। अपने पाश के अंदर (लगभग) जैसे बस्तियों का एक गुच्छा होगा:

for each civilization
  if civ.isAtWar
    civ.population -= civ.population * 0.05;
    civ.wealth -= 1000.0;
    civ.belligerence += 1.0;
  if civ.population < 100
    civ.negotiatePeace()

यह सब काम करने के बाद (या यदि आप डेटा स्टोर नहीं करना चाहते हैं) तो आपको सभी सिमुलेशन स्टेट को मानव-पठनीय प्रारूप जैसे पाठ, चित्र या आप जो भी चाहते हैं, उसकी व्याख्या करनी होगी। यह परीक्षण और त्रुटि है और आपके कार्यान्वयन के लिए बहुत विशिष्ट है।

आपके प्रश्न के लिए विशिष्ट: अपने प्रश्न में एक आरेख उत्पन्न करने के लिए, आपको विश्व क्षेत्रों को ट्रैक करना होगा (आरेख के ऊपर, एक्स अक्ष, यह बिंदु 1 है: मेरे उत्तर में क्षेत्र सूची बनाएं) और उनकी सभ्यताएं (रंगों में) आरेख, बिंदु 2 ) समय के माध्यम से (y अक्ष, बिंदु 3 में अनुकार लूप ।)

राज्य की मशीनेंव्यापक विषयों का अनुकरण करने में काफी अच्छे हैं (ऊपर कोड नमूना एक हार्ड-कोडेड स्टेट मशीन का एक अनुमान है) - इसलिए आप एक साधारण राज्य मशीन फ्रेमवर्क को लागू करके शुरू कर सकते हैं जो समग्र रूप से ट्वीक करना आसान है। प्रत्येक सभ्यता इन राज्य मशीनों में से एक के साथ शुरू होगी और सिमुलेशन प्रत्येक मोड़ के लिए प्रत्येक राज्य मशीन चलाएगा। प्रत्येक राज्य मशीन को अन्य राज्य मशीन के साथ बातचीत करने में सक्षम होने की आवश्यकता होगी: उदाहरण के लिए युद्ध शुरू करने से दूसरे नागरिक की राज्य मशीन पर प्रभाव पड़ेगा, संभवतः उनके आंतरिक राज्य के आधार पर अलग-अलग परिणामों के साथ - जैसे यदि वे 'अकाल' राज्य में हैं तो वे संभवतः शांति पर बातचीत करना चाहते हैं, लेकिन एक सभ्यता 'मुसीबत की तलाश में' प्रतिशोध की संभावना होगी। मशीन के प्रत्येक राज्य का सभ्यता पर सार्थक प्रभाव होगा ' प्रत्येक 'फ्रेम' (धन, जुझारूपन, आबादी, आदि) के दौरान ऊपर उल्लिखित मैट्रिक्स। सबसे महत्वपूर्ण बात यह है कि आपको हर फ्रेम पर राज्यों को बदलने की ज़रूरत नहीं है - बस जब अवसर और / या यादृच्छिक मौका उत्पन्न होता है: यह लंबे समय तक होने वाली घटनाओं (जैसे युद्ध) को होने देता है।


बहुत अच्छे उत्तर के लिए धन्यवाद, भले ही यह उन तकनीकी पहलुओं पर स्पर्श नहीं करता है
जिनके

@pdusen की टिप्पणी काफी लंबी हो गई, इसलिए मैंने "EDIT" चिह्न के तहत इसके साथ अपना उत्तर अपडेट किया।
बजे kaoD

2
यदि आप बुरा नहीं मानते हैं, तो मैं इस उत्तर को जोड़ने जा रहा हूं।
जोनाथन डिकिंसन

@JonathanDickinson सुनिश्चित करें, आगे बढ़ें :)
kaoD

@pdusen मैंने कुछ और कार्यान्वयन-विशिष्ट विवरण जोड़े।
जोनाथन डिकिंसन

8

हाँ वहाँ है। यहाँ एक गंदगी-सरल इतिहास जनरेटर है:

#!/usr/bin/env python
# to create a visualisation, run like this:
#    ./timeline.py --dot | dot -Tpng > filename.png
import sys
import random
from pprint import pprint
# Names is a newline separated list of nation names.
file = "names.txt"
names = open(file, "r").read().split("\n") 
history = []
dot = False
if len(sys.argv) > 1 and sys.argv[1] == "--dot":
  dot = True

def wrap(str, wrap='"'):
  return wrap+str+wrap

def merge(states, names):
  number = random.randint(2,3)
  mergers = [] 
  if number < len(states):
    mergers = random.sample(states, number)
    new_name = random.choice(names)
    states = list(set(states).difference(set(mergers)))
    states.append(new_name)
    names.remove(new_name)
    if dot:
      for state in mergers:
        print '"%s" -> "%s"'%(state, new_name)
      print '{rank=same; %s }'%wrap(new_name)
    else:
      print "MERGE %s ==> '%s'"%( ", ".join(map(wrap,mergers)), new_name)
  return states, names 


def split(states, names):
  number = random.randint(2,3)
  if number < len(names):
    splitter = random.choice(states)
    states.remove(splitter)
    new_states = random.sample(names, number)
    names = list(set(names).difference(set(new_states)))
    states = list(set(states).union(set(new_states)))
    if dot:
      for state in new_states:
        print '"%s" -> "%s"'%(splitter, state)
      print '{rank=same; %s }'%("; ".join(map(wrap, new_states)))
    else:
      print "SPLIT '%s' ==> %s"%(splitter, ", ".join(map(wrap,new_states)))
  return states, names

def revolt(states, names):
  old = random.choice(states)
  new = random.choice(names)
  names.remove(new)
  states.remove(old)
  states.append(new)
  if dot:
    print '"%s" -> "%s"'%(old, new)
    print '{rank=same; "%s"}'%new
  else:
    print "REVOLT '%s' ==> '%s'"%(old, new)
  return states, names

def conquest(states, names):
  if len(states) > 1:
    loser = random.choice(states)
    states.remove(loser)
    winner = random.choice(states)
    if dot:
      print '"%s" -> "%s" [label="conquered by"]'%(loser, winner)
    else:
      print "CONQUEST '%s' conquered '%s'"%(winner, loser)
  return states, names


#ignore empty names
names = [name for name in names if name] #yes, really.

origin = random.sample(names, random.randint(1,3))
names = list(set(names).difference(set(origin)))
history.append(origin) #random starting states

if dot:
  print "digraph g {"
  print "{rank=same; %s}"%("; ".join(map(wrap,origin)))
else:
  print("BEGIN %s"%(", ".join(map(wrap,history[0]))))

while names:
  func = random.choice([merge, split, revolt, conquest])
  states, names = func(history[-1], names)
  history.append(states)

if dot:
  print '{rank=same; %s}'%("; ".join(map(wrap,history[-1])))
  print "}"
else:
  print "END %s"%(", ".join(map(wrap,history[-1])))

जो इस तरह से उत्पादन का उत्पादन करता है:

यहाँ छवि विवरण दर्ज करें

विभिन्न रेखांकन बनाने के लिए उत्तराधिकारियों को समायोजित करें।

ऐसा करने का सबसे सरल तरीका func = random.choice([merge, split, revolt, conquest])एक ही नाम के एक से अधिक फ़ंक्शन के लिए लाइन को बदलना होगा । उदाहरण के लिए func = random.choice([merge, split, revolt, conquest, merge, merge])अधिक बार विलय करने वाले देशों को बढ़ावा मिलेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.