Java: Which structure to use for a multiple choice game - java

I'm trying to create a multiple choice game with 4 possible answers for each question.
During the main part of the game the player will be asked a question and will be prompted to input an answer.
In my code, along with the question and answer String, I will somehow need to be able to tell which is the correct answer and maybe even flag the question so as to not be repeated in later rounds. Also the possible answers need to be in randomized/different order between "playthroughs".
I'm trying to figure out what data structure to use to store all of the above, as to be able to write the code appropriately.
My first choice would be to have a main Hashmap<String, HashMap> and a second HashMap<String, Boolean>* that is stored into the first one. The first map will store the question strings as keys and the second HashMap(s) as values. The second HashMap will store the answers as keys and a boolean for each key, indicating which one is the correct answer, as value.
Kind of complicated but at least in theory it seems to work, although I still don't have a way to mark a question as "already asked".
My second choice would be a two dimensional array whose lines will represent a question, the 0 column being the question Strings, the 1,2,3,4 columns storing the answer strings, the 5 column storing the correct answer string, and maybe have a 7th column (6) storing a flag, marking if the question hasn't been asked already.
Although simpler in theory I fear this method would be really confusing to actually code with.
If there are better/easier ways to do this please tell me and maybe even elaborate on their benefits.

Java is an Object-Oriented language. You should use it.
Example: Create a class representing a question and the possible answers.
public class Question {
private String question;
private String correctAnswer;
private List<String> answerList;
}
Now, you can create a good useful constructor, where you give the question first, then all the answers using varargs, with the correct answer first:
new Question("How satisfied are you with this answer?",
"Extremely satisfied",
"Very satisfied",
"Somewhat satisfied",
"Not so satisfied");
Your constructor could then build the answers list and call Collections.shuffle(this.answers) to randomize them.
You then add all the questions to a List<Question> and call shuffle on that, so questions will be asked in random order, and only once.

Since this is all theoretical, you should consider using objects.
Make a Question class. Having it store your question strings along with an answer string.
You could store as many question strings as you want, say in an array. The answer could just be an integer representing the index of the correct answer.
As far as Hashmaps are concerned, you can use them, if you want to store unique ID values to each question, and look them up, but that's not really necessary.
You can store these Question objects in an Arraylist, add freely shuffle and iterate over them

Related

Unlimited objects using Java? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
NOTE: I am looking for simple feedback on this problem that I’m having, NOT for anyone to complete this problem.
Is it possible to create a program that can create an unlimited amount of objects simply using arrays and inheritance? For example, allowing an employer to use a system where they can create a new employee every time someone is hired. This program would also require unique identifiers for every single employee - so it would need to check one new employee ID against all other employee ID’s that have been created to ensure it’s not a duplicate.
I’ve done some research and some people have mentioned ArrayLists. I’m asking because this was a question given on a midterm, but I’m not looking for new ways to complete this program - just asking how doable it is using only arrays and inheritance. I know arrays are fixed, so I’m not sure how I’d continuously add new employees.
If I wanted to make an employee Jen for example, I know I’d go:
Employee jen = new Employee();
To make this program work, I assume I’d have to make generic objects, each with a different name than any other that has been created. Is this possible with what I’ve mentioned (using only arrays and inheritance)? It seems like this program would not be doable using this from what I've read, but a professor gave this problem so I'm wondering if there's another way to think about this problem.
Edited because people were making assumptions and not reading my question. Thanks in advance.
If you're not allowed to use ArrayLists, you could "expand" a normal Array manually. For example, check if the current array is full, and if it is, make a new array that is twice the size of the current array and copy all of its current values, and assign that new array as the current array.
It'll be more code and less efficient though than just using ArrayLists, as that's one of the main purpose of using Collections framework.
Anytime i have to perform a task like this, I always use ArrayLists, add new items to the ArrayList, then cast the ArrayList to an array prior to using it in a ListView etc.
However, in the case that I wouldn't have the ability to use an ArrayList first, you could always take the initial array and cast it into a second array of the original array size + 1.
String[] arr1 = new String[1];
String[] arr2;
arr2 = new String[arr1.length() + 1];
Then copy arr1 into arr2. This can be done manually, of course, but using a for loop would be most efficient.
for (int i = 0; i < arr1.length(); i++) {
arr2[i] = arr1[i];
}
Finally, you can add the final item into arr2 at the final index.
arr2[arr1.length() + 1] = "New Employee Information";
Similarly, you could delete an item in the reverse fashion. It gets a little more complex because you need to filter for the item that you're removing, or you'd need to know the array index of the item to remove it. But, by rebuilding the array, youll always have an array of the exact size of the items youre holding.
Obviously you can nest arrays and for loops to make this work the way you want it to. It isn't nearly as efficient as using the ArrayList, but it is an option.
Good Luck, and Happy Coding!

