Program Win/Loss statistics in Number Guessing Game for Python - python

I've written a program for a Number guessing game in Python which i have almost completed. However, there is one small problem i can't figure out. After the game finishes I want the statistics to be printed out for each player to a .txt with the following information:
Username | Win or Loss | Number of Guesses.
I can't figure out how to generate the Win/Loss statistic in the following line for each player:
f.write(str(playerName)+ '|' +str(numberOfGuesses)+'\n').
If anyone could please provide some advice it would be greatly appreciated. I have displayed part of the code as follows:
won = False
while numberOfGuesses < maxGuesses:
guess = int(input('What is your guess?: '))
numberOfGuesses += 1
if guess < number:
print('Too low')
if guess > number:
print('Too high')
if guess == number:
won = True
break
print('You have', str(maxGuesses - numberOfGuesses) + ' guesses remaining\n')
if won:
print('Congratulations!!! You guessed the number in ' + str(numberOfGuesses) + ' tries!')
else:
print('Game Over!!! You did not guess the correct number, the number was ' + str(number))
f = open('Statistics.txt', 'a')
f.write(str(playerName)+ '|' +str(numberOfGuesses)+'\n')
f.close()
f = open('Statistics.txt', 'r')
print(f.read())

It's pretty, simple.
To clarify, if won == True, you want to write "Won" to the line and if won == False, you want to write "Loss" to the line right?
win_or_loss = 'Loss'
if won:
win_or_loss = 'Win'
Then you just use this variable when you write to the file
f.write(str(playerName)+ '|' + win_or_loss + '|' +str(numberOfGuesses)+'\n')
Also, you don't need to wrap playerName in str() since it is already a string.

Since you have playerName in the mix, I assume you're trying to keep score stats per player. In that case, I suggest you create a dictionary keyed on player names. The values can be lists of [numCorrect, totalGuesses] per player. You would update numCorrect and totalGuesses during each player's turn as appropriate. In the end, you would walk through that dictionary and process the results.

Here's the logic to implement so you can get the Win/Loss stats.
For each game, you will have the following
Player Name, Win or Loss flag, Total Guesses.
Read statistics file to see if player exists. If player exists, then retrieve the following information:
Player Name, Win Count, Loss Count, Win-Loss Stats, Lowest Number of Guesses
* Win Count will be # of times player has won in the past
* Loss Count will be # of times player has lost in the past
* Win-Loss stat will be Win / (Win + Loss). If you want % then x by 100
* Lowest Number of Guesses for the first entry will be numberOfGuesses
For all subsequent entries, you need to update the record in the file based on new calculations as shown below.
If current game is win, win_count += 1
If current game is loss, loss_count += 1
win_loss stat will remain win_count / (win_count + loss_count)
if numberOfGuesses < lowest_number_of_guesses: lowest_number_of_guesses = numberOfGuesses.
#you can modify this with walrus option if you use 3.8+
Write back this stats to the file. This will keep track of the status for the player and you can use this to keep the stats updated every time the player plays
Since you are going to have a lot of I/O with the above logic, you may want to read the file into memory and calculate this in memory, then write to file as part of normal program exit. One challenge is that the data will be lost if the program abruptly crashes.
Hope this helps you implement a good logic.
I wanted to write this in comments but the max chars exceeded. So put this in the answer comments. I would prefer you write the code as it will help you with the implementation of the logic.

Related

Betting system won't seem to process the user input correctly, how can this be improved?

