UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Trying to create a reveal word for hangman game using replaceSubrange(range: with) method

Forums > 100 Days of Swift

in this line

... currentAnswer.text?.replaceSubrange(currentIndex...currentIndex, with: characterString) ...

and this line

... currentAnswer.text = currentAnswer.text?.replaceSubrange(range, with: characterString) ...

are giving me the errors "Type of expression is ambiguous without more context" and "No exact matches in call to instance method 'replaceSubrange", respectively.

I am trying to do two things. after extracting the buttontitle, i turned it into both a string and character. i am trying to check currentWord to see if it contains the buttonTitle variable, and if it does, I want to reveal the letter in the currentAnswer textfield. I got it to work, but the order was wrong, the position of each letter revealed was random. The second issue was if a letter appears in the word the user is trying to guess more than once, that letter should appear as many times in the currentAnswer textfield but it wouldn't and I have disable each letter if it is tapped so I obviously can't retap the letter again. Thanks for your help!


import UIKit

class ViewController: UIViewController {
            var currentIndex = 0
            var currentWord = String()
            var scoreLabel: UILabel!
            var wordLabel: UILabel!
            var letters = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
            var currentAnswer: UILabel!
            var usedLetters = [Character]()
            var wordList = ["arsenal", "mancity", "chelsea", "acmilan", "atlmdrd", "rmadrid", "munited"]
            var activatedButtons = [UIButton]()
            var letterButtonsArray = [UIButton]()
            var score = 0

    override func loadView() {

        view = UIView()
        view.backgroundColor = .white

        scoreLabel = UILabel()
        scoreLabel.translatesAutoresizingMaskIntoConstraints = false
        scoreLabel.text = "SCORE: "
        scoreLabel.font = UIFont.systemFont(ofSize: 25)
        view.addSubview(scoreLabel)

        wordLabel = UILabel()
        wordLabel.translatesAutoresizingMaskIntoConstraints = false
        wordLabel.numberOfLines = 0
        wordLabel.font = UIFont.systemFont(ofSize: 28)
        wordLabel.text = "Teams"
        wordLabel.textAlignment = .center
        wordLabel.setContentHuggingPriority(UILayoutPriority(1), for: .vertical)
        view.addSubview(wordLabel)

        currentAnswer = UILabel()
        currentAnswer.textAlignment = .left
        currentAnswer.translatesAutoresizingMaskIntoConstraints = false
        currentAnswer.text = "_______"
        currentAnswer.font = UIFont.systemFont(ofSize: 36)
        currentAnswer.isUserInteractionEnabled = false
        view.addSubview(currentAnswer)

        let submit = UIButton(type: .system)
        submit.translatesAutoresizingMaskIntoConstraints = false
        submit.setTitle("SUBMIT", for: .normal)
        submit.addTarget(self, action: #selector(submitTapped), for: .touchUpInside)
        view.addSubview(submit)

        let buttonView = UIView()
        buttonView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(buttonView)

        NSLayoutConstraint.activate([

            scoreLabel.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor),
            scoreLabel.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor),

            wordLabel.topAnchor.constraint(equalTo: scoreLabel.bottomAnchor, constant: 25),
            wordLabel.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.8),
            wordLabel.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor, constant: 55),

            currentAnswer.topAnchor.constraint(equalTo: wordLabel.bottomAnchor, constant: 20),
            currentAnswer.widthAnchor.constraint(equalTo: view.layoutMarginsGuide.widthAnchor, constant: 0.5),
            currentAnswer.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 320),
            submit.topAnchor.constraint(equalTo: currentAnswer.bottomAnchor, constant: 20),
            submit.centerXAnchor.constraint(equalTo: view.centerXAnchor),

            buttonView.topAnchor.constraint(equalTo: submit.bottomAnchor, constant: 20),
            buttonView.widthAnchor.constraint(equalToConstant: 550),
            buttonView.heightAnchor.constraint(equalToConstant: 320),
            buttonView.bottomAnchor.constraint(equalTo: view.layoutMarginsGuide.bottomAnchor, constant: -20),
            buttonView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            buttonView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor, constant: 0),
            buttonView.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor, constant: 0)

        ])

        let width = 80
        let height = 60

        for row in 0..<3{
            for col in 0..<9{
                let letterButton = UIButton(type: .system)
                letterButton.titleLabel?.font = UIFont.systemFont(ofSize: 36)
                letterButton.setTitle("A", for: .normal)
                let frame = CGRect(x: col*width, y: row*height, width: width, height: height)
                letterButton.frame = frame
                buttonView.addSubview(letterButton)
                letterButtonsArray.append(letterButton)
                letterButton.addTarget(self, action: #selector(letterTapped), for: .touchUpInside)
            }

        }

        let lastbutton = buttonView.subviews.last
        lastbutton?.removeFromSuperview()
        letterButtonsArray.removeLast()

    }

    override func viewDidLoad() {
        super.viewDidLoad()

        loadLevel()
        startGame()

        //end of view did load
    }

    func loadLevel(){
        letterButtonsArray.shuffle()
        letters.shuffle()
        if letters.count == letterButtonsArray.count{
            for i in 0..<letterButtonsArray.count{
                letterButtonsArray[i].setTitle(letters[i], for: .normal)
            }
        }
    }

    func startGame(){
        currentAnswer.text = ""
    }

    @objc func letterTapped(_ sender: UIButton){

//        let characterlist = wordList.map{Array($0)}
//        for sublist in characterlist {
//            for char in sublist{
//                usedLetters.append(char)
//                print("usedLetters are \(usedLetters)")
        guard let buttonTitle = sender.titleLabel?.text else {return}

        let char = Character(buttonTitle.lowercased())
        usedLetters.append(char)
        let characterString = String(char)
        print("used letters is \(usedLetters)")
        sender.isHidden = true
        currentWord = wordList[currentIndex]
//        for character in currentWord{
//            var CHARACTER = String()
//            if usedLetters.contains(character){
//                 CHARACTER = String(character)
//
//            }
//            currentAnswer.text? += CHARACTER
//
//        }

        if currentWord.contains(characterString){

            var indices = [Int]()

            for (index, letter) in currentWord.enumerated() {
                if letter == char{
                    indices.append(index)
                }
            }

            for index in indices {
                let currentIndex = currentWord.index(currentWord.startIndex, offsetBy: index)
                currentAnswer.text = currentAnswer.text?.replaceSubrange(currentIndex...currentIndex, with: characterString)

                let ranges = currentWord.ranges(of: characterString)
                for range in ranges {
                    currentAnswer.text = currentAnswer.text?.replaceSubrange(range, with: characterString)
                }

            }

        }

            }

    @objc func submitTapped(){

    }

            }

3      

no takers?

3      

@Geeljire wonders:

no takers?

I started looking at this and stopped when I got to the sea of constraints. It was too wide to cross.

It seems your original question about ambiguous subranges may have nothing to do with the interface code.

Can you duplicate the substitution problem in just a few lines of logic code in Playgrounds? Let's focus on the business end of this problem.

3      

currentAnswer.text = currentAnswer.text?.replaceSubrange(currentIndex...currentIndex, with: characterString)
currentAnswer.text = currentAnswer.text?.replaceSubrange(range, with: characterString)

Try breaking these lines up so you aren't trying to do everything in one line.

3      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.