Wagic DeckBuilder v1.2.7 (09/04/11)

All add-on programm and tools for wagic
Locked
Laylong
Posts: 51
Joined: Fri Aug 05, 2011 11:52 pm
Location: Innistrad
Contact:

Wagic DeckBuilder v1.2.7 (09/04/11)

Post by Laylong »

*** UPDATE ***
This is the first official release of Wagic Deck Builder:
http://cardboardboxstudios.zzl.org/Projects_Wagic.html
or
http://www.mediafire.com/file/flmt2dvhz ... _1.2.7.exe
Download here for the installer.
Program comes with the Deck Builder .exe and .py versions. This version is considered stable from my testing, so please if there are any bugs/crashes, report them here so I can fix them asap. Also included are 2 sample decks, Ajani Goldmane from AvN, and a modification of a deck from mtgvault called Killer Wolves (first strike + death touch wolves).

This program is a python script designed to build deck files for those who want to quickly assemble decks without working from within the game. This is ideal for searching your current edition of Wagic for supported cards and which sets they appear in. This is simply a working beta that does all I needed. Later features I'll add include:
-Fine tuned file output
-Improved user interface
-Wider error prevention handling (so your typos don't mess with your files, and program shouldn't crash)
-Fine tuned deck loading ( in case of non "Grizzly Bear (M10) *4" style file imports )
-Actual deck stats, not just deck size and card list
-Perhaps more!

*** Updated ***
There are 2 other python scripts currently compiled into this distribution. The first is a not complete custom set creator. This may or may not work, I can't remember what state that version is, you can mostly ignore it. The other however is a batch image resizer. I also don't remember what condition I left that in, but it may be more useful or at least easily (to a python scripter) be put into a working condition. These are projects that I'm working on and will likely also be refined, fixed, and distributed with the Deck Builder later. For now my intention is to just release the Deck Builder.

How to use:
-Requirements: Wagic (preferred windows version)

-Starting: Copy this code into a .py file (create a .txt file and rename the extension to .py, then open with notepad or likewise text program). Then create in the same folder as this program, a folder named "WDB" (caps, unless you change the first line inside printDeck() accordingly)

-Running: Open the program. If for any reason at any time the program crashes (closes immediately) you can use C: command to open the file by typing "cd C:<fulldirectorypathto>WagicDB.py" and it will explain the bug. If you're not a python programmer you can reply what it tells you and I'll keep record of such bugs.

-Changing Deck Details: Using menu 0 and 1 respectively give you options to name the deck and to give it a description. If none is set, there will be a default. Keep this in mind if you don't set one and print a deck. The next deck you print without setting the name will overwrite the previous.

-Adding Cards: Menu option 2 is to enter add card mode. From here, type in the card name you're looking for. Later features should include aided auto-correct features like capitalization correction, auto finish (ie typing kitsune will result in a list of all cards with "Kitsune" in their name). Until then, fully type out the card name with correct capitalization. If the card is supported, a list of sets will print out like: ['XXX'],['10E'],['M12']. To select a set, ignore XXX and and count each occurrence. Say you want the M12 edition to the card you just picked, Ignore XXX, 10E is 1, so press 2 and hit enter. Later editions will make this easier by writing out the full name of the sets (like ARC being Arch Enemy). Now finally choose how many. Sorry Relentless Rats users, but at the moment you'll have to manually set your copies. Only basic lands do not have a limit.
-Exiting Add Cards: Type "done" (without quotes) when complete.

-Checking Deck: Option 3 is to show the deck. This is a good way to check your land v spell break and total card count to the deck. This will be expanded later to be more purposeful.

-Print Deck: Once you've got everything ready to save, option 4 will print your deck to a text file (if left unchanged) to your WDB directory. Decks will be saved as their name.

-Load Deck: As long as you have a wagic supported deck.txt file in the WDB folder, you can type in its name (filename minus the .txt extension) and Wagic DeckBuilder will load up the deck name, description, and cards (editions and copies)

-Using Decks: Once you have your deck file, go to your wagic directory, navigate into your profiles/<yourprofile> directory. Place all saved decks into this folder and change their file names accordingly: every deck stored in this folder needs to be named "deck#.txt" where # is a consecutive number. For example: if you only have 1 deck: deck1.txt. if you later add 2 decks and keep the first: rename each new deck respectively as deck2.txt and deck3.txt.