I'm trying to code a game of craps in which the player has a virtual 'wallet' to gamble with. I've gotten to the user input part and it's not going as planned.
Here is what I have so far:
import random
import sys
money = "500"
# start the game
a = input("Hello travler, to start the game, please type 'yes'. If you are not ready to begin your journey, type 'no' ")
if a.lower() == "no":
sys.exit()
else:
print("Welcome")
print("Hold on... I'm missing something,")
name = input("What is your name, traveler?: ")
print("Welcome,", (name))
# those who need instructions can ask for it,
# others can start the game directly.
a = input("Welcome to a game that'll determine the rest of your life. Do you need instructions? (yes) or (no)? \n")
if a.lower() == "yes":
print('''1. the player will roll two six sided dice. the sum of the two dice is the player's number for the round.
2. rolling a 7 or an 11 as your first roll win you the game, but be weary, a 2, 3, or 12 automatically causes the player to lose. no more game for you. If a 4, 5, 6, 8, 9, or 10 are rolled on this first roll, that number becomes the 'point.'
3. the fated player continues to roll the two dice again until one of two things occur: either they roll the 'point' again, causing them to win the game; or they roll a 7, causing them to be doomed to the eternals.''')
elif a.lower() == "no":
print("may luck be with you on this fateful day,", name)
print("You will start off with 500 pieces of luck, if you leave this game with over 1000 pieces of luck, you will be fated for sucsess. On the other hand, should you drop below 0 peices of luck, you will find yourself in debt to the universe, a misfortune that few recover from.")
print("You currently have", money, "luck to spare")
# betting time
while True:
bet = input("How much luck do you wish to bet? ")
if bet.isdigit() is True:
if money > bet:
print("Bet accepted")
if bet.isdigit() is True:
if bet > money:
print("How unfortunate, you do not have the luck to make this bet.")
elif bet.isdigit() is False:
print ("Sorry, luck can only be quantitated in number values.")
# if you bet higher than your money, it wont allow you to bet within after that.
The code below the line # betting time is where I am hitting my head over.
I need the code to do the following:
check if the user input is in fact a number, if it's not a number, make them enter a new input
if the user input is a number, determine if it is within the amount they have in their 'wallet' (if not, make them input a new number)
if the number is within the amount in their 'wallet' and is a digit, give the user the option to "roll dice" triggering the game to start.
If they win, they need to be granted double what they bet, if they lose, they need to lose the amount they bet. The wallet will need to update after each play, giving the user the option to play again with their updated wallet (so if they bet 50 and win, their new balance will be 550. The process continues until the user either reaches 1000 or 0, causing the game to end either way.)
For checking if the user's bet is a number use the .isnumeric() function on your bet like:
bet.isnumeric()
to do the second thing you needed help with you could do:
if bet < wallet: blah blah blah elif
bet > wallet: print("You do not enough money")
around like that it with actual good syntax
to do dice you could use the random.randint() function like this:
random.randint(1,6)
I hope that helps!

local variable 'output_file' referenced before, this code worked a few weeks ago, now it doesnt work how is that possible?

This thing is hard to post code and context inside of.
#This is a menu driven multiplication game. i am attemtping to save the high
#score in a file named multiplication_game.txt...
def single_player():
in_file = open('multiplication_game.txt', 'r')
highest_times_selection = int(in_file.readline())
print('\n____now lets see how u do on the times tables____')
correct = 0
missed = 0
times_selection = int(input(
'\nPlease enter a times time table integer to practice: '))
#This simple generates the multiplation questions and checks for right or
#wrong.
for number in range(0,11):
print(times_selection, 'x' , number, '=')
user_answer=int(input('answer: '))
correct_answer = times_selection * number
if user_answer == correct_answer:
correct+=1
else:
missed+=1
#This is where if its a perfect score and a high times table than the
#previous saved score it should be opened and the new score saved in the
#text document.
if missed == 0 and times_selection > highest_times_selection :
output_file = open('multiplication_game.txt', 'w')
name = input('You have the highest Score!!\n enter your name: ')
output_file.write(str(times_selection)+ '\n')
output_file.write(name + '\n')
else:
print('you missed ', missed, 'and got', correct,'correct\n')
output_file.close()
Try to define output_file = None before any assignment of it.
Tip: before your last if-else condition.
This looks like homework, so I don't want to give you the answer but rather lead you to it.
Take a look at your if/else for your high score table, and walk through your code twice, taking a different branch (different part of the if/else) each time you reach this spot. Write down the variable names on paper as you define them, starting over with a new sheet of paper each time you walk through. If you access a variable, check it off on your list. If you try to access a variable that's not on your list, it's the same as python saying local variable referenced before assignment -- you're trying to access it before you've defined it.
Hope this helps, both in figuring out your problem and learning how to debug in the future.

Variables don't change after being run through a function

