4
\$\begingroup\$

I like the idea of element combining games, so I created my own after some thinking of how to make it. I'm mostly a beginner so I expect to get a lot of feedback talking about how messy my code might be.

I have it so it takes one command to make a element, all you have to do is provide how to make it and the name of the new element. It also has a saving feature which saves the list to a text file, while yes you could cheat and even add in (useless) your own elements (which don't do anything, hence why I said useless), I think it would remove the fun for the player so it isn't my biggest worry.

I think all that I need to do is maybe have an menu but I think I should add more elements. In the future I might edit it so the elements are just from a text file, so other people can create their own element combining games without knowing how to code.

The python file is 93 lines long, and the text file has the 4 elements you start out with as I think it's more faster then checking if it's the first time you played the game.

import os
class elementexcept(Exception): pass
elementshow = []
elementcheck = ""
def element(elementchecke, elemente):
    if elementcheck == elementchecke:
               if elemente in elementshow:
                   os.system('cls' if os.name == 'nt' else 'clear')
                   print("Element already exists.")
                   check = 1
                   raise elementexcept
               os.system('cls' if os.name == 'nt' else 'clear')
               elementshow.extend([elemente])
               check = 1
               raise elementexcept
with open('elementsavefile.txt', 'rU') as in_file:
    elementshow = in_file.read().split('\n')

while True:
    with open('elementsavefile.txt', 'w') as out_file:
        out_file.write('\n'.join(elementshow))
    check = 1
    for a, b in enumerate(elementshow, 1):
        print ('{} {}'.format(a, b))


    firstelement = input("First Element ")
    if not firstelement.isdigit():
        os.system('cls' if os.name == 'nt' else 'clear')
        print("Not a number.")
        continue

    firstelement = int(firstelement)

    if firstelement > int(len(elementshow)):
        os.system('cls' if os.name == 'nt' else 'clear')
        print("Element doesn't exist.")
        continue

    firstelement -= 1


    secondelement = input("Second Element ")
    if not secondelement.isdigit():
        os.system('cls' if os.name == 'nt' else 'clear')
        print("Not a number")
        continue

    secondelement = int(secondelement)

    if secondelement > int(len(elementshow)):
        os.system('cls' if os.name == 'nt' else 'clear')
        print("Element doesn't exist.")
        continue

    secondelement -= 1


    elementcheck = str(elementshow[firstelement] + "+" + elementshow[secondelement])

    try:
        while True:
             if check == 3:
                   os.system('cls' if os.name == 'nt' else 'clear')
                   print("No combination found...")
                   break
             if check == 2:
                   elementcheck = str(elementshow[secondelement] + "+" + elementshow[firstelement])

             element("Fire+Water", "Steam")
             element("Earth+Air", "Dust")
             element("Water+Earth", "Mud")
             element("Air+Fire", "Smoke")
             element("Air+Air", "Pressure")
             element("Water+Water", "Puddle")
             element("Puddle+Puddle", "Lake")
             element("Lake+Lake", "River")
             element("River+River", "Sea")
             element("Sea+Sea", "Ocean")
             element("Wave+Wave", "Tsunami")
             element("Air+Pressure", "Wind")
             element("Water+Wind", "Wave")
             element("Fire+Pressure", "Explosion")
             element("Water+Earth", "Mud")
             element("Mud+Fire", "Clay")
             element("Clay+Clay", "Clay Block")
             element("Clay Block+Clay Block", "Clay Wall")
             element("Clay Wall+Clay Wall", "Clay House")
             element("Clay House+Clay House", "Clay Village")
             element("Clay Village+Clay Village", "Clay Town")
             element("Clay Town+Clay Town", "Clay City")
             element("Earth+Earth", "Soil")
             element("Earth+Soil", "Grass")
             element("Grass+Soil", "Plant")
             element("Plant+Time", "Tree")
             element("Tree+Tree", "Forest")
             element("Forest+Earth", "Land")
             element("Clay City+Land", "Island")
             element("Island+Island", "Country")
             element("Country+Country", "Planet")
             element("Planet+Planet", "Solar System")
             element("Solar System+Solar System", "Galaxy")
             element("Galaxy+Galaxy", "Galaxy Cluster")
             element("Galaxy Cluster+Galaxy Cluser", "Universe")
             element("Fire+Planet", "Sun")
             element("Plant+Sun", "Energy")
             element("Life+Clay", "Human")
             element("Human+Human", "Love")
             element("Fire+Fire", "Lava")
             element("Lava+Air", "Stone")
             element("Air+Stone", "Sand")
             element("Sand+Fire", "Glass")
             element("Sand+Glass", "Time")
             element("Human+Time", "Corpse")
             element("Energy+Energy", "Life")
             element("Life+Life", "Birth")
             element("Life+Plant", "Animal")
             element("Animal+Air", "Bird")
             element("Life+Universe", "God")
             element("God+God", "Goddess")
             element("Goddess+Goddess", "Power")
             element("Power+Human", "Bodybuilder")
             element("Explosion+Planet", "Meteoroid")
             element("Meteoroid+Energy", "Meteorite")
             element("Lava+Water", "Temperature")
             element("Temperature+Water", "Cold")
             element("Temperature+Fire", "Hot")
             element("Water+Cold", "Ice")
             element("Meteroite+Meteorite", "Asteroid")
             element("Asteroid+Ice", "Comet")


             """element("", "")
             """


             check += 1
    except elementexcept:
        pass

The text file simply is just

Water
Fire
Earth
Air
\$\endgroup\$
  • \$\begingroup\$ "so I created my own" Technically you're re-making an already existing, relatively well-known game. There's an awful lot of code duplication going on so I may just be missing it, but isn't a game supposed to have user input? What's the reasoning behind your elementexcept class? \$\endgroup\$ – Mast Oct 16 '17 at 7:09
  • \$\begingroup\$ @Mast it does have userinput somewhere, firstelement = input("First Element ") etc... \$\endgroup\$ – Ludisposed Oct 16 '17 at 7:59
  • \$\begingroup\$ @Ludisposed Which seems to ask for a number instead of a string. \$\endgroup\$ – Mast Oct 16 '17 at 9:45
  • \$\begingroup\$ Later I created a version of the game that allows users to make their own element combining game simply with a text file. You could add "descriptions" by adding brackets, I think if you had to also type in the description it'd be tedious. Also I think it's just easier to type the number. \$\endgroup\$ – Jacklack3 Oct 16 '17 at 20:34
4
\$\begingroup\$

I really would suggest to use some more functions, because this code is currently a top-down approach. And you repeat quite a lot of code.

Why use functions?

  1. Organization -- As programs grow in complexity, having all the code live inside the main() function becomes increasingly complicated. A function is almost like a mini-program that we can write separately from the main program, without having to think about the rest of the program while we write it
  2. Reusability -- Once a function is written, it can be called multiple times from within the program. This avoids duplicated code and minimizes the probability of copy/paste errors. Functions can also be shared with other programs, reducing the amount of code that has to be written from scratch (and retested) each time.
  3. Testing -- Because functions reduce code redundancy, there’s less code to test in the first place. Also because functions are self-contained, once we’ve tested a function to ensure it works, we don’t need to test it again unless we change it.
  4. Extensibility -- When we need to extend our program to handle a case it didn’t handle before, functions allow us to make the change in one place and have that change take effect every time the function is called.
  5. Abstraction -- In order to use a function, you only need to know its name, inputs, outputs, and where it lives. You don’t need to know how it works, or what other code it’s dependent upon to use it.

That is why we need more functions

Let's divide up your game is smaller problems. We need...

  • a function to check if element is correct
  • a function that appends the newly create element to a file.
  • a function that reads the current elements from a file
  • a function to get user_input
  • a function for the main game

It is python standerd to have a if __name__ == '__main__': block.

Let's say you have a allelements.txt file somewhere, that makes it easier to add elements you just add them to the text file.

FireWater,Steam
EarthAir,Dust
WaterEarth,Mud
AirFire,Smoke
AirAir,Pressure
WaterWater,Puddle
PuddlePuddle,Lake
LakeLake,River

Final code

def get_all_alements(filename):
    elements = {}
    with open(filename, 'r') as file:
        for line in file.readlines():
            key, value = line.split(',')
            elements[key] = value.rstrip()
    return elements

def get_elements(filename):
    with open(filename, 'r') as file:
        elems = file.read().split('\n')
    return elems

def get_user_element(question, elements):
    while True:
        element = input(question)
        if element not in elements:
            print("This element does not exist")
        else:
            break

def append_element(filename, new_element):
    with open(filename, 'a') as file:
        file.write("\n{}".format(new_element))

def game():
    all_elements = get_all_alements('allelements.txt')

    while True:
        elements = get_elements('elementsavefile.txt')

        for idx, element in enumerate(elements):
            print ('{} {}'.format(idx, element))

        element_1 = get_user_element("First element: ", elements)
        element_2 = get_user_element("Second element: ", elements)

        new_element = element_1+element_2

        if new_element in all_elements:
            append_element('elementsavefile.txt', all_elements[new_element])
        else:
            print('No new element is created')

if __name__ == '__main__':
    game()

I know this might be alot of code and information in one go. But take your time and play with the code to see what it all does.

\$\endgroup\$
  • \$\begingroup\$ I don't really see how to make it so I can add elements, also i'm a beginner at Python, but what's the point of having literally everything functions when you could just have the things that repeat functions. Also since i'm a beginner I think that this is easy for me. Maybe it's just that there's so much change in the code that it's a bit too much for me. But thanks for the answer. :) \$\endgroup\$ – Jacklack3 Oct 16 '17 at 20:44
  • \$\begingroup\$ @Jacklack3 I edited my answer to show why we need more functions. \$\endgroup\$ – Ludisposed Oct 17 '17 at 7:18
  • \$\begingroup\$ Thanks! When I'm in the programming mood I'll take a look at it. c: \$\endgroup\$ – Jacklack3 Oct 19 '17 at 2:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.