AoM
Tutorials
Scripts
Tools


aoe2
Tutorials
Scripts
Tools


Comunuty
Links
Board

Impressum


Site
Datei Senden

 
 
Seite als Startseite festlegenE-Mail an den Webmaster Gästebuch
 

 

KI Tutorial von Spirit

 

Ein KI-Tutorial

von Alexander "Spirit" Braentel

Hallo ersteinmal und willkommen in diesem Tutorial. Um eine KI schreiben zu können, muss man zuerst wissen, was eine KI ist und wie sie aufgebaut ist. Daher habe ich diesen Text in zwei Teile geteilt: "Woraus besteht eine KI?" und "Wie schreibe ich eine KI?".

1. Woraus besteht eine KI?

Eine KI besteht aus Regeln(Rules). Und Regeln bestehen aus Fakten(Facts) und Aktionen(actions). Die Fakten fragen nach, ob eine oder mehrere Bedingungen erfüllt sind. Wenn diese erfüllt sind, werden die Fakten als wahr(true) gesehen und die Aktionen werden ausgeführt. Fakten sind zum Beispiel: "Das jetztige Zeitalter der KI ist das Ritterzeitalter" oder "Spieler 1 hat 20 Dorfbewohner". Aktionen sind zum Beispiel: "Greife jetzt an" oder "Gib Spieler 3 100 Gold". Wie manche vielleicht schon bemerk haben, hat eine KI-Regel viele Gemeinsamkeiten mit einem Schalter. Für die unter euch, die mit Schaltern gut umgehen können, wird es daher wahrscheinlich leichter eine KI zu schreiben. Nun zu den Reglen: Eine Regel ist ungefähr so aufgebaut:

(defrule
(Fakt)
(Fakt)
...
=>
(Aktion)
(Aktion)
...
)

"(defrule" sagt der KI das eine neue Regel beginnt.
"(Fakt)" definiert einen Fakt.
"=>" trennt Fakten und Aktionen.
"(Aktion)" definiert eine Aktion.
")" beendet eine Regel.
Außerdem kann man mit ";Text" Kommentare zu den einzelnen Regeln abgeben, die im Spiel später nicht angezeigt werden. (Man sollte zu JEDER Regel ein Kommentar schreiben, sonst sieht man später durch seine eigene KI nicht mehr durch.)

2. Wie schreibe ich eine KI?

Ein Tip vorweg: Alles Strategienummern, Gebäude, Einheiten, Technologien,... sind in der deutschen <a href="pack_hier_den_link_zur_cpsb.doc_bei_www.aoe2.de_rein" target="_blank">CPSB.doc</a> aufgelistet.Als erstes muss man zwei neue Dateien im Verzeichnis "Age of Empires II/Ai" erstellen: KI-Name.ai und KI-Name.per .
Die .ai-Datei sagt dem Spiel das die KI "KI-Name" existiert. In die .per-Datei kommen alle Regeln.

Jetzt öffnet die Datei KI-Name.per . Jetzt erkläre ich, wie man eine "Roh-KI"(ohne besondere Strategien oder Taktiken) schreibt. Als erstes kommen die Strategienummern für das dunkle Zeitalter. Dann kommt das Erschaffen von Einheiten im dunklen Zeitalter. Danach kommen die Gebäudeplatzierung im dunklen Zeitalter. Jetzt kommt die Erforschung der Technologien im dunklen Zeitalter. Danach kommt das alles für das Feudal-Zeitalter. Dann das alles für das Ritterzeitalter. Und zum Schluss das alles für das Imperialzeitalter.


; Bauten die fuer jedes Zeitalter gelten
(defrule
(housing-headroom < 5)
(can-build house)
=>
(build house)
)

(defrule
(dropsite-min-distance food > 3)
(can-build mill)
(food-amount < 2000)
=>
(build mill)
)

(defrule
(dropsite-min-distance wood > 3)
(can-build lumber-camp)
(wood-amount < 1000)
=>
(build lumber-camp)
)

