Bummer! This is just a preview. You need to be signed in with a Basic account to view the entire video.
Start a free Basic trial
to watch this video
Let's use exceptions to help control the flow of the game. We'll attack the story: As a guesser, I should be stopped from making a guess that has already been made, so that I do not waste turns.
Learn more
-
0:00
[MUSIC]
-
0:04
Welcome back.
-
0:06
We're getting ready to put the final touches on our MVP and
-
0:09
we've only got a few user stories left.
-
0:11
So the next one up is, as a guess or I should be stopped for
-
0:14
making a guess that has already been made, so that I do not waste turns.
-
0:19
Okay, so let's think this through real quick.
-
0:22
So when we pass a guess into our game object if you applyGuess,
-
0:25
we currently just add it to hits or misses.
-
0:28
What we need to do before we do any of that,
-
0:31
is to add a check to see if it's already been guessed.
-
0:35
Which we can do by seeing if it's in hits or misses.
-
0:39
Now if it has been guessed,
-
0:41
we need to let the caller on applyGuess know that they did something wrong.
-
0:45
We should do this at the game object level,
-
0:48
that way any other consumer of our game logic will benefit.
-
0:51
Then how should we let them know do you think?
-
0:56
Well it's exceptional behavior.
-
0:58
Hey, why don't we throw an exception, and
-
1:00
then any caller of that method can handle that.
-
1:03
Let's give it a try.
-
1:05
All right, so let's move this prevent multiple guesses into in progress, and
-
1:10
let's head over to our game class.
-
1:12
So let's take a look here in applyGuess.
-
1:17
So this is probably where we wanna run our check, right?
-
1:20
So before anything happens, let's do it.
-
1:22
We wanna see if what was passed in letter here is either in hits or misses.
-
1:27
So why don't we lean on indexOf.
-
1:29
Now remember, negative one shows that it's not found, so don't try to do this?
-
1:34
Why don't you go try to do this, see if misses has the letter, or
-
1:38
hits has the letter.
-
1:39
Go ahead, possibly.
-
1:41
Okay, here's how I did it.
-
1:43
So if misses.indexOf has the letter,
-
1:48
and again that's not not found.
-
1:52
If it's not not found, if it's found or
-
1:54
hits.indexOf(letter) is not equal to 1.
-
2:03
So again, that pipe means or, so
-
2:05
if either one of those is true, then we'll throw an exception.
-
2:09
I'm gonna go ahead and close my if.
-
2:11
So we'll throw this exception, right?
-
2:13
The argument that they passed in here was not allowed,
-
2:16
this letter argument is not allowed.
-
2:18
It's in the illegal argument, so
-
2:19
that sounds like an illegal argument exception, right?
-
2:22
So again, that's throw and we make a new one of those,
-
2:27
IllegalArgumentException, and it takes a message.
-
2:32
So let's go ahead and say letter has already been guessed.
-
2:42
Awesome, so that should do it.
-
2:44
So now what we need to do,
-
2:45
is we need to see whoever calls this method in any of our code.
-
2:48
We wanna make sure that they're handling this exception that can come out properly.
-
2:53
So in workspaces, what I can do is I come up here and I can say Edit, and
-
2:57
I can choose Find in Files.
-
2:59
Brings up a little search box up here, and I'm gonna try to find applyGuess.
-
3:04
And so what that'll do is it will search through all of our files, and
-
3:06
it found one here in Prompter where we're using it.
-
3:09
Which we know we just wrote this code.
-
3:10
But I wanted to show that example of how to use workspaces to find
-
3:14
where these exceptions might be called.
-
3:16
Okay, so the Prompter is currently returning the result of game.applyGuess.
-
3:21
So we don't want the exception to throw out a here basically.
-
3:25
Let's let's catch this.
-
3:26
So first thing we wanna do is we want to store that in a variable.
-
3:31
So let's go ahead and let's say boolean isHit equals that.
-
3:37
And then we wanna make sure that we still return it right,
-
3:39
cuz the method still wants a boolean.
-
3:41
So we'll say return isHit.
-
3:45
Okay, so now we
-
3:50
need to try to wrap this call to applyGuess in a try catch block.
-
3:55
So let's do that.
-
3:56
So let's make a new try.
-
4:00
Open that up.
-
4:00
I'm gonna go ahead and close that.
-
4:02
And then immediately we'll do a catch, and
-
4:05
we're catching the IllegalArgumentException.
-
4:12
Again you can name this whatever.
-
4:13
I like to name them, iae, IllegalArgumentException, and
-
4:17
we'll close the catch there.
-
4:19
Okay, so let's go ahead, and I wanna move this into the try.
-
4:26
And in here, what we'll do is we will just go ahead and
-
4:29
output the message that we have our hands already.
-
4:32
And we're in the Prompter, so we can prompt here.
-
4:34
And say printIn, and we'll just say that there was an error basically, and
-
4:38
it'll say getMessage, right?
-
4:40
That was that letter that could not be found that we put in.
-
4:42
So now we have a little bit of a problem, and
-
4:44
it might not be too obvious just looking at this.
-
4:47
So, remember how each one of these curly braces opens up a new scope.
-
4:53
Well, let's look at what we're doing in this try scope here.
-
4:56
We're declaring a variable called isHit in this scope.
-
5:01
But then we're attempting to use it in an outer scope here.
-
5:04
So see how this is an outside,
-
5:08
it's in the method scope but it's not in the try scope.
-
5:11
The declaration is happening inside the try scope.
-
5:14
If you tried to compile this, you would get an unknown symbol with an arrow
-
5:17
pointing right here to this isHit when you try to compile it,
-
5:20
which is basically saying, I have no idea what you're talking about.
-
5:23
That's because it's declared here.
-
5:24
So what we need to do, is we need to declare the variable
-
5:28
outside of the try block, so isHit equals false.
-
5:33
And then we can remove this declaration and just set it.
-
5:39
So there's no problem with the inner scope accessing this outer scope
-
5:44
here at the method scope it has access, this is declaring the method scope and
-
5:47
inner scope has access here but it's the other way around that doesn't work, right?
-
5:50
We can't define something in the inner and then how the outer work.
-
5:53
So now let's imagine what would happen.
-
5:55
So if we passed in a t and then we passed in a t again, so it's gonna come in here.
-
6:00
It's gonna call the applyGuess, and applyGuess is gonna throw an exception,
-
6:03
right, cuz it's gonna find that it's been found already.
-
6:06
So it's in hits, so one of these is true.
-
6:09
This one or this one is true, and it's gonna come in here,
-
6:11
it's gonna throw the new exception, and then it's gonna go right into here.
-
6:16
Now it's not gonna return and set this to false.
-
6:18
Even though it already is false.
-
6:19
It's not gonna return here.
-
6:20
It's gonna go pop right into here, and then we're gonna come through.
-
6:23
So let's give this a run.
-
6:35
All right, so let's figure out what we did.
-
6:37
13 errors, that can feel super overwhelming.
-
6:40
Let's see if we can figure out what happened.
-
6:43
So see all of these errors is just because of this one here, unclosed string literal.
-
6:49
So if we go to game.java, line 15.
-
6:54
I forgot a quote, why didn't you say something?
-
6:58
All right, let's try that again.
-
7:00
You probably do, you're probably sitting there yelling at the screen.
-
7:02
Why did you put a quarter?
-
7:05
Okay, so here we go.
-
7:06
So let's guess t.
-
7:07
Then I'm gonna guess t again.
-
7:09
And bam, it says t has already been guessed, did it?
-
7:14
What happens if we guess a capital T?
-
7:18
I'm glad we tested that.
-
7:22
Let's go ahead.
-
7:23
Let's flip it over to our board.
-
7:25
It took it as a different guess, didn't it?
-
7:28
Okay, so this is done, right?
-
7:30
Let's move this one over, and
-
7:32
unfortunately we're gonna do it one step forward, and we're gonna add another one.
-
7:35
So it's your let's add here, let's add a new error or
-
7:39
a BUG as we call them in programming.
-
7:41
Check the teacher's notes to find out the strange reasoning behind that
-
7:44
name for BUG.
-
7:45
But I'm gonna say BUG Uppercase and
-
7:49
lowercase values are treated differently.
-
7:55
And Trello has a nice little feature here when you come in to edit these.
-
8:01
Let's go ahead and set the label, let's make it red so it kinda sticks out,
-
8:04
it's a little louder.
-
8:05
So there we'll see that it's red.
-
8:07
I'm totally glad we checked, that could have been a big problem if people were
-
8:10
guessing uppercase letters, we would have been treating them completely separately.
-
8:14
Let's fix that right after this quick break.
You need to sign up for Treehouse in order to download course files.
Sign up