#
# Monty Hall Problem Simulation
# Author: Ryan Sturmer
#
import random
def play_round(doors, switch):
# Choose the location of the car
car = random.randint(1, doors)
# Contestant chooses a door
initial_choice = random.randint(1, doors)
# Monty opens ALL the other doors except one
if initial_choice != car:
monty_leaves = car # If the car wasn't chosen, Monty is forced to reveal its location
else:
while True:
monty_leaves = random.randint(1, doors)
if monty_leaves != initial_choice:
break
# monty_leaves is now the door that Monty DIDN'T open
if switch:
final_choice = monty_leaves
else:
final_choice = initial_choice
victory = (final_choice == car)
return victory, initial_choice, final_choice, car
def simulation(iterations, doors=3):
games_won_switch = 0
games_won_noswitch = 0
for i in range(iterations):
won_game, intial_choice, final_choice, car = play_round(doors, False)
if(won_game):
games_won_noswitch += 1
won_game, intial_choice, final_choice, car = play_round(doors, True)
if(won_game):
games_won_switch += 1
print ""
print " Monty Hall Simulation"
print "---------------------------------------------"
print " Iterations: %d" % iterations
print " Games won when switching doors: %d (%g%%)" % (games_won_switch, 100*float(games_won_switch)/float(iterations))
print "Games won when NOT switching doors: %d (%g%%)" % (games_won_noswitch, 100*float(games_won_noswitch)/float(iterations))
===========================================================================
I found this code from github.
When I run this code, the sum of games_won_switch and games_won_noswitch is not equals to iteration.
(For example, if I set iteration 1,000 -> it appears 996, 1,001, 1,008 not exact 1,000)
How can i fix problem this up?
There is no mistake in the code; it runs the simulations twice:
Once when the player chooses to switch doors every time, and another time when the player chooses to never switch doors. It then prints the results of both simulations.
The results are from independent simulations.
for i in range(iterations):
# Sim with player choose to open the door each time
won_game, intial_choice, final_choice, car = play_round(doors, False)
if(won_game):
games_won_noswitch += 1
# Sim with player choose NEVER to open the door
won_game, intial_choice, final_choice, car = play_round(doors, True)
if(won_game):
games_won_switch += 1
In consequence, because sim(open=True) is not (1 - sim(open=False)), but result from two sets of simulations, the addition of results may not add up precisely to the number of trials.
Related
There is module files as well but they work perfectly, the main problem is when you enter a module and it just printing out There is 'none' in here for every module. Additionally, if I wanted to change the fuel gain from 50 to randomly chose between 20,30,40 or 50.
The rest of the code works well but when the npc in a room is outputted it should say there is a 'workers' in here instead of just none for each module.
#Telium - Game
import random
#Global Variables
num_modules = 17 #Number of modules in the space station
module = 1 #Module of space station we are in
last_module = 0 #Last module we were in
possible_moves = [] #List of possible moves we can make
alive = True #Whether player is alive or not
won = False #Whether player has won
power = 100 #Amount of power the space station has
fuel = 500 #Amount of fuel the player has in flamethrower
locked = 0 #Module that has been locked by the player
queen = 0 #Location of queen alien
vent_shafts = [] #Location of ventilation shaft entrances
info_panels = [] #Location of info panels
workers = [] #Location of worker aliens
#procedure declarations
#This loads the global module
def load_module():
global module, possible_moves
possible_moves = get_modules_from(module)
output_module()
def get_modules_from(module):
moves = []
text_file = open("Charles_Darwin\module" + str(module) + ".txt", "r")
for counter in range(0,4):
move_read = text_file.readline()
move_read = int(move_read.strip())
if move_read != 0:
moves.append(move_read)
text_file.close()
return moves
def output_module():
global module
print()
print("--------------------------------------------------------------
-----------------------")
print()
print("You are in module",module)
print()
npc = spawn_npcs()
print("There is a ", npc ,"here")
def output_moves():
global possible_moves
print()
print("From here you can move to modules: | ",end='')
for move in possible_moves:
print(move,'| ',end='')
print()
def get_action():
global module, last_module, possible_moves, power
valid_action = False
while valid_action == False:
print("What do you want to do next ? (MOVE, SCANNER)")
action = input(">")
if action == "MOVE" or action.lower() == 'move' or action.lower()
== 'm' or action.higher() == 'M':
move = int(input("Enter the module to move to: "))
if move in possible_moves:
valid_action = True
last_module = module
module = move
#power is decreased by 1 for every move
power =- 1
else:
print("The module must be connected to the current
module.")
def spawn_npcs():
global num_modules, queen, vent_shaft, greedy_info_panels, workers
module_set = []
for counter in range(2,num_modules):
module_set.append(counter)
random.shuffle(module_set)
i = 0
queen = module_set[i]
for counter in range(0,3):
i=i+1
vent_shafts.append(module_set[i])
for counter in range(0,2):
i=i+1
info_panels.append(module_set[i])
for counter in range(0,3):
i=i+1
workers.append(module_set[i])
def check_vent_shafts():
global num_modules, module, vent_shafts, fuel
if module in vent_shafts:
print("There is a bank of fuel cells here.")
print("You load one into your flamethrower.")
fuel_gained = 50
print("Fuel was",fuel,"now reading:",fuel+fuel_gained)
fuel = fuel + fuel_gained
print("The doors suddenly lock shut.")
print("What is happening to the station?")
print("Our only escape is to climb into the ventilation shaft.")
print("We have no idea where we are going.")
print("We follow the passages and find ourselves sliding down.")
last_module = module
module = random.randint(1,num_modules)
load_module()
#Main Program starts here
#Menu options
print("ENTER 1 for instructions")
print("ENTER 2 to play")
print("ENTER 3 to quit")
menu = int(input("Please enter a number corresponding to what you want to
do: "))
if menu == 1:
instructions = input("Do you want to read the instructions(Y/N): ")
if instructions == "Y":
print("You, the player are trying to navigate around a space
station named the 'Charles Darwin' which contains many modules")
print("The aim of the game is to find a and trap the queen alien
called 'Telium' who is located somewhere randomly in the station, the
queen will try to escape to connectinhg modules so beware")
print("To win - you have to lock the queen in one of the modules
so she is trapped, you can kill her with a flamethrower, there is also
objects to help on the way so keep a look out")
spawn_npcs()
#Outputs where the queen, shafts, panels and workers are located
print("Queen alien is located in module:",queen)
print("Ventilation shafts are located in modules:",vent_shafts)
print("Information panels are located in modules:",info_panels)
print("Worker aliens are located in modules:",workers)
#when the players is alive, the module will load
while alive and not won:
load_module()
if won == False and alive == True:
output_moves()
get_action()
#if power is 0 then the user will die and the game will end
if power == 0:
print("You ran out of life support, you died")
alive == False
#win message once you have trapped the queen or when you run out of life
support
if won == True:
print("The queen is trapped and you burn it to death with your
flamethrower.")
print("Game over. You win!")
if alive == False:
print("The station has run out of power. Unable to sustain life
support, you die.")
check_vent_shafts()
First the easy part. You can randomly get 20, 30, 40 or 50 by using random.randint like this:
random.randint(2, 5) * 10
The harder part:
As you discussed with #Random Davis in the comments, you want to assign the npcs to random modules and then print which one you encounter.
To append three random (possibly repeating) modules, use
for _ in range(0,3):
vent_shafts.append(random.choice(module_set))
Using global variables (and the global keyword) is generally considered bad practice as it can cause sideeffects due to other parts of the program modifying a variable you wouldn't expect it to / forgot about. Try to use them as function parameters where needed and return the results
queen, vent_shafts, info_panels, workers = spawn_npcs(5)
def spawn_npcs(num_modules):
module_set = []
for i in range(2, num_modules):
module_set.append(i)
for _ in range(0,3):
vent_shafts.append(random.choice(module_set))
for _ in range(0,2):
info_panels.append(random.choice(module_set))
for _ in range(0,3):
workers.append(random.choice(module_set))
queen_module = module_set[0]
return queen_module, vent_shafts, info_panels, workers
Background
Recently I simplified a text-only game I was making:
Here is the code:
import time
#
# Declaration of classes -- game logic
#
class Action:
def __init__(self, description, newLocation):
self.description = description
self.newLocation = newLocation
class Location:
def __init__(self, name, description):
self.name = name
self.description = description
self.actions = []
def addAction(self, action):
self.actions.append(action)
def arrive(self):
print("----------------------------------------")
print('You arrived to: {}'.format(self.name))
print(self.description)
i = 0
print(" (0. Exit game)")
for action in self.actions:
i = i + 1
print(" {}. {}".format(i, action.description))
validChoice = False
while not validChoice:
try:
index = int(input("? : "))
if index == 0:
print("Abandoning your quest... :(")
return
if 0 < index and index <= len(self.actions):
validChoice = True
except ValueError:
pass
self.actions[index - 1].newLocation.arrive() # indexing is 0-based, but we get 1-based index from the user
#
# Declare your locations here -- data
#initial rooms
house = Location("house", "Inside the house there is a sweet aroma of rolls being baked.")
field = Location("field", "Grass swishes as you walk through it. a solitary horse is grazing in the field.")
stable = Location("stable", "You are greeted by the sound of various animal noises and the smell of various animal odors")
#secondary rooms-house
#declare location actions here
spawnPosition = Location("Spawn position", "You wake up in a sunny morning. After you get out of your bad, you decide to:")
spawnPosition.addAction(Action("for house", house))
spawnPosition.addAction(Action("for field", field))
spawnPosition.addAction(Action("for stable", stable))
#house options
house.addAction(Action("leave the house",field))
#
# The game starts here
#
print ("Cool Cousins Studios Presents...")
time.sleep(2) # Sleep for 2 seconds
print ("With use of Python Code...")
time.sleep(2) # Sleep for 2 seconds
print ("Adventure In Saldica")
time.sleep(2) # Sleep for 2 seconds
print ("(cue dramatic music)")
time.sleep(3) # Sleep for 3 seconds
spawnPosition.arrive() # This is all you need to do to initiate the game. When this function returns, your journey has concluded.
print("Bye-bye")
However, I don't know how I can make it change variable values based on the options/locations the user chooses. I've tried putting if statements in the Location.arrive function, but I'm wondering if there is a simpler way.
What I need to know:
How do I make and edit variables based on my location, and what is the simplest way to do it?
You should define a class for your character, where you would store their current location and you can present choices based on the current location or history of actions that the character has taken.
The Location class should contain the available actions you can make from that location and a function to present them when needed.
This way, you will only need to define each room once.
import time
#
# Declaration of classes -- game logic
#
class Character:
def __init__(self, name, location):
self.name: str = name
self.location: Location = location # initialize with some starting location
self.actions = [] # Store all the actions this player has taken
# Here we will have a never ending loop to get inputs from the user
while True:
newLocation = self.location.arrive()
self.actions.append(newLocation)
self.location = newLocation
if sum([1 for loc in self.actions if loc == house]) >= 2:
house.description = "Why are you back home? Go somewhere else."
if self.location == exitLocation:
break
print("\n\nYou visited:")
for i in self.actions:
print(i.name)
class Location:
def __init__(self, name, description, actions:list = []):
self.name = name
self.description = description
self.actions = actions # this should be a list of locations that can be visited from here
def arrive(self):
print("----------------------------------------")
print('You arrived to: {}'.format(self.name))
print(self.description)
i = 0
print(" (0. Exit game)")
for action in self.actions:
i = i + 1
print(" {}. for {}".format(i, action.name))
validChoice = False
while not validChoice:
try:
index = int(input("? : "))
if index == 0:
validChoice = True
print("Abandoning your quest... :(")
return exitLocation
if 0 < index and index <= len(self.actions):
validChoice = True
return self.actions[index - 1] # indexing is 0-based, but we get 1-based index from the user
except ValueError:
pass
#
# Declare your locations here -- data
#initial rooms
field = Location("field", "Grass swishes as you walk through it. a solitary horse is grazing in the field.")
stable = Location("stable", "You are greeted by the sound of various animal noises and the smell of various animal odors")
house = Location("house", "Inside the house there is a sweet aroma of rolls being baked.")
spawnPosition = Location("Spawn position", "You wake up in a sunny morning. After you get out of your bed, you decide to:", [field, stable, house])
exitLocation = Location("Exit Game", "Bye-bye")
#secondary rooms-house
# Declare location actions here
field.actions = [stable, house, spawnPosition]
stable.actions = [field, house, spawnPosition]
house.actions = [field, stable, spawnPosition]
#
# The game starts here
#
print ("Cool Cousins Studios Presents...")
time.sleep(2) # Sleep for 2 seconds
print ("With use of Python Code...")
time.sleep(2) # Sleep for 2 seconds
print ("Adventure In Saldica")
time.sleep(2) # Sleep for 2 seconds
print ("(cue dramatic music)")
time.sleep(3) # Sleep for 3 seconds
# Create a character and initialize with spawn position
character = Character("John", spawnPosition) # This is all you need to do to initiate the game. When this function returns, your journey has concluded.
print("----------------------------------------")
print("Bye-bye")
If you want to change the description of the room based on events that have occurred, you can read self.actions within the character object and modify the descriptions of the rooms there. Same goes for changing the available actions from a room. You would simply modify house.actions in that while loop, if you want to change which rooms you can visit from there after the user has completed some set of actions.
I'm new on python and I'm trying to do a Pokemon game (like the gameboy and nds games). I've created the pokemon and trainer classes and I want to implement the battle mechanics. I thought it was working fine, but then I found that if I lose the battle the program enters in an infinite loop.
I tried a lot to found the error and I discovered that when it exits the 'while alive(pokemon1) and alive(pokemon2)' loop, the pokemon1 hp returns to full hp but the pokemon2 remains with the current hp (I've put a print to show it). It makes non sense for me because the code is identical for both trainers. Anyone knows why is it happening? I want it to continue with the current hp of both pokemon at the end of the loops and battle.
Here is a sample of my code:
import copy
import random
class Pokemon(object):
def __init__(self, name, hp):
self.name = name
self.hp = hp
def ataque(self, oponent):
oponent.hp = oponent.hp - 150 #just for a test
class Trainer(object):
def __init__(self, name, *pokemon):
self.name = name
self.pokemon, self.pokemonname = [], []
for pkmn in pokemon:
self.pokemon.append(copy.deepcopy(pkmn))
self.pokemonname.append(pkmn.name)
weavile = Pokemon ('Weavile', 150) #change the hp to more than 150 if you want to win
garchomp = Pokemon ('Garchomp', 250)
roserade = Pokemon ('Roserade', 160)
ambipom = Pokemon ('Ambipom', 160)
me = Trainer('You', weavile) #or choose ambipom to win
cynthia = Trainer('Cynthia', garchomp)
def alive(pokemon): #check if the pokemon is alive
if pokemon.hp>0:
return True
if pokemon.hp<=0:
pokemon.hp=0
return False
def battle(trainer1, trainer2): #battle between two trainers
fight1, fight2 = True, True
while fight1 and fight2:
print ('Choose a pokemon:', trainer1.pokemonname)
pokemon1 = eval(input())
while not alive(pokemon1):
print (pokemon1.name, 'is out of batlle. Choose another pokemon')
pokemon1 = eval(input())
pokemon2 = random.choice(trainer2.pokemon)
while not alive(pokemon2):
pokemon2 = random.choice(trainer2.pokemon)
print (trainer1.name, 'chose', pokemon1.name, '\n', trainer2.name, 'chose', pokemon2.name)
while alive(pokemon1) and alive(pokemon2):
pokemon1.ataque(pokemon2)
if alive(pokemon2):
pokemon2.ataque(pokemon1)
print (pokemon1.name, pokemon1.hp)
print (pokemon2.name, pokemon2.hp)
print (trainer1.pokemon[0].name, trainer1.pokemon[0].hp) #here its returning the original hp
print (trainer2.pokemon[0].name, trainer2.pokemon[0].hp) #here its returning the current hp, as it should
if not any(alive(pokemon) for pokemon in trainer1.pokemon):
fight1 = False
if not any(alive(pokemon) for pokemon in trainer2.pokemon):
fight2 = False
battle(me, cynthia)
If you run the code in the way I wrote here, you need to choose one of your pokemon on the list (there's only one: weavile - to simplify), so just type weavile. After that, weavile will attack and then be attacked by garchomp. Weavile will be defeated (0 hp) in the first hit but after the loop 'while alive(pokemon1)...' it will show that weavile still has 150 hp and it will continue to ask you to choose a pokemon even if it's already dead.
If you want to win: choose ambipom instead of weavile in 'me' object or change the weavile hp to more than 150 in weavile object. If you do this it will run as I want and end the battle.
I'm trying to create a text-based adventure game and all is going well until I encountered a problem with assigning points to attributes. I've been using this website to help with the process but realized that it might be in Python 2. Here's all that I've done so far code:
#Date started: 3/13/2018
#Description: text-based adventure game
import random
import time
def display_intro():
print('It is the end of a 100-year war between good and evil that had \n' +
'killed more than 80% of the total human population. \n')
time.sleep(3)
print('The man who will soon be your father was a brave adventurer who \n' +
'fought for the good and was made famous for his heroism. \n')
time.sleep(3)
print('One day that brave adventurer meet a beautiful woman who he later \n' +
'wed and had you. \n')
time.sleep(3)
def get_gender(gen=None):
while gen == None: # input validation
gen = input('\nYour mother had a [Boy or Girl]: ')
return gen
def get_name(name = None):
while name == None:
name = input("\nAnd they named you: ")
return name
def main():
display_intro()
gender_num = get_gender()
charater_name = get_name()
print("You entered {} {}.".format(gender_num, charater_name))
if __name__ == "__main__":
main()
character_name = get_name()
# Assignning points Main
my_character = {'name': character_name, 'strength': 0, 'wisdom': 0, 'dexterity': 0, 'points': 20}
#This is a sequence establises base stats.
def start_stat():
print("\nThis is the most important part of the intro\n")
time.sleep(3)
print("This decides your future stats and potentially future gameplay.")
time.sleep(4)
print("\nYou have 20 points to put in any of the following category:
Strength, Health, Wisdom, or Dexterity.\n")
def add_charater_points(): # This adds player points in the beginnning
attribute = input("\nWhich attribute do you want to assign it to? ")
if attribute in my_character.keys():
amount = int(input("By how much?"))
if (amount > my_character['points']) or (my_character['points'] <= 0):
print("Not enough points!!! ")
else:
my_character[attribute] += amount
my_character[attribute] -= amount
else:
print("That attribute doesn't exist!!!")
def print_character():
for attribute in my_character.keys():
print("{} : {}".format(attribute, my_character[attribute]))
playContinue = "no"
while playContinue == "no":
Continue = input("Are you sure you want to continue?\n")
if Continue == "yes" or "Yes" or "y":
playContinue = "yes"
start_stat()
add_charater_points()
else:
display_intro()
gender_num = get_gender()
charater_name = get_name()
running = True
while running:
print("\nYou have {} points left\n".format(my_character['points']))
print("1. Add points\n2. Remove points. \n3. See current attributes. \n4. Exit\n")
choice = input("Choice: ")
if choice == "1":
add_charater_points()
elif choice == "2":
pass
elif choice == "3":
print_character()
elif choice == "4":
running = False
else:
pass
And here's what happens when I run it:
It is the end of a 100-year war between good and evil that had
killed more than 80% of the total human population.
The man who will soon be your father was a brave adventurer who fought for
the good and was made famous for his heroism.
One day that brave adventurer meet a beautiful woman who he later wed and
had you.
Your mother had a [Boy or Girl]: boy
And they named you: Name
You entered boy Name.
And they named you: Name
Are you sure you want to continue?
yes
This is the most important part of the intro
This decides your future stats and potentially future gameplay.
You have 20 points to put in any of the following category: Strength,
Health, Wisdom, or Dexterity.
Which attribute do you want to assign it to? strength
By how much? 20
You have 20 points left
1. Add points
2. Remove points.
3. See current attributes.
4. Exit
Choice: 3
name : Name
strength : 0
wisdom : 0
dexterity : 0
points : 20
You have 20 points left
1. Add points
2. Remove points.
3. See current attributes.
4. Exit
Choice:
Oh, and prompt for the name of the play goes again twice for some reason. Also, what does the my_character.keys() under def add_charater_points() mean? Since I just started to learn to code python, if there are any other tips you guys can give me it would be greatly appreciated.
The last two lines of this snippet
if (amount > my_character['points']) or (my_character['points'] <= 0):
print("Not enough points!!! ")
else:
my_character[attribute] += amount
my_character[attribute] -= amount
add the character points to the attribute, and immediately subtract them again. I think you might mean
my_character['points'] -= amount
Your repeated prompt is probably because you have a whole lot of code that logically seems to belong in function main() but is coded to run after main() finishes.
Trying out some OOP in python, I tried to create a Monty Hall Problem simulation that is giving odd results. I implement three different strategies that a player can choose from, either to stay with the first door selected, switch to the second closed door, or randomly choose between them.
import random
class Door():
behind = None
is_open = False
is_chosen = False
def __init__(self,name=None):
self.name = name
def open(self):
self.is_open = True
def choose(self):
self.is_chosen = True
class Goat():
is_a = 'goat'
class Car():
is_a = 'car'
class Player():
door = None
def choose(self,door):
self.door = door
self.door.choose()
def open(self):
self.door.open()
if self.door.behind.is_a == 'car':
return True
return False
def play(strategy):
player = Player()
items = [Goat(),Goat(),Car()]
doors = [Door(name='a'),Door(name='b'),Door(name='c')]
for door in doors:
item = items.pop()
door.behind = item
random.shuffle(doors)
player.choose(random.choice(doors))
if strategy == 'random':
if random.choice([True,False]):
for door in doors:
if not door.is_open and not door.is_chosen:
final = door
break
else:
final = player.door
elif strategy == 'switch':
for door in doors:
if not door.is_open and not door.is_chosen:
final = door
break
elif strategy == 'stay':
final = player.door
player.choose(final)
if player.open():
return True
else:
return False
## Play some games
for strategy in ['random','switch','stay']:
results = []
for game in range(0,10000):
if play(strategy):
results.append(True)
else:
results.append(False)
## Gather the results
wins = 0
loses = 0
for game in results:
if game:
wins += 1
else:
loses += 1
print 'results:\tstrategy={}\twins={}\tloses={}'.format(strategy,str(wins),str(loses))
But every time I run it, I get something like:
results: strategy=random wins=3369 loses=6631
results: strategy=switch wins=3369 loses=6631
results: strategy=stay wins=3320 loses=6680
Why is this giving nearly the same results for each strategy? Shouldn't the 'switch' strategy give a ratio of ~66% wins and 'stay' give ~33%?
You're not playing the game correctly. After the contestant chooses a door, the host reveals a goat behind one of the other two doors, and then offers the contestant the opportunity to switch -- you're allowing a choice between three doors instead of two. Here's a revised play() function:
def play(strategy):
player = Player()
items = [Goat(), Goat(), Car()]
doors = [Door(name='a'), Door(name='b'), Door(name='c')]
random.shuffle(items)
for door in doors:
item = items.pop()
door.behind = item
player.choose(random.choice(doors))
# player has chosen a door, now show a goat behind one of the other two
show = None
for door in doors:
if not (door.is_open or door.is_chosen) and door.behind.is_a == 'goat':
show = door
show.open()
break
# The player has now been shown a goat behind one of the two doors not chosen
if strategy == 'random':
if random.choice([True, False]):
for door in doors:
if not (door.is_open or door.is_chosen):
final = door
break
else:
final = player.door
elif strategy == 'switch':
for door in doors:
if not (door.is_open or door.is_chosen):
final = door
break
elif strategy == 'stay':
final = player.door
player.choose(final)
return player.open()
That produces results like:
results: strategy=random wins=4977 loses=5023
results: strategy=switch wins=6592 loses=3408
results: strategy=stay wins=3368 loses=6632