(defrule
(dropsite-min-distance gold > 3)
(can-build mining-camp)
=>
(build mining-camp)
)

(defrule
(can-build market)
(building-type-count-total market < 1)
=>
(build market)
)

(defrule
(can-build blacksmith)
(building-type-count-total blacksmith < 1)
=>
(build blacksmith)
)

(defrule
(can-build castle)
(building-type-count-total castle < 1)
(unit-type-count-total villager >= 75)
=>
(build castle)
)

(defrule
(can-build monastery)
(building-type-count-total monastery < 1)
=>
(build monastery)
)

(defrule
(can-build university)
(building-type-count-total university < 1)
=>
(build university)
)

(defrule
(can-build dock)
(building-type-count-total dock < 1)
=>
(build dock)
)

; WICHTIG: Alle dicken Kommentare muss man nicht in die KI schreiben! Sie sollen nur die einzelen Befehle erklären.
; "(housing-headroom <Zeichen> <Zahl>) wird true, wenn die KI noch weniger(<) als, mehr(>) als oder genausoviele(==) wie <Zahl> Einheiten produzieren kann.
;"(can-build <Gebäudename>)" wird true, wenn die KI ein <Gebäudename> bauen kann.
;"(build <Gebäudename>)" sagt der KI, das sie ein <Gebäudename> bauen soll.
;"(dropside-min-distance <Ressourcenname> <Zeichen> <Zahl>)" wird true, wenn die Distanz zwischen <Ressourcenname>sammelstelle und <Ressourcenname>depot größer(>), ;kleiner(<) oder gleich(==) <Zahl> ist.
;"(<Ressourcenname>-amount <Zeichen> <Zahl>)" wird true, wenn die KI mehr(>), weniger(<) oder genausoviel(==) wie <Zahl> <Ressourcenname> besitzt.
; "(unit-type-count-total <Einheitenname> <Zeichen> <Zahl>)" wird true, wenn die KI weniger(<) als, mehr(>) als oder genausoviele(==) wie <Zahl> von <Einheitenname> besitzt.
; "(building-type-count-total <Gebäudename> <Zeichen> <Zahl>)" wird true, wenn die KI weniger(<) als, mehr(>) als oder genausoviele(==) wie <Zahl> von <Gebäudename> besitzt.

; Bauten im Dark-Age
(defrule
(building-type-count-total town-center < 1)
(can-build town-center)
=>
(build town-center)
)

(defrule
(building-type-count-total farm < 10)
(current-age == dark-age)
(can-build farm)
=>
(build farm)
)

; "(current-age == <Zeitalter>)" wird true, wenn die KI im Zeitalter <Zeitalter> ist.

; Einheitenproduktion im Dark-Age
(defrule
(current-age == dark-age)
(can-train villager)
(unit-type-count-total villager < 30)
=>
(train villager)
)

; "(can-train <Einheitenname>)" wird true, wenn die KI <Einheitenname> produzieren kann.
; "(train <Einheitenname>)" sagt der KI, das sie <Einheitenname> produzieren soll.

; Strategienummern im Dark-Age
(defrule
(current-age == dark-age)
=>
(set-strategic-number sn-percent-civilian-explorers 0)
(set-strategic-number sn-percent-civilian-builders 30)
(set-strategic-number sn-percent-civilian-gatherers 70)
(set-strategic-number sn-cap-civilian-explorers 0)
(set-strategic-number sn-cap-civilian-builders 5)
(set-strategic-number sn-cap-civilian-gatherers 25)
(set-strategic-number sn-total-number-explorers 1)
(set-strategic-number sn-percent-enemy-sighted-response 50)
(set-strategic-number sn-enemy-sighted-response-distance 50)
(disable-self)
)