Keep in mind, this is still fairly early beta. There's obviously error handling lacking. Comments and bug reports welcome.

Last update: 01/29/12

Code: Select all

# ------ Wagic Deck Builder ------ #
# -------------------------------- #
#        Created by Laylong        #
#  Designed for use with Wololo's  #
#       Wagic the homebrew         #
# -------------------------------- #

import os
theDeck = ["DeckName","The deck description"]
Version = "1.2.9" # Beta
WthDir = "Wagic0160"
dStats = [0,[],[],[]]  # x, [], [], []
# x - number of cards in deck
# ['G','W','B','R','U','C'] - deck uses listed colors
# [g,w,b,r,u,c] - deck has these many lands
# [g,w,b,r,u,c] - deck has these many spells
moreCards = True

infile = open("WagicInfo.txt")
lines = infile.read()
infile.close()
lines = lines.split("\n")
WthDir = lines[0]

def main():
    os.system("cls")
    print 'This is the Wagic Deck Builder [' + Version + ']'
    features = ["Set Name","Set Description","Add Card","Show Deck","Print Deck","Load Deck","Empty Deck","Exit"]
    run = True
    while run:
        print ".[" + theDeck[0] + "]."
        menu = 0
        while menu >= 0 and menu <= len(features):
            opt = 0
            for i in features:
                print str(opt) + ": " + i
                opt = opt + 1
            menu = raw_input('> ')
        choice = features[int(menu)]
        os.system("cls")
        if choice == "Add Card":
            global moreCards
            moreCards = True
            while(moreCards):
                addCard()
        elif choice == "Set Name":
            setName()
        elif choice == "Set Description":
            setDesc()
        elif choice == "Show Deck":
            showDeck()
        elif choice == "Print Deck":
            printDeck()
        elif choice == "Show Stats":
            showStats()
        elif choice == "Load Deck":
            readDeck()
        elif choice == "Empty Deck":
            clearDeck()
        elif choice == "func(test)":
            readDeck()
        elif choice == "Exit":
            run = False;
        else:
            print "Choice [" + choice + "] is not valid or available."
    
    #raw_input("End")  # Dont need if runing from batch
   
def setName():  
    theDeck[0] = raw_input('What will you name this deck?\n> ')
    print "\nOk, so " + theDeck[0] + " it is."
 
def setDesc():
    theDeck[1] = raw_input('How shall you describe this deck?\n> ') 
    print "\n" + theDeck[1][:len(theDeck[1])/2] + "..blah blah, yea, ok, sounds good to me." 
    
def addCard():
    bLands = ["Forest","Plains","Swamp","Mountain","Island"]
    cardIsLand = False
    setAlpha = False
    setDigit = False
    
    search = raw_input('Card?\n' + str(dStats[0]) + '> ') 
    if search == "done" or search == "exit":
       global moreCards
       moreCards = False
       return 0
    elif search == "cls" or search == "clear":
        os.system("cls")
        return 0
        
        
    search = propCap(search)
    if supportedCard(search):
        pSets = findCard(search)
        if "Done" in pSets:
            global moreCards
            moreCards = False
            return 0
        else:
            print pSets
        use = -1  
        agree = ""
        
        while not (setDigit or setAlpha):        # While not yet alpha or digit selection
            use = raw_input('Pick a set this card appears in.\n> ')
            if use.isdigit() and int(use) in range(len(pSets)):
                if len(pSets) > 10:
                    agree = raw_input("Use " + pSets[int(use)] + " for this card? Y/N \n>")
                    if agree == "y" or agree == "Y" or agree == "yes":
                        setDigit = True
                else:
                    setDigit = True
            elif use in ["10E","9ED","8ED","7ED","6ED","5ED","5DN","4ED","3ED","2ED"]:  # These count as isDigit
                setAlpha = True
            elif use.isalpha():
                for item in pSets:
                    if use == item:
                        setAlpha = True
                        break
                        
                        
        for item in bLands:                      # check each land type
            if search == item:                   # against being the searched card  
                cardIsLand = True
        num = -1
        if not cardIsLand:
            while True:
                num = raw_input('And how many will you use?\n> ')
                if num.isdigit() and int(num) in range(5): #break out condition
                    break
        else:
            while True:
                num = raw_input('And how many will you use?\n> ')
                if num.isdigit() and num >= 1:
                    break
                
        dStats[0] = dStats[0] + int(num)
        
        if setDigit:
            cardinfo = [search,pSets[int(use)],num]
        elif setAlpha:
            cardinfo = [search,use,num]
        else:
            cardinfo = [search,"XXX",num]
        print cardinfo
        global theDeck
        theDeck.append(cardinfo)
    
    else:
        print search + " is not a supported card"

