How to implement a for loop - python

I have my for loop set up, but im missing one condition and just don't know where to put it! Let's say the user already picked "a1" and picks it again. I don't want that value to be used but instead tell him it's already been picked and let him pick again. I tried making it but the way I had it, it told him that he already picked it, but didn't let him go again.
def inputCoordinate():
coordinate = False
while not coordinate :
user = (input("Enter your move: "))
if user in List:
if user == "a1":
value = "O"
gameboard[0] = value
playedmoves.append("a1")
elif user == "a2":
value = "O"
gameboard[3] = value
playedmoves.append("a2")
elif user == "a3":
value = "O"
gameboard [6] = value
playedmoves.append("a3")
elif user == "b1":
value = "O"
gameboard[1] = value
playedmoves.append("b1")
elif user =="b2":
value = "O"
gameboard[4] = value
playedmoves.append("b2")
elif user == "b3":
value = "O"
gameboard[7] = value
playedmoves.append("b3")
elif user =="c1":
value = "O"
gameboard[2]=value
playedmoves.append("c1")
elif user == "c2":
value = "O"
gameboard[5] = value
playedmoves.append("c2")
elif user == ("c3"):
value = "O"
gameboard[8] = value
playedmoves.append("c3")
else:
print("invalid Coordinates")
continue
return value
playedmoves =("a1","b2")
List = ("a1", "a2", "a3", "b1", "b2", "b3", "c1", "c2", "c3")

So you want to force the user to repeatedly enter a move until they enter a valid one. That means that you need to wrap the input statement in a loop, something like this:
while some_condition_is_not_met:
user = input("Enter your move: ")
if not valid_move(user):
print "bad move, please re-enter"
You could make the while loop depend on a variable that gets set when the user enters a valid move:
good_move = False
while not good_move:
user = input("Enter your move: ")
if valid_move(user):
good_move = True
else:
print "bad move, please re-enter"

Just test against playedmoves right where you are testing if the move is valid:
if user in List and user not in playedmoves:
You really want to use a mapping here to translate position to index:
pos_to_index = {"a1": 0, "a2": 3, "a3": 6, "b1": 1, "b2": 4, "b3": 7, "c1": 2, "c2": 5, "c3": 8}
def inputCoordinate():
while True:
user = (input("Enter your move: "))
index = pos_to_index.get(user)
if index is not None and gameboard[index] not in ('O', 'X'):
gameboard[index] = 'O'
else:
print("invalid Coordinates")
continue
return 'O'
Here we use the gameboard to see if a move is still available; if there is a naught or cross there already, the move is obviously not a valid one. The pos_to_index mapping gets rid of the 9 if statements in one go.

Isn't using a Dictionary in this case waaaay simplier?
playedmoves = []
moves = {"a1":0, "a2":3, "a3":6, "b1":2, "b2":4, "b3":7, "c1":2, "c2":5, "c3":8}
if user in moves and not in playedmoves:
gameboard[moves[user]] = "0"
playedmoves.append(user)
else:
print("Invalid coordinates.")

Suggest to rewrite like this:
mapping = {"a1": 0, "a2": 3, ... }
List = mapping.keys()
playedmoves =("a1","b2")
def inputCoordinate():
coordinate = False
while not coordinate :
user = (input("Enter your move: "))
value = "0" # <---
if user in List:
gameboard[mapping[user]] = value
playedmoves.append(user)
else:
print("invalid Coordinates")
continue
return value

Related

Validate a record in a dict list, if found, update, if not, insert (Python)