(defrule
(current-age == dark-age)
=>
(set-strategic-number sn-food-gatherer-percentage 70)
(set-strategic-number sn-wood-gatherer-percentage 30)
(set-strategic-number sn-gold-gatherer-percentage 0)
(set-strategic-number sn-stone-gatherer-percentage 0)
(set-strategic-number sn-total-number-explorers 1)
(set-strategic-number sn-percent-enemy-sighted-response 50)
(set-strategic-number sn-enemy-sighted-response-distance 50)
(set-strategic-number sn-minimum-explore-group-size 1)
(set-strategic-number sn-maximum-explore-group-size 1)
(set-strategic-number sn-number-explore-groups 1)
(disable-self)
)

(defrule
(current-age == dark-age)
=>
(set-strategic-number sn-food-dropsite-distance 3)
(set-strategic-number sn-wood-dropsite-distance 3)
(set-strategic-number sn-gold-dropsite-distance 3)
(set-strategic-number sn-stone-dropsite-distance 3)
(set-strategic-number sn-minimum-town-size 12)
(set-strategic-number sn-maximum-town-size 26)
(disable-self)
)

; Alle Strategienummern sind in der deutschen CPSB.doc erklärt.

; Research im Dark-Age
(defrule
(unit-type-count-total villager >= 10)
(can-research ri-loom)
=>
(research ri-loom)
)

(defrule
(unit-type-count-total villager >= 30)
(can-research feudal-age)
(current-age == dark-age)
=>
(research feudal-age)
)

; "(can-research ri-<Technologie>) wird true, wenn die KI <Technologie> erforschen kann.
; "(research <Technologie>)" sagt der KI, das sie <Technologie> erforschen soll.

; Strategienummern fuers Feudal-Age
(defrule
(current-age == feudal-age)
=>
(set-strategic-number sn-percent-civilian-explorers 0)
(set-strategic-number sn-percent-civilian-builders 35)
(set-strategic-number sn-percent-civilian-gatherers 65)
(set-strategic-number sn-cap-civilian-explorers 0)
(set-strategic-number sn-cap-civilian-builders 10)
(set-strategic-number sn-cap-civilian-gatherers 50)
(set-strategic-number sn-total-number-explorers 1)
(set-strategic-number sn-percent-enemy-sighted-response 50)
(set-strategic-number sn-enemy-sighted-response-distance 50)
(disable-self)
)

(defrule
(current-age == feudal-age)
=>
(set-strategic-number sn-food-gatherer-percentage 60)
(set-strategic-number sn-wood-gatherer-percentage 30)
(set-strategic-number sn-gold-gatherer-percentage 10)
(set-strategic-number sn-stone-gatherer-percentage 0)
(set-strategic-number sn-total-number-explorers 1)
(set-strategic-number sn-percent-enemy-sighted-response 50)
(set-strategic-number sn-enemy-sighted-response-distance 50)
(set-strategic-number sn-minimum-explore-group-size 1)
(set-strategic-number sn-maximum-explore-group-size 1)
(set-strategic-number sn-number-explore-groups 1)
(disable-self)
)

(defrule
(current-age == feudal-age)
=>
(set-strategic-number sn-food-dropsite-distance 3)
(set-strategic-number sn-wood-dropsite-distance 3)
(set-strategic-number sn-gold-dropsite-distance 3)
(set-strategic-number sn-stone-dropsite-distance 3)
(set-strategic-number sn-minimum-town-size 12)
(set-strategic-number sn-maximum-town-size 26)
(set-strategic-number sn-minimum-defend-group-size 20)
(set-strategic-number sn-maximum-defend-group-size 20)
(set-strategic-number sn-maximum-attack-group-size 30)
(set-strategic-number sn-minimum-attack-group-size 30)
(set-strategic-number sn-attack-intelligence 1)
(disable-self)
)

; Alle Strategienummern sind in der deutschen CPSB.doc erklärt.

; Einheitenproduktion im Feudal-Age
(defrule
(current-age == feudal-age)
(can-train villager)
(unit-type-count-total villager < 60)
=>
(train villager)
)

(defrule
(current-age == feudal-age)
(can-train archer-line)
(unit-type-count-total archer-line < 10)
=>
(train archer-line)
)

