I am making a text based game with my friend for a programming class, we are avoiding using object oriented stuff so please avoid those suggestions. to use the program I would normally do type "help" then I can go in any direction to move like "right", "left", "down" and "up" when I try to use those commands I get an error. this happend after I added the spawnMonster command part
#Connor and Griffin's text based adventure
import os
import random
############################
####---Variable setup---####
#########ADD COMMAND VARIATION############
#########ADD ITEM LISTS#################
commands = 1 #for debuging only please
maxHealth = 100 #Default begin health
health = 100 #Current health
mana = 0 #THERES NO MAGIC
mapS = [5, 5]
objects = {}
color = "0f"
output = "" #this is where whats happening is told to you
level = 1
canMove = 1
playerSym = "P"
# for activeQuests remember that if the value is 0 its not completed and if its 1 its completed
activeQuests = {"Journey To Riverwood": 0}
# Add new quest names above^
commandList = {"help", "legend", "color", "show inv", "quests", "console", "up", "left", "right", "down", "clear", "map"}
#Default inventory
inv = {"apple(s)":2, "shortsword":1, "gold":50,"cloth shirt":1,"pair of cloth pants":1,"pair of shoes":1}
clearedSpaces = []
##### "Name":baseDMG #####
monsters = {"Goblin":1, "Troll":3, "Bear":2, "Giant Spider": 1, "Bandit":1, "Goblin Chief":3}
###########################
###########################
##### Name:lv:monsterSpawnRate #####
zones = {"Forest":[1,90]}
#######################
#---Quest Log Stuff---#
def checkQuest():
for questn in activeQuests:
print("\n------", questn, "------")
if activeQuests[questn] == 0:
print("\nNot Complete")
else:
print("\nComplete")
######Description for quests######
if questn == "Journey To Riverwood":
print("""
Welcome to Connor and Griffins excellent adventure!
try out some of the commands like; help, quests,
color, inv or show inv. now using your new found
commands move to the city of riverwood.\n\n""")
#########################
#########################
############################
###---Scenes/Functions---###
def mapSize(x, y):
global mapS
mapS = [x, y]
####Ads point to map
def addObject(name, x, y, symbol):
objects[name] = [x, y, symbol]
legend[symbol] = name
#### Clears some variables
def roomStart():
global objects
objects = {}
global legend
legend = {"░":"Unknown area"}
global roomName
roomName = "BLANK"
def newArea():
for area in zones:
global spawnChance
spawnChance = zones[area][1]
def spawnMonster():
enemy, DMG = random.choice(monsters)
return enemy
def moveToNewSpace():
rand = random.randint(1,100)
if rand <= spawnChance:
global spawnedMonster
spawnMonster()
###Move player
def changePos(name, newx, newy):
objects[name][0] += newx
objects[name][1] += newy
global clearedSpaces
clearedSpaces.append([objects[name][0],objects[name][1]])
moveToNewSpace()
###First room
def roomBegin():
roomStart()
mapSize(15,10)
global roomName
roomName = "Forest"
newArea()
addObject("Riverwood",10,5,"R")
addObject("Griffin's House",2,2,"G")
addObject("Player",2,3,playerSym) #######Remember to make a "ChangePos" command to change the pos of the player when they move#######
clearedSpaces.append([2,3])
################### MAPPING HERE ##################
def makeMap():
print("\n------"+roomName+"------")
for y in range(mapS[1]):
line = ""
numy = y+1
for x in range(mapS[0]):
numx = x + 1
for place in objects:
if objects[place][:2] == [numx, numy]:
line += objects[place][2]
break
else:
if [numx, numy] in clearedSpaces:
line += " "
else:
line += "░"
print(line)
print("\n----Legend----\n")
for thing in legend:
print(thing + " - " + legend[thing])
############################
############################
#######################
###--- MAIN LOOP ---###
roomBegin()
while 1 == 1:
makeMap()
print("\n\n" + output + "\n\n")
print("\n\nHealth is at ",health,"/",maxHealth)
command = input("Enter action: ")
if command.lower() == "quests":
os.system("cls")
checkQuest()
elif command.lower() == "legend":
os.system("cls")
print("\n----Legend----\n")
for thing in legend:
print(thing + " - " + legend[thing])
elif command.lower() == "help":
os.system("cls")
print("\n\n------HelpMenu------\n")
for comd in commandList:
print(comd)
elif command.lower() == "color":
newc = input("new color: ")
os.system("color 0" + newc)
os.system("cls")
elif command.lower() == "show inv" or command.lower() == "inv" or command.lower() == "inventory":
os.system("cls")
print("\n------Inventory------\n")
for item in inv:
print(" ", inv[item]," ", item)
elif command.lower() == "console":
if commands == 1:
consolecmd = input("Enter a command: ")
os.system(consolecmd)
else:
print("Sorry, you dont have permition to use that command.")
elif command.lower() == "up":
if canMove == 1:
os.system("cls")
changePos("Player", 0,-1)
else:
os.system("cls")
output += "\nCant move that way right now!"
elif command.lower() == "down":
if canMove == 1:
os.system("cls")
changePos("Player", 0,1)
else:
os.system("cls")
output += "\nCant move that way right now!"
elif command.lower() == "left":
if canMove == 1:
os.system("cls")
changePos("Player", -1,0)
else:
os.system("cls")
output += "\nCant move that way right now!"
elif command.lower() == "right":
if canMove == 1:
os.system("cls")
output = "There are some trees here, and a small pond"
changePos("Player", 1,0)
else:
os.system("cls")
output += "\nCant move that way right now!"
elif command.lower() == "clear":
os.system("cls")
else:
os.system("cls")
print("Previous attempt was an invalid command, try again.")
#######END MAIN#######
######################
The random.choice function requires a sequence.
In a previous version of your code (or maybe it was code from a classmate of yours just having similar but not identical problems with similar code?), you had the monsters stored in a list, like [("Goblin", 1), ("Troll", 3), …]. For that code, random.choice works, because a list is a sequence.
But now you have a dict. And a dict is not a sequence.
You can get a list of all of the keys in a dict just by writing list(d). So, you could do this:
return random.choice(list(monsters))
But you're not actually getting any benefit from monsters being a dict from what I can tell, so why not just use a list in the first place?
monsters is a dictionary. It is being passed to random.choice(), however, random.choice() accepts a sequence as its argument (from which it randomly selects one element). This will not work for a dictionary and you will see a KeyError exception if you try.
Since you just want to return an enemy from spawnMonster() you can instead use the keys of monsters which is a list:
monsters = {"Goblin":1, "Troll":3, "Bear":2, "Giant Spider": 1, "Bandit":1, "Goblin Chief":3}
def spawnMonster():
return random.choice(monsters.keys())
Update
Since you are using Python 3 you can do this instead (also works in Python 2):
def spawnMonster():
return random.choice(tuple(monsters))
Related
main.py:
import keyboard
import ui
import os
os.system("cls")
ui.play[ui.counter] = "> " + ui.play[ui.counter] + " <"
ui.navmenuprint(ui.play)
while True:
while ui.state == "play":
keypressed = keyboard.read_key()
while keyboard.is_pressed("down"): pass
while keyboard.is_pressed("up"): pass
while keyboard.is_pressed("enter"): pass
if keypressed == "up":
os.system("cls")
ui.navup(ui.play, ui.play2)
ui.navmenuprint(ui.play)
if keypressed == "down":
os.system("cls")
ui.navdown(ui.play, ui.play2)
ui.navmenuprint(ui.play)
if keypressed == "enter":
if ui.counter == 0:
ui.switchstate("shop")
if ui.counter == 1:
ui.switchstate("shop")
if ui.counter == 2:
ui.switchstate("shop")
if ui.counter == 3:
ui.switchstate("shop")
while ui.state == "shop":
keypressed = keyboard.read_key()
while keyboard.is_pressed("down"): pass
while keyboard.is_pressed("up"): pass
while keyboard.is_pressed("enter"): pass
if keypressed == "up":
os.system("cls")
ui.navup(ui.shop, ui.shop2)
ui.navmenuprint(ui.shop)
if keypressed == "down":
os.system("cls")
ui.navdown(ui.shop, ui.shop2)
ui.navmenuprint(ui.shop)
if keypressed == "enter":
if ui.counter == 0:
ui.switchstate("play")
if ui.counter == 1:
ui.switchstate("play")
if ui.counter == 2:
ui.switchstate("play")
if ui.counter == 3:
ui.switchstate("play")
if ui.counter == 4:
ui.switchstate("play")
ui.py:
import os
from termcolor import cprint
state = "play"
counter = 0
play = ["TOSHOP", "TOSHOP", "TOSHOP","TOSHOP"]
play2 = ["TOSHOP", "TOSHOP", "TOSHOP","TOSHOP"]
shop = ["TOPLAY", "TOPLAY","TOPLAY","TOPLAY","TOPLAY"]
shop2 = ["TOPLAY", "TOPLAY","TOPLAY","TOPLAY","TOPLAY"]
def switchstate(fromwhere):
global state, counter
if fromwhere == "play":
counter = 0
state = fromwhere
play = play2.copy()
os.system("cls")
play[counter] = "> " + play[counter] + " <"
navmenuprint(play)
if fromwhere == "shop":
counter = 0
state = fromwhere
shop = shop2.copy()
os.system("cls")
shop[counter] = "> " + shop[counter] + " <"
navmenuprint(shop)
def navup(list1, list2):
global counter
if counter != 0:
list1[counter] = list2[counter]
counter -= 1
list1[counter] = "> " + list1[counter] + " <"
else:
list1[counter] = list2[counter]
counter -= 1
list1[counter] = "> " + list1[counter] + " <"
counter = len(list1) - 1
print (counter)
def navdown(list1,list2):
global counter
if counter != len(list1) - 1:
list1[counter] = list2[counter]
counter += 1
list1[counter] = "> " + list1[counter] + " <"
else:
list1[counter] = list2[counter]
counter = 0
list1[counter] = "> " + list1[counter] + " <"
print (counter)
def navmenuprint(list):
global counter
for i in list:
print(i)
This code is an extract from my little homemade console game project, I tried to delete all unnecessary code, I successfully made a working interactive menu which means I want to achieve navigation with up and down arrow in menu and currently selected item show as > item <, handle error if list out of index, state handling (for switching screens).
Unfortunately I had to make a few ugly workaround to make this happen or I just too beginner to figure it out.
Python 3.11, I don't want to use additional modules.
The problem:
Go down to 4th item (counter variable value will be 3)
Press Enter
Go down to 5th item (counter variable value will be 4)
Press Enter
Press down
Actual:
TOSHOP
> TOSHOP <
TOSHOP
> TOSHOP <
Expected:
TOSHOP
> TOSHOP <
TOSHOP
TOSHOP
I understand my code and spent many hours to solve this issue but I have no idea why it's faulty.
I think counter variable value is good everywhere.
I make sure to reset "play" and "shop" list to original form and counter variable to 0.
I had to expand global variables with lists inside switchstate function:
def switchstate(fromwhere):
global state, counter, play, play2, shop, shop2
I am making a very creative tetris clone for a project with a friend and we have custom sprites for every shape (including the rotations) and we made a wall of else if statements for the rotations. It's supposed to work like this: It calls a random shape out of list of the main 7 shapes and every time the user presses "a" it changes the left facing gif of that shape using the giant el if wall. However, we ran unto an error where instead of executing the elif statements, it just skips to the last line and changes to the J shape no matter what shape was called in the random statement. Any help would be awesome, thank you! (We are still learning btw) also the rotate function is also supposed to happen when the user presses the "d" key but its supposed to change to the other direction.
import turtle as trtl
import random as rand
wn = trtl.Screen()
#configurations
tetris = trtl.Turtle()
drawer = trtl.Turtle()
background = trtl.Turtle()
starty = int(-400)
square = ("sqaure_block.gif")
s_block_normal = ("S_block_norm.gif")
s_block_standing = ("S_block_right.gif")
invert_s_block_normal = ("Z_block_norm.gif")
invert_s_block_standing = ("Z_block_right.gif")
l_block_normal = ("L_block_norm.gif")
l_block_180 = ("L_block_180.gif")
l_block_right = ("L_block_right.gif")
l_block_left = ("L_block_left.gif")
line_normal = ("line_block_norm.gif")
line_standing = ("line_block_standing.gif")
t_block_normal = ("T_block_norm.gif")
t_block_180 = ("T_block_180.gif")
t_block_right = ("T_BLOCK_RIGHT.gif")
t_block_left = ("T_block_left.gif")
j_block_normal = ("J_block_norm.gif")
j_block_180 = ("J_block_180.gif")
j_block_right = ("J_block_right.gif")
j_block_left = ("J_block_left.gif")
wn.addshape (square)
wn.addshape(s_block_normal)
wn.addshape(s_block_standing)
wn.addshape(invert_s_block_normal)
wn.addshape(invert_s_block_standing)
wn.addshape(l_block_normal)
wn.addshape(l_block_180)
wn.addshape(l_block_right)
wn.addshape(l_block_left)
wn.addshape(line_normal)
wn.addshape(line_standing)
wn.addshape(t_block_normal)
wn.addshape(t_block_180)
wn.addshape(t_block_right)
wn.addshape(t_block_left)
wn.addshape(j_block_normal)
wn.addshape(j_block_180)
wn.addshape(j_block_right)
wn.addshape(j_block_left)
Tshape = [square, s_block_normal, invert_s_block_normal, l_block_normal, line_normal, t_block_normal, j_block_normal]
squarecor = [-50, -25, -100, -50]
wn.bgcolor("lightblue")
background.speed("fastest")
background.hideturtle()
background.pu()
background.goto(-400,-200)
background.fillcolor("blue")
background.pencolor("blue")
background.begin_fill()
background.pd()
background.goto(400,-200)
background.goto(400,-350)
background.goto(-400,-350)
background.goto(-400,-200)
background.end_fill()
#sprite direction change
def sprite_right():
global tetris
tetris.hideturtle()
if (tetris.shape(s_block_normal)):
tetris.shape(s_block_standing)
elif (tetris.shape(invert_s_block_normal)):
tetris.shape(invert_s_block_standing)
elif (tetris.shape(line_normal)):
tetris.shape(line_standing)
elif (tetris.shape(l_block_normal)):
tetris.shape(l_block_right)
elif (tetris.shape(t_block_normal)):
tetris.shape(t_block_right)
elif (tetris.shape(j_block_normal)):
tetris.shape(j_block_right)
elif (tetris.shape(l_block_right)):
tetris.shape(l_block_180)
elif (tetris.shape(t_block_right)):
tetris.shape(t_block_180)
elif (tetris.shape(j_block_right)):
tetris.shape(j_block_180)
elif (tetris.shape(s_block_standing)):
tetris.shape(s_block_normal)
elif (tetris.shape(invert_s_block_standing)):
tetris.shape(invert_s_block_normal)
elif (tetris.shape(line_standing)):
tetris.shape(line_normal)
elif (tetris.shape(l_block_180)):
tetris.shape(l_block_left)
elif (tetris.shape(t_block_180)):
tetris.shape(t_block_left)
elif (tetris.shape(j_block_180)):
tetris.shape(j_block_left)
elif (tetris.shape(l_block_left)):
tetris.shape(l_block_normal)
elif (tetris.shape(t_block_left)):
tetris.shape(t_block_normal)
elif (tetris.shape(j_block_left)):
tetris.shape(j_block_normal)
tetris.showturtle()
def sprite_left():
tetris.hideturtle()
if (tetris.shape(s_block_normal)):
tetris.shape(s_block_standing)
elif (tetris.shape(invert_s_block_normal)):
tetris.shape(invert_s_block_standing)
elif (tetris.shape(line_normal)):
tetris.shape(line_standing)
elif (tetris.shape(l_block_normal)):
tetris.shape(l_block_left)
elif (tetris.shape(t_block_normal)):
tetris.shape(t_block_left)
elif (tetris.shape(j_block_normal)):
tetris.shape(j_block_left)
elif (tetris.shape(l_block_left)):
tetris.shape(l_block_180)
elif (tetris.shape(t_block_left)):
tetris.shape(t_block_180)
elif (tetris.shape(j_block_left)):
tetris.shape(j_block_180)
elif (tetris.shape(s_block_standing)):
tetris.shape(s_block_normal)
elif (tetris.shape(invert_s_block_standing)):
tetris.shape(invert_s_block_normal)
elif (tetris.shape(line_standing)):
tetris.shape(line_normal)
elif (tetris.shape(l_block_180)):
tetris.shape(l_block_right)
elif (tetris.shape(t_block_180)):
tetris.shape(t_block_right)
elif (tetris.shape(j_block_180)):
tetris.shape(j_block_right)
elif (tetris.shape(l_block_right)):
tetris.shape(l_block_normal)
elif (tetris.shape(t_block_right)):
tetris.shape(t_block_normal)
elif (tetris.shape(j_block_right)):
tetris.shape(j_block_normal)
tetris.showturtle()
'''
def (fast_down):
global tetris
tetris.setheading(270)
tetris.forward(10)
'''
#turn right
def turn_right():
tetris.speed("fastest")
tetris.setheading(0)
tetris.speed(1)
tetris.forward(10)
tetris.speed("fastest")
tetris.setheading(270)
#turn left
def turn_left():
tetris.speed("fastest")
tetris.setheading(180)
tetris.speed(1)
tetris.forward(10)
tetris.speed("fastest")
tetris.setheading(270)
#down
#tetris container/backround
drawer.pensize(5)
drawer.speed("fastest")
drawer.penup()
drawer.goto(150, 200)
drawer.pendown()
drawer.setheading(270)
drawer.forward(400)
drawer.setheading(180)
drawer.forward(300)
drawer.setheading(90)
drawer.forward(400)
drawer.hideturtle()
#game WIP!!!!!!!!!!
y = 0
space = int(1)
tracer = True
def spawn_T():
new_T=rand.choice(Tshape)
tetris.shape(t_block_180)
tetris.pu()
tetris.goto(0, 200)
tetris.setheading(270)
tetris.forward(10)
'''
if ((abs(space - starty)) < 200):
tetris.forward(2)
else:
'''
tetris.stamp()
'''
space = space =+ 1
'''
tetris.hideturtle()
tetris.goto(0,200)
tetris.showturtle()
if (y == 0):
spawn_T()
#changeing the directions of the sprites
#events
wn.onkeypress(turn_right, "Right")
wn.onkeypress(turn_left, "Left")
wn.onkeypress(sprite_right, "a")
wn.onkeypress(sprite_left, "d")
'''
wn.onkeypress(fast_down, "s")
'''
wn.listen()
wn.mainloop()
Here is the google drive file https://drive.google.com/drive/folders/1Q_zXEqm4aFHQ4RV-ZvEXCK2Wi7SHMxrW?usp=share_link
I think the indentation is wrong here. Maybe try putting the last else-statement one tab further?
Please use elif instead of the else: if formulation to get away from the bewildering indentation - here's how it should look:
def sprite_right():
global tetris
tetris.hideturtle()
if (tetris.shape(s_block_normal)):
tetris.shape(s_block_standing)
elif (tetris.shape(invert_s_block_normal)):
tetris.shape(invert_s_block_standing)
elif (tetris.shape(line_normal)):
tetris.shape(line_standing)
elif (tetris.shape(l_block_normal)):
tetris.shape(l_block_right)
elif (tetris.shape(t_block_normal)):
tetris.shape(t_block_right)
elif (tetris.shape(j_block_normal)):
tetris.shape(j_block_right)
elif (tetris.shape(l_block_right)):
tetris.shape(l_block_180)
elif (tetris.shape(t_block_right)):
tetris.shape(t_block_180)
elif (tetris.shape(j_block_right)):
tetris.shape(j_block_180)
elif (tetris.shape(s_block_standing)):
tetris.shape(s_block_normal)
elif (tetris.shape(invert_s_block_standing)):
tetris.shape(invert_s_block_normal)
elif (tetris.shape(line_standing)):
tetris.shape(line_normal)
elif (tetris.shape(l_block_180)):
tetris.shape(l_block_left)
elif (tetris.shape(t_block_180)):
tetris.shape(t_block_left)
elif (tetris.shape(j_block_180)):
tetris.shape(j_block_left)
elif (tetris.shape(l_block_left)):
tetris.shape(l_block_normal)
elif (tetris.shape(t_block_left)):
tetris.shape(t_block_normal)
elif (tetris.shape(j_block_left)):
tetris.shape(j_block_normal)
tetris.showturtle()
def sprite_left():
tetris.hideturtle()
if (tetris.shape(s_block_normal)):
tetris.shape(s_block_standing)
elif (tetris.shape(invert_s_block_normal)):
tetris.shape(invert_s_block_standing)
elif (tetris.shape(line_normal)):
tetris.shape(line_standing)
elif (tetris.shape(l_block_normal)):
tetris.shape(l_block_left)
elif (tetris.shape(t_block_normal)):
tetris.shape(t_block_left)
elif (tetris.shape(j_block_normal)):
tetris.shape(j_block_left)
elif (tetris.shape(l_block_left)):
tetris.shape(l_block_180)
elif (tetris.shape(t_block_left)):
tetris.shape(t_block_180)
elif (tetris.shape(j_block_left)):
tetris.shape(j_block_180)
elif (tetris.shape(s_block_standing)):
tetris.shape(s_block_normal)
elif (tetris.shape(invert_s_block_standing)):
tetris.shape(invert_s_block_normal)
elif (tetris.shape(line_standing)):
tetris.shape(line_normal)
elif (tetris.shape(l_block_180)):
tetris.shape(l_block_right)
elif (tetris.shape(t_block_180)):
tetris.shape(t_block_right)
elif (tetris.shape(j_block_180)):
tetris.shape(j_block_right)
elif (tetris.shape(l_block_right)):
tetris.shape(l_block_normal)
elif (tetris.shape(t_block_right)):
tetris.shape(t_block_normal)
elif (tetris.shape(j_block_right)):
tetris.shape(j_block_normal)
tetris.showturtle()
That said, because this is all the code you've provided, it's not possible to run it and examine why it's not working. Can you please provide an example of an implementation of these functions?
According to the documentation, shape() returns the current shape with no parameters, and sets it with one parameter. Therefore in:
if tetris.shape(s_block_normal):
shape(name) returns None, which is always False. So, if you change to:
if tetris.shape() == s_block_normal:
It should function as required.
Also, you can get rid of the if ladder completely by, for instance, something like:
next_left_shape = {s_block_normal: s_block_standing,
invert_s_block_normal: invert_s_block_standing,
... }
tetris.shape(next_left_shape[tetris.shape()])
I was searching on the internet for projects do with python and came up with a Tic Tac Toe game. But now i'm kind of stuck in some part of the code because i can't store the player moves.
Well, to be honest, i maybe know how to do it, but i'll be using A LOT of if, elif and else. Is there another way i can do it without writing 100+ lines of code just to store some data using my current code?
Ps: It needs to be OOP, as i am learning it right now :l
import msvcrt as m # Using it for 'Press any key to continue' thing.
import os
import keyboard
class TicTacToe:
def __init__(self):
self.difficultAI = 1
self.playWith = 1 # 3 = Strings and Numbers
self.playerOne = None
self.PlayerTwo = None
def menuSelection(self):
os.system('cls')
print(f'[1] - Play\n'
f'[2] - Options\n'
f'[3] - Exit')
try:
option = int(input('I\'ll go with '))
except ValueError as valueError:
print(f'Invalid Option\n'
f'Following error: {valueError}\n'
f'Press any key to continue...')
m.getch() # Waiting for any key to be pressed.min
os.system('cls')
objectRun.menuSelection() # Call menuSelection again.
if option == 1:
objectRun.play()
elif option == 2:
pass
elif option == 3:
exit()
else:
print(f'You should choose something between 1 and 3, and not {option}'
f'Press any key to continue...')
m.getch()
objectRun.menuSelection()
def drawBoard(self, topL='?', topM='!', topR='?',
midL='!', midM='?', midR='!',
lowL='?', lowM='!', lowR='?'):
board = {
'top-L': topL,
'top-M': topM,
'top-R': topR,
'mid-L': midL,
'mid-M': midM,
'mid-R': midR,
'low-L': lowL,
'low-M': lowM,
'low-R': lowR,
}
print(' {0} | {1} | {2}\n'
'----------\n'
' {3} | {4} | {5}\n'
'----------\n'
' {6} | {7} | {8}\n'.format(board['top-L'], board['top-M'], board['top-R'],
board['mid-L'], board['mid-M'], board['mid-R'],
board['low-L'], board['low-M'], board['low-R']))
# change that stupid name when done
def play(self):
os.system('cls')
print(f'[1] - Player VS Player\n'
f'[2] - Player VS Machine\n'
f'[3] - Return')
try:
option = int(input('I\'ll go with '))
except ValueError as valueError:
print(f'Invalid Option\n'
f'Following error: {valueError}\n'
f'Press any key to continue...')
m.getch()
objectRun.play()
try:
os.system('cls')
self.drawBoard()
if option == 1:
if self.playWith == 1: # Numbers
isBoardFull = False # Not using it right now, but ok... I guess.
while isBoardFull != True:
print('Player 1, it\'s your turn\n'
'You can choose between 1 (TOP LEFT) up to 9 (BOTTOM RIGHT)')
self.playerOne = int(input('I\'ll go with '))
self.playerOptions()
elif self.playWith == 2: # Strings
pass
else: # Strings and Numbers
pass
elif option == 2:
pass
elif option == 3:
objectRun.menuSelection()
else:
print(f'You should choose something between 1 and 3, and not {option}'
f'Press any key to continue...')
m.getch()
objectRun.play()
except:
print('ERROR AT LINE 126, GO FIND WHAT IS WRONG')
def playerOptions(self):
if self.playerOne == 1:
os.system('cls')
self.drawBoard(topL='X')
elif self.playerOne == 2:
os.system('cls')
self.drawBoard(topM='X')
elif self.playerOne == 3:
os.system('cls')
self.drawBoard(topR='X')
elif self.playerOne == 4:
os.system('cls')
self.drawBoard(midL='X')
elif self.playerOne == 5:
os.system('cls')
self.drawBoard(midM='X')
elif self.playerOne == 6:
os.system('cls')
self.drawBoard(midR='X')
elif self.playerOne == 7:
os.system('cls')
self.drawBoard(lowL='X')
elif self.playerOne == 8:
os.system('cls')
drawBoard(lowM='X')
elif self.playerOne == 9:
os.system('cls')
self.drawBoard(lowR='X')
else:
pass
def options(self):
os.system('cls')
print(f'[1] - Difficult\n'
f'[2] - P\n'
f'[3] - Exit')
try:
option = int(input('I\'ll go with '))
except ValueError as valueError:
print(f'You should choose something between 1 and 3, and not {option}'
f'Press any key to continue...')
m.getch()
objectRun.menuSelection()
self.difficultAI = int(input('[1] - EASY\n'
'[2] - MEDIUM\n'
'[3] - HARD\n'
'I\'ll go with '))
self.playWith = int(input('[1] - NUMBERS\n'
'[2] - STRING\n'
'[3] - BOTH\n'
'I\'ll go with '))
if __name__ == '__main__':
objectRun = TicTacToe()
objectRun.menuSelection()
Store the current board as dictionary within self.
Initialize your board with the default starting characters.
def __init__(self):
self.difficultAI = 1
self.playWith = 1 # 3 = Strings and Numbers
self.playerOne = None
self.PlayerTwo = None
self.board = {'topL':'?', 'topM':'!', 'topR':'?',} #fill in the rest
Your drawBoard would need adjusted like this...
def drawBoard(self):
board = {
'top-L': self.board['topL'],
'top-M': self.board['topM'],
'top-R': self.board['topR'],
And then I would have a separate method for a "move"
def makeMove(self, player, position):
if self.board[position] not in ['X', 'O']:
self.board[position] = player
self.drawboard()
else:
# error statement and send back to make a new move...
In general, I would have separate methods for the main loop of the game vs everything else. Right now you have a lot of things going on inside the main loop when it should be just sending you to different methods of your game like playerOptions, makeMove, drawBoard, etc. until someone wins or ties.
This question already has answers here:
Defining lists as global variables in Python
(3 answers)
Slicing list inside a method (Python 3)
(1 answer)
Closed 5 years ago.
I have the following code:
import sys
import os.path
import ConfigParser
import copy
import time
import colorama
from colorama import init
from colorama import Fore, Back, Style
init()
#init variables
discoveredelements = []
discoveredgroups = []
combo = []
savefile = ConfigParser.ConfigParser()
os.chdir(os.getcwd())
#init other stuff
class style:
BOLD = '\033[1m'
END = '\033[0m'
def combos():
#all combos
combo.append(('Air', 'Air', 'Wind'))
combo.append(('Earth', 'Earth', 'Pressure'))
combo.append(('Fire', 'Fire', 'Explosion'))
combo.append(('Water', 'Water', 'Sea'))
combo.append(('Air', 'Earth', 'Dust'))
combo.append(('Air', 'Fire', 'Energy'))
combo.append(('Air', 'Water', 'Steam'))
combo.append(('Earth', 'Fire', 'Lava'))
combo.append(('Earth', 'Water', 'Swamp'))
combo.append(('Fire', 'Water', 'Alcohol'))
def mainmenu():
print(style.BOLD + "ALCHEMY" + style.END)
print(style.BOLD + "Load Game" + style.END)
print(style.BOLD + "New Game" + style.END)
print(style.BOLD + "Exit" + style.END)
print("Type \"load\" or \"new\" or \"exit\" ")
mainmenuinput = raw_input()
if mainmenuinput == "exit":
sys.exit()
elif mainmenuinput == "load":
if os.path.exists('save.ini'):
savefile.read('save.ini')
discoveredelements = savefile.get('Elements','discoveredelements')
print("Game Loaded")
rungame()
else:
print("Save file not found, check file directory or start a new game.")
mainmenu()
elif mainmenuinput == "new":
if os.path.exists("save.ini"):
print("Current save file will be overwritten. Proceed?")
print("Y or N")
overwriteinput = raw_input()
if overwriteinput == "Y":
newgame()
rungame()
elif overwriteinput == "N":
mainmenu()
else:
newgame()
rungame()
def newgame():
save = open('save.ini','w')
#reset data
savefile.add_section('Elements')
savefile.add_section('Groups')
savefile.set('Elements','discoveredelements',"")
savefile.set('Groups','discoveredgroups',"")
#adds the default elements
discoveredelements.append("Air")
discoveredelements.append("Earth")
discoveredelements.append("Fire")
discoveredelements.append("Water")
savefile.set('Elements','discoveredelements',discoveredelements)
discoveredgroups.append("Air")
discoveredgroups.append("Earth")
discoveredgroups.append("Fire")
discoveredgroups.append("Water")
savefile.set('Groups','discoveredgroups',discoveredgroups)
savefile.write(save)
save.close()
print("Game Loaded")
def gameloop():
#actual gameplay
print("Type two elements (seperately) or \"list\" or \"hint\" or \"save\" or \"exit\"")
gameinput = raw_input()
if gameinput == "list":
displayelements = copy.copy(discoveredelements)
print(','.join(map(str, displayelements)))
gameloop()
elif gameinput == "hint":
if (time.time() - timerstart) >= 10:
print('hint')
timerstart = time.time()
gameloop()
else:
print("Hint is still on cooldown")
gameloop()
elif gameinput == "save":
savefile.set('Elements','discoveredelements',discoveredelements)
savefile.set('Groups','discoveredgroups',discoveredgroups)
print("Game saved")
elif gameinput == "exit":
savefile.read('save.ini')
savelist = savefile.get('Elements','discoveredelements')
if len(savelist) < len(discoveredelements):
print("Game not saved! Do you wish to exit without saving?")
print("Y or N")
overwriteinput = raw_input()
if overwriteinput == "Y":
mainmenu()
else:
gameloop()
else:
elementA = gameinput
elementB = raw_input()
if (elementA in discoveredelements) and (elementB in discoveredelements):
i = 0
created = 0
while True:
if (combo[i][0] == elementA and combo[i][1] == elementB) or (combo[i][1] == elementA and combo[i][0] == elementB):
print("You created " + combo[i][2])
discoveredelements.append(combo[i][2])
created = 1
break
i += 1
if i == len(combo):
break
if created == 0:
print("No elements created")
gameloop()
else:
print("Error, using non-existent or not yet discovered elements")
gameloop()
def rungame():
#initializing game
timerstart = time.time()
displayelements = copy.copy(discoveredelements)
print(','.join(map(str, displayelements)))
gameloop()
#game starts here
print(Style.RESET_ALL)
combos()
mainmenu()
When I type "load" into the console, nothing is outputted for displayelements. So I tried to see if the list contained anything (and if the copy.copy() worked or not) by doing print(displayelements) and it printed []
Then I checked if discoveredelements contained anything and it did:
['Air', 'Earth', 'Fire', 'Water']
Why isn't the copy.copy() working?
EDIT:
I declared discoveredelements as global:
global discoveredelements
discoveredelements = []
The copying still doesn't work, displayelements is still an empty list.
To assign to a global var in function you must declare is as global:
discoveredelements = []
def func():
# a new var is created in the scope of this function
discoveredelements = [1,2,3,4]
func()
print (discoveredelements)
discoveredelements = []
def func():
# declare as global
global discoveredelements
# assign to the global var
discoveredelements = [1,2,3,4]
func()
print (discoveredelements)
def menurender():
global pos
global menulist
line1=menulist[pos]
if pos == len(menulist):
line2="back"
else:
line2=menulist[pos+1]
lcd.clear()
lcd.message(str(pos)+' ' +line1+ "\n"+str(pos+1)+' '+ line2)
In my block of code, I have a conditional in the menurender() function that checks to make sure that the list menulist has a valid index before referencing it, but i receive IndexError: list index out of range. I understand that the else statement is causing it, but I am confused because python shouldn't be executing it.
Full code
#!/usr/bin/python
#################################################
#IMPORTS#########################################
#################################################
from Adafruit_CharLCDPlate import Adafruit_CharLCDPlate
from Adafruit_I2C import Adafruit_I2C
#################################################
#OBJECTS#########################################
#################################################
lcd = Adafruit_CharLCDPlate()
#################################################
#VARIABLES#######################################
#################################################
#current button value
prevbutton = "NULL"
#for SELECT key and determining clicks
action = False
#variable for menu position
pos = 0
#on screen cursor 0 for top line, 1 for bottom line
cursor = 0
#Handles list structure and action when clicked
menulist= []
menulist.append("CPU")
menulist.append("RAM")
menulist.append("STORAGE")
menulist.append("NETWORK")
#get input from keys and return the currently pressed key
def buttonstatus():
bstatus = "Null"
if lcd.buttonPressed(lcd.SELECT) == True:
bstatus="SELECT"
elif lcd.buttonPressed(lcd.UP) == True:
bstatus="UP"
elif lcd.buttonPressed(lcd.DOWN) == True:
bstatus="DOWN"
elif lcd.buttonPressed(lcd.LEFT) == True:
bstatus="LEFT"
elif lcd.buttonPressed(lcd.RIGHT) == True:
bstatus="RIGHT"
return bstatus
#checks buttons pressed and converts that into action for top menu
def getinput():
global prevbutton
global pos
if buttonstatus() != prevbutton:
prevbutton = buttonstatus()
if buttonstatus() == "SELECT":
print "select"
elif buttonstatus() == "DOWN":
pos = pos + 1
elif buttonstatus() == "UP":
pos = pos -1
#elif buttonstatus() == "LEFT":
#print "left"
#elif buttonstatus() == "RIGHT":
#print "right"
#defines bounds for the position of the cursor
def posbounds():
global pos
global menulist
if pos < 0:
pos = 0
if pos == len(menulist):
pos = len(menulist)
#code renders the menu on the LCD
def menurender():
global pos
global menulist
line1=menulist[pos]
if pos == len(menulist):
line2="back"
else:
line2=menulist[pos+1]
lcd.clear()
lcd.message(str(pos)+' ' +line1+ "\n"+str(pos+1)+' '+ line2)
while True:
getinput()
posbounds()
menurender()
There are lots if values for pos != len(menulist) for which menulist[pos+1] gives an IndexError (including pos == len(menulist) - 1). You should check
if pos > (len(menulist) - 2):
You should probably change if pos == len(menulist): to if pos == len(menulist) - 1: if you want to check if pos is the index of the last element, or to if pos == len(menulist) - 2: if you want to check for the second to last element.
A better way of doing this may be by using a try ... except block.
try:
line2 = menulist[pos+1]
except IndexError:
# Out of range -> pos is greater than len(menulist)-1
line2 = 'back'
However - this doesn't seem lika a Pythonic way of doing anything at all in Python. Maybe you could tell us what you are trying to achieve, and someone here may propose a better way of doing it.