I have a minor problem because of my understanding of how this works. I have a function to play the dice game, then send the results in a list to another function where valid the dice results, the list takes the name of the player and the values ​​of the dice, it looks like this:
['John', 1, 2, 3, 3, 3]
Then I'm trying to save the record in a dict, to later save it in a new list, where all the information of the players will be, it will look like this:
[
{
'Name': 'luis',
'Dice': (1, 2, 3, 3, 3),
'Bet': 500
}, {
'Name': 'andrew',
'Dice': (2, 2, 2, 1, 2),
'Bet': 500
}
]
But I don't know how to do the following:
If the list is empty, without player dictionaries, save the first one based on a previous validation.
Whose validation is that it checks if the "key" Name already has the "value" of the player's name, if so, it does not insert a new one, like the first point, but it updates the value of the "key" dice to the new values ​​of the dice you receive.
Here is my full code:
import os
import random as r
from colorama import *
os.system('cls')
player_data = []
def validate_values(list_values):
dice_player_values = list_values[1], list_values[2], list_values[3], list_values[4], list_values[5]
player = {
"Name": list_values[0],
"Dice": dice_player_values,
"Bet": 500
}
if(1 not in list_values):
print(Fore.RED + Style.BRIGHT + list_values[0] + ", next, don't have enough look." + Style.RESET_ALL)
os.system('pause')
play_dice()
else:
# player_data.append(player)
# next((item for item in player_data if item["name"] == list_values[0]), None)
for dato in player_data:
if(dato["Name"] != list_values[0]):
player_data.append(player)
continue
else:
dato["Name"]["Dice"] = dice_player_values
contar_unos = list_values.count(1)
print("It find's: ", str(contar_unos) , ", one.")
print(player_data)
os.system('pause')
play_dice()
def play_dice():
os.system('cls')
dice_values = []
dice_values.clear()
print(Fore.GREEN + "What's your name? : " + Style.RESET_ALL)
player_name = input().lower()
dice_values.append(player_name)
dice_one = r.randint(1,3)
dice_values.append(dice_one)
dice_two = r.randint(1,3)
dice_values.append(dice_two)
dice_three = r.randint(1,3)
dice_values.append(dice_three)
dice_four = r.randint(1,6)
dice_values.append(dice_four)
dice_five = r.randint(1,6)
dice_values.append(dice_five)
print(dice_values)
os.system('pause')
validate_values(dice_values)
return dice_values
dice = play_dice()
I think your error is where you are checking if there's already a player with a certain name in the list:
for dato in player_data:
if(dato["Name"] != list_values[0]):
player_data.append(player)
continue
This is only checking if the current item in the list has a person with that specific name. You need to check them all at once before you do anything. So you could do something like this:
newPlayer = false
for dato in player_data:
if dato['Name'] == list_values[0]:
dato['Dice'] = dice_player_values
newPlayer = true
break
if newPlayer == true:
player_data.append(player)

TicTacToe doesn't apply Win-Conditions && Wrong moves on minimax