(defrule
(current-age == feudal-age)
(can-train militiaman-line)
(unit-type-count-total militiaman-line < 20)
=>
(train militiaman-line)
)

(defrule
(current-age == feudal-age)
(can-train spearman-line)
(unit-type-count-total spearman-line < 10)
=>
(train spearman-line)
)

(defrule
(current-age == feudal-age)
(can-train skirmisher-line)
(unit-type-count-total skirmisher-line < 10)
=>
(train skirmisher-line)
)

; Bauten im Feudal-Age
(defrule
(current-age == feudal-age)
(can-build barracks)
(building-type-count-total barracks < 1)
=>
(build barracks)
)

(defrule
(current-age == feudal-age)
(can-build archery-range)
(building-type-count-total archery-range < 1)
=>
(build archery-range)
)

(defrule
(current-age == feudal-age)
(can-build stable)
(building-type-count-total stable < 1)
=>
(build stable)
)

(defrule
(current-age == feudal-age)
(can-build farm)
(building-type-count-total farm < 20)
=>
(build farm)
)

; Research im Feudal-Age
(defrule
(can-research ri-wheel-barrow)
(unit-type-count-total villager >= 45)
=>
(research ri-wheel-barrow)
)

(defrule
(can-research ri-town-watch)
(unit-type-count-total villager >= 45)
=>
(research ri-town-watch)
)

(defrule
(can-research ri-double-bit-axe)
=>
(research ri-double-bit-axe)
)

(defrule
(can-research ri-gold-mining)
=>
(research ri-gold-mining)
)

(defrule
(can-research ri-stone-mining)
=>
(research ri-stone-mining)
)

(defrule
(can-research ri-fletching)
=>
(research ri-fletching)
)

(defrule
(can-research ri-horse-collar)
=>
(research ri-horse-collar)
)

(defrule
(unit-type-count-total villager >= 60)
(can-research castle-age)
=>
(research castle-age)
)

; Angriff im Feudal-Age
(defrule
(current-age == feudal-age)
(unit-type-count-total skirmisher-line >= 10)
(unit-type-count-total spearman-line >= 10)
(unit-type-count-total militiaman-line >= 20)
(unit-type-count-total archer-line >= 10)
=>
(attack-now)
)

; "(attack-now)" sagt der KI, das sie jetzt angreifen soll.

; Strategienummern fuers Castle-Age
(defrule
(current-age == castle-age)
=>
(set-strategic-number sn-percent-civilian-explorers 0)
(set-strategic-number sn-percent-civilian-builders 35)
(set-strategic-number sn-percent-civilian-gatherers 65)
(set-strategic-number sn-cap-civilian-explorers 0)
(set-strategic-number sn-cap-civilian-builders 20)
(set-strategic-number sn-cap-civilian-gatherers 70)
(set-strategic-number sn-total-number-explorers 1)
(set-strategic-number sn-percent-enemy-sighted-response 50)
(set-strategic-number sn-enemy-sighted-response-distance 50)
(disable-self)
)

(defrule
(current-age == castle-age)
=>
(set-strategic-number sn-food-gatherer-percentage 50)
(set-strategic-number sn-wood-gatherer-percentage 25)
(set-strategic-number sn-gold-gatherer-percentage 20)
(set-strategic-number sn-stone-gatherer-percentage 5)
(set-strategic-number sn-total-number-explorers 1)
(set-strategic-number sn-percent-enemy-sighted-response 50)
(set-strategic-number sn-enemy-sighted-response-distance 50)
(set-strategic-number sn-minimum-explore-group-size 1)
(set-strategic-number sn-maximum-explore-group-size 1)
(set-strategic-number sn-number-explore-groups 1)
(disable-self)
)

(defrule
(current-age == castle-age)
=>
(set-strategic-number sn-food-dropsite-distance 3)
(set-strategic-number sn-wood-dropsite-distance 3)
(set-strategic-number sn-gold-dropsite-distance 3)
(set-strategic-number sn-stone-dropsite-distance 3)
(set-strategic-number sn-minimum-town-size 12)
(set-strategic-number sn-maximum-town-size 26)
(set-strategic-number sn-minimum-defend-group-size 20)
(set-strategic-number sn-maximum-defend-group-size 20)
(set-strategic-number sn-maximum-attack-group-size 30)
(set-strategic-number sn-minimum-attack-group-size 30)
(set-strategic-number sn-attack-intelligence 1)
(disable-self)
)

; Alle Strategienummern werden in der deutschen CPSB.doc erklärt.

; Einheitenproduktion im Castle-Age
(defrule
(current-age == castle-age)
(unit-type-count-total villager < 90)
(can-train villager)
=>
(train villager)
)

(defrule
(current-age == castle-age)
(can-train archer-line)
(unit-type-count-total archer-line < 10)
=>
(train archer-line)
)

(defrule
(current-age == castle-age)
(can-train militiaman-line)
(unit-type-count-total militiaman-line < 20)
=>
(train militiaman-line)
)

(defrule
(current-age == castle-age)
(can-train spearman-line)
(unit-type-count-total spearman-line < 10)
=>
(train spearman-line)
)

(defrule
(current-age == castle-age)
(can-train skirmisher-line)
(unit-type-count-total skirmisher-line < 10)
=>
(train skirmisher-line)
)

(defrule
(current-age == castle-age)
(can-train longbowman-line)
(unit-type-count-total longbowman-line < 10)
=>
(train longbowman-line)
)

; Bauten im Castle-Age
(defrule
(dropsite-min-distance stone > 3)
(current-age == castle-age)
(can-build mining-camp)
(stone-amount < 1000)
=>
(build mining-camp)
)

(defrule
(current-age == castle-age)
(building-type-count-total farm < 30)
(can-build farm)
=>
(build farm)
)

; Research im Castle-Age
(defrule
(can-research ri-hand-cart)
=>
(research ri-hand-cart)
)

(defrule
(can-research ri-heavy-plow)
=>
(research ri-heavy-plow)
)

(defrule
(can-research ri-bow-saw)
=>
(research ri-bow-saw)
)

(defrule
(can-research ri-gold-shaft-mining)
=>
(research ri-gold-shaft-mining)
)

(defrule
(can-research ri-murder-holes)
=>
(research ri-murder-holes)
)

(defrule
(can-research ri-town-patrol)
=>
(research ri-town-patrol)
)

(defrule
(can-research ri-bodkin-arrow)
=>
(research ri-bodkin-arrow)
)

(defrule
(can-research imperial-age)
(unit-type-count-total villager == 90)
=>
(research imperial-age)
)

; Angriff im Castle-Age
(defrule
(current-age == castle-age)
(unit-type-count-total skirmisher-line >= 10)
(unit-type-count-total spearman-line >= 10)
(unit-type-count-total militiaman-line >= 20)
(unit-type-count-total archer-line >= 10)
(unit-type-count-total longbowman-line >= 10)
=>
(attack-now)
)

; Strategienummern fuers Imperial-Age
(defrule
(current-age == imperial-age)
=>
(set-strategic-number sn-percent-civilian-explorers 0)
(set-strategic-number sn-percent-civilian-builders 35)
(set-strategic-number sn-percent-civilian-gatherers 65)
(set-strategic-number sn-cap-civilian-explorers 0)
(set-strategic-number sn-cap-civilian-builders 20)
(set-strategic-number sn-cap-civilian-gatherers 70)
(set-strategic-number sn-total-number-explorers 1)
(set-strategic-number sn-percent-enemy-sighted-response 50)
(set-strategic-number sn-enemy-sighted-response-distance 50)
(disable-self)
)

(defrule
(current-age == imperial-age)
=>
(set-strategic-number sn-food-gatherer-percentage 40)
(set-strategic-number sn-wood-gatherer-percentage 30)
(set-strategic-number sn-gold-gatherer-percentage 20)
(set-strategic-number sn-stone-gatherer-percentage 10)
(set-strategic-number sn-total-number-explorers 1)
(set-strategic-number sn-percent-enemy-sighted-response 50)
(set-strategic-number sn-enemy-sighted-response-distance 50)
(set-strategic-number sn-minimum-explore-group-size 1)
(set-strategic-number sn-maximum-explore-group-size 1)
(set-strategic-number sn-number-explore-groups 1)
(disable-self)
)

(defrule
(current-age == imperial-age)
=>
(set-strategic-number sn-food-dropsite-distance 3)
(set-strategic-number sn-wood-dropsite-distance 3)
(set-strategic-number sn-gold-dropsite-distance 3)
(set-strategic-number sn-stone-dropsite-distance 3)
(set-strategic-number sn-minimum-town-size 15)
(set-strategic-number sn-maximum-town-size 30)
(set-strategic-number sn-minimum-defend-group-size 20)
(set-strategic-number sn-maximum-defend-group-size 20)
(set-strategic-number sn-maximum-attack-group-size 30)
(set-strategic-number sn-minimum-attack-group-size 30)
(set-strategic-number sn-attack-intelligence 1)
(disable-self)
)

; Alle Strategienummern werden in der deutschen CPSB.doc erklärt.

; Einheitenproduktion im Imperial-Age
(defrule
(current-age == imperial-age)
(unit-type-count-total villager < 120)
(can-train villager)
=>
(train villager)
)

(defrule
(current-age == imperial-age)
(can-train archer-line)
(unit-type-count-total archer-line < 10)
=>
(train archer-line)
)

(defrule
(current-age == imperial-age)
(can-train militiaman-line)
(unit-type-count-total militiaman-line < 20)
=>
(train militiaman-line)
)

(defrule
(current-age == imperial-age)
(can-train spearman-line)
(unit-type-count-total spearman-line < 10)
=>
(train spearman-line)
)

(defrule
(current-age == imperial-age)
(can-train skirmisher-line)
(unit-type-count-total skirmisher-line < 10)
=>
(train skirmisher-line)
)

(defrule
(current-age == imperial-age)
(can-train longbowman-line)
(unit-type-count-total longbowman-line < 10)
=>
(train longbowman-line)
)

; Bauten im Imperial-Age
(defrule
(dropsite-min-distance stone > 3)
(current-age == imperial-age)
(can-build mining-camp)
(stone-amount < 1000)
=>
(build mining-camp)
)

(defrule
(current-age == imperial-age)
(can-build farm)
(building-type-count-total farm < 40)
=>
(build farm)
)

; Research im Imperial-Age
(defrule
(can-research ri-two-man-saw)
=>
(research ri-two-man-saw)
)

(defrule
(can-research ri-bracer)
=>
(research ri-bracer)
)

(defrule
(can-research ri-hoardings)
=>
(research ri-hoardings)
)

; Angriff im Imperial-Age
(defrule
(current-age == imperial-age)
(unit-type-count-total skirmisher-line >= 10)
(unit-type-count-total spearman-line >= 10)
(unit-type-count-total militiaman-line >= 20)
(unit-type-count-total archer-line >= 10)
(unit-type-count-total longbowman-line >= 10)
=>
(attack-now)
)


So, das war es erstmal von mir. Vielleicht werde ich irgendwanneinmal schreiben, wie man noch zusätzliche Taktiken programmiert, aber das sollte eigendlich jeder von euch allein herausfinden, indem er die deutsche CPSB.doc ließt.

(Wie es bei Tutorials so üblich ist, verweise ich jetzt zum Schluß bei Fragen, Kritik, Wünschen, Lob, etc. auf meine E-Mail-Adresse: Algor_2@hotmail.com
Viel Spaß beim Programmieren einer KI!
(Wenn ihr wollt, könnt ihr eure fertigen KI's an mich senden, damit ich mal sehe wie gut ihr seit und ich eventuell noch Tips geben kann.)

 

 

 

© 2002 by Death_Maggy