patternpythonMajor
Plague Inc. in Python - Extremely Early Stage
Viewed 0 times
plagueextremelyearlypythonstageinc
Problem
I've been working to create a game in Python similar to Plague Inc. and instead of just writing one big clump of code and then getting it reviewed, I wanted to do it stage-by-stage and make it a little easier. Also, reviews might possibly help me later on in the development process.
```
import datetime
import random
countries = [
dict(Name = "China", Population = "1,363,560,000"),
dict(Name = "India", Population = "1,242,070,000"),
dict(Name = "United States", Population = "317,768,000"),
dict(Name = "Indonesia", Population = "249,866,000"),
dict(Name = "Brazil", Population = "201,032,714"),
dict(Name = "Pakistan", Population = "186,015,000"),
dict(Name = "Nigeria", Population = "173,615,000"),
dict(Name = "Bangladesh", Population = "152,518,015"),
dict(Name = "Russia", Population = "143,700,000"),
dict(Name = "Japan", Population = "127,120,000"),
dict(Name = "Mexico", Population = "119,713,203"),
dict(Name = "Philippines", Population = "99,329,000"),
dict(Name = "Vietnam", Population = "89,708,900"),
dict(Name = "Egypt", Population = "86,188,600"),
dict(Name = "Germany", Population = "80,716,000"),
dict(Name = "Iran", Population = "77,315,000"),
dict(Name = "Turkey", Population = "76,667,864"),
dict(Name = "Thailand", Population = "65,926,261"),
dict(Name = "France", Population = "65,844,000"),
dict(Name = "United Kingdom", Population = "63,705,000"),
dict(Name = "Italy", Population = "59,996,777"),
dict(Name = "South Africa", Population = "52,981,991"),
dict(Name = "South Korea", Population = "50,219,669"),
dict(Name = "Colombia", Population = "47,522,000"),
dict(Name = "Spain", Population = "46,609,700"),
dict(Name = "Ukraine", Population = "45,410,071"),
dict(Name = "Kenya", Population = "44,354,000"),
dict(Name = "Argentina", Population = "40,117,096"),
dict(Name = "Poland", Population = "38,502,396"),
dict(Name = "Sudan", Population = "37,964,000"),
dict(Name = "Uga
```
import datetime
import random
countries = [
dict(Name = "China", Population = "1,363,560,000"),
dict(Name = "India", Population = "1,242,070,000"),
dict(Name = "United States", Population = "317,768,000"),
dict(Name = "Indonesia", Population = "249,866,000"),
dict(Name = "Brazil", Population = "201,032,714"),
dict(Name = "Pakistan", Population = "186,015,000"),
dict(Name = "Nigeria", Population = "173,615,000"),
dict(Name = "Bangladesh", Population = "152,518,015"),
dict(Name = "Russia", Population = "143,700,000"),
dict(Name = "Japan", Population = "127,120,000"),
dict(Name = "Mexico", Population = "119,713,203"),
dict(Name = "Philippines", Population = "99,329,000"),
dict(Name = "Vietnam", Population = "89,708,900"),
dict(Name = "Egypt", Population = "86,188,600"),
dict(Name = "Germany", Population = "80,716,000"),
dict(Name = "Iran", Population = "77,315,000"),
dict(Name = "Turkey", Population = "76,667,864"),
dict(Name = "Thailand", Population = "65,926,261"),
dict(Name = "France", Population = "65,844,000"),
dict(Name = "United Kingdom", Population = "63,705,000"),
dict(Name = "Italy", Population = "59,996,777"),
dict(Name = "South Africa", Population = "52,981,991"),
dict(Name = "South Korea", Population = "50,219,669"),
dict(Name = "Colombia", Population = "47,522,000"),
dict(Name = "Spain", Population = "46,609,700"),
dict(Name = "Ukraine", Population = "45,410,071"),
dict(Name = "Kenya", Population = "44,354,000"),
dict(Name = "Argentina", Population = "40,117,096"),
dict(Name = "Poland", Population = "38,502,396"),
dict(Name = "Sudan", Population = "37,964,000"),
dict(Name = "Uga
Solution
Some thoughts:
-
As the game goes on, you’ll need to record more information about the countries. Whether they’re doing medical research, border closures, infection/mortality rates, etc. Rather than storing all this information in a list of dictionaries, I’d suggest creating objects for each country. Here’s a simple example:
Also follow martijnn2008’s advice, and load the countries from an external file (probably a CSV). Keeping the data separate from the code is generally good practice. You’d probably be better off having a small dataset in the program to start with, as you build the basic logic, then start using the full data set later.
As unholysampler suggests, use an int for the population; this will make your life much easier later when chunks of the population start dying. You can always define a function that does nice comma-printing on your population data later.
-
Have different functions for parts of the game. For example, a
This will make it easier to reuse this code later – for example, if the user gets to the end of the game and you want to ask "Play again?", you can just redirect them to
-
Rather than expecting the user to enter a name that’s formatted exactly as it’s stored in your data, you could:
-
Do something to clean up messy input. For example, right now, "china" is an invalid input, but any reasonable person can see what they meant. Perhaps do something like
And weirdness happens if I choose a country name which isn't on your list. You could perhaps just ask again and again until you get an answer, or just pick one at random for me. I just want to get on with the game!
-
Just offer them a choice from a numbered list. Here’s a very crude mockup of how that might work:
-
Magic numbers as arguments to
ETA: The problem arises because you’re assuming that the window is 55 characters wide (for example, the
What if, later, you want to add the Independent Former Republic of New South Nebelsbad? Stuff like that might cause you problems if you’re rigid about the width.
-
In your import statements, I would write
Cuts out
That looks much more natural, and is unambiguous.
-
As the game goes on, you’ll need to record more information about the countries. Whether they’re doing medical research, border closures, infection/mortality rates, etc. Rather than storing all this information in a list of dictionaries, I’d suggest creating objects for each country. Here’s a simple example:
class Country(object):
def __init__(self, name, population):
self.name = name
self.population = population
china = Country("China", 1363560000)Also follow martijnn2008’s advice, and load the countries from an external file (probably a CSV). Keeping the data separate from the code is generally good practice. You’d probably be better off having a small dataset in the program to start with, as you build the basic logic, then start using the full data set later.
As unholysampler suggests, use an int for the population; this will make your life much easier later when chunks of the population start dying. You can always define a function that does nice comma-printing on your population data later.
-
Have different functions for parts of the game. For example, a
start_game() function which just includes the code for setting up a new game, then another function news_bulletin() which prints a random news bulletin.This will make it easier to reuse this code later – for example, if the user gets to the end of the game and you want to ask "Play again?", you can just redirect them to
start_game() rather than jumping through hoops.-
Rather than expecting the user to enter a name that’s formatted exactly as it’s stored in your data, you could:
-
Do something to clean up messy input. For example, right now, "china" is an invalid input, but any reasonable person can see what they meant. Perhaps do something like
if start_country.lower() in list_of_countries:
# more code hereAnd weirdness happens if I choose a country name which isn't on your list. You could perhaps just ask again and again until you get an answer, or just pick one at random for me. I just want to get on with the game!
-
Just offer them a choice from a numbered list. Here’s a very crude mockup of how that might work:
Which country would you like to choose?
1 China
2 India
3 United States
Type the corresponding number: # wait for input
3
You have chosen "United States"-
Magic numbers as arguments to
ljust() throughout your code. Icky and fragile. Pull them out and make them variables, or better try to compute the necessary values on the fly.ETA: The problem arises because you’re assuming that the window is 55 characters wide (for example, the
print '-' * 55 line). You should pull this out into a window_width variable, so you don't have problems later on (and if necessary, can adapt it for wider or narrower windows).What if, later, you want to add the Independent Former Republic of New South Nebelsbad? Stuff like that might cause you problems if you’re rigid about the width.
-
In your import statements, I would write
from datetime import datetimeCuts out
datetime.datetime statements, which just look weird. Also note that your MM-DD-YY may confuse players for whom that isn’t their default date system. How about>>> current_date = datetime.datetime.strftime(datetime.date.today(), "%d %B, %Y")
>>> print current_date
29 April, 2014That looks much more natural, and is unambiguous.
Code Snippets
class Country(object):
def __init__(self, name, population):
self.name = name
self.population = population
china = Country("China", 1363560000)if start_country.lower() in list_of_countries:
# more code hereWhich country would you like to choose?
1 China
2 India
3 United States
Type the corresponding number: # wait for input
3
You have chosen "United States"from datetime import datetime>>> current_date = datetime.datetime.strftime(datetime.date.today(), "%d %B, %Y")
>>> print current_date
29 April, 2014Context
StackExchange Code Review Q#48517, answer score: 20
Revisions (0)
No revisions yet.