|
Thanks, that does look better. Putting the 2 func in a single func worked. But now, my else statement isn't working. It increases score by one no matter what. Also, it is increasing score even if an error message comes up. How do I say increase score unless all of the error func's don't come up?
func isOriginal(word: String) -> Bool {
!usedWords.contains(word)
}
func isPossible(word:String) -> Bool {
var tempWord = rootWord.lowercased()
for letter in word {
if let pos = tempWord.firstIndex(of: letter){
tempWord.remove(at: pos)
} else {
return false
}
}
return true
}
func isReal(word: String) -> Bool {
let checker = UITextChecker()
let range = NSRange(location: 0, length: word.utf16.count)
let mispelledRange = checker.rangeOfMisspelledWord(in: word, range: range, startingAt: 0, wrap: false, language: "en")
return mispelledRange.location == NSNotFound
}
func isSame(word: String) -> Bool{
if word == rootWord {
return false
}
return true
}
func isShort(word: String) -> Bool{
let wordLength = word.count
if wordLength < 3 {
return false
}
return true
}
func wordError(title: String, message: String){
errorTitle = title
errorMessage = message
showingError = true
}
func increaseScore(){
if usedWords.count <= 5 {
score += 1
} else {
score += usedWords.count - 2
|
|
Your issue is not "where you declare" the function, just keep it at the same level as the other functions. The answer is "where do you use it".
Essentially you should call the function near the end of addNewWord() just after you update the usedWords array. So if we passed all the checks (isOriginal, isPossible etc...) then we can update the score.
Hope that helps.
|
|
1: I put increaseScore at the end of all of the guard func, and the else statement is working, but it still increases even if there is an error.
2: How can I refresh the app when I hit the Restart button? right now it just gives a new word
import SwiftUI
struct ContentView: View {
@State private var usedWords = [String]()
@State private var rootWord = ""
@State private var newWord = ""
@State private var score = 0
@State private var errorTitle = ""
@State private var errorMessage = ""
@State private var showingError = false
var body: some View {
NavigationView {
Form{
VStack {
TextField("Enter your word", text: $newWord, onCommit: both)
.textFieldStyle(RoundedBorderTextFieldStyle())
.autocapitalization(.none)
.padding()
List(usedWords, id: \.self) {
Image(systemName: "\($0.count).circle")
Text($0)
}
VStack{
Text("Score: \(score)")
}
}
.navigationBarTitle(rootWord)
.navigationBarItems(
trailing: Button(action: {
startGame()
}, label: { Text("Restart") })
)
.onAppear(perform: startGame)
.alert(isPresented: $showingError){
Alert (title: Text(errorTitle), message: Text(errorMessage), dismissButton: .default(Text("Ok")))
}
}
}
}
func addNewWord(){
let answer = newWord.lowercased()
.trimmingCharacters(in: .whitespacesAndNewlines)
guard answer.count > 0 else{
return
}
guard isOriginal(word: answer) else {
wordError(title: "Word used already", message: "Be more original")
return
}
guard isPossible(word: answer) else {
wordError(title: "Word not recognized", message: "You can't just make them up you know!")
return
}
guard isReal(word: answer) else {
wordError(title: "Word not possible", message: "That isn't a real word")
return
}
guard isShort(word: answer) else {
wordError(title: "Word is too short", message:"Needs to be 3 or more letters")
return
}
guard isSame(word: answer) else {
wordError(title: "You can't use \(rootWord)", message: "")
return
}
increaseScore()
usedWords.insert(answer, at: 0)
newWord = ""
}
func startGame(){
if let startWordsURL = Bundle.main.url(forResource: "start", withExtension: "txt"){
if let startWords = try?
String(contentsOf: startWordsURL){
let allWords = startWords.components(separatedBy: "\n")
rootWord = allWords.randomElement() ?? "silkworm"
return
}
}
fatalError("Could not load start.txt from bundle.")
}
func isOriginal(word: String) -> Bool {
!usedWords.contains(word)
}
func isPossible(word:String) -> Bool {
var tempWord = rootWord.lowercased()
for letter in word {
if let pos = tempWord.firstIndex(of: letter){
tempWord.remove(at: pos)
} else {
return false
}
}
return true
}
func isReal(word: String) -> Bool {
let checker = UITextChecker()
let range = NSRange(location: 0, length: word.utf16.count)
let mispelledRange = checker.rangeOfMisspelledWord(in: word, range: range, startingAt: 0, wrap: false, language: "en")
return mispelledRange.location == NSNotFound
}
func isSame(word: String) -> Bool{
if word == rootWord {
return false
}
return true
}
func isShort(word: String) -> Bool{
let wordLength = word.count
if wordLength < 3 {
return false
}
return true
}
func wordError(title: String, message: String){
errorTitle = title
errorMessage = message
showingError = true
}
func increaseScore(){
if usedWords.count <= 5 {
score += 1
} else {
score += usedWords.count - 2
}
}
func both(){
increaseScore()
addNewWord()
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
}
|
|
func both(){
increaseScore()
addNewWord()
}
Here you call increaseScore then addNewWord , so your score will always increase before addNewWord (and its many guard statements) is even called.
But also...
Inside the addNewWord function, you again call increaseScore after all the guard statements, meaning the score will be increased a second time if the guard statements pass.
|
|
As per the previous comment, you don't need the both() function in the onCommit, but instead just the addNewWord function. Inside of it, you should also move the increaseScore() function after the usedWords.insert in order for your score to be updated properly. You calculate the score based on the array count so make sure it gets updated before you calculate.
As for the restart, it should give you a new word at the top and an empty list... all the button should technically do is reset the usedWords array, and startNewGame().
|
|
How do I reset the usedWords array? I've tried usedWords[] and usedWords[]() in my Button (action:, but I keep getting an error
|
|
Also, my else statement is still not working
if usedWords.count <= 5 {
score += 1
} else {
score += usedWords.count - 2
}
|
|
Have your button call startGame and while that should reset usedWords, I like to make sure of it, so I also reset it inside the startGame function usedWords = [] just after the rootWord line.
|
|
Ok. Thank you. That totally worked. How about the If ... else statement? It only increase by 1 no matter the word length.
|
|
Word length is not being scored by you. You are simply adding the score based on the number of words. If the total words is less or equal to 5 you add 1, otherwise you add (Total number of words - 2)... Your else statement will only work starting with the 6th word you find.
|
|
Ok. I changed usedWords to wordLength.
func increaseScore(word: String){
let wordLength = word.count
if wordLength <= 5 {
score += 1
} else {
score += wordLength - 2
but when I call increaseScore
usedWords.insert(answer, at: 0)
newWord = ""
increaseScore()
i get an error "Missing argument for parameter 'word' in call"
|
|
Right, because your increaseScore function needs to know the length of the current word in order to increase the score properly: let wordLength = word.count
So you have to supply a word parameter when you call increaseScore . Presumably, that should be: increaseScore(word: answer)
|
|
would that be in the func increaseScore()? or would that be when I call increaseScore()?
also, I don't have an "answer" variable. would that be usedWords?
|
|
That would be when you call increaseStore . You already have it in the parameter to that function: func increaseScore(word: String)
I was basing what I wrote on the fact that you are currently (at least the last time you posted significant code) calling increaseScore from within the addNewWord function, where you do have an answer variable; you are using it in all those guard statements to check if the user got it right.
|
|
You were right, I just totally looked over it . Adding (word: answer) totally worked, and now the app works exactly how I want. thank you so much for taking the time to help.
|