HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMajor

Spin-the-bottle-like game

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thebottlespinlikegame

Problem

I've started coding about 3 weeks ago, just for fun and maybe practical uses later. My GF dared me to make a PGM that would replace this dice game where you roll two dice, one with body parts and one with actions, then resulting in stuff like 'kiss, lips'.

All I know is off of YouTube and sites such as Stack Overflow. I would appreciate if I could get tips and constructive criticism on how to code more efficient, clear, correct and maybe more 'pythonic'.

A bunch of notes are in there to clarify what I'm doing. As far as I've tested it is working correctly. As you will see there is a load/save function intended to store the game data to a text file.

```
def enterplayers():
# Set players for the game
global player1
player1 = input('Enter player 1 name: ')

global player2
player2 = input('Enter player 2 name: ')

global playerlist
playerlist = [player1, player2]

global player
player = cycle(playerlist)

def enteractions():
# Add actions to existing (or empty) list
print("Add ACTIONS and enter 'q' when done")
while True:
nextitem = input("Add: ")
if nextitem == 'q':
break
elif nextitem == '':
continue
else:
nextitem = nextitem.lower()
if ' ' in nextitem:
nextitem = nextitem.replace(' ', '_')
actionlist.append(nextitem)

def enterbp():
# Add body parts to existing (or empty) list
print("Add BODY PARTS and enter 'q' when done")
while True:
nextitem = input("Add: ")

if nextitem == 'q':
break
elif nextitem == '':
continue
else:
nextitem = nextitem.lower()
if ' ' in nextitem:
nextitem = nextitem.replace(' ', '_')
bplist.append(nextitem)

def loaddata():
#empty them out in case something there
global bplist
bplist = []

global actionlist
actionlist = []

#Load each one in its

Solution

First off, welcome to programming and Python. They are both awesome!

Ok, with this being your first foray into coding, instead of giving specific code improvements, I will give some high-level recommendations and then let you use them as you will.

Style

Python has an official style guide called PEP8 that defines the preferred way to style your code. It touches on variable naming conventions, proper white space, flow of code, etc. I strongly advise taking a look and trying to make your code fit what it says.

Classes

This program description is basically built for object-oriented programming (OOP). Classes are very easy to create in Python and provide simple ways to access similar data. Below is a skeleton Die class that can be used to represent one of your dice in your game:

class Die():
    def __init__(self, options=[]):
        # This is the function that is called when a new `Die` instance
        # is created. The `options` parameter is optional (denoted with the `=`).
        self.options = options 

    def __str__(self):
        # This 'magic method' is called when you used the `print` function.
        return ', '.join(self.options)

    def add_options(self, options):
        # Adds multiple options. HINT: use the following method.

    def add_option(self, option):
        # Add an option to the current list

    def roll(self):
        # Return one of its options based on a random number


From this point, using a Die is as easy as:

>>>body_parts = Die(['arm', 'leg', 'nose'])
 >>>body_parts.add_options(['head', 'foot'])
 >>>body_parts.roll()
 'leg'
 >>>print(body_parts)
 arm, leg, nose, head, foot


Much of your code can be pulled into classes (Die as above, Game, Player, etc.). This is evident by how much you use the global keyword. Having to use a variable in many places implies a relationship between the variable and the functions it is used in. This relationship is one of the main ideas behind OOP.

Strings

You do a lot of print statements. That is fine. However, you can take out about 95% of them if you use triple-quote syntax. Essentially by using '''Some text''' Python keeps the structure of the string as it looks in the code. So your menu function can be scaled down from this:

def menu():
    print()
    print('- - - - - - - - - - - -')
    print('   MAIN MENU')
    print()
    print('1. Start game')
    print()
    print('2. Enter player names')
    print('3. Add actions')
    print('4. Add body parts')
    print()
    print('6. Load data')
    print('7. Save data')
    print()
    print('8. Print instructions')
    print('9. Quit ')
    print('- - - - - - - - - - - -')
    print()


to this:

def menu():
    print('''
- - - - - - - - - - - -
   MAIN MENU
1. Start game

2. Enter player names
3. Add actions
4. Add body parts

5. Load data
6. Save data

7. Print instructions
8. Quit
- - - - - - - - - - - -
''')


Also, you have some statments that use strings like this:

file.write('player1: ' + player1 + '\n')


A simple way of writing this is using the format() function provided by Python:

file.write('player1: {}\n'.format(player1))


This way we don't have to worry about all of the string concatenation that is happening in the old statement.

Miscellaneous Thoughts

Here are some random improvements I can see:

-
replace()

There is no need to check for a substring in a string before replacing. If there are none, replace() will handle it gracefully:

>>>'Hello Planet!'.replace('Planet', 'World')
Hello World!
>>>'Hello World!'.replace('Planet', 'World')
Hello World!


-
'Infinite' Loops

While I love while True loops in the right circumstances, you do not need most (if not all) of them. Take you while-loop in enterbp:

def enterbp():
    # Add body parts to existing (or empty) list
    print("Add BODY PARTS and enter 'q' when done")
    while True:
        nextitem = input("Add: ")

        if nextitem == 'q':
            break
        elif nextitem == '':
            continue
        else:
            nextitem = nextitem.lower()
            if ' ' in nextitem:
                nextitem = nextitem.replace(' ', '_')
            bplist.append(nextitem)


This could be simplified to:

def enterbp():
    # Add body parts to existing (or empty) list
    print("Add BODY PARTS and enter 'q' when done")

    nextitem = input("Add: ")
    while nextitem != 'q':
        if nextitem == '':
            continue

        bplist.append(nextitem.lower().replace(' ', '_'))  

        nextitem = input("Add: ")


-
Using lists

lists are awesome. You could simply use a list to implement your menu:

# This is a list of functions.
menu_options = [play, enterplayers, enteractions, enterbp,
                loaddata, savedata, instructions, quit]

choice = input('What do you choose: ')

# Finds the correct function, then calls it
menu_options[choice-1]()


There are other things, but I think this i

Code Snippets

class Die():
    def __init__(self, options=[]):
        # This is the function that is called when a new `Die` instance
        # is created. The `options` parameter is optional (denoted with the `=`).
        self.options = options 

    def __str__(self):
        # This 'magic method' is called when you used the `print` function.
        return ', '.join(self.options)

    def add_options(self, options):
        # Adds multiple options. HINT: use the following method.

    def add_option(self, option):
        # Add an option to the current list

    def roll(self):
        # Return one of its options based on a random number
>>>body_parts = Die(['arm', 'leg', 'nose'])
 >>>body_parts.add_options(['head', 'foot'])
 >>>body_parts.roll()
 'leg'
 >>>print(body_parts)
 arm, leg, nose, head, foot
def menu():
    print()
    print('- - - - - - - - - - - -')
    print('   MAIN MENU')
    print()
    print('1. Start game')
    print()
    print('2. Enter player names')
    print('3. Add actions')
    print('4. Add body parts')
    print()
    print('6. Load data')
    print('7. Save data')
    print()
    print('8. Print instructions')
    print('9. Quit ')
    print('- - - - - - - - - - - -')
    print()
def menu():
    print('''
- - - - - - - - - - - -
   MAIN MENU
1. Start game

2. Enter player names
3. Add actions
4. Add body parts

5. Load data
6. Save data

7. Print instructions
8. Quit
- - - - - - - - - - - -
''')
file.write('player1: ' + player1 + '\n')

Context

StackExchange Code Review Q#51272, answer score: 21

Revisions (0)

No revisions yet.