Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 15 von 25

Thema: Daten aus dem Spiel abfragen

  1. #1
    Registrierter Benutzer
    Registriert seit
    16.11.20
    Beiträge
    16

    Daten aus dem Spiel abfragen

    Hallo zusammen,

    ich wollte mich mit einer ungwöhnlichen Idee an euche wenden:

    Ich baue mitunter sehr große Kolonialreiche und nutze sehr ausführlich Handelsrouten um Waren über ein umfangreiches Streckennetz zu Zentren zu transportieren, in denen sie weiter verarbeitet werden oder nach Europa ausgeschifft.

    Hier will ich verschiedene Dinge im Blick behalten wie:
    - werden in einer Kolonie genügend Waren angeliefert zum Weiterverarbeiten? z.B. Tabak, damit die Fabrik immer genügend Rohstoff hat.
    - Ist eine Strecke überlastet weil z.B. ein Planwagen oder eine Galeone nicht ausreichen?
    - Werden alle Waren von einer Kolonie bereits abgeholt und staut sich nichts auf?

    Bisher pflege ich so etwas in einer recht komplexen Excel-Datei, in ich ich für Kolonien Informationen wie z.B. die Produktion bestimmter Güter, oder eine Verbindung zwischen zwei Kolonien per automatisiertem Planwagen manuell eintrage.

    Ich frage mich, ob es die Möglichkeit gibt, bsw. über eine Datenbankabfrage oder andere Möglichkeiten, auf die Daten im laufenden Spiel selbst zuzugreifen?

    Weiß hierzu jemand eine Antwort?

  2. #2
    Ad Astra Avatar von Ronnar
    Registriert seit
    27.10.08
    Beiträge
    3.258
    Wenn du dich ein klein wenig mit Python auskennst, kannst du auf diese Informationen direkt im Spiel zugreifen bzw. sie berechnen und dir daraus z.B. einen Statistik-Screen zu Produktion und Transport erstellen.

  3. #3
    Registrierter Benutzer
    Registriert seit
    16.11.20
    Beiträge
    16
    Hallo Ronnar,

    hört sich interessant an. Hast du ein paar erste Tipps dazu und vielleicht ein gutes Tutorial für Python?
    Ich habe Erfahrung mit C++ und VBA,... ich denke in Python kann man sich reindenken.

  4. #4
    ε•ω=1 Avatar von Ramkhamhaeng
    Registriert seit
    19.07.10
    Ort
    Aralkum
    Beiträge
    9.896
    Hallo,

    wenn du die Daten ründlich in eine Textdatei schreiben willst, wäre hier ein Beispiel zu finden: https://github.com/Charriu84/CloseTo...anager.py#L498

    (Die Zeilen, die von der BugMod abhängen, müsstest du ersetzen, da es das Modul in Col nicht gibt.)


    Wenn du interaktiv zugreifen willst:
    Ich habe für Civ4 eine Variante erstellt mit der man per Konsole auf ein laufendes Spiel zugreifen kann:
    https://github.com/civ4-mp/pyconsole

    Baust du das ein kannst du dann beliebige Anfragen stellen ohne die Mod zu verändern.
    Ist aber eher was für fortgeschrittene Modder.

    Im Allgemeinen musst du beachten, dass Civ4 noch Python 2.4 nutzt. Die Python-Tutorials für Python3 sind also nicht 1:1 übertragbar.

    Als Referenz hier noch die Python-Api von Civ4: https://kirk.zulan.net/PythonAPI/index.html
    Ist sehr ähnlich zu der von Col. Die fehlenden Funktionsaufrufe für Col muss man im Code nachschlagen (oder generiert sich die PythonApi selber für Col:TAC)

  5. #5
    Registrierter Benutzer
    Registriert seit
    21.08.21
    Beiträge
    16
    Hallo Mahony1987,

    du kannst doch im Spiel auch einstellen, ab welcher Menge was wohin transportiert wird. Ergo brauchst du keine Notizen oder Tabellen zu führen. Beispiel: Du willst, dass in einer City mit Zigarrenfabrik genug Tabak ankommt. Dann belieferst du sie einfach mit reichlich davon. In der Zigarrenstadt stellt du aber z.B. ein Export-Limit ein bspw. 100 Tabak, oder wenn deine Wagen weit fahren müssen eben mehr, zb. 500. Dann tust du von dieser Zigarrenstadt aus einen Tabak-Export einrichten, zum Beispiel zurück zu der Herkunftsstadt (lach) oder Verkauf nach Europa oder oder oder... Deine Zigarrenstadt ist jedenfalls immer mit Tabak versorgt.

    Zu deinen Fragen:
    - Ist eine Strecke überlastet weil z.B. ein Planwagen oder eine Galeone nicht ausreichen?
    - Werden alle Waren von einer Kolonie bereits abgeholt und staut sich nichts auf?
    Das siehst du doch in Europa, wenn ein Schiff randvoll ist Dort siehst du ja auch von wo es kommt (beim wegschicken). Also einfach ein weiteres Schiff mit gleicher Route losschicken.
    Auch siehst du es ja in der Stadt, wenn da was voll ist. Pack ein Schiff dazu und fertig.

    Tipp: Ich mach es so, dass alle Verkaufrouten zugleich in Europa ankommen. So brauchst du immer nur auf das Verkaufssymbol klicken und loschicken, auf das Verkaufssymbol klicken und loschicken,...usw.. Dann hast du nicht mehr in jeder Runde das Gefummel
    Oder du nutzt das Zollhaus. Ich persönlich hasse es und baue es nie.

    Tipp: Du kannst auch in den XML rumfummeln und die Lagerkapazitäten erhöhen. Ich hab beim Lagerhaus +500 eingestellt und bei der Erweiterung +100.000 Aber wenn ich über 2000 Waffen in einer Stadt hab, schenke ich den Überfluss immer den befreundeten Ureinwohnern, die haben dann eine Menge Spaß damit

    Ich persönlich nenne die Schiffe dann auch so wie die Städte. Um das zu vereinfachen mache ich vor meinen Stadtnamen Nummern. Beispielsweise: 01 Goldcity. Die Schiffe auf der Verkaufsroute nenne ich dann nur 01. Bei mehreren eben 01 a, 01 b. So braucht man nicht immer den Stadtnamen schreiben.

    Hoffe das hilft.... ich persönlich würde reichlich Spielspaß verlieren, wenn ich ständig in Tabellen tüfteln oder mich um Warenzeugs kümmern müsste. Das läuft doch alles automatisch. - Wenn du nicht der Meinung bist, nenne mal ein ganz genaues Beispiel.... dann kann ich vllt. helfen. Ich spiele seit den 90ern Col und brauchte nie so tüfteln. Und wenn du die ersten 100.000 Gold erreicht hast, wirst du merken, dass du gar kein Geld mehr brauchst

    Um Langeweile zu verhindern, kannst du auch einstellen, dass du gegen mehr Spieler spielst. Ich spiele aktuell gegen 14. Zudem kannst du einstellen, dass gegenerische Schiffe NICHT mehr den Ort einer Versenkung für X Runden vermeiden, denn dann ist ja jedesmal tote Hose im Ozean - und die Lager der Gegner platzen. Auch an den Kaperungen von Schiffen kannst du rumspielen. Auch kannst du WTP-Schiffe zu TAC holen, falls dir TAC mehr gefallen sollte. Bei mir bspw. ist ein enormer Schiffsverkehr Krieg ohne Ende... Aber vllt. weißt du das auch schon alles Ich kenne dich ja nicht...
    Auch das Fregatten-Event ein wenig verändert... Fregatten erhöhen, z.b. auf 5, dann 15, dann 25, und du musst herrlich fummelig mit deinen Piraten durch die Fregatten manövrieren

    So, hoffe ich konnte irgendwie helfen oder Anreize geben.

    Es grüßt
    Micha
    Geändert von Micha1979 (20. Januar 2022 um 20:32 Uhr)

  6. #6
    Registrierter Benutzer
    Registriert seit
    16.11.20
    Beiträge
    16
    Hallo Micha,

    danke für deine freundlichen Ratschläge und deine ausführliche Beschreibung. Bitte sei nicht zu enttäuscht, wenn ich trotzem in eine andere Richtung weiter gehe.
    Für mich geht es nicht nur um den Spaß am Spiel, sondern auch um den Spaß am Programmieren. Hier praktische kleine Tools zu entwicklen und auszuprobieren ist so etwas wie das Spiel selbst spielen.

    Aber jeder tickt da anders,... wäre ja schlimm wenn nicht.

    Viele grüße,
    Mahony

  7. #7
    Registrierter Benutzer
    Registriert seit
    16.11.20
    Beiträge
    16
    Zitat Zitat von Ramkhamhaeng Beitrag anzeigen
    Hallo,

    wenn du die Daten ründlich in eine Textdatei schreiben willst, wäre hier ein Beispiel zu finden: https://github.com/Charriu84/CloseTo...anager.py#L498

    (Die Zeilen, die von der BugMod abhängen, müsstest du ersetzen, da es das Modul in Col nicht gibt.)

    Hi Ramkhamhaeng,

    ich habe mich mal an den ersten Python Schritten versucht und arbeite mit Anaconda und PyCharm 3.1.

    Alle Infos in eine Textdatei schreiben wäre ein sehr guter Anfang für mich.

    Ich habe den Code den du empfohlen hast (Siehe Zitat) einfach mal in die main.py eines neuen Projekts kopiert, bekomme aber nich 91 Fehler und diverse Warnungen ausgegeben.

    Kannst du mir noch einen Tip geben, warum so viele Fehler aufkommen und unter welchen Bedingungen das Skript funktioniert?

    1) Muss das Spiel laufen?
    2) Kann ich das Skript über PyCharm ausführen?
    3) ...

    Habe hier noch keine Ahnung.

  8. #8
    Registrierter Benutzer
    Registriert seit
    16.11.20
    Beiträge
    16
    Hallo zusammen,

    ich habe mich mit Ramkhamhaengs Post beschäftigt und erfolgreich am Ende jedes Zuges eine Textdatei schreiben lassen.

    Nun möchte ich in diese Textdatei gerne eine Liste aller Kolonien schreiben. Leider weiß ich nicht woran ich mich orientieren kann.

    Welche Funktion / welchen Aufruf benötige ich um hier eine for-Schleife zu programmieren?

    Wie kann ich auf Merkmale einer Kolonie zugreifen?

    Aus dieser API werde ich leider nicht schlau: https://kirk.zulan.net/PythonAPI/index.html

  9. #9
    ε•ω=1 Avatar von Ramkhamhaeng
    Registriert seit
    19.07.10
    Ort
    Aralkum
    Beiträge
    9.896
    Hallo,

    ich kann die Frage auch gleich direkt beantworten
    Hier ein Minimalbeispiel bei dem eine Liste mit den Stadtnamen und der Position aller Städte/Kolonien von Spieler '0' erstellt wird.
    Das Beispiel ist von Civ4, aber ich hoffe es kann ohne Änderungen auch für Civ4:Col verwendet werden.

    Code:
    pl = gc.getPlayer(0)          # Erster Spieler
    (city, iter)  = pl.firstCity(False)   # Erste Stadt, wenn Argument False, letzte Stadt wenn True
    cNames = []
    while city is not None:
        position = "(%i,%i)" % (city.plot().getX(), city.plot().getY())
        cNames.append("%-30s %s" % (
              city.getName().encode("utf-8"),
              position)
    
       (city, iter) = pl.nextCity(iter, False)
    Die Funktion .firstCity gibt ein Tupel zurück. Die zweite Variable des Tupels ist ein 'Iterator-Objekt'. Das wird dann zum Iterieren über die Liste aller Städte wiederverwendet, wenn man .nextCity aufruft. Daher ist das dort ein Input-Parameter.

    Gruß Ramk

  10. #10
    Registrierter Benutzer
    Registriert seit
    16.11.20
    Beiträge
    16
    Hi Ramk,

    klappt einwandfrei, kann jetzt alle Kolonienamen in ein Textfile schreiben lassen.

    Jetzt frage ich mich, wie weit ich das treiben kann:
    Ich würde gerne eine Liste mit allen Kolonien machen in der für jede Kolonie aufgelistet ist:
    für jedes der 9 Felder:
    - Landschaftstyp (Prärie,... etc.)
    - Vegetation (Wald, Buschland,...)
    - Modernisierung (Bauernhof, Lager,...)
    - was für ein Kolonist da sitzt (Erfahrener Bauer, freier Kolonist,...)
    - was der Kolonist da produziert (Nahrung, Eisen,...)

    für jedes der Gebäude
    - was ist es für ein Gebäude (Zimmerei, Sägerwerk, Stadthalle,...)
    Für jedes Gebäude:
    - welcher Kolonist sitzt auf dem Platz (wie oben)


    Hast du da einen guten Tipp, wie ich mich dem annähern kann?

  11. #11
    ε•ω=1 Avatar von Ramkhamhaeng
    Registriert seit
    19.07.10
    Ort
    Aralkum
    Beiträge
    9.896
    Hallo Mahony,

    da die Koordinaten der Kolonien schon bekannt sind könntest du per "plot = CyMap().plot(iX,iY)" auf die umliegenden Felder zugreifen. Das Plot-Objekt hat dann viele nützliche Eigenschaften wie z.B. .getTerrainType() und .getFeatureType() für die ersten beiden Fragen.
    Da sich die Funktionsaufrufe von Civ4 und Col unterscheiden habe ich heute mit Hilfe des Skripts PythonApi eine Version für Colonization (bisher ohne TAC-Änderungen) erstellt, welche du hier finden kannst: https://kirk.zulan.net/Col/PythonAPI/


    Um nun die anderen Funktionsaufrufe für die von dir gewünschten Werte zu kommen empfehle ich einen Blick in die "Berater-Bildschirme" und das MainInterface.
    Diese Dateien findest du unter "Assets/Python/Screens". Sind relativ lang und unübersichtlich, aber wenn du weißt, dass der von dir gesuchte Wert in einem Beraterbildschirm angezeigt wird kann man dort suchen. Alternativ kann man nach Schlüsselwörtern auf der PythonAPI-Seite suchen.


    Beispiel: Für die Liste der Gebäude einer Kolonie findet man in CvMainInterface.py ab Zeile 2250:
    Code:
    			# 3 D BUILDINGS
    				for iSpecial in range(gc.getNumSpecialBuildingInfos()):
    					BuildingPresent = False
    					for iBuilding in range(gc.getNumBuildingInfos()):
    						if (pHeadSelectedCity.isHasBuilding(iBuilding)):
    							if(gc.getBuildingInfo(iBuilding).getSpecialBuildingType() == iSpecial):
    								BuildingPresent = True
    								break
    Sofern ich es richtig verstehe, verbirgt sich hinter der doppelten Schleife die Eigenschaft von Colonization, dass es Ketten von Gebäuden gibt "Palisade -> Fort", aber immer nur das beste dieser Gebäude angezeigt wird. D.h. je nachdem was du ausgeben willst brauchst du nur die innere Schleife (alle Gebäude auflisten) oder die äußere Schleife (nur die Top-Gebäude einer Kette).


    Viel Spaß beim Coden

  12. #12
    Registrierter Benutzer
    Registriert seit
    16.11.20
    Beiträge
    16
    Hi Ramk,

    erst mal vielen Dank für die API und den Tip mit der CvMainInterface.py.

    Ich bin jetzt an einer Stelle in meinem Projekt, wo ich scheinbar Python nicht verstehe.

    warum geht Code 1, während Code 2 nicht geht? Code 3 geht aber wieder.

    Code 1:
    Code:
    	def onSaveGame(self, argsList):
    		"return the string to be saved - Must be a string"
    		datei = open('E:\\Cloud\\Onedrive\\Spiele\\Colonization IV (TAC)\\Python Collection\\test.txt', 'w')
    		pl = gc.getPlayer(0)  # Erster Spieler
    		(city, iter) = pl.firstCity(False)  # Erste Stadt, wenn Argument False, letzte Stadt wenn True
    		cNames = []
    		while city is not None:
    			position = "(%i,%i)" % (city.plot().getX(), city.plot().getY())
    			cNames.append("%-30s %s" % (city.getName().encode("utf-8"),position))
    			for iSpecial in range(gc.getNumSpecialBuildingInfos()):
    				BuildingPresent = False
    				for iBuilding in range(gc.getNumBuildingInfos()):
    					datei.write(city.getName().encode("utf-8"))
    					datei.write(" Building2: ")
    					datei.write("\r")
    			(city, iter) = pl.nextCity(iter, False)
    		datei.write("Close")
    		datei.close()
    		return ""

    Code 2:
    Code:
    	def onSaveGame(self, argsList):
    		"return the string to be saved - Must be a string"
    		datei = open('E:\\Cloud\\Onedrive\\Spiele\\Colonization IV (TAC)\\Python Collection\\test.txt', 'w')
    		pl = gc.getPlayer(0)  # Erster Spieler
    		(city, iter) = pl.firstCity(False)  # Erste Stadt, wenn Argument False, letzte Stadt wenn True
    		cNames = []
    		while city is not None:
    			position = "(%i,%i)" % (city.plot().getX(), city.plot().getY())
    			cNames.append("%-30s %s" % (city.getName().encode("utf-8"),position))
    			for iSpecial in range(gc.getNumSpecialBuildingInfos()):
    				BuildingPresent = False
    				for iBuilding in range(gc.getNumBuildingInfos()):
    					datei.write(city.getName().encode("utf-8"))
    					datei.write(" Building2: ")
    					if (city.isHasBuilding(iBuilding)):
    						if (gc.getBuildingInfo(iBuilding).getSpecialBuildingType() == iSpecial):
    					datei.write("\r")
    			(city, iter) = pl.nextCity(iter, False)
    		datei.write("Close")
    		datei.close()
    		return ""
    Code 3
    Code:
    	def onSaveGame(self, argsList):
    		"return the string to be saved - Must be a string"
    		datei = open('E:\\Cloud\\Onedrive\\Spiele\\Colonization IV (TAC)\\Python Collection\\test.txt', 'w')
    		pl = gc.getPlayer(0)  # Erster Spieler
    		(city, iter) = pl.firstCity(False)  # Erste Stadt, wenn Argument False, letzte Stadt wenn True
    		cNames = []
    		while city is not None:
    			position = "(%i,%i)" % (city.plot().getX(), city.plot().getY())
    			cNames.append("%-30s %s" % (city.getName().encode("utf-8"),position))
    			for iSpecial in range(gc.getNumSpecialBuildingInfos()):
    				BuildingPresent = False
    				for iBuilding in range(gc.getNumBuildingInfos()):
    					if (city.isHasBuilding(iBuilding)):
    						if (gc.getBuildingInfo(iBuilding).getSpecialBuildingType() == iSpecial):
    							datei.write(city.getName().encode("utf-8"))
    							datei.write(" Building2: ")
    							datei.write("\r")
    			(city, iter) = pl.nextCity(iter, False)
    		datei.write("Close")
    		datei.close()
    		return ""
    Geändert von Mahony1987 (07. Januar 2024 um 20:41 Uhr)

  13. #13
    ε•ω=1 Avatar von Ramkhamhaeng
    Registriert seit
    19.07.10
    Ort
    Aralkum
    Beiträge
    9.896
    Kritische Stelle beim zweiten ist das innerste if-Statement:
    Code:
    if (city.isHasBuilding(iBuilding)):
        if (gc.getBuildingInfo(iBuilding).getSpecialBuildingType() == iSpecial):
    datei.write("\r")
    Da hinter dem Doppelpunkt kein weiterer Code folgt, aber in Python statt '{', '}' die Einrückung der Zeilen für die Strukturierung des Codes verwendet wird, ist für den Interpreter/Compiler die folgende Zeile falsch eingerückt.
    Um dieses Problem zu umgehen gibt es in Python das spezielle Schlüsselwort „pass“, was in anderen Programmiersprachen vergleichbar mit '{ }' ist.

    Richtig wäre also
    Code:
    if (city.isHasBuilding(iBuilding)):
        if (gc.getBuildingInfo(iBuilding).getSpecialBuildingType() == iSpecial):
            pass
    datei.write("\r")
    Bewirken würden die If-Statements dann natürlich nichts.

  14. #14
    Registrierter Benutzer
    Registriert seit
    16.11.20
    Beiträge
    16
    ahh, verstanden,.... Python ist doch noch etwas anders als VBA

    Eine Ausgabe zu den Gebäuden in jeder Kolonie habe ich hinbekommen. mal schaun, was nächstes WE alles geht.

  15. #15
    Registrierter Benutzer
    Registriert seit
    16.11.20
    Beiträge
    16
    Hallo Ramk,

    ich wollte mich damit beschäftigen, die Ausgabe in eine Funktion zu verschieben, damit ich sie bei mehreren Events nutzen kann.

    Sieht nun folgendermaßen aus, funktioniert leider nicht:

    Code:
    	def onSaveGame(self, argsList):
    		"return the string to be saved - Must be a string"
    		pl = gc.getPlayer(0)  # Erster Spieler
    		safeAPICol2Building()
    		return ""
    
    
    	def safeAPICol2Building():
    		Col2Building = open('E:\\Cloud\\Onedrive\\Spiele\\Colonization IV (TAC)\\CurrentGame\\Col2Building.txt', 'w')
    		pl = gc.getPlayer(0)  # Erster Spieler
    		(city, iter) = pl.firstCity(False)  # Erste Stadt, wenn Argument False, letzte Stadt wenn True
    		cNames = []
    		Col2Building.write("Kolonie Name;Gebäudestrang;Gebäude\n")
    		while city is not None:
    			position = "(%i,%i)" % (city.plot().getX(), city.plot().getY())
    			cNames.append("%-30s %s" % (city.getName().encode("utf-8"),position))
    			for iSpecial in range(gc.getNumSpecialBuildingInfos()):
    				BuildingPresent = False
    				Col2Building.write(city.getName().encode("utf-8"))
    				Col2Building.write(";")
    				Col2Building.write(gc.getSpecialBuildingInfo(iSpecial).getText().encode("utf-8"))
    				Col2Building.write(";")
    				for iBuilding in range(gc.getNumBuildingInfos()):
    					if (city.isHasBuilding(iBuilding)):
    						if (gc.getBuildingInfo(iBuilding).getSpecialBuildingType() == iSpecial):
    							Col2Building.write(gc.getBuildingInfo(iBuilding).getText().encode("utf-8"))
    				Col2Building.write("\n")
    			(city, iter) = pl.nextCity(iter, False)
    		Col2Building.close()
    Verschiebe ich den Code in die onSaveGame wird mir die Datei wie gewünscht ausgegeben.

    Mache ich beim Aufruf etwas falsch?

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •