It is currently 25 Apr 2024, 10:11
   
Text Size

I'm Insane: An auto-coding tool

Moderator: CCGHQ Admins

I'm Insane: An auto-coding tool

Postby Xander9009 » 08 May 2015, 19:57

I've had an idea for a long time of a tool like thefiremind's generators, but more powerful. I wanted it to be able to parse abilities that are relatively simple, but too complex for the generators.

I've started work on it, and it's actually coming along very nicely. It's being written in AutoHotKey, because what I'm most comfortable in. It's not the most powerful language for a tool like this, and I should probably write it in Python or something. But, I decided to just jump into it, and that means using what I know.

It can currently handle life gain, life loss, card drawing, targeting (single targets only), and destruction. It can build a simple filter that only consists of card types, subtypes, supertypes, and permanent (or any of those prefixed with "non"). It can also handle any number of those together. So, "noncreature permanent" results in the filter you'd expect.

Determines everything about the ability from the text alone, meaning from the user's point of view, the only thing they do is tell it the ability text and card name, and it'll produce the code to do so.

Run the program with the parameters "Destroy target nonbasic land." "Some Card Name", and the clipboard will be set to the following (note that "Some Card Name" is there because it requires the name of the card being processed in case the ability itself has the card name in reference to itself):
Code: Select all
<SPELL_ABILITY>
<TARGET tag="CARD_QUERY_CHOOSE_CREATURE_TO_DESTROY" definition="0" compartment="0" count="1" />
<TARGET_DEFINITION id="0">
local filter = ClearFilter()
filter:Add( FE_TYPE, OP_IS, CARD_TYPE_CREATURE)
</TARGET_DEFINITION>
<RESOLUTION_TIME_ACTION>
local target = EffectDC():Get_Targets(0) and EffectDC():Get_Targets(0):Get_CardPtr(0)
if target ~= nil then
target:Destroy()
end
</RESOLUTION_TIME_ACTION>
</SPELL_ABILITY>
(I have another utility which can be used after the card is saved to indent everything properly.)
It can't handle more the one target, though. And it doesn't yet handle AI_SIMPLIFIED_TARGETING tags. But it's more versatile than I expected it to be after just a few hours of works.

