This week's book giveaways are in the Cloud and AI/ML forums.
We're giving away four copies each of Cloud Native Patterns and Natural Language Processing and have the authors on-line!
See this thread and this one for details.
Win a copy of Cloud Native PatternsE this week in the Cloud forum
or Natural Language Processing in the AI/ML forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Devaka Cooray
  • Liutauras Vilda
  • Jeanne Boyarsky
  • Bear Bibeault
Sheriffs:
  • Paul Clapham
  • Knute Snortum
  • Rob Spoor
Saloon Keepers:
  • Tim Moores
  • Ron McLeod
  • Piet Souris
  • Stephan van Hulst
  • Carey Brown
Bartenders:
  • Tim Holloway
  • Frits Walraven
  • Ganesh Patekar

Help with Number Guessing Game

 
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
I am new to java and programming in general. I am about 3 weeks into a computer science course and I'm having a little trouble completing my first big assignment. We are supposed to create a number guessing game with options.
If the player chooses option 1, the computer guesses a number the player is thinking of. If they choose Option 2, the player guesses a number the computer is thinking of. Option 3 shows the game statistics and option 4 ends the game. I think i have options 1 and 2 completed (but I welcome any suggestions and/or improvements). I am stuck with how to get the game statistics part. Game statistics should include how many tries on average it took the computer to guess the player number, and how many tries on average it took the player to guess the computer's number, along with the number of games of each played. (I added a game and try counter to my options, but I do not know how to get them into the main class.) Statistics should also display the number of times the player lied to the computer, and don't include those games in the statistics. I do not know how to tell if the player lied to the computer.


Here is what I have so far:


 
author & internet detective
Posts: 39391
761
Eclipse IDE VI Editor Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jessica,
Welcome to CodeRanch!

Have you learned about instance variables yet? That's where you define the variables outside a method so that all the game methods can access them.
 
Saloon Keeper
Posts: 6032
58
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Instead of
I suggest changing the name of "option1" to something like "guessNumber". So, you'd end up with
which is more readable and easier to follow.
 
Sheriff
Posts: 13549
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Jessica Lawrence wrote:Statistics should also display the number of times the player lied to the computer, and don't include those games in the statistics. I do not know how to tell if the player lied to the computer.


When you have the computer guess the hidden number, you obviously don't have it guess randomly, right? It has a certain algorithm that you're using to narrow down the field of possible values (basically, a binary search). That algorithm depends on the human player giving the correct clues. If the wrong clues are given to the computer, the algorithm doesn't work. If the computer runs through the search algorithm and ends up with no logical guesses left to make, then you can be pretty sure that the human player lied or at best, "misled" the computer. You'll have to make sure you include some logic in your code that will detect when that happens.
 
Junilu Lacar
Sheriff
Posts: 13549
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:you obviously don't have it guess randomly, right?


Well, color me disappointed. Looks like you did somewhat have the computer guess randomly. Why would you do that? The Binary Search algorithm would guarantee that the computer will need no more than 9 tries to guess a number between 1 and 500, assuming it is always given the correct clues. (2^9 = 512)  That algorithm always start at the halfway point of the possible range of numbers. You're starting at some random point within the possible range. That simulates what a naive human player would do. A logical player will use the Binary search algorithm for maximum efficiency.
 
Saloon Keeper
Posts: 3406
149
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote: (...)


What is wrong with an algorithm that guesses randomly (assuming it will always lead to the correct outcome)? That such an algo is not optimal, will become evident when you look at the statistics, where it will be apparent that the human (assumed to use a more advanced strategy) scores way better, and that will make you think further.

Coming to the question of statistics:
suppose you have a class 'GameStatistics', having the fields 'numberOfGamesPlayed' and 'TotalNumberOfGuesses', and has a method 'addNewData(int nrOfGuesses). (and orf course a method that cauculates the average number of guesses).

When you initialize your game, you can create two instance fields, 'computerStats' and 'humanStats', that you initialize with, say,

and likewise for the human.
Whenever a guessing session ends, you update the statistics for the player at hand.

Having that, you should be able to present the stats.
 
Junilu Lacar
Sheriff
Posts: 13549
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

1. Choose names that express the intent (what it represents), not implementation (how it came to be or does things)

Consider these two names:  "randNum" vs. "secret"

Which of the two names tells you what it represents (intent/purpose)? Which one tells you how the value came to be (an implementation detail)? See this article for more guidelines on choosing good names to use in your programs: Ottinger's Rules for Variable and Class Naming

2. Format your code properly so that the logic structures can be easily discerned. When you don't line up and indent the code properly, it's harder to follow the logic and you can easily introduce (or hide) bugs as a result. That section of code is properly formatted as this:


The way you had formatted it before, it looked like the closing brace on line 122 matched the opening brace on line 110. Properly formatted, it's clear that the closing brace on line 122 matches another opening brace higher up in the code listing. I prefer to use a different style of formatting, which is probably more common for Java programs:

Coding and indentation styles are either a matter of preference or standard chosen by an organization. Choose a style you prefer and use it consistently or follow the style you're required to follow by your professor or programming team. Just be consistent in applying it.

3. Don't Repeat Yourself (That's a programming principle)

It may take you a while to start recognizing when you have it but try to find ways to remove duplication in your code. This requires a lot of practice.

4. Don't make redundant comments.

The comment on line 108 is redundant. That's the same thing that the code is saying. And you spelled "too" incorrectly. Double whammy.

I won't even say anything about the comments on lines 111 and 117, Captain Obvious.  

Actually, it looks like the comment on line 117 was copy pasted from line 110.  Bad practice. Now your comment is wrong.

You could make your code more expressive and eliminate the need for comments by refactoring the formula to their own little methods:
 
Junilu Lacar
Sheriff
Posts: 13549
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Piet Souris wrote:What is wrong with an algorithm that guesses randomly (assuming it will always lead to the correct outcome)?


There's nothing wrong per se but it's not something I would expect a computer simulation to do. I'd expect the programmer to choose the most efficient (and logical) algorithm as possible, unless of course the requirement was to simulate a naive human player. Call me strict but if I were the professor, I'd give points for effort but take points off for logic. (Caveat: if the student can successfully argue their case, e.g. there was no stipulation in the requirements to make the computer play in "smart" mode, then I'd gladly give points back. But then again, I'd make sure to put that stipulation in the problem statement)
 
Piet Souris
Saloon Keeper
Posts: 3406
149
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, if you were my professor, I guess we would be in for some firm discussions then!    

But I'll postpone my answer until OP is satisfied with her code (including the statistics).
 
Marshal
Posts: 65005
246
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Again, welcome to the Ranch

Junilu Lacar wrote:. . . Format your code properly . . .

Junilu is right. It might make us look like fusspots saying that sort of thing, but we see lots of people who have strange things happening to their code and becausee they haven't indented it according to one of the well‑known conventions. It is even more confusing when the actual indentation error slips past the compiler; we even see people who write classes inside other classes because they haven't got their {} propperly matched. You will doubtless be aware of the use of a decent text editor (see this old post of mine and our FAQ) , but you will know nothing about writing backwards, but both those things will help with formatting.
An else‑if is a particularly confusing example for indentation. You would think that line 115 should be moved to the right of line 109, but the else matches the if, so the two should be at the same indentation level. I know you have been taught, quite correctly, that every else needs {} and the following if is nested insdie that else, but if you do that you will end up with code looking like this:-But nobody ever indents else‑ifs like that. Everybody writes this sort of thing:-
 
Jen Lawrence
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Piet Souris wrote:

Coming to the question of statistics:
suppose you have a class 'GameStatistics', having the fields 'numberOfGamesPlayed' and 'TotalNumberOfGuesses', and has a method 'addNewData(int nrOfGuesses). (and orf course a method that cauculates the average number of guesses).

When you initialize your game, you can create two instance fields, 'computerStats' and 'humanStats', that you initialize with, say,

and likewise for the human.
Whenever a guessing session ends, you update the statistics for the player at hand.

Having that, you should be able to present the stats.




Thank you for your suggestions. I am confused by the concept of methods and classes.....Can you elaborate a little more? I think I kind of understand what you are suggesting. Am I headed in the right direction?



I am just not sure how to get the numbers from my playerTries and computerTries into this class or into any class besides the one they exist in.
 
Jen Lawrence
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:

Junilu Lacar wrote:you obviously don't have it guess randomly, right?


Well, color me disappointed. Looks like you did somewhat have the computer guess randomly. Why would you do that? The Binary Search algorithm would guarantee that the computer will need no more than 9 tries to guess a number between 1 and 500, assuming it is always given the correct clues. (2^9 = 512)  That algorithm always start at the halfway point of the possible range of numbers. You're starting at some random point within the possible range. That simulates what a naive human player would do. A logical player will use the Binary search algorithm for maximum efficiency.



Hi Junilu,
I did not even think to make the computer smarter at this game as I can barely figure it out myself
Thank you for catching my typos and indents as well! I have corrected those. And thank you for the link on how to properly name variables and classes.
 
Junilu Lacar
Sheriff
Posts: 13549
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Piet Souris wrote:Well, if you were my professor, I guess we would be in for some firm discussions then!    


No doubt. But the fact that I'd be your professor, you're kind of at the losing end of any disagreement that comes down to a matter of opinion rather than logic or fact.
 
Jen Lawrence
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Is this looking better as far as spacing? I used switch to get rid of some of the ifs and I tried to clean up the rest of my ifs and else ifs. I realize that I am duplicating a lot, but I am not sure how to simplify it...and I'm still stuck on the stats and how to code for the player lying.
 