i am trying to learn python and have been trying to programm a simple tictactoe game.
Below is the code:
import random
class TicTacToe03:
def __init__(self):
# first, the board
self.board = self.board = [" ", " ", " ", " ", " ", " ", " ", " ", " "]
# then, the symbols the players will choose
self.playerSymbol = ""
self.aiSymbol = ""
# the game is always ongoing, unless somebody won
self.gameOngoing = True
# you also need to tell the ai how different conditions are evaluated
self.scoreBoard = {
self.playerSymbol: -10, # if the player wins, it is seen as smth bad from the ai
self.aiSymbol: 10,
"tie": 0
}
# every tictactoe game starts by drawing the board
def drawBoard(self):
print("""
{} | {} | {}
-----------
{} | {} | {}
-----------
{} | {} | {}
""".format(*self.board))
# then, eveybody chooses what the like
def chooseYourPlayer(self):
self.playerSymbol = input("choose your player X/O ").upper()
if self.playerSymbol == "X":
self.aiSymbol = "O"
else:
self.aiSymbol = "X"
# everybody has to behave and leave their turn when it's over
def nextPlayer(self, player):
if player == self.playerSymbol:
return self.aiSymbol
return self.playerSymbol
# ppl also have to be able to make moves
def move(self, player, index):
self.board[index] = player
# and find what moves they CAN make, so they don't override each-other
def availableMoves(self):
availableMoves = []
for fieldIndex in range(len(self.board)):
if self.board[fieldIndex] == " ":
availableMoves.append(fieldIndex) # yes, i append indexes, not empty fields
return availableMoves
def getMoves(self, player):
playerMoves = []
for fieldIndex in range(len(self.board)):
if self.board[fieldIndex] == player:
playerMoves.append(fieldIndex)
return playerMoves
# here is the algo to check who won, based on a set of winPos is subset of playerMoves
def won(self):
winningPositions = [{0, 1, 2}, {3, 4, 5}, {6, 7, 8},
{0, 4, 8}, {2, 4, 6}, {0, 3, 6},
{1, 4, 7}, {2, 5, 8}]
for player in ("X", "O"):
playerPositions = self.getMoves(player)
for position in winningPositions:
if position.issubset(playerPositions):
print(player + "wins")
self.gameOngoing = False
return player
if self.board.count(" ") == 0: # and this dude outside of the main loop
print("Guess it's a draw")
self.gameOngoing = False
return "tie"
def minimax(self, isMaximizing, player):
if not self.gameOngoing: # base in minimax: if this is an end-state, return it's evaluation
return self.scoreBoard[self.won()]
if isMaximizing:
bestScore = float("-Infinity") # the worst eval for max
for move in self.availableMoves():
self.move(player, move)
score = self.minimax(False, self.nextPlayer(player)) # you should pick the max of what your opponent chooses
self.move(" ", move)
bestScore = max(bestScore, score)
return bestScore
else:
bestScore = float("Infinity")
for move in self.availableMoves():
self.move(player, move)
score = self.minimax(True, self.nextPlayer(player))
self.move(" ", move)
bestScore = min(bestScore, score)
return bestScore
def findOptimalMove(self, player):
goldenMiddle = 0
choices = []
for move in self.availableMoves():
self.move(player, move)
score = self.minimax(True, player)
self.move(" ", move)
if score > goldenMiddle:
choices = [move] # this is a one-element list
break
elif score == goldenMiddle:
choices.append(move)
# here is the code block that mustn't be wrongly interpreted:
# the idea is: you choose a random element, from a ONE-ELEMENT list!!!
if len(choices) > 0:
return random.choice(choices)
else:
return random.choice(self.availableMoves())
def play(self):
self.chooseYourPlayer()
while self.gameOngoing:
personMove = int(input("Choose a position (1-9) "))
self.move(self.playerSymbol, personMove - 1)
self.drawBoard()
if not self.gameOngoing:
break
print("Computer choosing move...")
aiMove = self.findOptimalMove(self.aiSymbol)
self.move(self.aiSymbol, aiMove)
self.drawBoard()
print("Thanks for playing :)")
tictactoe = TicTacToe03()
tictactoe.play()
The game "works", as of it displays the fields of the user, however it won't show whether anybody won or not.
As you can see, i tried implementing the simple minimax algorithm, but that doesn't work properly either, because the ai just chooses the next available field to go to and not the one it logically should.
As for the errors i am getting: i only got one once, after the board was full and it was the following: IndexError: Cannot choose from an empty sequence (on line 133).
I have also posted another version of this, where the "winning" issue is not present ( TicTacToe and Minimax ), but since nobody was answering that question, I thought it would be helpful asking again (sorry if i did anything wrong)
As always, I remain open to suggestions and ways to improve my code :)
In my opinion, the only issue is that you forgot to call self.won() in the play() method:
def play(self):
self.chooseYourPlayer()
while self.gameOngoing:
personMove = int(input("Choose a position (1-9) "))
self.move(self.playerSymbol, personMove - 1)
self.drawBoard()
self.won() #<--- call self.won() here
if not self.gameOngoing:
break
print("Computer choosing move...")
aiMove = self.findOptimalMove(self.aiSymbol)
self.move(self.aiSymbol, aiMove)
self.drawBoard()
print("Thanks for playing :)")
I think you tried to do something similar in minimax() method. But I didn't understand what did you mean by:
if not self.gameOngoing:
return self.scoreBoard[self.won()]

For loop over dict.items() in battleships python game

