#English and Spanish Text Twist
#schnzrs aka aidan
print "Do not close this window!"
#These functions should import on any modern version of Python.
from random import randint
from time import time, sleep
from threading import Thread
#Just a quit function.
def quit(): raise SystemExit
#TCL is not installed in some cases!
try:
from Tkinter import *
from tkMessageBox import *
except ImportError:
#The user gets a text file message in case of tkinter/tcl fail.
errorfile=file("errorlog.txt", "w")
errorfile.write("There was an error importing tkinter graphics library. Make sure you have Tkinter installed for Python.")
errorfile.close()
#------------Global variables--------------
vowels=['a','e','i', 'o', 'u']
#This call holds global variables.
#Reasoning for storing these vars in class is that they can be updated in-function with out the function returning anything
class globalstats:
score=0
language=None
#-------Select Language Dialog and Functions------
def selectEnglish():
globalstats.language="english"
root.destroy()
def selectSpanish():
globalstats.language="spanish"
root.destroy()
#Here is the window for selecting the language.
root=Tk()
root.config(bg="light steel blue")
root.protocol("WM_DELETE_WINDOW", quit)
root.title("Select Language")
root.minsize(300,160)
root.maxsize(300,160)
l=Label(text="What language would you like to \nmake words for?", bg="light steel blue", font=("times", 12, "bold")).pack()
englishButton=Button(text="English", command=selectEnglish, font=("times", 16, "bold"), bd=4, bg="blue").place(x=110, y=50)
spanishButton=Button(text="Spanish", command=selectSpanish, font=("times", 16, "bold"), bd=4, bg="red").place(x=108, y=100)
root.mainloop()
#---------More Global Variables--------------
if globalstats.language=="english":
english=True
spanish=False
elif globalstats.language=="spanish":
english=False
spanish=True
#--------------File Testing-----------------
#The file with all the spanish or english words will be attempted to open.
try:
if spanish: f=open("res\spanishwords.txt")
elif english: f=open("res\englishwords.txt")
f.close(); del f
#Error message if failure to open the spanishwords or englishwords file.
except IOError:
root=Tk()
root.withdraw()
showerror("Oh no.", "The application failed to find the " + globalstats.language + "words.txt file. That file is required to start the program. The file could of been renamed or deleted.")
quit()
#---------------Generator Functions----------
#These functions are not made by me. These are functions from python.org.
def product(*args, **kwds):
pools = map(tuple, args) * kwds.get('repeat', 1)
result = [[]]
for pool in pools:
result = [x+[y] for x in result for y in pool]
for prod in result:
yield tuple(prod)
def permutations(iterable, r=None):
pool = tuple(iterable)
n = len(pool)
r = n if r is None else r
for indices in product(range(n), repeat=r):
if len(set(indices)) == r:
yield tuple(pool[i] for i in indices)
#---------------Core functions--------------
def randomchars():
finaltext=""
for i in range(6):
#These ranges make sure best possible char combos are made
if spanish:
num=randint(0, 194)
else:
num=randint(0, 19
if num in range(0, 26): l="a"
elif num in range(26, 32): l="b"
elif num in range(32, 40): l="c"
elif num in range(40, 53): l="d"
elif num in range(53, 67): l="e"
elif num in range(67, 69): l="f"
elif num in range(69, 72): l="h"
elif num in range(72, 85): l="i"
elif num==86: l="j"
elif num in range(85, 96): l="l"
elif num in range(96, 102): l="m"
elif num in range(102, 116): l="n"
elif num in range(118, 133): l="o"
elif num in range(133, 13
: l="p"
elif num in range(138, 140): l="q"
elif num in range(140, 155): l="r"
elif num in range(155, 171): l="s"
elif num in range(171, 182): l="t"
elif num in range(182, 191): l="u"
elif num in range(191, 193): l="v"
elif num in range(193, 194): l="y"
else: l="k"
finaltext+=l
return finaltext
def list2str(_list):
finaltext=""
for i in _list:
finaltext+=i
finaltext+= " "
return finaltext
def twist(text):
#This randomly rearranges chars.
finaltext=""
randoms=[]
count=0
while 1:
if count>5: break
while count<6:
num=randint(0, 5)
if num in randoms:
break
else:
finaltext+=text[num]
randoms.append(num)
count+=1
return finaltext
def translate(text):
#This translates something into the form of syntax the dictionairy files use.
finaltext="*"
finaltext+=text
finaltext+="#"
return finaltext
def find(text, num):
#This finds all the combos.
if spanish: f=open("res\spanishwords.txt", "r")
elif english: f=open("res\englishwords.txt", "r")
f.seek(0)
words=f.read()
f.close()
text=list(text)
#Make the generator a tuple
combos=tuple(permutations(text, num))
poswords=[]
for i in range(len(combos)):
combo=combos[i]
#Make the combos into strings.
#Before -> (("a","b","c"),("d","e","f")) After -> ("abc", "def").
combo="".join(combo)
combo2=translate(combo)
test=words.find(combo2)
if combo in poswords:
pass
elif test!=-1:
poswords.append(combo)
return poswords
def findall():
#Most powerful function in program.
#Generates near-perfect random chars from randomchars() and uses find() to find all possible words.
dofind=True
while dofind==True:
_all=[]
makechars=True
while makechars==True:
dovowel=False
chars=randomchars()
charlist=[]
#Begging checking for no duplicate chars.
for i in range(len(chars)):
if chars[i] in charlist:
#Found duplicate 
makechars=True
dovowel=False
break
elif i+1==len(chars):
#Done finding duplicates.
dovowel=True
break
else: charlist.append(chars[i])
if dovowel==True:
vowelcount=0
#Begging checking for enough voweles, this makes sure random chars can make words.
for i in range(len(chars)):
if chars[i] in vowels:
vowelcount+=1
elif i+1==len(chars) and vowelcount>=2:
#Success!
makechars=False
break
elif i+1==len(chars) and vowelcount<2:
#Not enough vowels.
makechars=True
break
elif vowelcount>3:
#Too many vowels!
makechars=True
break
else: pass
six=find(chars, 6)
five=find(chars, 5)
four=find(chars, 4)
three=find(chars, 3)
#The random chars will be added to list
_all.append(chars)
#Then all the possible words will be added
_all+=six
_all+=five
_all+=four
_all+=three
#Just a failsafe if too little words.
if len(_all)<15: pass
else: dofind=False
return _all
def gettypes(_list):
#This function gets the ammount of 3, 4, 5, and 6 letter words in a list.
three=0
four=0
five=0
six=0
for index in range(len(_list)):
strlen=len(_list[index])
if strlen==3: three+=1
elif strlen==4: four+=1
elif strlen==5: five+=1
elif strlen==6: six+=1
types=[]
types.append(three)
types.append(four)
types.append(five)
types.append(six)
return types
#-----------------GUI Functions----------------
def about(): showinfo("About", "Game made by schnzrs aka aidan. \n\nProgrammed in Python 2.7\nUses Tkinter graphics library. \n\n(C) 2011")
def _help(): showinfo("Help", "This is Text Twist in " + globalstats.language + ". You get random letters, and you must re-arrange them to make as many words as possible.")
#Starts game. Destroys home screen widgets.
def startgame():
start.destroy()
welcome.destroy()
me.destroy()
main()
def controls(): showinfo("Controls", "While your cursor is in the entry box, you can press enter to (of course) enter text. Either shift key can be pressed to twist the text.")
def main():
#This is the most important function in the whole program!
def check():
#This is another powerful function. It is pretty much the core of the game.
#It gets the text entered and tests it for correctness and scores it.
#Lets get the data then remove the user text from the box.
userchars=entry.get()
userchars=userchars.lower()
entry.delete(0, END)
length=len(userchars)
if userchars=="":
return
checkLabel.place(x=270, y=350)
if length<3:
checkLabel.config(text="Word too short!", fg="red")
return
elif length>6:
checkLabel.config(text="Word too long!", fg="red")
return
else:
#This makes sure user does not cheat and uses same word twice.
#More importantly it makes sure user used the right chars.
usedchars=[]
for index in range(length):
if userchars[index] in usedchars:
checkLabel.config(text="Wrong letters!", fg="red")
return
elif userchars[index] in list(chars):
usedchars.append(userchars[index])
else:
checkLabel.config(text="Wrong letters!", fg="red")
return
#Another anti cheat lines. This makes sure user does not enter same word over and over.
if userchars in localstats.words:
checkLabel.config(text="Word already used!", fg="red")
return
elif userchars in poswords:
localstats.words.append(userchars)
checkLabel.config(fg="blue")
if length==3:
localstats.three+=1
threeLabel.config(text=("Three Letter: " + str(localstats.three) + " of " + str(threeLetters)))
checkLabel.config(text="+100 Points!")
globalstats.score+=100
localstats.score+=100
elif length==4:
localstats.four+=1
fourLabel.config(text=("Four Letter: " + str(localstats.four) + " of " + str(fourLetters)))
checkLabel.config(text="+200 Points!")
globalstats.score+=200
localstats.score+=200
elif length==5:
localstats.five+=1
fiveLabel.config(text=("Five Letter: " + str(localstats.five) + " of " + str(fiveLetters)))
checkLabel.config(text="+500 Points!")
globalstats.score+=500
localstats.score+=500
elif length==6:
localstats.six+=1
sixLabel.config(text=("Six Letter: " + str(localstats.six) + " of " + str(sixLetters)))
checkLabel.config(text="+1000 Points!")
globalstats.score+=1000
localstats.score+=1000
lvlScoreLabel.config(text="Level Score: " + str(localstats.score))
totalScoreLabel.config(text="Total Score: " + str(globalstats.score))
#User actually did everything right... except it's not a word!
else: checkLabel.config(text="Not a word!", fg="red")
def cleanup():
lvlScoreLabel.destroy()
totalScoreLabel.destroy()
timeLabel.destroy()
checkLabel.destroy()
wordsLabel.destroy()
threeLabel.destroy()
fourLabel.destroy()
fiveLabel.destroy()
sixLabel.destroy()
charTop.destroy()
charLabel.destroy()
twistB.destroy()
enter.destroy()
entry.destroy()
#Twists the letters on screen.
def gui_twist(): charLabel.config(text=twist(chars))
#Same as above function, but used for binding events.
def bindTwist(event): gui_twist()
def end():
#This function is called when the timer runs out.
def newlvl():
newLevelButton.destroy()
scoreLabel.destroy()
timeLabel.destroy()
#The program is recursive. I know it is ugly, but I don't feel like fixing it.
main()
#Now the widgets will be destroyed.
cleanup()
missedList=missedWords()
missedStr="Words you missed are:\n\n" + list2str(missedList)
scoreLabel=Label(text="Congratulations! You got " + str(localstats.score) + " points...", font=("times", 20, "bold"), bd=3, bg="gold", relief=RAISED)
scoreLabel.place(x=100, y=50)
timeLabel=Label(text="in " + str(dTime) + " seconds!", font=("arial", 14, "italic"), bg="light steel blue")
timeLabel.place(x=230, y=100)
newLevelButton=Button(text="New Level", bd=3, font=('arial', 16, 'bold'
, bg="yellow", command=newlvl)
newLevelButton.place(x=240, y=200)
if len(missedList)==0: missedStr="Congratulations! No words missed!"
showinfo("Missed Words", missedStr)
def countdown():
#This is the function that will be threaded. It shows the amount of time left.
timeLeft=dTime
endTime=int(time()) + dTime
while endTime>int(time()):
if int(endTime-time())<11:
#Exception. This sometimes randomly fails.
try: timeLabel.config(fg="purple")
except: pass
timeStr="Time Left: " + str(int(endTime-time()))
#Sometimes this also fails. I'm not sure why. I'm adding an exception.
try: timeLabel.config(text=timeStr)
except: pass
sleep(1)
def missedWords():
#This finds the words user missed.
missed=[]
for i in poswords:
if i not in localstats.words: missed.append(i)
return missed
#Check function that is bind-able.
def bindCheck(event): check()
#All local stats (in main function) will be stored in this class.
#Reasoning for class is that variables can be updating in function without returning anything.
class localstats:
score=0
words=[]
three=0
four=0
five=0
six=0
#I am disabling this code for now. Since this app is multi-threaded, serious issues can happen.
#If the user skips the level, sometimes python will completely crash.
"""
if globalstats.updateMenu:
fileMenu.add_command(label="Skip Level", command=end)
globalstats.updateMenu=False
"""
#This is super important here. We get the random letters and the possible words.
allfound=findall()
chars=allfound[0]
poswords=allfound[1:]
#Get the amount of certain types of words (three letters words, four letters words...)
types=gettypes(poswords)
threeLetters=types[0]
fourLetters=types[1]
fiveLetters=types[2]
sixLetters=types[3]
length=len(poswords)
#This makes the time the user has to enter words until level ends.
if length<5: dTime=30
elif length>=5 and length<=10: dTime=60
elif length>=10 and length<=15: dTime=80
elif length>=15 and length<=20: dTime=100
elif length>=20 and length<=25: dTime=120
else: dTime=140
#When the countdown ends, do the end function.
#This is not in the other thread since Tkinter is not thread safe.
root.after(dTime*1000, end)
#Main labels.
charTop=Label(text="Letters are...", font=("times", 14, "italic"), bg="light steel blue")
charTop.place(x=284, y=6)
charLabel=Label(text=chars, font=("arial", 36, "bold"), bg="orange", bd=5, relief=RAISED)
charLabel.place(x=276, y=30)
checkLabel=Label(font=("times", 24, "bold"), text="", bg="light steel blue")
timeLabel=Label(font=("arial", 18, "bold"), text="", bd=4, bg="tomato", relief=RAISED)
timeLabel.place(x=275, y=185)
lvlScoreLabel=Label(font=("arial", 18, "bold"), text="Level Score: 0", bg="tomato", bd=4, relief=RAISED,)
lvlScoreLabel.place(x=275, y=235)
totalScoreLabel=Label(font=("arial", 18, "bold"), text="Total Score: " + str(globalstats.score), relief=RAISED, bg="tomato", bd=4)
totalScoreLabel.place(x=275, y=285)
#Labels for types of words found.
wordsLabel=Label(text=("Words Found"), relief=RAISED, bd=4, bg="light green", font=("times", 18, "bold"))
wordsLabel.place(x=40, y=90)
threeLabel=Label(text=("Three Letter: 0 of " + str(threeLetters)), font=('calibri', 14, 'bold'
, relief=GROOVE, bd=4, bg="light sea green")
threeLabel.place(x=30, y=140)
fourLabel=Label(text=("Four Letter: 0 of " + str(fourLetters)), font=('calibri', 14, 'bold'
,relief=GROOVE, bd=4, bg="light sea green")
fourLabel.place(x=30, y=180)
fiveLabel=Label(text=("Five Letter: 0 of " + str(fiveLetters)), font=('calibri', 14, 'bold'
,relief=GROOVE, bd=4, bg="light sea green")
fiveLabel.place(x=30, y=220)
sixLabel=Label(text=("Six Letter: 0 of " + str(sixLetters)), font=('calibri', 14, 'bold'
, relief=GROOVE, bd=4, bg="light sea green")
sixLabel.place(x=30, y=260)
#Buttons and bindings.
entry=Entry(width=15)
#If the Enter key is pressed, run the check function.
#If either Shift keys are pressed, do the twist function.
entry.bind("<Return>", bindCheck)
entry.bind("<Shift_L>", bindTwist)
entry.bind("<Shift_R>", bindTwist)
entry.place(x=310, y=110)
enter=Button(text="Enter", font=("times", 12, "bold"), bd=4, bg="yellow", command=check)
enter.place(x=294, y=140)
twistB=Button(text="Twist", font=("times", 12, "bold"), bd=4, bg="yellow", command=gui_twist)
twistB.place(x=365, y=140)
#Start the timer thread.
#Sometimes an exception is raised when the program closes.
timeThread=Thread(target=countdown)
timeThread.setDaemon(True)
timeThread.start()
#Enable this to cheat.
#print chars
#print poswords
#---------------GUI Core-------------------
#Application window.
root=Tk()
root.config(bg="light steel blue")
root.geometry("600x400")
if spanish: root.title("Spanish Text Twist")
elif english: root.title("English Text Twist")
root.minsize(600, 400)
root.maxsize(600, 400)
#Menu stuff
menuBar=Menu()
root.config(menu=menuBar)
fileMenu = Menu(menuBar)
helpMenu = Menu(menuBar)
viewMenu = Menu(menuBar)
menuBar.add_cascade(label="File", menu=fileMenu)
menuBar.add_cascade(label="Help", menu=helpMenu)
fileMenu.add_command(label="About", command=about)
fileMenu.add_command(label="Quit", command=quit)
helpMenu.add_command(label="Help", command=_help)
helpMenu.add_command(label="Controls", command=controls)
#Buttons
start=Button(text="Start Game!", bd=3, font=('arial', 14, 'bold'
, bg="yellow", command=startgame)
start.pack()
start.place(x=230, y=200)
#Labels
if spanish: welcome=Label(text="Welcome to Spanish Text Twist!", bg="orange", bd=4, relief=GROOVE, font=('cambria', 22, 'bold'
)
elif english: welcome=Label(text="Welcome to English Text Twist!", bg="orange", bd=4, relief=GROOVE, font=('cambria', 22, 'bold'
)
welcome.place(x=90, y=10)
me=Label(text="Made by schnzrs aka aidan", bg="light steel blue", font=('calibri', 12, 'italic'
)
me.place(x=220, y=60)
root.mainloop()
#English and Spanish Text Twist
#schnzrs aka aidan
print "Do not close this window!"
#These functions should import on any modern version of Python.
from random import randint
from time import time, sleep
from threading import Thread
#Just a quit function.
def quit(): raise SystemExit
#TCL is not installed in some cases!
try:
from Tkinter import *
from tkMessageBox import *
except ImportError:
#The user gets a text file message in case of tkinter/tcl fail.
errorfile=file("errorlog.txt", "w")
errorfile.write("There was an error importing tkinter graphics library. Make sure you have Tkinter installed for Python.")
errorfile.close()
[/quote]
is there a video of this showing this off?
Copyright © 2026, NextGenUpdate.
All Rights Reserved.