Reverse words in Java without using any language specific functions

I have been going through the Java interview questions asked by my company and came across one that I can't seem to find the solution.
Here is the question:
Please write a method (function) accepting as single parameter a
string and reversing the order of the words in this string.
The " " is the word separator and any other char is considered as being part of a word. In order to simplify, please consider that there is always one space between the words.
Important - You are NOT allowed to use other strings or arrays or other data structures containing several elements - just plain atomic variables such as integers, chars etc.
Also, it is not allowed to use any other language specific string function other than the function giving you the length of the string.
Expected result:
"hello my beautiful world" -> "world beautiful my hello"
So, I can't use: chars[], str.split(), str.charAt(), str.substring(), StringBuilder, another declaration of String.
Should I use recursion to do it?
Since, String is Immutable and uses encapsulation,
There is no solution to your problem. You can't update the values directly, no setters are available and without the access to the getters (since you can only use .length), you can't read the value.
So, I would suggest to respond that Immutability and encapsulation prevent you from doing so.
In real life as a software engineer, you'll sometimes be asked to do things that are technically impossible or even nonsensical. Sometimes the person asking will be someone important like your boss or a big customer.
If someone actually asks you this interview question, then you're in one of those situations. That makes this question pretty interesting, and you might want to figure out what the best way to answer really is.
If someone asked me, this is how I would answer, and as an interviewer, this is the kind of answer I would award the most points for:
1) Explain how it's technically impossible to meet the requirements, but do it without making me feel stupid. This shows diplomacy.
2) Figure out what I really want. In this case, the interviewer probably wants to see if you know how to reverse the words in a string using low-level operations. This is a perfectly reasonable C language question, for example. Figuring out what the interviewer really wants shows experience and judgement.
3) Provide an answer that gives me what I want. Write this method in Java, but take a StringBuilder instead of a string, and call only length(), charAt(), and setCharAt(). This shows the expertise that the interviewer wants to see.

Is there a method in Java that lets you find the index of an element in an int array? [duplicate]

This question already has answers here:
Where is Java's Array indexOf?
(13 answers)
Closed 9 years ago.
I need to assess the last int in an array where a certain conditional is met. My program can work out what that int is, but it needs to also know where it's position was in the array. I searched on stack-exchange and someone posted this:
Arrays.asList(array).indexOf(indexPos);
As a possible solution, but I am not sure if I am doing it right, because I get the error
cannot find symbol. I also allowed:
int test = Arrays.asList(array).indexOf(indexPos);
And then tried to print test, but I could not even get to that point. Thanks.
You may need to import java.util.Arrays to get the symbol.
There is no guaranteed way of finding the position of an element in an array except for looping over the array - that is basically what your asList snippets are doing.
This will work as long as your arrays don't have duplicate values. If you need to handle duplicate values, you may need to rethink you data structs.
Someone posted a similar question that someone else asked. It seems that this has worked for me.
The Code is:
java.util.Arrays.asList(seq).indexOf(indexPos);
and the Question:Where is Java's Array indexOf?
Yes you have the method defined in List interface. So you need to use asList() function followed by indexOf() function.
If the array is not sorted you can use java.util.Arrays.asList(theArray).indexOf(o)
If the array is sorted, you can make use of a binary search function(improves performance) java.util.Arrays.binarySearch(theArray, o)
As for the error make sure you have imported java.util.Arrays. Also that you have defined Array seq and int indexPos which makes your code int test = Arrays.asList(seq).indexOf(indexPos);.

