# Need help improving number guessing game

B

#### Bruno Desthuilliers

feba a écrit :
whitespaces (inlcuding newlines, tabs etc).

Ahh. I had removed it because it didn't seem to do anything, but I've

And I understand your dictionary stuff correctly now, I think, and I
worked it in. Currently, I have:

import random

def safeint(prompt="y"):
while True:
x = input(prompt)
try:
x = int(x)
except ValueError:
else:
break
return x

def safestr(prompt="y"):
while True:
x = input(prompt)
try:
x = str(x)

Doesn't input already return a string ?
except ValueError:
else:
break
return x

You could as well replace the 'break' statement by 'return x' - since
returning will obviously break the loop

Now don't you notice kind of a pattern in these two functions ?
obviously, the only thing that change is the conversion/validation part.
The good news is that Python functions are objects too, so you can pass
them as params to another function. The generic version of your above
code could be:

def safeinput(prompt, convert):
while True:
x = input(prompt)
try:
x = convert(x)
except ValueError, e:
print("Bad input : %s" % e)
else:
return x

then you can use it for int:

i = safeinput("Please enter an integer", int)

or use more complex conversion/validation:

def yesno(s):
s = s.strip().lower()
if not s in ("y", "n"):
# we return a boolean
return s == 'y'

answer = safeinput("really do this ?", yesno)

Last point : if your conversion/validation function needs more arguments
than the value to convert - ie : converting to an int and vaidating this
int is in a specified range, which require mini and maxi arguments for
the range - you can use partial evaluation[1]:

from functools import partial

def int_in_range(x, mini, maxi):
x = int(x)
if not mini <= x <= maxi:
raise ValueError("%s is not in range (%s, %s)" % (x, mini, maxi))
return x

i = safeinput(
"Please enter an int between 1 and 99",
partial(int_in_range, mini=1, maxi=99)
)

[1] given the function f(x, y): return x + y, the partial evaluation
partial(f, x=2) is a function fx(y) that when called returns the result
of f(2, y).

(snip)
I'd need to find out how those work,

Mostly as glorified dicts with associated functions. Your game and
players dicts are obvious candidates. Whenever you see a dict with a
more or less defined "structure" and a set of functions working on this
dict, you have in fact a class waiting to be born.

and I have a list of python stuff
to read piling up anyway... That said, I think for something like
that, something that's not a major flaw, I'd prefer to make something
else, and maybe work on this again later on. There is only so much
guessing numbers one person can take.

Indeed. That was just a suggestion, and it would have been pretty
interesting IMHO as a basis for a "from Q&D procedural scripting to OO
application programing" tutorial.

F

#### feba

The good news is that Python functions are objects too, so you can pass
them as params to another function.

duh, duh, duh, duh, duh! I knew I was missing something there. Thanks.
if not mini <= x <= maxi:

also thanks for this, I forgot about that. But I have it as

if not minr < guess < maxr:

because it's to DISALLOW the numbers to stay the same.
That was just a suggestion, and it would have been pretty
interesting IMHO as a basis for a "from Q&D procedural scripting to OO
application programing" tutorial.

Yeah, I can see that.

D

#### D'Arcy J.M. Cain

You could also do this to be a little more user friendly:
if not (s and s[0] in ("y", "n")):

Or reverse the test for clarity.

R

#### r.drew.davis

6; can anyone think of anything else to add on to/do with this game?
With the minr/maxr display, multiplayer, score keeping, and
automation, I'm just about all of ideas. All I can think of left to
add is 3 and 4 player modes, or a fork where player 2 can't win
(kekekekeke. Though I'm not sure how to do it...), both of which I
feel are somewhat pointless for a game like this. If I can't learn
anything more from it, I will probably go back to reading python
guides for a bit, and then try to make something else.

Well, if you want to aim for several more rounds of refinement, how
about having the game allow many players identified by name
and have it keep records in a file: player name, number of times
played, best score, best elapsed time for game completion - for each
player. Can you do it in such a way that multiple people on different
PC's can all play the game at the same time and not scribble over each
other's scores? One approach would be to insist that the player's
using a network mount of a disk from somewhere. A fancier approach
would be to have a score keeping "service" that runs somewhere and
each player's computer uses the network to interact with that score
keeping service. Besides the game playing front end to the score
keeping service, maybe you should have an administrative front end to
the score keeping service to allow you to delete the names of deceased
game players. (The only thing keeping him on his perch were tiny
little nails through his feet).

Can just anyone play the game or does the administrator have to add
their name as an authorized player to the score keeping service before
they are allowed to play? Is it "Scout's honor" that palyers are who
they say they are, or is there some kind of authentication for a
player to "prove" their identify before they are allowed to play?

I remember many years ago back in graduate school, a friend
implemented a clone of "pong" with record keeping. People would sit
with that stupid game into the middle of the night striving to improve
their standings in the best score display. May be more addictive
with a "harder" game than this number guessing game but having your
score being visible to other players can be powerful motivation to
strive for better scores. If only my friend had figured out a way to
have the little DEC GT40 demand quarters if the player wanted to play
again, he'd have had most of his tuition nicely covered.

thing you could strive to do is change the game from a "tty" interface
to something more screen oriented. e.g. instead of having a prompt
for "play again (y or n):" you'd have buttons on the screen that the
player can click that say "quit" or "start new game". Note that the
player might decide to click on either of those buttons at any time,
not just after they have completed a game. Python has several many
different libraries that would give you a basis for building such a
"graphical user interface" (GUI) version of your game, but I'm not
experienced enough to tell you which GUI package you should look into.

Not so much related to the business of making a niftier game, but
another area you might want to look into is change management (e.g.
"subversion") so you can track the evolution and refinement of your
source code over time. The player-visible part of that is perhaps
just to have something that announces which revision of the game they
are running such that you can tell from that which revision of the
source code to look at if you are tracking down a fix for a problem
they have encountered and reported to you.

Drew

A

#### Arnaud Delobelle

There was a thread about "is not" recently. Python also allows "not in".

if s not in ("y", "n"):
You could also do this to be a little more user friendly:
if not (s and s[0] in ("y", "n")):

Or:
if s[:1] not in ("y", n"):