0

I'm trying to create a Android Hangman app as a bit of self-learning, and so far it's going well, but (typically) the last feature is causing me problems.

So far I have a random word, a timed game, a word by length and now am trying to add on a word by category.

Originally, before the category stage, I have been reading the contents of a text file and using them to populate an ArrayList which a word can be chosen from. Now, as I need a Key:Value pair (category:word) I swapped it out for a Hashmap and check for the next word in the text file that starts with a period "." which donates it to be category. I then use this as the Key and the next bunch of words before the next period "." to be the words.

As, hopefully, some of you may have spotted, this caused a problem in that the Keys have to be unique, so true to hillbilly form, I simply swapped the Key:Value format to be Value:Key... which works great... as a random word.

Note: I had to change the Hashmap for a LinkedHashMap so that I could search by index for a random word at position 'x'.

The problem I have now is that it's a bit hit-and-miss when searching by category. Sometimes it works fine, sometime the wrong category is shown for the word to guess - I don't know why, I've been through the debugger loads of times and it. just. happens?!?!?

Ideally, I would like to be able to return all the words for a given category so that I can pick one from random, but as I say, it's a bit hit and miss whether they're going to match or not.

This is the code I've written for the reading and sorting of the text file:

private String word;
private List<String> words = new ArrayList<>();
private LinkedHashMap<String, String> map = new LinkedHashMap<>();

public List<String> readTextFileAsList(Context ctx, int resId) {
    InputStream inputStream = ctx.getResources().openRawResource(resId);
    InputStreamReader inputreader = new InputStreamReader(inputStream);
    BufferedReader bufferedreader = new BufferedReader(inputreader);
    String line;

    String category = null;
    try {
        //While there are still lines left
        while (( line = bufferedreader.readLine()) != null) {
            //Add to hash map
            if (line.contains(".")) {
                //Remove the proceeding period, donating a category
                line = line.substring(1, line.length());
                //Set the category name to the current line
                category = null;
                category = line;
            } else {
                //Add to the hashmap
                map.put(line, category);
                //Add to the array
                words.add(line);
            }
        }
    }
    catch (IOException e) {
        return null;
    }
    return words;
}

and I'm currently validating it by searching again if the returned category doesn't match the selected category, like so:

if (!wordBank.getCategory(randomNumber).equals(wordCategorySelected)) {
                generateRandomWord(sizeOfWordBank);
            }

I have tried this, but to no avail =(

Any help on how I can get this to reliably work would be a great help.

Thanks!

Community
  • 1
  • 1
  • 5
    Maybe I am over simplifying but is there a reason you can't use a `HashMap>` to solve your first problem - that keys must be unique? With this you can map a bunch of words to a category. Seems like doing it that way would be more correct and logical, and might solve some of your other problems too. – nhouser9 Sep 16 '16 at 20:02
  • ^^ I second these two comments, as they beat me to it. – Cmoraski Sep 16 '16 at 20:03
  • @Cmoraski 1 now, I call jinx :) – Tibrogargan Sep 16 '16 at 20:04
  • Thanks both, sounds good, but how would i search through the list according to the Key? – Richard KeMiKaL GeNeRaL Denton Sep 16 '16 at 20:05
  • The category is the key. Everything in the list associated with that category has the same key. Is there some other reason you need to search through all the words? – Tibrogargan Sep 16 '16 at 20:06
  • Why are you not using `Map>`? In other words the category name as key and a `List` of words as value. Also use an `ArrayMap` instead of a `HashMap`. `ArrayMaps` are much more memory efficient which is important on mobile devices. – Xaver Kapeller Sep 16 '16 at 20:07
  • @XaverKapeller ArrayMap isn't part of the standard library. Unless the memory saved > cost of loading an extra library it's not worth it – Tibrogargan Sep 16 '16 at 20:10
  • @Tibrogargan I need to search through all of the words in their entirety as I have a number of game types, some of which just pick a random word from any category. – Richard KeMiKaL GeNeRaL Denton Sep 16 '16 at 20:13
  • @Tibrogargan Yes it is part of the framework. And the "extra library" you are referring to is the support library. Why would any app not use the support library? And as I said the support library just contains a backport of the `ArrayMap` for API levels 4 and up. You can use the framework version if you only support API level 19 and up. – Xaver Kapeller Sep 16 '16 at 20:14
  • @RichardKeMiKaLGeNeRaLDenton If you take care to keep your List sorted, finding any element is going to be easy (binary search) and returning a random element is even easier. (An alternative to using a List may be to use a SortedSet. Finding things would be easier, returning a random element harder, but you would be guaranteed of no duplication) – Tibrogargan Sep 16 '16 at 20:28
  • @XaverKapeller same reason you would not use any library: you don't benefit by doing so. If his application is not already using it, loading it just for the minor savings provided by swapping HashMap for ArrayMap is probably not worth it. – Tibrogargan Sep 16 '16 at 20:35
  • @Tibrogargan Yes, I am the first person to not use a library if there is an alternative, but its the support library. It's basically mandatory at this point, you can't really make an app without it anymore - at least not without a lot more effort. Most components and functionality is only published through the support library anymore as part of the overall effort to extract framework components and publish them separately so they can be updated independently from the OS. And as I already said: The `ArrayMap` is a framework component, I don't understand why you are arguing with me. – Xaver Kapeller Sep 16 '16 at 20:40

0 Answers0