4
\$\begingroup\$

This is a python game that I am working on. It is a grid based treasure hunt game in which you collect coins from specific tiles (some tiles ask you questions in which you need to answer correctly in order to get coins), and after a number of moves the coins that you end up with are recorded and put in a file. At the moment I haven't fully implemented everything to the final game but I am using SQlite3 for the backend database of storing questions/answers and for the front end Tkinter and Pygame. Any advice on how to improve my code, organise it, make it more efficient or anything else would be good to know. Thanks.

import pygame, sys
import random
from pygame.locals import *
from tkinter import ttk
import tkinter
from tkinter import messagebox
import sqlite3

conn = sqlite3.connect('games.db')

c = conn.cursor()

#creates table        
#c.execute("""CREATE TABLE game (
#            questionID integer PRIMARY KEY AUTOINCREMENT,
#            question text,
#            answer text
#            )""")
#execute only once

#SQL QUESTION ADD/REMOVE/GET
def insert_question(emp):
    c.execute("INSERT INTO game VALUES (?, ?, ?)", (emp))
    conn.commit()

def get_question():
    c.execute("SELECT * FROM game")
    return c.fetchall()

def remove_question(emp):
    c.execute("DELETE from game WHERE question = ?", [emp])
    conn.commit()

#Tkinter
window = tkinter.Tk()
window.title("Treasure Hunt Game!")

labelOne = ttk.Label(window, text = """ ~~~~~~~~~~~~~ MENU ~~~~~~~~~~~~~
""")#label displays instruction
labelOne.grid(row = 0, column = 0)#places label in a grid

def showInstructions():
    messagebox.showinfo("Instructions", "shows instructions")#messagebox used for more simple functions (showing messages)

btn = ttk.Button(window, text = "View instructions", command = showInstructions)
btn.grid(row = 1, column = 0)#places button in a grid

def showLeaderboard():
    messagebox.showinfo("Leaderboard", "shows leaderboard")
    window.destroy()


btn = ttk.Button(window, text = "View leaderboard", command = showLeaderboard)
btn.grid(row = 2, column = 0)

def showQuestions():
    emps = get_question()
    messagebox.showinfo("List of questions/answers", emps)

btn = ttk.Button(window, text = "View all questions", command = showQuestions)
btn.grid(row = 3, column = 0)

btn = ttk.Button(window, text = "Continue", command = showLeaderboard)
btn.grid(row = 4, column = 0)

labelTwo = ttk.Label(window, text = "Enter a math question:")
labelTwo.grid(row = 5, column = 0)

mathquestion = tkinter.StringVar()#value type is classified as a string

userEntryQ = ttk.Entry(window, width = 30, textvariable = mathquestion)
userEntryQ.grid(row = 6, column = 0)

labelTwo = ttk.Label(window, text = "Enter the answer to this question:")
labelTwo.grid(row = 7, column = 0)

mathanswer = tkinter.StringVar()

userEntryQ = ttk.Entry(window, width = 30, textvariable = mathanswer)
userEntryQ.grid(row = 8, column = 0)

def answer():
    mathquestion1 = mathquestion.get()
    mathanswer1 = mathanswer.get()
    emp_1 = (None, mathquestion1, mathanswer1)
    insert_question(emp_1)

    emps = get_question()
    print(emps)

btn = ttk.Button(window, text = "Submit", command = answer)
btn.grid(row = 8, column = 1)

labelTwo = ttk.Label(window, text = "Enter question to remove:")
labelTwo.grid(row = 9, column = 0)

removequestion = tkinter.StringVar()

userEntryQ = ttk.Entry(window, width = 30, textvariable = removequestion)
userEntryQ.grid(row = 10, column = 0)

def remove():
    removequestion1 = removequestion.get()
    remove_question(removequestion1)

btn = ttk.Button(window, text = "Submit", command = remove)
btn.grid(row = 10, column = 1)

window.mainloop()

#MAIN GAME
#colours
black = (0, 0, 0)
white = (255, 255, 255)
brown = (153, 76, 0)
blue  = (0, 0, 255)
grey  = (192,192,192)

#game dimensions
tilesize = 20
mapwidth = 30
mapheight = 20

