Home > Software engineering >  Replacing duplicate substrings in a string replaces only one of them
Replacing duplicate substrings in a string replaces only one of them

Time:01-07

I'm making a simple hangman game in Go, but I have come across an error, the unknow_string string (will be shown in the code) has _ characters so the other player guessing the letters can see the length of the word, whenever the player enters a correct letter, I want it to replace the nth (n depending on which index the letter is found in the word) _ character with the letter, which has been successful, but with one problem. If the word has two duplicate letters, only one of them is replaced.

I created a separate function called iterate (function because I want to avoid nested code), to iterate over all indexes. but it didn't work, here's the code:

package main

import (
    "fmt"
    "strings"
)

var input string
var word string
var unknown_word []string
var unknown_word_string string
var index int
var guesses int
var change_unknown_word_string []byte

func main() {
    fmt.Println("Welcome to hangman")
    fmt.Println("Player 1, choose a word!")
    fmt.Scan(&word)
    for i := 1; i <= len(word); i   {
        unknown_word = append(unknown_word, "_")
    }
    unknown_word_string = strings.Join(unknown_word, "")
    for {
        fmt.Println("Player 2, guess a letter or a word")
        fmt.Println(unknown_word_string)
        fmt.Scan(&input)
        if guesses == 6 {
            fmt.Println("Player 2 lost! Player 1's word was: ", word)
            break
        } else if unknown_word_string == input {
            fmt.Println("Player 1 lost! Player 2 guessed the word by guessing the letter!")
        }
        if strings.Contains(word, input) && word != input {
            index = strings.Index(word, input)
            iterate()
            fmt.Println("You guessed a letter!")
        } else if word == input {
            fmt.Println("Player 1 lost! Player 2 guessed the word by guessing the whole word!")
            break
        } else {
            fmt.Println("Nothing found")
            guesses  
        }
    }
}
func iterate() {
    change_unknown_word_string = []byte(unknown_word_string)
    for i := 0; i < len(change_unknown_word_string); i   {
        if change_unknown_word_string[i] == change_unknown_word_string[index] {
            change_unknown_word_string[i] = []byte(input)[0]
        }
    }
    unknown_word_string = string(change_unknown_word_string)
}

CodePudding user response:

The comparison if change_unknown_word_string[i] == change_unknown_word_string[index] makes no sense, as unknown_word_string obviously contains _ at those positions.

You should be comparing word[i] == input[0] in the loop instead.

But note that converting a string to a byte array is not Unicode-friendly. It's better to work with runes (Unicode code points) instead, this way you're not limited to latin1 characters.

func iterate() {
    needle := []rune(input)[0]
    haystack := []rune(word)
    buf := []rune(unknown_word_string)
    for i := range haystack {
        if haystack[i] == needle {
            buf[i] = needle
        }
    }
    unknown_word_string = string(buf)
}

Bonus note: this comparison is wrong

        if unknown_word_string == input {
            fmt.Println("Player 1 lost! Player 2 guessed the word by guessing the letter!")
        }

It should be if unknown_word_string == word and be located immediately after the call to iterate().

  • Related