Piet Souris
Saloon Keeper
Posts: 3406
149
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Junilu
Forget about opnions and logic, let's fight this out in a way that real men fight it out: you black belt Aikido against me, blue belt Jiu-Jitsu and Karate! And help atributes like walking sticks and rollators are out, of course!  

But first lets help Jessica, I will only do the statistics part, for when it comes to refactoring and similar, I don't stand a chance, since you are the undisputed CodeRanch World Champion HeavyWeight Refactoring.

@Jessica
what you presented is a method 'gameStatistics', but what I meant is a genuine class 'GameStatistics', for instance:

Now, in your Game class, incorporate two fields:


When the computer has finished succesfully a guessing session, using N attempts, then it is time to update the computers statistics:

and likewise when the human has guessed the secret number.

And when the option is chosen to display the statistics, then it is simply a matter of calling the 'getAverage' method for the computerStats and the humanStats.

I hope it is clear what I meant. If not, please ask, if it is, I leave you to Junilu!
 
Junilu Lacar
Sheriff
Posts: 13549
223
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Piet Souris wrote:@Junilu
Forget about opnions and logic, let's fight this out in a way that real men fight it out: you black belt Aikido against me, blue belt Jiu-Jitsu and Karate! And help atributes like walking sticks and rollators are out, of course!  


I'm sure if we met on the street, it would be nothing but handshakes, hugs, and pats on the back flying between us. You, pardner, have come a long way since you first joined us and I think I speak for everyone in saying that we value your contributions to the Ranch

However, given the unofficial title you have bestowed upon me, I must defend my humility by taking a stab at refactoring the code you suggested. (Keep in mind this is all in good sport, given with the utmost respect for a fellow martial artist)

Let's start with the good: Representing the game statistics as a separate concern. I like the idea because it moves the responsibility out of the Game class and eliminates the need to maintain multiple sets of instance variables. This not only tightens the scope of those variables, it also helps you DRY up the Game class. The result is a more cohesive Game class and a cohesive GameStatistics class. Again, we must recognize this as a good design choice.

Additional refactorings I would make can be "discussed" and negotiated. These are not things I would insist on doing. If it were just up to me, I'd do them but would not argue too strongly for them either. Here's how I would prefer to see that class written:

My coding style preference is to not explicitly write down anything Java does by default. In this case, Java provides a no-arg default constructor and it also initializes the instance variables to 0, so I eliminated the code that does those things explicitly. I also declared the class as final since the current requirements do not have any justification to allow the class to be extended.

As always, I prefer names and declarations to speak for themselves. I prefer the alternative names shown because they are closer matches to how I would talk about the ideas represented:

"How many guesses were there in that round?"

"How many total guesses have there been [through all rounds played so far]? That is, what's the guess total at this point?"

"On average, how many guesses per round played does it take to figure out what the secret number was?"

This is why I always insist on reading the code out loud when I'm pair programming (or even when I'm programming solo).
 
Jen Lawrence
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Piet @Junilu, I am sorry, but you have both lost me. We are just starting to learn about methods, we have not yet learned about classes.
 
Campbell Ritchie
Marshal
Posts: 65005
246
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In which case, how on earth do you write methods? Methods have no existence without surrounding methods classes.
 
Jen Lawrence
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I just meant I am completely new to programming. I am 3 weeks into my first computer science class. We are learning about methods and how to write and organize them, but I do not know how to create a new class or what to put in it. I am just going to turn in what I have and hope for the best.
 
Piet Souris
Saloon Keeper
Posts: 3406
149
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi Jen,

I didn't expect your answer. I don't want to go beyond what you have been taught yet, so forget for the moment about that GameStatistics class.

First of all: what have you been taught about static variables, instance variables and local variables? The reason I ask is that you have local variables in your main, like computerGames and computerTries, (see your latest code) but that the number of guesses is determined in an instance method, either 'guessNumber()' or 'playerguess()'. That is an unfortunate construction, asking for trouble. It is begging for a rewrite of your code. Explanation of this would take quite some time, so let me adjust your code as little as pssible to get the statistics part up and running.

Global health warning: never ever do this in your coming programs!

I gave the two guessing methods a return value, so that they return the number of guesses that were needed in that session. Having that number returned, I can, in the main method, update the statistics values, that I use in the printing of the statistics variables when option 3 is chosen.

So, have a look at what I did. Again, it is against all rules of clean ccoding, so be it for now.

If you want to, we can discuss what is wrong about your code, but I leave that up to you. It depends much on how far you are with your course.

Anyway, here is the slightly adjusted code:

 
Campbell Ritchie
Marshal
Posts: 65005
246
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Have you been through any tutorials?
 
Don't get me started about those stupid light bulbs.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!