coins = 0
ship = 1
water = 2
rock = 3
movesMade = 4

#dictionary for texture of the map
textures = { #the transform function scales the photo to the tile size
    ship : pygame.transform.smoothscale(pygame.image.load('ship.png'), (tilesize, tilesize)),
    water: pygame.transform.smoothscale(pygame.image.load('water.png'), (tilesize, tilesize)),
    rock: pygame.transform.smoothscale(pygame.image.load('rock.png'), (tilesize, tilesize)),
    coins: pygame.transform.smoothscale(pygame.image.load('chest.png'), (tilesize, tilesize)),
    movesMade: pygame.transform.smoothscale(pygame.image.load('player.png'), (tilesize, tilesize))
    }

inventory = {
    coins: 0,
    movesMade: 0
    }

#image that will represent player
PLAYER = pygame.transform.smoothscale(pygame.image.load('player.png'), (tilesize, tilesize))

#position of the player
playerPos = [0,0]

resources = [coins, movesMade]

#utilise list comprehension to create grid
tilemap = [[water for w in range(mapwidth)] for h in range(mapheight)]

pygame.init()

#set up display
displaysurf = pygame.display.set_mode((mapwidth*tilesize,mapheight*tilesize + 60))


invfont = pygame.font.Font('FreeSansBold.ttf', 18)

#loops through each row
for rw in range(mapheight):
    for cl in range(mapwidth):
        randomnumber = random.randint(0,15)
        if randomnumber == 0 or randomnumber == 1:
            tile = rock
        elif randomnumber == 2 or randomnumber == 3 :
            tile = ship
        else:
            tile = water
        #sets position in the grid
        tilemap[rw][cl] = tile

visit = {}
while True:

    displaysurf.fill(black) #background color

    #user events
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == KEYDOWN:
            if event.key == K_RIGHT and playerPos[0] < mapwidth - 1:
                playerPos[0] += 1
            if event.key == K_LEFT and playerPos[0] > 0:
                playerPos[0] -= 1
            if event.key == K_UP and playerPos[1] > 0:
                playerPos[1] -= 1
            if event.key == K_DOWN and playerPos[1] < mapheight -1:
                playerPos[1] += 1
            if event.key == K_SPACE:
                pos = (playerPos[1], playerPos[0])
                if not pos in visit: # checks whether a tile has been used
                    visit[pos] = True 
                    currentTile = tilemap[playerPos[1]][playerPos[0]]
                    if currentTile == rock:
                        inventory[movesMade] += 1
                        percent = 30 # coins are kept with a probability of 30 percent and will be lost by 70 percent
                        ran1 = random.randint(0,100) # random value in [0, 99]
                        if ran1 >= percent:
                            inventory[coins] = 0
                        else:
                            inventory[coins] += 100

                    elif currentTile == ship:
                        inventory[coins] += 20
                        inventory[movesMade] += 1

    #loops through each row 
    for row in range(mapheight):
        #loops through each column in row
        for column in range(mapwidth):
            displaysurf.blit(textures[tilemap[row][column]], (column*tilesize,row*tilesize))

    displaysurf.blit(PLAYER,(playerPos[0]*tilesize,playerPos[1]*tilesize))

    placePosition = 10
    for item in resources:
        displaysurf.blit(textures[item],(placePosition, mapheight*tilesize + 20))
        placePosition += 30
        #text displays amount of coin
        textObj = invfont.render(str(inventory[item]), True, white, black)
        displaysurf.blit(textObj,(placePosition, mapheight*tilesize + 20))
        placePosition += 50

    #if inventory[coins] > 100:
    #    break
    pygame.display.update()
\$\endgroup\$
3
\$\begingroup\$

Some suggestions:

  • There is very little structure. A game like this would typically have at least Game, Question, Answer, Storage and Window classes and a main method which just creates a Game and runs it.
  • Pull out fields or constants (as appropriate) for magic values such as strings and numbers, so a reader can know at a glance what they are, rather than just their value.
  • Run the code through flake8 and pycodestyle to get hints about non-pythonic code such as the variable names.
\$\endgroup\$

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.