I'm writing a small game in python in which certain events happen and effect variables which need to stay in certain parameters. I have the main file and then another file which has all of the events in them. Some of the values are changed in the function then supposed to change the overall values in main (Sorry if that doesnt make sense)
Here's the part in main:
while (army > -100 and army < 100 and people > -100 and people < 100 and church > -100 and church < 100 and affairs > -100 and money < 100 and money > -100):
os.system('clear')
#Top Bar. Should Stay throughout game.
print("[-]==[King: " + king + "]==[Years in power:" + str(years) +"]==[Army: " + str(army) + "]==[People: " + str(people) + "]==[Church: " + str(church) + "]==[Foreign Affairs: " + str(affairs) + "]==[Economy: " + str(money) +"]==[-]")
print(people)
event1(army, people, church, affairs, money, years)
That loops until one of the parameters falls below 0 then there's losing conditions
Right now there is only one event, and it's not quite finished, but I only need one thing to at least see a change in the values.
Here that:
def event1(army, people, church, affairs, money, years):
#Feilds are Flooding
print("")
print("Sire! The Feilds in the eastern baronies are flooding! What should we do?")
print("")
print("Choices:")
print("1: The rain will pass, do nothing. (~Money, People)")
print("2: Have the Royal Builders build flood protection! (~Money, People)")
print("")
c=input("Your choice sire: ")
while True:
if c > 2:
print("")
print("Please chose a valid option")
print("Your choice sire: ")
continue
if c == 1:
time.sleep(2)
print("")
print("You do nothing, your people starve from flooded feilds (-People, +Money)")
money = money+20
people = people-20
years = years+1
raw_input("Press Enter to go to the next year")
return money
return years
return people
break
After it runs the event the values people, money and years are all supposed to change, but when it loops, nothing changes.
Any help is appreciated! Thank you!
Those are local variables. As soon as you leave the method scope, the value is lost, unless you return and actually use the returned values.
In your caller, assign your variables with the new returned values:
money, years, people = event1(army, people, church, affairs, money, years)
and in event1, perform only one return (others are unreachable) of the tuple containing the 3 values you want to return (which is unpacked to the 3 upper level eponymous variables):
return money, years, people
YOU DO NOT NEED THE RETURN!!!!!!!!!!!!!!!!!!!! COMPLETELY REMOVE IT! READ THIS! (should help)
The return in fact ruins your command, and there is a really easily explainable way to understand how it works.
First I need to explain something, because I am kind of confused about your code. Return is used to make the value of your command whatever you have returned. Return is used like this:
def AddThreethousandTwohundredSeventyNineToNum(num):
num = num + 3279
return num
and then
print AddThreethousandTwohundredSeventyNineToNum(4)
It should print "3283". (3279 + 4)
print printThreethousandTwohundredSeventyNineToNum(2)
It will print "3281".
You can also do cool things like:
if AddThreethousandTwohundredSeventyNineToNum(x) == y:
DoSomething
All return does is make the value OF THE FUNCTION whatever you want it to be. In the last code, the function looks for what I made num, and sees that it is 4 or 2, so it does num = num + 3279, so num gets increased by 3279 (3273 or 3271). When you do return num, it makes THE FUNCTION equal num.
That means what you have done is changed all those beatiful values in lines 21-23 (money, people, etc.) and technically that is all you had to do. However, when you returned the numbers, you made your command not only change those values, but also become a number, and obviously you cant just have a number lying around in your command. Or else the interpreter will not understand.
I hope I was clear enough, and if not, please please PLEASE tell me (please).

Python 3.4 Dice Rolling Simulator Code Error

So I have my code here for a dice rolling simulator game that I am creating using PyDev in Eclipse Neon Python 3.4. Where you guess a number and a number from 1-6 will randomly generate and if you get the number right, you move on, etc.
guess1 = input("Enter your first guess as to which side the dice will roll on (1-6): ")
import random
dice_side = ['1','2','3','4','5','6']
game = print(random.choice(dice_side))
if guess1 == game:
print("Congrats that's the correct guess!")
else:
print("That's the wrong guess!")
I tested out the code and everytime I put in a number, the console always print "That's the wrong guess!". Even when the number I guess matched the generated number. I can't quite figure out what's wrong with this. I was thinking maybe I should use a while loop instead. However, I wanted to know if I can do it this way and what's wrong with this particular code. I am new to Python so any help is appreciated. Thanks in advance!
print() returns None. If you print game after that line you will see it's value. To fix:
game = random.choice(dice_side)
In order to understand why your game isn't working you should try to understand first what's wrong with this line game = print(random.choice(dice_side)). Here's a modified version of your game which will give you some clues, try to run it and understand it, then just review your script:
import random
dice_side = ['1', '2', '3', '4', '5', '6']
game = random.choice(dice_side)
print("Dice has been rolled... :D {0}".format(game))
guess = -1
number_attempts = 0
while True:
guess = raw_input("Which side the dice has rolled on (1-6): ")
number_attempts += 1
if guess == game:
print("Congrats that's the correct guess! You've tried {0} times".format(
number_attempts))
break
print("That's the wrong guess!")
One advice, once you've discovered why isn't working, just try to add more and more new features till your game becomes really addictive and interesting... but the most important, just have fun :)