I am making the game battleships in Python and have gotten stuck on a piece of code. I have made a 10x10 grid board where the player/computer will place 5 ships with different sizes. The ships are stored in a dictionary.
I have #hastagged the spot where I am stuck. When the player tries to place a ship that a spot which is not available, it prints "invalid choice" and the player should be able to place it again. But the loop continues and therefore skips placing that ship. I've tried calling the function "player_place_ships" but then it starts all over and places duplicates of the ships that are already placed.
I was thinking of creating a count in the for loop and starting the loop again from where it left off before the "invalid choice" but unsure if it's doable to start a for loop from dict.items at a specific spot?
Hoping there is a kind soul out there with some advice, I'm rather new at python so might be using bad/unorthodox codes here.
Here is the code:
#Dictionary for ships
ships = {'A': 5, 'B': 4, 'C': 3, 'S': 3, 'D': 2}
#Create player board
player_board = []
for player_row in range(10):
player_board.append([])
for player_col in range(10):
player_board[player_row].append('.')
#Print player board
def print_player_board(player_board):
for player_row in player_board:
print(" ".join(player_row))
def player_place_ships(player_board, ships):
for i, j in ships.items():
ori = input('Enter orientation, v or h: ')
x = int(input('Enter row: '))
y = int(input('Enter col: '))
place = x,y
placement = player_board[x][y]
if ori == 'v' and placement == '.':
for k in range(j):
player_board[x][y] = i
player_board[x+k][y] = i
elif ori == 'h' and placement == '.':
player_board[x][y] = i
player_board[x][y+k] = i
elif ori != 'v' or 'h' and placement != '.':
print('Invalid choice, please try again.') #This is where I'm stuck
player_place_ships(player_board, ships)
print_player_board(player_board)
Here is a screenshot of the output so you know what I mean:
You might fix your issue with a while ship_not_placed
def player_place_ships(player_board, ships):
for i, j in ships.items():
ship_not_place = true
while ship_not_placed :
ori = input('Enter orientation, v or h: ')
x = int(input('Enter row: '))
y = int(input('Enter col: '))
place = x,y
placement = player_board[x][y]
if ori == 'v' and placement == '.':
for k in range(j):
player_board[x][y] = i
player_board[x+k][y] = i
ship_not_place = false
elif ori == 'h' and placement == '.':
player_board[x][y] = i
player_board[x][y+k] = i
ship_not_place = false
elif ori != 'v' or 'h' and placement != '.':
print('Invalid choice, please try again.')
or just with a while true and break out of the while instead of changing ship_not_placed (I never understood what was the best practice between the two)

Menu-driven collection of non-negative integers

