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()