Trying to make a small dice game - only works for one player, want to implement multiple players

I'm totally new to Python and programming in general, and just starting to learn how to crawl, basically. I decided to learn programming by doing, and so I tried to develop a little dice game.
The main intention (i did not manage to succeed in making the code like i wanted it to) was to make a game with the following rules:
The game is played by two or more players
There is only one dice involved in the game
Object of the game is to be the first to get at least 100 points
A player is chosen by random to go first: The player can roll the dice as many times as s/he likes, and the points are accumulated. However, if the dice returns 1, the player loses the accumulated points. At any time, the player can choose to stop rolling the dice and secure the points. By doing this, the player loses its turn, and the next player can start rolling. Points that are secured, can never be lost.
When first trying to make this code, I wanted to make it with classes and functions, but I just couldn't make that work. Also I couldn't figure out how to design the game for multiple players. I tried working with lists and dictionaries, but I just kept pulling my hair. So I just tried to make the game for 1 player, where the objective is to reach a 100 points in fewest rounds (a new round starts everytime you secure points). Not very fun, but at least I got it to work (well, sort of).
I would highly appreciate any comments to my little program. Please note it's my first code, and I know it is really badly written. I want to hear how you guys think the code could be improved, and how I should go about in organizing the code for multiple players. I'm interested in learning to program for mobile devices at a later stage, and want to eventually turn this little game into an app so I can play with friends (for fun and as a way to learn the how-to's).
Hope the indents are adjusted properly.
from random import choice # Importing the random element to create the dice
score = 0
rounds = 1
secured = 0
unsecured = 0
ask = "N/A"
while secured+unsecured < 100:  # Check if the total score is below 100
a = int(choice([1,2,3,4,5,6])) # Choose a dice number
if a == 1: # Check if the dice is one
if ask == "s": # Check if the player secured the last score
print ("Good thing you just secured your score, because you now rolled a 1.")
print ("Because of this, you only lost your round, not any points! :)")
if ask =="N/A": # Check if the player rolled a one on the first throw
print ("************* Round 1 ***********")
print ("Tough luck, you rolled a ONE on your first roll. You lost one round.")
rounds +=1
if ask == "r": # Check if the player lost points that was unsecured
print ("")
print ("***** UH UH UH UH UH - YO ROLLED A ONE ******")
print ("You lost the", unsecured,"points you didn't secure")
unsecured = 0  # Player loses the unsecured points
rounds +=1 # Increase round number
else:
unsecured = unsecured + a # If the dice returned something else than one, the player wins the points
print ("")
print ("")
print ("************ Round ", rounds, "**************")
print ("")
if a > 1: # Only display the dice if the dice is higher than one (if it's one it has already been printed)
print ("You rolled a ", a)
print ("")
print ("Unsecured points: ", unsecured)
print ("Secured points:" , secured)
print ("The sum of secured and unsecured pointsare:",secured+unsecured, "points")
print ("")
ask = input ("Roll the dice or secure? (r/s) ")
if ask == "s":
secured = secured+unsecured # If player chooses to secure the points, the points are added
score = 0
rounds +=1 # Increase round
if unsecured == 0: # Check if player was an idiot and chose to secure 0 points
print ("You chose to secure zero points, not very clever! You wouldn't risk anything by rolling the dice, and you lost the round!")
else:
print ("You chose to secure your", unsecured, "points, and you have secured", secured, "points in total")
print ("")
unsecured = 0 # Reset unsecured points, since it is added to secure points
input ("Press Enter to roll the dice:")
else:
if ask == "r":
score = unsecured+a
else:
print ("Congrats!  You made ",secured+unsecured, "points in", rounds , "rounds")

Categories