Just for testing, I tried out "Destroy target nonlegendary creature. Draw a cards. Lose 2 life." and got the following (which I manually indented, but otherwise didn't change).
Code: Select all
<SPELL_ABILITY>
   <TARGET tag="CARD_QUERY_CHOOSE_NONLEGENDARY_CREATURE_TO_DESTROY" definition="0" compartment="0" count="1" />
   <TARGET_DEFINITION id="0">
      local filter = ClearFilter()
      filter:Add( FE_SUPERTYPE, OP_NOT, SUPERTYPE_LEGENDARY)
      filter:Add( FE_TYPE, OP_IS, CARD_TYPE_CREATURE)
   </TARGET_DEFINITION>
   <RESOLUTION_TIME_ACTION>
      local target = EffectDC():Get_Targets(0) and EffectDC():Get_Targets(0):Get_CardPtr(0)
      if target ~= nil then
         target:Destroy()
      end
   </RESOLUTION_TIME_ACTION>
</SPELL_ABILITY>

<SPELL_ABILITY>
   <RESOLUTION_TIME_ACTION>
      EffectController():DrawCards(1)
   </RESOLUTION_TIME_ACTION>
</SPELL_ABILITY>

<SPELL_ABILITY>
   <RESOLUTION_TIME_ACTION>
      EffectController():LoseLife(2)
   </RESOLUTION_TIME_ACTION>
</SPELL_ABILITY>
Obviously, I'll have to make it keeps abilities in the same ability block where possible, but I'm rather pleased with it. I don't imagine it'll ever be able to handle anything complicated, but I should be able to manage to get it to handle: performing an action on multiple targets (Downpour), resolutions separated by 'and' (Night's Whisper), tapping, bouncing, exiling, scrying, typical mana abilities (not ones with strange effects, but Abzan Banner should be doable), cloning, creating tokens, damaging, sacrificing, discarding, milling, regeneration/regen prevention, possibly granting simple abilities, and probably most of the filtering functions. That's the goal, at least. Just to see how much can be done without anyone having to manually code them. (Also, because of the way I'm using the clipboard to temporarily store the output and because I'll eventually add an optional save to file function, it should be usable from just about any language, so it can be easily tied into TFM's Card Generator.)

Current code | Open
Code: Select all
FileEncoding, UTF-8

Parameters = %0%
If ( Parameters = 2 )
{
   AbilityText = %1%
   CardName = %2%
} Else If ( Parameters = 0 )
{
   AbilityText := "Draw two cards."
   CardName := "Divination"
} Else
{
   MsgBox, Invalid number of parameters. Expected 2 parameters.`n1: "%1%"`n2: "%2%"
   ExitApp
}

AbilityList := Object()
SubjectList := Object()
VerbList := Object()
ObjectList := Object()
DetailsList := Object()

SubjectDictionary := Object()
SubjectDictionary.Insert("you", "EffectController()")
SubjectDictionary.Insert("owner", "GetOwner()")
SubjectDictionary.Insert("CARDNAME", "EffectSource()")

VerbDictionary := Object()
VerbDictionary.Insert("draw", "draw")
VerbDictionary.Insert("draws", "draw")
VerbDictionary.Insert("life", "life")
VerbDictionary.Insert("destroy", "destroy")
VerbDictionary.Insert("discard", "discard")
VerbDictionary.Insert("discards", "discard")

ObjectDictionary := Object()
ObjectDictionary.Insert("you", "EffectController()")
ObjectDictionary.Insert("card", "card")
ObjectDictionary.Insert("cards", "card")
ObjectDictionary.Insert("target", "target")

DetailsDictionary := Object()
DetailsDictionary.Insert("gain", "gain")
DetailsDictionary.Insert("gains", "gain")
DetailsDictionary.Insert("lose", "lose")
DetailsDictionary.Insert("loses", "lose")

ResolutionVerbs := Object()
ResolutionVerbs.Insert("draw", 1)
ResolutionVerbs.Insert("destroy", 2)
ResolutionVerbs.Insert("discard", 3)
ResolutionVerbs.Insert("life", 3)

FE_Misc := Object()
FE_Misc.Insert("permanent", "FE_IS_PERMANENT, true")
FE_Misc.Insert("nonpermanent", "FE_IS_PERMANENT, false")

FE_Type := Object()
FE_Type.Insert("artifact", "CARD_TYPE_ARTIFACT")
FE_Type.Insert("creature", "CARD_TYPE_CREATURE")
FE_Type.Insert("enchantment", "CARD_TYPE_ENCHANTMENT")
FE_Type.Insert("instant", "CARD_TYPE_INSTANT")
FE_Type.Insert("land", "CARD_TYPE_LAND")
FE_Type.Insert("plane", "CARD_TYPE_PLANE")
FE_Type.Insert("planeswalker", "CARD_TYPE_PLANESWALKER")
FE_Type.Insert("sorcery", "CARD_TYPE_SORCERY")
FE_Type.Insert("scheme", "CARD_TYPE_SCHEME")
FE_Type.Insert("tribal", "CARD_TYPE_TRIBAL")

FE_SuperType := Object()
FE_SuperType.Insert("basic", "SUPERTYPE_BASIC")
FE_SuperType.Insert("legendary", "SUPERTYPE_LEGENDARY")
FE_SuperType.Insert("world", "SUPERTYPE_WORLD")
FE_SuperType.Insert("snow", "SUPERTYPE_SNOW")
FE_SuperType.Insert("ongoing", "SUPERTYPE_ONGOING")

FE_SubType := Object()
FE_SubType.Insert("contraption", "ARTIFACT_TYPE_CONTRAPTION")
FE_SubType.Insert("equipment", "ARTIFACT_TYPE_EQUIPMENT")
FE_SubType.Insert("fortification", "ARTIFACT_TYPE_FORTIFICATION")
FE_SubType.Insert("aura", "ENCHANTMENT_TYPE_AURA")
FE_SubType.Insert("shrine", "ENCHANTMENT_TYPE_SHRINE")
FE_SubType.Insert("curse", "ENCHANTMENT_TYPE_CURSE")
FE_SubType.Insert("desert", "LAND_TYPE_DESERT")
FE_SubType.Insert("forest", "LAND_TYPE_FOREST")
FE_SubType.Insert("island", "LAND_TYPE_ISLAND")
FE_SubType.Insert("lair", "LAND_TYPE_LAIR")
FE_SubType.Insert("locus", "LAND_TYPE_LOCUS")
FE_SubType.Insert("mine", "LAND_TYPE_MINE")
FE_SubType.Insert("mountain", "LAND_TYPE_MOUNTAIN")
FE_SubType.Insert("plains", "LAND_TYPE_PLAINS")
FE_SubType.Insert("swamp", "LAND_TYPE_SWAMP")
FE_SubType.Insert("tower", "LAND_TYPE_TOWER")
FE_SubType.Insert("urzas", "LAND_TYPE_URZAS")
FE_SubType.Insert("human", "CREATURE_TYPE_HUMAN")
FE_SubType.Insert("advisor", "CREATURE_TYPE_ADVISOR")
FE_SubType.Insert("anemone", "CREATURE_TYPE_ANEMONE")
FE_SubType.Insert("angel", "CREATURE_TYPE_ANGEL")
FE_SubType.Insert("anteater", "CREATURE_TYPE_ANTEATER")
FE_SubType.Insert("antelope", "CREATURE_TYPE_ANTELOPE")
FE_SubType.Insert("ape", "CREATURE_TYPE_APE")
FE_SubType.Insert("archer", "CREATURE_TYPE_ARCHER")
FE_SubType.Insert("archon", "CREATURE_TYPE_ARCHON")
FE_SubType.Insert("artificer", "CREATURE_TYPE_ARTIFICER")
FE_SubType.Insert("assassin", "CREATURE_TYPE_ASSASSIN")
FE_SubType.Insert("atog", "CREATURE_TYPE_ATOG")
FE_SubType.Insert("aurochs", "CREATURE_TYPE_AUROCHS")
FE_SubType.Insert("avatar", "CREATURE_TYPE_AVATAR")
FE_SubType.Insert("badger", "CREATURE_TYPE_BADGER")
FE_SubType.Insert("barbarian", "CREATURE_TYPE_BARBARIAN")
FE_SubType.Insert("basilisk", "CREATURE_TYPE_BASILISK")
FE_SubType.Insert("bat", "CREATURE_TYPE_BAT")
FE_SubType.Insert("bear", "CREATURE_TYPE_BEAR")
FE_SubType.Insert("beast", "CREATURE_TYPE_BEAST")
FE_SubType.Insert("beeble", "CREATURE_TYPE_BEEBLE")
FE_SubType.Insert("berserker", "CREATURE_TYPE_BERSERKER")
FE_SubType.Insert("bird", "CREATURE_TYPE_BIRD")
FE_SubType.Insert("blinkmoth", "CREATURE_TYPE_BLINKMOTH")
FE_SubType.Insert("boar", "CREATURE_TYPE_BOAR")
FE_SubType.Insert("bringer", "CREATURE_TYPE_BRINGER")
FE_SubType.Insert("brushwagg", "CREATURE_TYPE_BRUSHWAGG")
FE_SubType.Insert("camarid", "CREATURE_TYPE_CAMARID")
FE_SubType.Insert("camel", "CREATURE_TYPE_CAMEL")
FE_SubType.Insert("caribou", "CREATURE_TYPE_CARIBOU")
FE_SubType.Insert("carrier", "CREATURE_TYPE_CARRIER")
FE_SubType.Insert("cat", "CREATURE_TYPE_CAT")
FE_SubType.Insert("centaur", "CREATURE_TYPE_CENTAUR")
FE_SubType.Insert("cephalid", "CREATURE_TYPE_CEPHALID")
FE_SubType.Insert("chimera", "CREATURE_TYPE_CHIMERA")
FE_SubType.Insert("citizen", "CREATURE_TYPE_CITIZEN")
FE_SubType.Insert("cleric", "CREATURE_TYPE_CLERIC")
FE_SubType.Insert("cockatrice", "CREATURE_TYPE_COCKATRICE")
FE_SubType.Insert("construct", "CREATURE_TYPE_CONSTRUCT")
FE_SubType.Insert("coward", "CREATURE_TYPE_COWARD")
FE_SubType.Insert("crab", "CREATURE_TYPE_CRAB")
FE_SubType.Insert("crocodile", "CREATURE_TYPE_CROCODILE")
FE_SubType.Insert("cyclops", "CREATURE_TYPE_CYCLOPS")
FE_SubType.Insert("dauthi", "CREATURE_TYPE_DAUTHI")
FE_SubType.Insert("demon", "CREATURE_TYPE_DEMON")
FE_SubType.Insert("deserter", "CREATURE_TYPE_DESERTER")
FE_SubType.Insert("devil", "CREATURE_TYPE_DEVIL")
FE_SubType.Insert("djinn", "CREATURE_TYPE_DJINN")
FE_SubType.Insert("dragon", "CREATURE_TYPE_DRAGON")
FE_SubType.Insert("drake", "CREATURE_TYPE_DRAKE")
FE_SubType.Insert("dreadnought", "CREATURE_TYPE_DREADNOUGHT")
FE_SubType.Insert("drone", "CREATURE_TYPE_DRONE")
FE_SubType.Insert("druid", "CREATURE_TYPE_DRUID")
FE_SubType.Insert("dryad", "CREATURE_TYPE_DRYAD")
FE_SubType.Insert("dwarf", "CREATURE_TYPE_DWARF")
FE_SubType.Insert("efreet", "CREATURE_TYPE_EFREET")
FE_SubType.Insert("egg", "CREATURE_TYPE_EGG")
FE_SubType.Insert("elder", "CREATURE_TYPE_ELDER")
FE_SubType.Insert("elemental", "CREATURE_TYPE_ELEMENTAL")
FE_SubType.Insert("elephant", "CREATURE_TYPE_ELEPHANT")
FE_SubType.Insert("elf", "CREATURE_TYPE_ELF")
FE_SubType.Insert("elk", "CREATURE_TYPE_ELK")
FE_SubType.Insert("eye", "CREATURE_TYPE_EYE")
FE_SubType.Insert("faerie", "CREATURE_TYPE_FAERIE")
FE_SubType.Insert("ferret", "CREATURE_TYPE_FERRET")
FE_SubType.Insert("fish", "CREATURE_TYPE_FISH")
FE_SubType.Insert("flagbearer", "CREATURE_TYPE_FLAGBEARER")
FE_SubType.Insert("fox", "CREATURE_TYPE_FOX")
FE_SubType.Insert("frog", "CREATURE_TYPE_FROG")
FE_SubType.Insert("fungus", "CREATURE_TYPE_FUNGUS")
FE_SubType.Insert("gargoyle", "CREATURE_TYPE_GARGOYLE")
FE_SubType.Insert("giant", "CREATURE_TYPE_GIANT")
FE_SubType.Insert("gnome", "CREATURE_TYPE_GNOME")
FE_SubType.Insert("goat", "CREATURE_TYPE_GOAT")
FE_SubType.Insert("goblin", "CREATURE_TYPE_GOBLIN")
FE_SubType.Insert("golem", "CREATURE_TYPE_GOLEM")
FE_SubType.Insert("gorgon", "CREATURE_TYPE_GORGON")
FE_SubType.Insert("graveborn", "CREATURE_TYPE_GRAVEBORN")
FE_SubType.Insert("gremlin", "CREATURE_TYPE_GREMLIN")
FE_SubType.Insert("griffin", "CREATURE_TYPE_GRIFFIN")
FE_SubType.Insert("hag", "CREATURE_TYPE_HAG")
FE_SubType.Insert("harpy", "CREATURE_TYPE_HARPY")
FE_SubType.Insert("hellion", "CREATURE_TYPE_HELLION")
FE_SubType.Insert("hippo", "CREATURE_TYPE_HIPPO")
FE_SubType.Insert("homarid", "CREATURE_TYPE_HOMARID")
FE_SubType.Insert("homunculus", "CREATURE_TYPE_HOMUNCULUS")
FE_SubType.Insert("horror", "CREATURE_TYPE_HORROR")
FE_SubType.Insert("horse", "CREATURE_TYPE_HORSE")
FE_SubType.Insert("hound", "CREATURE_TYPE_HOUND")
FE_SubType.Insert("hydra", "CREATURE_TYPE_HYDRA")
FE_SubType.Insert("illusion", "CREATURE_TYPE_ILLUSION")
FE_SubType.Insert("imp", "CREATURE_TYPE_")
FE_SubType.Insert("incarnation", "CREATURE_TYPE_INCARNATION")
FE_SubType.Insert("insect", "CREATURE_TYPE_INSECT")
FE_SubType.Insert("jellyfish", "CREATURE_TYPE_JELLYFISH")
FE_SubType.Insert("juggernaut", "CREATURE_TYPE_JUGGERNAUT")
FE_SubType.Insert("kavu", "CREATURE_TYPE_KAVU")
FE_SubType.Insert("kirin", "CREATURE_TYPE_KIRIN")
FE_SubType.Insert("kithkin", "CREATURE_TYPE_KITHKIN")
FE_SubType.Insert("knight", "CREATURE_TYPE_KNIGHT")
FE_SubType.Insert("kobold", "CREATURE_TYPE_KOBOLD")
FE_SubType.Insert("kor", "CREATURE_TYPE_KOR")
FE_SubType.Insert("kraken", "CREATURE_TYPE_KRAKEN")
FE_SubType.Insert("lammasu", "CREATURE_TYPE_LAMMASU")
FE_SubType.Insert("leech", "CREATURE_TYPE_LEECH")
FE_SubType.Insert("leviathan", "CREATURE_TYPE_LEVIATHAN")
FE_SubType.Insert("lhurgoyf", "CREATURE_TYPE_LHURGOYF")
FE_SubType.Insert("licid", "CREATURE_TYPE_LICID")
FE_SubType.Insert("lizard", "CREATURE_TYPE_LIZARD")
FE_SubType.Insert("manticore", "CREATURE_TYPE_MANTICORE")
FE_SubType.Insert("masticore", "CREATURE_TYPE_MASTICORE")
FE_SubType.Insert("mercenary", "CREATURE_TYPE_MERCENARY")
FE_SubType.Insert("merfolk", "CREATURE_TYPE_MERFOLK")
FE_SubType.Insert("metathran", "CREATURE_TYPE_METATHRAN")
FE_SubType.Insert("minion", "CREATURE_TYPE_MINION")
FE_SubType.Insert("minotaur", "CREATURE_TYPE_MINOTAUR")
FE_SubType.Insert("monger", "CREATURE_TYPE_MONGER")
FE_SubType.Insert("mongoose", "CREATURE_TYPE_MONGOOSE")
FE_SubType.Insert("monk", "CREATURE_TYPE_MONK")
FE_SubType.Insert("moonfolk", "CREATURE_TYPE_MOONFOLK")
FE_SubType.Insert("mutant", "CREATURE_TYPE_MUTANT")
FE_SubType.Insert("myr", "CREATURE_TYPE_MYR")
FE_SubType.Insert("mystic", "CREATURE_TYPE_MYSTIC")
FE_SubType.Insert("nautilus", "CREATURE_TYPE_NAUTILUS")
FE_SubType.Insert("nephilim", "CREATURE_TYPE_NEPHILIM")
FE_SubType.Insert("nightmare", "CREATURE_TYPE_NIGHTMARE")
FE_SubType.Insert("nightstalker", "CREATURE_TYPE_NIGHTSTALKER")
FE_SubType.Insert("ninja", "CREATURE_TYPE_NINJA")
FE_SubType.Insert("nomad", "CREATURE_TYPE_NOMAD")
FE_SubType.Insert("octopus", "CREATURE_TYPE_OCTOPUS")
FE_SubType.Insert("ogre", "CREATURE_TYPE_OGRE")
FE_SubType.Insert("ooze", "CREATURE_TYPE_OOZE")
FE_SubType.Insert("orb", "CREATURE_TYPE_ORB")
FE_SubType.Insert("orc", "CREATURE_TYPE_ORC")
FE_SubType.Insert("orgg", "CREATURE_TYPE_ORGG")
FE_SubType.Insert("ouphe", "CREATURE_TYPE_OUPHE")
FE_SubType.Insert("ox", "CREATURE_TYPE_OX")
FE_SubType.Insert("oyster", "CREATURE_TYPE_OYSTER")
FE_SubType.Insert("pegasus", "CREATURE_TYPE_PEGASUS")
FE_SubType.Insert("pentavite", "CREATURE_TYPE_PENTAVITE")
FE_SubType.Insert("pest", "CREATURE_TYPE_PEST")
FE_SubType.Insert("phelddagrif", "CREATURE_TYPE_PHELDDAGRIF")
FE_SubType.Insert("phoenix", "CREATURE_TYPE_PHOENIX")
FE_SubType.Insert("pincher", "CREATURE_TYPE_PINCHER")
FE_SubType.Insert("pirate", "CREATURE_TYPE_PIRATE")
FE_SubType.Insert("plant", "CREATURE_TYPE_PLANT")
FE_SubType.Insert("prism", "CREATURE_TYPE_PRISM")
FE_SubType.Insert("rabbit", "CREATURE_TYPE_RABBIT")
FE_SubType.Insert("rat", "CREATURE_TYPE_RAT")
FE_SubType.Insert("rebel", "CREATURE_TYPE_REBEL")
FE_SubType.Insert("reflection", "CREATURE_TYPE_REFLECTION")
FE_SubType.Insert("rhino", "CREATURE_TYPE_RHINO")
FE_SubType.Insert("rigger", "CREATURE_TYPE_RIGGER")
FE_SubType.Insert("rogue", "CREATURE_TYPE_ROGUE")
FE_SubType.Insert("salamander", "CREATURE_TYPE_SALAMANDER")
FE_SubType.Insert("samurai", "CREATURE_TYPE_SAMURAI")
FE_SubType.Insert("sand", "CREATURE_TYPE_SAND")
FE_SubType.Insert("saproling", "CREATURE_TYPE_SAPROLING")
FE_SubType.Insert("satyr", "CREATURE_TYPE_SATYR")
FE_SubType.Insert("scarecrow", "CREATURE_TYPE_SCARECROW")
FE_SubType.Insert("scorpion", "CREATURE_TYPE_SCORPION")
FE_SubType.Insert("scout", "CREATURE_TYPE_SCOUT")
FE_SubType.Insert("serf", "CREATURE_TYPE_SERF")
FE_SubType.Insert("serpent", "CREATURE_TYPE_SERPENT")
FE_SubType.Insert("shade", "CREATURE_TYPE_SHADE")
FE_SubType.Insert("shaman", "CREATURE_TYPE_SHAMAN")
FE_SubType.Insert("shapeshifter", "CREATURE_TYPE_SHAPESHIFTER")
FE_SubType.Insert("sheep", "CREATURE_TYPE_SHEEP")
FE_SubType.Insert("skeleton", "CREATURE_TYPE_SKELETON")
FE_SubType.Insert("slith", "CREATURE_TYPE_SLITH")
FE_SubType.Insert("sliver", "CREATURE_TYPE_SLIVER")
FE_SubType.Insert("slug", "CREATURE_TYPE_SLUG")
FE_SubType.Insert("snake", "CREATURE_TYPE_SNAKE")
FE_SubType.Insert("soldier", "CREATURE_TYPE_SOLDIER")
FE_SubType.Insert("soltari", "CREATURE_TYPE_SOLTARI")
FE_SubType.Insert("spawn", "CREATURE_TYPE_SPAWN")
FE_SubType.Insert("specter", "CREATURE_TYPE_SPECTER")
FE_SubType.Insert("spellshaper", "CREATURE_TYPE_SPELLSHAPER")
FE_SubType.Insert("sphinx", "CREATURE_TYPE_SPHINX")
FE_SubType.Insert("spider", "CREATURE_TYPE_SPIDER")
FE_SubType.Insert("spike", "CREATURE_TYPE_SPIKE")
FE_SubType.Insert("spirit", "CREATURE_TYPE_")
FE_SubType.Insert("splinter", "CREATURE_TYPE_SPLINTER")
FE_SubType.Insert("sponge", "CREATURE_TYPE_SPONGE")
FE_SubType.Insert("squid", "CREATURE_TYPE_SQUID")
FE_SubType.Insert("squirrel", "CREATURE_TYPE_SQUIRREL")
FE_SubType.Insert("starfish", "CREATURE_TYPE_STARFISH")
FE_SubType.Insert("survivor", "CREATURE_TYPE_SURVIVOR")
FE_SubType.Insert("tetravite", "CREATURE_TYPE_TETRAVITE")
FE_SubType.Insert("thalakos", "CREATURE_TYPE_THALAKOS")
FE_SubType.Insert("thopter", "CREATURE_TYPE_THOPTER")
FE_SubType.Insert("thrull", "CREATURE_TYPE_THRULL")
FE_SubType.Insert("treefolk", "CREATURE_TYPE_TREEFOLK")
FE_SubType.Insert("triskelavite", "CREATURE_TYPE_TRISKELAVITE")
FE_SubType.Insert("troll", "CREATURE_TYPE_TROLL")
FE_SubType.Insert("turtle", "CREATURE_TYPE_TURTLE")
FE_SubType.Insert("unicorn", "CREATURE_TYPE_UNICORN")
FE_SubType.Insert("vampire", "CREATURE_TYPE_VAMPIRE")
FE_SubType.Insert("vedalken", "CREATURE_TYPE_VEDALKEN")
FE_SubType.Insert("viashino", "CREATURE_TYPE_VIASHINO")
FE_SubType.Insert("volver", "CREATURE_TYPE_VOLVER")
FE_SubType.Insert("wall", "CREATURE_TYPE_WALL")
FE_SubType.Insert("warrior", "CREATURE_TYPE_WARRIOR")
FE_SubType.Insert("weird", "CREATURE_TYPE_WEIRD")
FE_SubType.Insert("whale", "CREATURE_TYPE_WHALE")
FE_SubType.Insert("wizard", "CREATURE_TYPE_WIZARD")
FE_SubType.Insert("wolf", "CREATURE_TYPE_WOLF")
FE_SubType.Insert("wolverine", "CREATURE_TYPE_WOLVERINE")
FE_SubType.Insert("wombat", "CREATURE_TYPE_WOMBAT")
FE_SubType.Insert("worm", "CREATURE_TYPE_WORM")
FE_SubType.Insert("wraith", "CREATURE_TYPE_WRAITH")
FE_SubType.Insert("wurm", "CREATURE_TYPE_WURM")
FE_SubType.Insert("yeti", "CREATURE_TYPE_YETI")
FE_SubType.Insert("zombie", "CREATURE_TYPE_ZOMBIE")
FE_SubType.Insert("zubera", "CREATURE_TYPE_ZUBERA")
FE_SubType.Insert("ally", "CREATURE_TYPE_ALLY")
FE_SubType.Insert("trap", "CREATURE_TYPE_TRAP")
FE_SubType.Insert("eldrazi", "CREATURE_TYPE_ELDRAZI")
FE_SubType.Insert("praetor", "CREATURE_TYPE_PRAETOR")
FE_SubType.Insert("werewolf", "CREATURE_TYPE_WEREWOLF")

StringReplace, AbilityText, AbilityText, %CardName%, CARDNAME, ALL

CurrentIndex := 0
Actions := 0

Loop, Parse, AbilityText, .
{
   CurrentIndex += 1
   AbilityList[CurrentIndex] := A_LoopField
   Loop, Parse, A_LoopField, %A_Space%
   {
      StringLower, LoopField, A_LoopField
      If ( SubjectList[CurrentIndex] = "" )
      {
         If SubjectDicationary.HasKey(LoopField)
         {
            SubjectList[CurrentIndex] = SubjectDictionary[LoopField]
            Continue
         }
      }
      If ( VerbDictionary.HasKey(LoopField) )
      {
         VerbList[CurrentIndex] := VerbDictionary[LoopField]
         Actions += 1
         Continue
      } Else If ( ObjectDictionary.HasKey(LoopField) )
      {
         ObjectList[CurrentIndex] := ObjectDictionary[LoopField]
         Continue
      } Else If ( DetailsDictionary.HasKey(LoopField) or DetailsDictionary.HasKey(SubStr(LoopField, 4, StrLen(LoopField)-3)) or FE_Type.HasKey(LoopField) or FE_Type.HasKey(SubStr(LoopField, 4, StrLen(LoopField)-3)) or FE_SubType.HasKey(LoopField) or FE_SubType.HasKey(SubStr(LoopField, 4, StrLen(LoopField)-3)) or FE_SuperType.HasKey(LoopField) or FE_SuperType.HasKey(SubStr(LoopField, 4, StrLen(LoopField)-3)) or FE_Misc.HasKey(LoopField))
      {
         AddDetails(CurrentIndex, LoopField)
         Continue
      } Else If ToNumber(LoopField) is Number
      {
         AddDetails(CurrentIndex, ToNumber(LoopField))
         Continue
      }
   }
}
Index := 1
CurrentAbilityType := ""
CurrentActionType := ""
While ( Index <= Actions )
{
   ;MsgBox, %Index%/%Actions%
   Ability := AbilityList[Index]
   Subject := SubjectList[Index]
   Verb := VerbList[Index]
   Object := ObjectList[Index]
   Details := DetailsList[Index]
   Details1 := Details[1]
   Details2 := Details[2]
   ;MsgBox, Ability: %Ability%`nSubject: %Subject%`nVerb: %Verb%`nObject: %Object%`nDetails1: %Details1%`nDetails2: %Details2%
   Code := ""
   
   If ( Subject = "" )
   {
      Subject := "EffectController()"
   }
   Code .= OpenAbilityBlock(Ability) . "`n"
   Code .= PerformAction(Subject, Object, Verb, Details) . "`n"
   Code .= CloseAbilityBlock() . "`n"
   
   CodeFinal .= Code . "`n"
   Index += 1
}
OldClipboard := Clipboard
Clipboard := CodeFinal
While ( Clipboard = CodeFinal )
{
   Sleep, 1
}
Clipboard := OldClipboard
ExitApp

ToNumber(String)
{
   If String is Number
   {
      Return String
   } Else If ( String = "a" or String = "an" or String = "one" )
   {
      Return 1
   } Else If ( String = "two" )
   {
      Return 2
   } Else If ( String = "three" )
   {
      Return 3
   } Else If ( String = "four" )
   {
      Return 4
   } Else If ( String = "five" )
   {
      Return 5
   } Else If ( String = "six" )
   {
      Return 6
   } Else If ( String = "seven" )
   {
      Return 7
   } Else If ( String = "eight" )
   {
      Return 8
   } Else If ( String = "nine" )
   {
      Return 9
   } Else If ( String = "ten" )
   {
      Return 10
   } Else
   {
      Return NotANumber
   }
}

AddDetails(Index, Detail)
{
   Global
   If ( DetailsList[Index].MaxIndex() = "" )
   {
      DetailsList[Index] := Object()
   }
   DetailsList[Index].Insert(Detail)
}

OpenAbilityBlock(Ability)
{
   Global
   IfInString, Ability, :
   {
      CurrentAbilityType := "<ACTIVATED_ABILITY>"
      Return "<ACTIVATED_ABILITY>"
   } Else If ( SubStr(Ability, 1, 5) = "When " or SubStr(Ability, 1, 9) = "Whenever " or SubStr(Ability, 1, 3) = "If " or SubStr(Ability, 1, 3) = "At " )
   {
      CurrentAbilityType := "<TRIGGERED_ABILITY>"
      Return "<TRIGGERED_ABILITY>"
   } Else
   {
      CurrentAbilityType := "<SPELL_ABILITY>"
      Return "<SPELL_ABILITY>"
   }
}

CloseAbilityBlock()
{
   Global
   AbilityCloseTag := "</" . SubStr(CurrentAbilityType, 2, StrLen(CurrentAbilityType)-1)
   CurrentAbilityType = ""
   Return AbilityCloseTag
}

OpenActionBlock(Verb)
{
   Global
   If ( ResolutionVerbs.HasKey(Verb) )
   {
      CurrentActionType := "<RESOLUTION_TIME_ACTION>"
      Return "<RESOLUTION_TIME_ACTION>"
   } Else If ( ContinuousVerbs.HasKey(Verb) )
   {
      CurrentActionType := "<CONTINUOUS_ACTION>"
      Return "<CONTINUOUS_ACTION>"
   }
   CurrentActionType := ""
   Return ""
}

CloseActionBlock()
{
   Global
   ActionCloseTag := "</" . SubStr(CurrentActionType, 2, StrLen(CurrentActionType)-1)
   CurrentActionType = ""
   Return ActionCloseTag
}

HasValue(Object, Value)
{
   For Index, Element in Object
   {
      If ( Element = Value )
      {
         Return True
      }
   }
   Return False
}

If FE_Type.HasKey("creature")
{
   MsgBox, FE_Type has key: creature
}

FilterLookUp(Type)
{
   Global
   StringUpper, TypeUpper, Type
   If ( SubStr(Type, 1, 3) = "non" )
   {
      StringTrimLeft, Type, Type, 3
      Operator := "OP_NOT"
   } Else
   {
      Operator := "OP_IS"
   }
   If FE_Type.HasKey(Type)
   {
      Return "FE_TYPE, " . Operator . ", " . FE_Type[Type]
   } Else If FE_SubType.HasKey(Type)
   {
      Return "FE_SUBTYPE, " . Operator . ", " . FE_SubType[Type]
   } Else If FE_SuperType.HasKey(Type)
   {
      Return "FE_SUPERTYPE, " . Operator . ", " . FE_SuperType[Type]
   }   Else If FE_Misc.HasKey(Type)
   {
      Return FE_Misc[Type]
   }
   MsgBox, Not found
}

PerformAction(Subject, Object, Verb, Details)
{
   Global
   If ( Object = "target" )
   {
      LocalIndex := 1
      While ( LocalIndex <= Details.MaxIndex() )
      {
         DetailsTemp := Details[LocalIndex]
         StringUpper, TargetTypeTemp, DetailsTemp
         TargetType := TargetType = "" ? TargetTypeTemp : TargetType . "_" . TargetTypeTemp
         LocalIndex += 1
      }
      StringUpper, VerbUpper, Verb
      Code .= "<TARGET tag=""CARD_QUERY_CHOOSE_" . TargetType . "_TO_" . VerbUpper . """ definition=""0"" compartment=""0"" count=""1"" />`n"
      Code .= "<TARGET_DEFINITION id=""0"">`n"
      Code .= "local filter = ClearFilter()`n"
      LocalIndex := 1
      While ( LocalIndex <= Details.MaxIndex() )
      {
         Code .= "filter:Add( " . FilterLookUp(Details[LocalIndex]) . ")`n"
         LocalIndex += 1
      }
      Code .= "</TARGET_DEFINITION>`n"
      Code .= OpenActionBlock(Verb) . "`n"
      Code .= "local target = EffectDC():Get_Targets(0) and EffectDC():Get_Targets(0):Get_CardPtr(0)`n"
      Code .= "if target ~= nil then`n"
      OpenEnded += 1
   } Else
   {
      Code .= OpenActionBlock(Verb) . "`n"
   }
   If ( Verb = "destroy" )
   {
      Code .= Object . ":Destroy()`n"
   } Else If ( Verb = "draw" )
   {
      Code .= Subject . ":DrawCards(" . Details[1] . ")`n"
   } Else If ( Verb = "life" )
   {
      First := Details[1]
      Second := Details[2]
      If ( First = "gain" or Second = "gain" )
      {
         Function := "GainLife"
      } Else If ( First = "lose" or Second = "lose" )
      {
         Function := "LoseLife"
      }
      If First is Number
      {
         Amount := First
      } Else If Second is Number
      {
         Amount := Second
      }
      If ( ( Function = "GainLife" or Function = "LoseLife" ) and (Amount != "" ) )
      {
         Code .=  Subject . ":" . Function . "(" . Amount . ")`n"
      }
   }
   While ( OpenEnded > 0 )
   {
      Code .= "end`n"
      OpenEnded -= 1
   }
   Code .= CloseActionBlock()
}
_______________________________
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
User avatar
Xander9009
Programmer
 
Posts: 2905
Joined: 29 Jun 2013, 07:44
Location: Indiana, United States
Has thanked: 121 times
Been thanked: 445 times

Re: I'm Insane: An auto-coding tool

Postby RiiakShiNal » 08 May 2015, 23:00

Well, I'll state that you're less insane than I am. It is a sound idea, you acknowledge that you will likely hit an upper limit to what can be done, you found a project that you wanted to do (which will likely be appreciated by several members of the community), and you have already shared your source code (that based on your basic tests appears to be working). On the bonus side you started small.
RiiakShiNal
Programmer
 
Posts: 2185
Joined: 16 May 2011, 21:37
Has thanked: 75 times
Been thanked: 497 times


Return to Programming Talk

Who is online

Users browsing this forum: No registered users and 22 guests


Who is online

In total there are 22 users online :: 0 registered, 0 hidden and 22 guests (based on users active over the past 10 minutes)
Most users ever online was 4143 on 23 Jan 2024, 08:21

Users browsing this forum: No registered users and 22 guests

Login Form