Prevent treemap merging on collision

Edit: I should have probably mentioned that I am extremely new to Java programming. I just started with the language about two weeks ago.
I have tried looking for an answer to this questions, but so far I haven't found one so that is why I am asking it here.
I writing java code for an Dungeons and Dragons Initiative Tracker and I am using a TreeMap for its ability to sort on entry. I am still very new to java, so I don't know everything that is out there.
My problem is that when I have two of the same keys, the tree merges the values such that one of the values no longer exists. I understand this can be desirable behavior but in my case I cannot have that happen. I was hoping there would be an elegant solution to fix this behavior. So far what I have is this:
TreeMap<Integer,Character> initiativeList = new TreeMap<Integer,Character>(Collections.reverseOrder());
Character [] cHolder = new Character[3];
out.println("Thank you for using the Initiative Tracker Project.");
cHolder[0] = new Character("Fred",2);
cHolder[1] = new Character("Sam",3,23);
cHolder[2] = new Character("John",2,23);
for(int i = 0; i < cHolder.length; ++i)
{
initiativeList.put(cHolder[i].getInitValue(), cHolder[i]);
}
out.println("Initiative List: " + initiativeList);
Character is a class that I have defined that keeps track of a player's character name and initiative values.
Currently the output is this:
Initiative List: {23=John, 3=Fred}
I considered using a TreeMap with some sort of subCollection but I would also run into a similar problem. What I really need to do is just find a way to disable the merge. Thank you guys for any help you can give me.
EDIT: In Dungeons and Dragons, a character rolls a 20 sided dice and then added their initiative mod to the result to get their total initiative. Sometimes two players can get the same values. I've thought about having the key formatted like this:
Key = InitiativeValue.InitiativeMod
So for Sam his key would be 23.3 and John's would be 23.2. I understand that I would need to change the key type to float instead of int.
However, even with that two players could have the same Initiative Mod and roll the same Initiative Value. In reality this happens more than you might think. So for example,
Say both Peter and Scott join the game. They both have an initiative modifier of 2, and they both roll a 10 on the 20 sided dice. That would make both of their Initiative values 12.
When I put them into the existing map, they both need to show up even though they have the same value.
Initiative List: {23=John, 12=Peter, 12=Scott, 3=Fred}
I hope that helps to clarify what I am needing.
If I understand you correctly, you have a bunch of characters and their initiatives, and want to "invert" this structure to key by initiative ID, with the value being all characters that have that initiative. This is perfectly captured by a MultiMap data structure, of which one implementation is the Guava TreeMultimap.
There's nothing magical about this. You could achieve something similar with a
TreeMap<Initiative,List<Character>>
This is not exactly how a Guava multimap is implemented, but it's the simplest data structure that could support what you need.
If I were doing this I would write my own class that wrapped the above TreeMap and provided an add(K key, V value) method that handled the duplicate detection and list management according to your specific requirements.
You say you are "...a TreeMap for its ability to sort on entry..." - but maybe you could just use a TreeSet instead. You'll need to implement a suitable compareTo method on your Character class, that performs the comparison that you want; and I strongly recommend that you implement hashCode and equals too.
Then, when you iterate through the TreeSet, you'll get the Character objects in the appropriate order. Note that Map classes are intended for lookup purposes, not for ordering.

Combinatorics in Java with trees

For a project that I'm currently working on I am dealing with a list of lists of integers, something of the form:
{[1,2];[5];[3,6,7]}
The idea here is that I'm trying to resolve an n-dimensional array into a list of the local maxima that occur in whatever particular axis I happen to be looking at. My question is this: I would like to get out a list of what would essentially be points in this n-dimensional space that contains every possible combination of entries of this list. For example, I would want the above to return:
{[1,5,3];[1,5,6];[1,5,7];[2,5,3];[2,5,6];[2,5,7]}
With the ordering not actually mattering to me. My first idea in how to approach this would be to boil this down to a tree where each path represents a possible combination and outputting every possible path, but I'm really not sure if this is the best way of going about it, and I am unfamiliar enough with Java's tree classes to be unsure if this would actually be straightforward to implement or not. Ideas?
Ah, my mistake, totally a duplicate.

Categories