def removeCard():
    if len(theDeck) > 2:
        deckToScreen()
        remove = raw_input("Card name?\n>")
        print "Code not complete"
    else:
        print "There are no cards to remove."

def clearDeck():
    global theDeck
    global dStats
    dStats[0] = 0
    theDeck = ["DeckName","The deck description"]
    
        
def findCard(card):
    possSets = ["XXX"]
    
    setsdir = os.path.join(WthDir,"Res\sets")
    sets = os.listdir(setsdir)
    for i in sets:
        if len(i) == 3:
            cardfile = os.path.join(setsdir,i,"_cards.dat")
            infile = open(cardfile)
            text = infile.read()
            infile.close()
        
            index = text.find(card)
            if not index == -1:
                possSets.append(i)
                
    return possSets
    
def supportedCard(card):
    lookfor = "name=" + card
    
    primdir =  os.path.join(WthDir,"Res\sets\primitives")
    supported = primdir + "\mtg.txt"
    
    infile = open(supported)
    text = infile.read()
    infile.close()
    
    index = text.find(lookfor)
    if not index == -1:
        print "Card is currently supported in sets:"
        return True
    else:
        return False
        

def cardExtract(card):       # pull important data from a card
    lookfor = "name=" + card
    infile = open(os.path.join(WthDir,"Res\sets\primitives\mtg.txt"))
    text = infile.read()
    infile.close()
    cardData = ["name=","mana=","type=","subtype="]   # just worry about these types for now
    
    index = text.find(lookfor)
    if not index == -1:
        textCrop = text[index:]           # top trim
        indexE = textCrop.find("[/card]") # find bottom of card
        textCrop = textCrop[:indexE]      # bottom trim
        lines = textCrop.split("\n")
        for i in lines:                   # only extract what's useful
            if i[:5] == "name=":
                cardData[0] = i[i.find("=")+1:]
            elif i[:5] == "mana=":
                cardData[1] = i[i.find("=")+1:]
            elif i[:5] == "type=":
                cardData[2] = i[i.find("=")+1:]
            elif i[:8] == "subtype=":
                cardData[3] = i[i.find("=")+1:]
                
        return cardData
            
    else:
        print "Error: [" + card + "] wasn't found" 
    

def propCap(card):
    card = card.lower()
    words = card.split()
    lowers = ["of","the","to","a","in"]
    
    i = 0
    words[0] = words[0].capitalize() # not using capwords because some 
    while i < len(words):            #  words need to be lower still
        if words[i] not in lowers and i > 0:   #  thats them here
            words[i] = words[i].capitalize()
        if words[i].find("-") > 0:
            hyph = words[i].find("-")
            words[i] = words[i][:hyph+1] + words[i][hyph+1].upper() + words[i][hyph+2:]
        i += 1 
    card = " ".join(words)
    return card
        

def deckToScreen():
    # Check cards for their type
    colCreatures = []        # collection of creatures for the deck
    colSpells = []           # collection of non-creature non-lands
    colLands = []            # collection of lands
    i = 2
    longest = 0
    
    while i < len(theDeck):
        sort = cardExtract(theDeck[i][0])        # get the card info for sorting
        if sort[2] == "Creature" or sort[2] == "Legendary Creature":
            colCreatures.append(theDeck[i])
        elif sort[2] == "Basic Land" or sort[2] == "Land":
            colLands.append(theDeck[i])
        else:                # this includes all non-creature non-land spells
            colSpells.append(theDeck[i])
        if len(theDeck[i][0]) > longest:
            longest = len(theDeck[i][0])
        i += 1
    
    colCreatures.sort()
    colSpells.sort()
    # When added, Lands sorted by no. of copies
    
    for i in colCreatures:
        output = i[0] + " (" + i[1] + ")" + " " * (longest - len(i[0])) + "    *" + str(i[2]) + "\n"
        print output    
    for i in colSpells:
        output = i[0] + " (" + i[1] + ")" + " " * (longest - len(i[0])) + "    *" + str(i[2]) + "\n"
        print output
    for i in colLands:
        output = i[0] + " (" + i[1] + ")" + " " * (longest - len(i[0])) + "    *" + str(i[2]) + "\n"
        print output 
    print "\n"

