So im using HyperSkill and im on the last stage of the rock paper scissors game, here is a link to the stage and directions.
https://hyperskill.org/projects/314/stages/1768/implement
Anyway im confused on why i'm receiving an IllegalArgumentsException on my copyOfRange method in my determineWinner method. I know that it takes 3 arguments the Original Array the star and finish, as far as i can tell all my arguments are in range. Any help with helping me understand this and nudge me in the right direction would be greatly appreciated ๐
here is my gist of what i have so far.
https://gist.github.com/AviTheBrown/848ee7b0ae63b788473c80818f3404e0
#getting IllegalArgumentsException and confused
1 messages ยท Page 1 of 1 (latest)
<@&987246399047479336> please have a look, thanks.
While you are waiting for getting help, here are some tips to improve your experience:
If nobody is calling back, that usually means that your question was not well asked and hence nobody feels confident enough answering. Try to use your time to elaborate, provide details, context, more code, examples and maybe some screenshots. With enough info, someone knows the answer for sure.
Don't forget to close your thread using the command </help-thread close:1027500463647621170> when your question has been answered, thanks.
Throws:
ArrayIndexOutOfBoundsException โ if from < 0 or from > original.length
IllegalArgumentException โ if from > to
NullPointerException โ if original is null
So in this case, your from > to
Which probably means your weaponIndex is not actually getting read properly
You should print out the value of weaponIndex and see what it is @pastel hamlet
Thank you let me check that out. ๐
it comes back as -1, so now i need to figure out how to actually get the index that corresponds to the weapon in the Array?
well now
it means it couldn't find the index
ok
so now try printing the contents of the array
lol i see where this is going.
but i thought this would fill the array
private String setWeapons(String gameWeapons) {
GameWeaponsArr = gameWeapons.split(",");
this.gameWeapons = Arrays.toString(GameWeaponsArr);
// encase the user accidentally presses the space bar.
return gameWeapons.replace(" ", "");
}
Detected code, here are some useful tools:
@drifting cradle
but the determineWinner is called after the method to fill the array is called. therefore shouldnt it be fille.
filled*
You are printing out the hashcode of the array. Do
System.out.println(Arrays.toString(GameWeaponsArr));
You'll still get the same error, but now at least you can see the contents of the array
let me know once you did that ๐
hmm check this out.
Ope sorry my internet went down๐
Once it says Hello, your name
Enter this:
rock,paper,scissors
so i have the deafault wrong. its not copying in the GameWeaponArr??
@drifting cradle
look at this method
private String getComputerChoice() {
String theWeapon = "";
if (Objects.equals(gameWeapons, "rock,paper,scissors")){
Random random = new Random();
int randomNumForDefault = random.nextInt(3);
switch (randomNumForDefault) {
case 0 -> theWeapon = "rock";
case 1 -> theWeapon = "paper";
case 2 -> theWeapon = "scissors";
}
} else {
Random rand = new Random();
int randomIndex = rand.nextInt(GameWeaponsArr.length);
theWeapon = GameWeaponsArr[randomIndex];
}
return theWeapon;
}
if the user just presses enter the default weapons should be rock paper scissors. but i think im doing something wrong here.
yeah
so
If the user enters nothing, your setWeapons() should default it to the appropriate weapons
@drifting cradle actually this is the wrong code. this is what i wanted to show you
private String setWeapons(String gameWeapons) {
GameWeaponsArr = gameWeapons.split(",");
this.gameWeapons = Arrays.toString(GameWeaponsArr);
// encase the user accidentally presses the space bar.
return gameWeapons.replace(" ", "");
}
yes!
if it is empty, populate it with rock paper and scissors
this is what is came up with.
private String setWeapons(String gameWeapons) {
if (gameWeapons.equals("")) {
gameWeapons = "rock,paper,scissors";
}
GameWeaponsArr = gameWeapons.split(",");
this.gameWeapons = Arrays.toString(GameWeaponsArr);
// encase the user accidentally presses the space bar.
return gameWeapons.replace(" ", "");
}
it works and fills it with the default.
but there is still the exception.
are you still printing out weaponIndex?
no let me see.
I'm sure it's still -1
because you are not setting GameWeaponsArr
you should have an if/else in that statement
if the user input is empty:
set gameWeapons to rock/paper/scissors
set array to rock,paper,scissors
else:
split the input
set gameWeapons to input
set array to input
not its not. it actually prints the right index
but isnt the elements displayed in the array [rock, paper, scissors]?
ah wait sorry
didn't see you split it
okay yeah you are all good then with filling it
thank but for some reson it still gives that same eception
something just came up irl, I would love to continue helping, I can continue if you give me maybe 15 minutes
ok thanks ๐
I can tell you right now though
your logic behind copying what is after the array and before is incorrect
since you never take into account if it's the last index or not of the array
but give me 15
ok
Okay hey sorry I'm back you still here?
@drifting cradle im here
so
i see what you mean im not checking where the selectedWeapon is located in the arr.
my brain didnt even think about that.
well I think it's actually weirdly enough fine
String[] firstArray = Arrays.copyOfRange(GameWeaponsArr, 0, weaponIndex);
// the second Array are all the elements that are listed after the selectedWeapon
String[] secondArray = Arrays.copyOfRange(GameWeaponsArr, weaponIndex + 1, GameWeaponsArr.length);
you shouldn't subtract 1 from the length
oh ok. i thought that lenght counts all the elements but it starts from 1 not 0 as the index does. thats why i thought to subtract 1
well it's exlusive
so the to can lie outside the array
so in this case, you were picking the very last index
but it wasn't being used since it's not inclusive
oh ok i see.
this is good. but if you see the rules from the project its very confusing and i dont know how to loop the elements to get the results they want.
if users input an empty line, start the game with default options: rock, paper, and scissors.
Once the game options are defined, output Okay, let's start.
Regardless of the chosen options, your program, obviously, should identify which option beats which. You can use the following algorithm. First, every option produces a draw when opposed to itself. Secondly, every option beats half of the other options and is defeated by another half. How to determine which options are stronger or weaker? Take the list of options provided by the user and pick the option that you want to know the relationships of. Take all other options from the user's list. Add them to the list of options that precede the chosen option. Now, you have another list of options that don't include the user's option with a different order of elements inside. First are the options that follow the chosen one in the original list; then, there are the ones that precede it. So, in this "new" list, the first half of the options defeat the "chosen" option, and the second half is beaten by it.
For example, the user's list of options is rock,paper,scissors,lizard,spock. You want to know what options are weaker than lizard. By looking at the list spock,rock,paper,scissors you realize that spock and rock beat lizard. Paper and scissors are defeated by it. For spock, it'll be almost the same, but it'll get beaten by rock and paper, and prevail over scissors and lizard.
so you really already have everything
i see where im messing up.
in this line
For example, the user's list of options is rock,paper,scissors,lizard,spock. You want to know what options are weaker than lizard. By looking at the list spock,rock,paper,scissors you realize that spock and rock beat lizard.
so spock is the first element in the new Arr. so does this create an array that will follow that patter.
String[] firstArray = Arrays.copyOfRange(GameWeaponsArr, 0, weaponIndex);
String[] secondArray = Arrays.copyOfRange(GameWeaponsArr, weaponIndex + 1, GameWeaponsArr.length);
List<String> newWeaponList = new ArrayList<>(Arrays.asList(secondArray));
newWeaponList.addAll(Arrays.asList(firstArray));
String[] finalArray = newWeaponList.toArray(new String[0]);
well
right
so you make an arraylist with the secondarray
then you add the first array content into it
then split the array in half
the first part of it wins
the second part loses
but what if the userWeapon is the last element like you said???
thank you again for helping me. i know its late. if i cant get this ill just move on to another project ๐ข
ah sorry, my mind isn't in it right now sorry ๐
okay I am back and concentrated ๐
you have one more off by one erorr
List<String> seconsHalfOfList = new ArrayList<>(newWeaponList.subList((newWeaponList.size() / 2), newWeaponList.size()));
@pastel hamlet then i think it works perfectly
@ you drink coffe ? lol
๐ maybe..
so I think if you try that out, it should work with just rock,paper,scissors
ok let me see
@drifting cradle yessss it does ๐ (with rock paper scissors)
lets see with the others.
now to test it with the others ๐
I think it will work
dang you had a lot of off by 1 errors
you pretty much had the logic on point
yesss passed 2 test ๐ but ...
it doesnt handle the invalid input right. my if else is off i think.
That's because you are validating input in the wrong place
It should be the very first party
statement in the method*
Just add a check before you do anything fancy with lists
yeah your right. let me implement.
ok there is a few other things i need to do with the code before hand to check that.
@drifting cradle i did this and it checks the invalid correctly.
List<String> gameWeaponList1 = new ArrayList<>(Arrays.asList(GameWeaponsArr));
if (userWeapon.equals("!rating")) {
System.out.printf("Your rating: %d\n", getRating());
} else if (userWeapon.equals("!exit")) {
endGame();
} else if (!gameWeaponList1.contains(userWeapon)){
System.out.println("Invalid input");
} else {
// initializes the variable to the index number of the userW
I dunno what the instructions state to do if they enter invalid data
but you could also do something like this in determineWinner
if(!Arrays.asList(GameWeaponsArr).contains(userWeapon)){
System.out.println("bad input");
return;
}
@drifting cradle i got it to test 7 and it failed because its reading the file wrong.
no i got the Invalid to work ๐
the file
should be a .txt file with the names
Tim 350
Jane 350
Alex 350
Bob 350
i check it with is this.
private int readContentOfFile(File file) {
Scanner scanner1;
try {
scanner1 = new Scanner(file);
while (scanner1.hasNext()) {
String[] userData = scanner1.nextLine().split(" ");
if (userName.equals(userData[0])) {
rating = Integer.parseInt(userData[1]);
}
}
} catch (IOException e) {
System.out.printf("Unable to execute %s", file.getPath());
}
return rating;
}
static File file = new File("../rating.txt");
from my Main class
ok i fixed
awesome ๐
let me try one more thing then its bed time lol
still failing a test?
yeah but i dont think this is a "me" thing is a bug i think.
in the project comments section they say there is a bug in that there should be a user name Bob that has a score of 350 as a starting point. so i put Bob in the file with a score of 350 but it still fails. then i take Bob out and assign him the rating/score of 350 and it still fails.
waittt hold on lol.
i didnt increase rating by 100 when they win ๐
now the last test. lol
๐ฅณ almost done!
hell yeah! Grats ๐บ
thank so much!
of course
how can i add you as friend in case in the future i need your input again??
I'm afraid I can't do that. Part of the discord rules here :(. But you are always welcomed to continue making questions here
I or someone else will always take a look
ok ๐
/help-thread close