else
set theList to a reference to theNumbers -- works if you remove "a reference to"
set theType to "number"
end if
repeat
set origList to {}
display dialog "Ready to start?" with title "Round " & roundNum
repeat with wordNum from 1 to wordCount
set w to some item of theList -- "some" doesn't seem to want to deal with a reference to a list
OK, I was able to combine the two games. The code could prabably be cleaned up and shortened. What do you think?
property memDesc : {"Seconds to memorise each word or number:" & tab & tab, ¬
"Number of words or numbers to memorise each round:" & tab & tab, ¬
"Number of characters or digits in each word or number-string:" & tab}
property memVal : {2, 4, 5}
property upperLimit : {30, 30, 24}
property lowerLimit : {1, 2, 3}
display dialog "MemoryBuilder [Extreme Edition] Version 1.0"
display dialog "Rules: You may choose how long (in seconds) to hold each word or number and how many words or numbers appear each round. Moreover, you may choose how many letters or digits appear in each word or number. The difficulty rating is ajusted to reflect your choices. Good Luck!"
to setup_game()
set selected_Item to 1
set checkChar to «data utxt2713» as Unicode text
repeat
tell memVal's items
set diffRating to 30 * (item 3) * (item 2) / (item 1) div 3
repeat with i from 1 to count
set item i to memDesc's item i & item i
end repeat
set l to it
end tell
set c to choose from list l with prompt "Set the difficulty level for this game:" with title ¬
"Current Difficulty Rating: " & diffRating default items l's item selected_Item ¬
OK button name "Edit" cancel button name "Play"
if c is false then exit repeat
tell c's item 1 to repeat with selected_Item from 1 to count l
if it is l's item selected_Item then exit repeat
end repeat
set Btn to "+"
repeat
set Btn to button returned of (display dialog memDesc's item selected_Item & ¬
memVal's item selected_Item buttons {checkChar, "-", "+"} default button Btn)
if Btn is checkChar then exit repeat
tell memVal's item selected_Item to if Btn is "+" then
if it < upperLimit's item selected_Item then ¬
set memVal's item selected_Item to it + 1
else if it > lowerLimit's item selected_Item then
set memVal's item selected_Item to it - 1
end if
end repeat
end repeat
end setup_game
to play_game()
set {showTime, wordCount, charCount} to memVal
set theWords to paragraphs of (do shell script "awk " & quoted form of ¬
("length == " & memVal's item -1) & " /usr/share/dict/words | tr \"A-Z\" \"a-z\"")
set theNumbers to "0123456789"
set roundNum to 1
display dialog "Which game would you like to play?" buttons {"Words", "Numbers", "Cancel"} default button 3
if button returned of result is "Words" then
set theList to theWords
set theType to "word"
repeat
set origList to {}
display dialog "Ready to start?" with title "Round " & roundNum
repeat with wordNum from 1 to wordCount
set w to some item of theList -- "some" doesn't seem to want to deal with a reference to a list
set origList's end to w
display dialog return & tab & tab & tab & tab & w with title ¬
"Round " & roundNum & "- " & theType & " " & wordNum & " of " & ¬
wordCount buttons {"Cancel"} giving up after showTime
end repeat
set entryForm to ""
repeat wordCount - 1 times
set entryForm to entryForm & return
end repeat
set entryList to paragraphs 1 thru wordCount of (text returned of (display dialog "Please list the " & ¬
wordCount & " " & theType & "s" & " in the correct order:" default answer entryForm) & entryForm)
set errorList to {}
repeat with i from 1 to wordCount
set origWord to origList's item i
set entryWord to entryList's item i
if origWord is not entryWord then set errorList's end to origWord & tab & tab & entryWord
end repeat
set correctCount to wordCount - (count errorList)
set roundNum to roundNum + 1
set continueBtn to "Round " & roundNum & "."
if correctCount is wordCount then
set btns to {"Cancel", continueBtn}
else
set btns to {"Cancel", "Show Errors", continueBtn}
end if
set Btn to button returned of (display dialog "Correct answers: " & (correctCount * 100 / wordCount + 0.5) ¬
div 1 & "% (" & correctCount & " of " & wordCount & ")." buttons btns default button 2)
if Btn is "Show Errors" then
choose from list errorList with prompt "Original" & tab & tab & ¬
"Entered" OK button name continueBtn with empty selection allowed
if result is false then return
end if
end repeat
else
set theList to theNumbers
set theType to "number"
repeat
set origList to {}
display dialog "Ready to start?" with title "Round " & roundNum
repeat with wordNum from 1 to wordCount
set w to ""
repeat charCount times
set w to w & some item of theList
end repeat
set origList's end to w
display dialog return & tab & tab & tab & tab & w with title ¬
"Round " & roundNum & " - " & theType & " " & wordNum & " of " & ¬
wordCount buttons {"Cancel"} giving up after showTime
end repeat
set entryForm to ""
repeat wordCount - 1 times
set entryForm to entryForm & return
end repeat
set entryList to paragraphs 1 thru wordCount of (text returned of (display dialog "Please list the " & ¬
wordCount & " " & theType & "s" & " in the correct order:" default answer entryForm) & entryForm)
set errorList to {}
repeat with i from 1 to wordCount
set origWord to origList's item i
set entryWord to entryList's item i
if origWord is not entryWord then set errorList's end to origWord & tab & tab & entryWord
end repeat
set correctCount to wordCount - (count errorList)
set roundNum to roundNum + 1
set continueBtn to "Round " & roundNum & "."
if correctCount is wordCount then
set btns to {"Cancel", continueBtn}
else
set btns to {"Cancel", "Show Errors", continueBtn}
end if
set Btn to button returned of (display dialog "Correct answers: " & (correctCount * 100 / wordCount + 0.5) ¬
div 1 & "% (" & correctCount & " of " & wordCount & ")." buttons btns default button 2)
if Btn is "Show Errors" then
choose from list errorList with prompt "Original" & tab & tab & ¬
"Entered" OK button name continueBtn with empty selection allowed
if result is false then return
end if
end repeat
end if
end play_game
setup_game()
play_game()
In terms of going for a shorter version, it wasn’t just the first part of each script that was the same. Much of the second section in each was quite similar, too (on account of my bone idleness). While I originally intended to produce a hybrid, I was a little short of time - but I’ve now merged the two originals by editing my last version above. (Since they were so similar anyway, I thought it better to do that, rather than post yet another lengthy variation.)
One benefit of merging the way I have is that, if number-words are chosen, the dictionary words aren’t loaded at all. This saves a few moments at the start of a game. (I also removed the lower limits so that all values can go down to 1.)
Since I was combining the originals, I didn’t incorporate any of your additional stuff - but feel free to pinch and adapt as you wish.
You know, ATST, I was just playing this game (Kai’s last version, anyway) and realized that not only must the word or number strings be remembered, the strings must also be in the right order. One you can’t remember must be “dummied” or all subsequent numbers are “wrong” because they are out of position.
So – how about making the game accept the answer strings in any order?
I was thinking of modifying it to be like the original game with single digits and letters so that you must give the word strings or number strings in reverse order. That would make a person think harder (and really task the working memory). I’m going to try this tomorrow.
Now you are asking if I can make it so that it accepts the word or number strings in any order. I guess the thing to do would be to make it such that you can choose what type of order to give the answers and assign a point value. Mish-mash order would be the lowest value, standard order would be a higher point value, and reverse order would be the highest point value.
I could figure out how to do reverse order now, but the other options would seem to change both sections of Kai’s code greatly beyond my present capabilities (at least I think that is the case).
If you’ll be saving this as an application, I would move that info into the Startup Screen. (Put that text into the Description area in Script Editor, and check the “Startup Screen” box when saving as an application.)
Bear in mind that, with this method, the list you iterate through must contain the original words, rather than those entered by the user. Otherwise, in certain situations, you might get some spurious results.
For example, compare this result:
set x to {"A", "B", 1, 2, 3}
set y to {2, 2, 1, 1, "B"}
set e to 0
repeat with p in y
if x does not contain p then set e to e + 1
end repeat
e --> 0
… with this:
set x to {"A", "B", 1, 2, 3}
set y to {2, 2, 1, 1, "B"}
set e to 0
repeat with p in x
if y does not contain p then set e to e + 1
end repeat
e --> 2
There’s also an added complication here, because the game displays errors at the end of each round. So it’s necessary to filter out all matching words, possibly from different positions in each list, to compare any remaining mismatches. (I’ve adjusted my code to demonstrate one way of doing this.)
That’s interesting. I’m going to see if I can set it up so that you can choose which order you want to answer in. And base the difficulty off that in the setup menu.
OK I wasn’t able to do my original intention given in the previous post, but I was able to set it up so that the words “number” or “word” appear in the various dialog boxes depending on the relative game your playing. And I was able to set it up so that you must give the answer in reverse, which the program checks to see if you’re right.
property memDesc : {"Seconds to see each word or number:" & tab, ¬
"Words or numbers in each round:" & tab & tab, ¬
"Length of each word or number:" & tab & tab, ¬
"Words or numbers made up of:" & tab & tab}
property memVal : {2, 4, 3, "Characters"}
property upperLimit : {30, 30, 24}
to setup_game()
set selected_Item to 1
set checkChar to «data utxt2713» as Unicode text
repeat
tell memVal's items
set diffRating to 10 + 30 * (item 3) * (item 2) / (item 1) div 3
repeat with i from 1 to count
set item i to memDesc's item i & item i
end repeat
set l to it
end tell
set c to choose from list l with prompt "Set your preferences for this game:" with title ¬
"Current Difficulty Rating: " & diffRating default items l's item selected_Item ¬
OK button name "Edit" cancel button name "Play"
if c is false then exit repeat
tell c's item 1 to repeat with selected_Item from 1 to count l
if it is l's item selected_Item then exit repeat
end repeat
if selected_Item is 4 then
set memVal's item selected_Item to button returned of (display dialog memDesc's item selected_Item ¬
buttons {"Numbers", "Characters"} default button memVal's item selected_Item)
else
set btn to "+"
repeat
set btn to button returned of (display dialog memDesc's item selected_Item & ¬
memVal's item selected_Item buttons {checkChar, "-", "+"} default button btn)
if btn is checkChar then exit repeat
tell memVal's item selected_Item to if btn is "+" then
if it < upperLimit's item selected_Item then ¬
set memVal's item selected_Item to it + 1
else if it > 1 then
set memVal's item selected_Item to it - 1
end if
end repeat
end if
end repeat
end setup_game
to play_game()
set {showTime, wordCount, charCount, wordType} to memVal
set wordChars to wordType is "Characters"
if wordChars then
set wordList to paragraphs of (do shell script "awk " & quoted form of ¬
("length == " & charCount) & " /usr/share/dict/words | tr \"A-Z\" \"a-z\"")
set theType to "word"
else
set charList to "0123456789"
set theType to "number"
end if
set roundNum to 1
repeat
set origList to {}
display dialog "Ready to start?" with title "Round " & roundNum
repeat with wordNum from 1 to wordCount
if wordChars then
set w to some item of wordList
else
set w to ""
repeat charCount times
set w to w & some character of charList
end repeat
end if
set origList's end to w
display dialog return & tab & tab & tab & tab & w with title ¬
"Round " & roundNum & " - " & theType & " " & wordNum & " of " & ¬
wordCount buttons {"Cancel"} giving up after showTime
end repeat
set entryForm to ""
repeat wordCount - 1 times
set entryForm to entryForm & return
end repeat
set entryList to paragraphs 1 thru wordCount of (text returned of (display dialog "Please list the " & ¬
wordCount & " " & theType & "'s" & " in the reverse order:" default answer entryForm) & entryForm)
set errorList to {}
repeat with i from 1 to wordCount
set origList to reverse of origList -- This reverses the original order of the numbers or words.
set origWord to origList's item i
set entryWord to entryList's item i
if origWord is not entryWord then set errorList's end to origWord & tab & tab & entryWord
end repeat
set correctCount to wordCount - (count errorList)
set roundNum to roundNum + 1
set continueBtn to "Round " & roundNum & "."
if correctCount is wordCount then
set btns to {"Cancel", continueBtn}
else
set btns to {"Cancel", "Show Errors", continueBtn}
end if
set btn to button returned of (display dialog "Correct answers: " & (correctCount * 100 / wordCount + 0.5) ¬
div 1 & "% (" & correctCount & " of " & wordCount & ")." buttons btns default button 2)
if btn is "Show Errors" then
choose from list errorList with prompt "Original" & tab & tab & ¬
"Entered" OK button name continueBtn with empty selection allowed
if result is false then return
end if
end repeat
end play_game
setup_game()
play_game()
OK I can’t figure out what I did wrong, but it seems it has to do with this piece of code:
set errorList to {}
repeat with i from 1 to wordCount
set origList to reverse of origList -- This reverses the original order of the numbers or words.
set origWord to origList's item i
set entryWord to entryList's item i
if origWord is not entryWord then set errorList's end to origWord & tab & tab & entryWord
end repeat
set errorList to {}
repeat with i from 1 to wordCount
why is the next line inside the loop? - you’re reversing every time, not once.
set origList to reverse of origList -- This reverses the original order of the numbers or words.
set origWord to origList's item i
set entryWord to entryList's item i
if origWord is not entryWord then set errorList's end to origWord & tab & tab & entryWord
end repeat
This works:
set origList to {1, 2, 3, 4, 5}
set entryList to {5, 4, 3, 2, 1}
set errorList to {}
set origList to reverse of origList -- This reverses the original order of the numbers or words.
repeat with i from 1 to count of origList
set origWord to origList's item i
set entryWord to entryList's item i
if origWord is not entryWord then set errorList's end to origWord & tab & tab & entryWord
end repeat
errorList
I’m now going to try and develope a little mental math game completely on my own. I’ll keep you guys updated.
In the meantime, Is it possible to do basic graphics on applescript? I’d like to try and add a game to the memory test, where you have a grid and a dot flashes randomly on it, and continues like the previous memory tests, and then you have to point out where on the grid the dots were. CAn applescript do that, or do I need something like XCode?
property memDesc : {"Seconds to see the problem:" & tab, ¬
"Length of each number:" & tab & tab}
property memVal : {10, 2}
property upperLimit : {60, 5}
to setup_game()
set selected_Item to 1
set checkChar to «data utxt2713» as Unicode text
repeat
tell memVal's items
set diffRating to 10 + 30 * (item 2) / (item 1) div 3
repeat with i from 1 to count
set item i to memDesc's item i & item i
end repeat
set l to it
end tell
set c to choose from list l with prompt "Set your preferences for this game:" with title ¬
"Current Difficulty Rating: " & diffRating default items l's item selected_Item ¬
OK button name "Edit" cancel button name "Play"
if c is false then exit repeat
tell c's item 1 to repeat with selected_Item from 1 to count l
if it is l's item selected_Item then exit repeat
end repeat
set btn to "+"
repeat
set btn to button returned of (display dialog memDesc's item selected_Item & ¬
memVal's item selected_Item buttons {checkChar, "-", "+"} default button btn)
if btn is checkChar then exit repeat
tell memVal's item selected_Item to if btn is "+" then
if it < upperLimit's item selected_Item then ¬
set memVal's item selected_Item to it + 1
else if it > 1 then
set memVal's item selected_Item to it - 1
end if
end repeat
end repeat
end setup_game
to play_game()
set {showTime, charCount} to memVal
set charList to "0123456789"
set roundNum to 1
repeat
set origList to {}
display dialog "Ready to start?" with title "Round " & roundNum
set w to ""
set n to ""
repeat charCount times
set w to w & some character of charList
set n to n & some character of charList
end repeat
set origList's end to w
display dialog return & tab & tab & tab & tab & w & " times " & n with title ¬
"Round " & roundNum & " - What is " & w & " * " & n & "?" buttons {"Cancel"} giving up after showTime
set entryForm to ""
set entryForm to entryForm & return
set entryList to (text returned of (display dialog "Please type the answer: " default answer entryForm) & entryForm)
set errorList to {}
set origWord to origList
set entryWord to entryList
if origWord is not entryWord then set errorList's end to origWord & tab & tab & entryWord
set correctCount to w * n
set roundNum to roundNum + 1
set continueBtn to "Round " & roundNum & "."
if correctCount is charCount then
set btns to {"Cancel", continueBtn}
else
set btns to {"Cancel", continueBtn}
end if
set btn to button returned of (display dialog "Correct answer: " & correctCount buttons btns default button 2)
end repeat
end play_game
setup_game()
play_game()
I’d appreciate your imput on how to make it run smoother and improve it. Let me know what you think!