def showDeck():
    spells = 0
    lands = 0
    total = 0
    bLands = ["Forest","Plains","Swamp","Mountain","Island"]
    deckToScreen()
    
    for i in theDeck[2:]:
        if i[0] in bLands:
            lands += int(i[2])
        else:
            spells += int(i[2])
            
        total = int(lands) + int(spells)
    print theDeck[0] + " has " + str(spells) + " spells and " + str(lands) + " (basic) lands."
    print "This deck contains a total of " + str(total) + " cards."
        
def printDeck():
    # Check cards for their type
    colCreatures = []        # collection of creatures for the deck
    colSpells = []           # collection of non-creature non-lands
    colLands = []            # collection of lands
    i = 2
    longest = 0
    
    while i < len(theDeck):
        sort = cardExtract(theDeck[i][0])        # get the card info for sorting
        if sort[2] == "Creature" or sort[2] == "Legendary Creature":
            colCreatures.append(theDeck[i])
        elif sort[2] == "Basic Land" or sort[2] == "Land":
            colLands.append(theDeck[i])
        else:                # this includes all non-creature non-land spells
            colSpells.append(theDeck[i])
        if len(theDeck[i][0]) > longest:
            longest = len(theDeck[i][0])
        i += 1

    colCreatures.sort()
    colSpells.sort()
    # When added, Lands sorted by no. of copies
    
    saveto = "WDB//" + theDeck[0] + ".txt"
    outfile = open(saveto,"w")
    
    output = "#NAME:" + theDeck[0] + "\n"
    outfile.write(output)
    output = "#DESC:" + theDeck[1] + "\n"
    outfile.write(output)
    output = "#This is a Wagic DeckBuilder [" + Version + "] generated file.\n"
    outfile.write(output)
    
    print "Exporting " + str(len(theDeck)-2) + " unique cards..."
        
    output = "\n# // Creatures // ...\n"
    outfile.write(output)
    for i in colCreatures:
        print "C - " + str(i)
        output = i[0] + " (" + i[1] + ")" + " " * (longest - len(i[0])) + "    *" + str(i[2]) + "\n"
        outfile.write(output)     
    output = "\n# //  Spells   // ...\n"
    outfile.write(output)
    for i in colSpells:
        print "S - " + str(i)
        output = i[0] + " (" + i[1] + ")" + " " * (longest - len(i[0])) + "    *" + str(i[2]) + "\n"
        outfile.write(output)
    output = "\n# //   Lands   // ...\n"
    outfile.write(output)
    for i in colLands:
        print "L - " + str(i)
        output = i[0] + " (" + i[1] + ")" + " " * (longest - len(i[0])) + "    *" + str(i[2]) + "\n"
        outfile.write(output) 
        
    print "\n"  


def readDeck():
    deck = raw_input("Open deck: ")
    deck = deck + ".txt"
    infile = open(os.path.join("WDB",deck))
    text = infile.read()
    infile.close()
    i = 2
    iS = 0
    iE = 0
    global theDeck
    global dStats
    
    lines = text.split("\n")
    
    theDeck[0] = lines[0][6:]          # Deck name
    theDeck[1] = lines[1][6:]          # Deck description
    if len(lines[2]) > 0 and lines[2][0] == "#":   # This is likely a WDB file
        print "Loading a WDB v(" + lines[2][30:35] +") deck."
        i = 3
    else:
        print "Loading from a handwritten file."
        i = 2
    
    while i < len(lines):
        if len(lines[i]) <= 0 or lines[i][0] == "#" or lines[i][0] == " ":       # Ignore these, they arent cards
            i = i            # don't ask
        else:
            pieces = []
            iE = lines[i].find(" (")
            pieces.append(lines[i][:iE])
            iS = iE + 2
            iE = lines[i].find(")")
            pieces.append(lines[i][iS:iE])
            iS = lines[i].find("*") + 1
            pieces.append(lines[i][iS:])
            dStats[0] = dStats[0] + int(lines[i][iS:])
            print "Adding card: " + str(pieces)
            theDeck.append(pieces)
        i += 1 
    print "\n"
    