I'm attempting to create a menu-driven program where python will accept a collection of non-negative integers. It will calculate the mean and median and display the values on the screen. I want my first option to be "Add a number to the list/array", I want my second option to be "Display the mean", the third to be "Display the median", the fourth "Print the list/array to the screen", the fifth "Print the list/array in reverse order" and the last option "Quit". So far I have gotten:
def main():
myList = [ ]
addOne(myList)
choice = displayMenu()
while choice != '6':
if choice == '1':
addOne(myList)
elif choice == '2':
mean(myList)
elif choice == '3':
median(myList)
elif choice == '4':
print(myList)
elif choice == '5':
print(myList)
choice = displayMenu()
print ("\nThanks for playing!\n\n")
def displayMenu():
myChoice = '0'
while myChoice != '1' and myChoice != '2' \
and myChoice != '3' \
and myChoice != '4' and myChoice != '5':
print("""\n\nPlease choose
1. Add a number to the list/array
2. Display the mean
3. Display the median
4. Print the list/array to the screen
5. Print the list/array in reverse order
6. Quit
""")
myChoice = input("Enter option---> ")
if myChoice != '1' and myChoice != '2' and \
myChoice != '3' and myChoice != '4' and myChoice != '5':
print("Invalid option. Please select again.")
return myChoice
#This should make sure that the user puts in a correct input
def getNum():
num = -1
while num < 0:
num = int(input("\n\nEnter a non-negative integer: "))
if num < 0:
print("Invalid value. Please re-enter.")
return num
#This is to take care of number one on the list: Add number
def addOne(myList):
while True:
try:
num = (int(input("Give me a number:")))
num = int(num)
if num < 0:
raise exception
print("Thank you!")
break
except:
print("Invalid. Try again...")
myList.append(num)
#This should take care of the second on the list: Mean
def mean(myList):
myList = [ ]
listSum = sum(myList)
listLength = len(myList)
listMean = listSum / listLength
print("The mean is", listMean)
#This will take care of number three on the list: Median
def median(myList):
median = 0
sortedlist = sorted(myList)
lengthofthelist = len(sortedlist)
centerofthelist = lengthofthelist / 2
if len(sortedlist) % 2 ==0:
return sum(num[center - 1:center + 1]) / 2.0
else:
return num[center]
print("The mean is", centerofthelist)
#This will take care of the fourth thing on the list: Print the list (In order)
def sort(myList):
theList.sort(mylist)
print(myList)
#This will take care of the fifth thing on the list
def reversesort(myList):
theList.sort(reverse=True)
print(myList)
main()
After I run the program I can't get past creating the list.
Corrected code with minimum changes:
def main():
myList = []
choice = 1
while choice != 6:
if choice == 1:
option1(myList)
elif choice == 2:
option2(myList)
elif choice == 3:
option3(myList)
elif choice == 4:
option4(myList)
elif choice == 5:
option5(myList)
choice = displayMenu()
print ("\nThanks for playing!\n\n")
def displayMenu():
myChoice = 0
while myChoice not in [1, 2, 3, 4, 5]:
print("""\n\nPlease choose
1. Add a number to the list/array
2. Display the mean
3. Display the median
4. Print the list/array
5. Print the list/array in reverse order
6. Quit
""")
myChoice = int(input("Enter option---> "))
if myChoice not in [1, 2, 3, 4, 5]:
print("Invalid option. Please select again.")
return myChoice
# Option 1: Add a number to the list/array
def option1(myList):
num = -1
while num < 0:
num = int(input("\n\nEnter a non-negative integer: "))
if num < 0:
print("Invalid value. Please re-enter.")
myList.append(num)
# Option 2: Display the mean
def option2(myList):
print("The mean is ", sum(myList) / len(myList))
# Option 3: Display the median
def option3(myList):
sortedlist = sorted(myList)
if len(sortedlist) % 2:
median = myList[int(len(sortedlist) / 2)]
else:
center = int(len(sortedlist) / 2)
median = sum(myList[center-1:center+1]) / 2
print("The median is", median)
# Option 4: Print the list/array
def option4(myList):
print(sorted(myList))
# Option 5: Print the list/array in reverse order
def option5(myList):
print(sorted(myList, reverse=True))
main()
How I would do this:
The first part of the following code are a set of constants to customize the style of the menu. Then a set of functions representing each option are defined. The following 3 functions should not be modified, they generate the menu, display it and close the application. Then the main section starts, where you need to pass every option as an argument to setOptions(). The rest should not be modified either as it is the main loop.
# Menu formatting constants
MENU_HEADER = "Please choose an option:"
MENU_FORMAT = " * {:2}. {}"
MENU_QUIT_S = "Quit"
MENU_ASK_IN = "Enter option: "
MENU_INT_ER = "ERROR: Invalid integer. Please select again."
MENU_OPT_ER = "ERROR: Invalid option. Please select again."
END_MESSAGE = "Thanks for playing!"
# OPTIONS FUNCTIONS START HERE
def addElement(l):
""" Add a number to the list/array. """
n = -1
while n < 0:
try:
n = int(input("Enter a non-negative integer: "))
except ValueError:
print("It needs to be an integer.")
n = -1
else:
if n < 0:
print("It needs to be a non-negative integer.")
l.append(n)
def mean(l):
""" Calculate the mean. """
print("Mean: {:7.2}".format(sum(l) / len(l)))
def median(l):
""" Calculate the median. """
l = sorted(l)
p = int(len(l) / 2)
print("Median: {:7.2}".format(l[p] if len(l)%2 else sum(l[p-1:p+1])/2))
def oprint(l):
""" Print the list/array. """
print(sorted(l))
def rprint(l):
""" Print the list/array in reverse order. """
print(sorted(l, reverse=True))
# OPTIONS FUNCTIONS END HERE
def onQuit(l):
""" Function to execute when quitting the application. """
global quit
quit = True
print(END_MESSAGE)
def setOptions(*args):
""" Generates the menu and the options list. """
# Menu header and quit option (option 0)
menu = [MENU_HEADER]
options = [onQuit]
# Passed arguments represent texts and functions of additional options
for i, f in enumerate(args, start=1):
menu.append(MENU_FORMAT.format(i, f.__doc__.strip()))
options.append(f)
# We print the option 0 the last one
menu.append(MENU_FORMAT.format(0, MENU_QUIT_S))
# Returning both the menu and the options lists
return tuple(menu), tuple(options)
def displayMenu(menu):
""" Display the menu and get an option that is an int. """
while True:
for line in menu:
print(line)
try:
choice = int(input(MENU_ASK_IN))
except ValueError:
print(MENU_INT_ER)
else:
return choice
if __name__ == '__main__':
# Pass the option functions to the setOptions function as arguments
menu, options = setOptions(
addElement,
mean,
median,
oprint,
rprint
)
# Initiate the needed variables and start the loop
l = []
quit = False
while not quit:
c = displayMenu(menu)
try:
f = options[c]
except IndexError:
print(MENU_OPT_ER)
else:
f(l)
There is an indentation error inside your function addOne.
myList.append(num) is inside the while loop, and just before that you have a break, so the number is never appended to the list because we have left the loop already.

error making text based game spawn monster

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))

Categories

Resources