def showStats():
    print "This deck has " + dStats[0] + " cards in it."

    
if __name__ == '__main__':
    main()
Last edited by Laylong on Mon Jan 30, 2012 12:03 am, edited 4 times in total.
http://cardboardboxstudios.zzl.org/Projects_Wagic.html
------------------------Main decks-------------------------
[W: Pride of Ajani] [G: 6000 Rings] [WGB: Redeads]
Zethfox
Posts: 3029
Joined: Thu Jun 10, 2010 11:28 pm

Re: Wagic DeckBuilder v0.1.3 (08/05/11)

Post by Zethfox »

i love you. that is all. :D :D :D :D :D :D
devi59
Posts: 157
Joined: Sat May 09, 2009 5:56 pm
Location: South Dakota, USA
Contact:

Re: Wagic DeckBuilder v0.1.3 (08/05/11)

Post by devi59 »

Zethfox wrote:i love you. that is all. :D :D :D :D :D :D
I second the love. THANKS!!
Laylong
Posts: 51
Joined: Fri Aug 05, 2011 11:52 pm
Location: Innistrad
Contact:

Re: Wagic DeckBuilder v1.2.7 (09/04/11)

Post by Laylong »

There is a new official update to WDB. Check it out, several bug fixes including but not limited to:
-extended list of returned to lowercase words (ie: "the","of","in")
-support for hyphenated words (ie: "Nacatl Hunt-Pride", even though this card is not supported yet)
-fixed issues involved with set selections
-suited your wagic directory to the file WagicInfo.txt to be supported with .exe version
http://cardboardboxstudios.zzl.org/Projects_Wagic.html
------------------------Main decks-------------------------
[W: Pride of Ajani] [G: 6000 Rings] [WGB: Redeads]
Laylong
Posts: 51
Joined: Fri Aug 05, 2011 11:52 pm
Location: Innistrad
Contact:

Re: Wagic DeckBuilder v1.2.7 (09/04/11)

Post by Laylong »

For current need, those who wish to use WDB to build their new Wagic0171 decks, here is a temporary solution. Go into wherever you installed WDB (probably C:\Program Files (x86)\Wagic Deck Builder) and change this file: WagicInfo.txt to whatever directory you have the unzipped contents of core_0171.zip into a folder named Res
like this:

Code: Select all

/<root dir>
 -/Res
  --/ai
  --/campaigns
  --/graphics
  --<etc>...
WagicInfo.txt

Code: Select all

C:\Users\Laylong\My Documents\WTH0171_Win\Wagic0171
1.2.7
Where to the above example, <root dir> = "C:\Users\Laylong\My Documents\WTH0171_Win\Wagic0171"

This is only a dirty hack method to get immediate results while I rework the system. I may also decide to change to a "search queue" method of resource loading. You can simply copy the mtg.txt into your WDB installation directory, or it will try to find a directory in your documents that contains either "wth" or "wagic", then step into it untill it finds the /sets folder it needs, handling .zip folders if needed as in the new 0171 release.
http://cardboardboxstudios.zzl.org/Projects_Wagic.html
------------------------Main decks-------------------------
[W: Pride of Ajani] [G: 6000 Rings] [WGB: Redeads]
bevis0405
Posts: 1
Joined: Wed Aug 17, 2022 7:24 am

Re: Wagic DeckBuilder v1.2.7 (09/04/11)

Post by bevis0405 »

Wagic DeckBuilder is a web-based deck building tool that's ideal for the person who likes to build decks from scratch. The tool allows you to create and manage custom decks, as well as share them with your friends and family. The program supports both standard playing card and Tarot cards, so it can be used for both Tarot and playing card readings. drift hunters 5 letter words
Locked