So, I'm just fooling around in python, and I have a little error. The script is supposed to ask for either a 1,2 or 3. My issue is that when the user puts in something other than 1,2 or 3, I get a crash. Like, if the user puts in 4, or ROTFLOLMFAO, it crashes.
EDIT: okay, switched it to int(input()). Still having issues
Here is the code
#IMPORTS
import time
#VARIABLES
current = 1
running = True
string = ""
next = 0
#FUNCTIONS
#MAIN GAME
print("THIS IS A GAME BY LIAM WALTERS. THE NAME OF THIS GAME IS BROTHER")
#while running == True:
if current == 1:
next = 0
time.sleep(0.5)
print("You wake up.")
time.sleep(0.5)
print("")
print("1) Go back to sleep")
print("2) Get out of bed")
print("3) Smash alarm clock")
while next == 0:
next = int(input())
if next == 1:
current = 2
elif next == 2:
current = 3
elif next == 3:
current = 4
else:
print("invalid input")
next = 0
Use raw_input() not input() the latter eval's the input as code.
Also maybe just build a ask function
def ask(question, choices):
print(question)
for k, v in choices.items():
print(str(k)+') '+str(v))
a = None
while a not in choices:
a = raw_input("Choose: ")
return a
untested though
since the input() gives you string value and next is an integer it may be the case that crash happened for you because of that conflict. Try next=int(input()) , i hope it will work for you :)
Related
First of all, I am totally new in Python, having just started to learn it. I know a lot of stuff about C++ however and I am just trying to implement some of those in Python.
I have done quite a search on it but I couldn't find any solution that fits my requirement. Please see the following code,
import os
class _Getch:
"""Gets a single character from standard input. Does not echo to the
screen."""
def __init__(self):
try:
self.impl = _GetchWindows()
except:
print("Error!")
def __call__(self): return self.impl()
class _GetchWindows:
def __init__(self):
import msvcrt
def __call__(self):
import msvcrt
return msvcrt.getch()
def mainfun():
check = fh = True
while check:
fh = True
arr = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
print ("Welcome to Tic Tac Toe Game!!!\n\n")
print("Enter 1 to Start Game")
print("Enter 2 to Exit Game")
a = _Getch()
if a == "1":
while fh:
os.system("cls")
drawboard()
playermove()
fh = checkresult()
elif a == "2":
break
As you can see, What I am trying to do here is asking the user to press a number from 1 and 2 and then store that number in "a" and then use it for my requirements.
Now, I first tried using this,
input('').split(" ")[0]
But this didn't work. It required me to always Press Enter after having typed 1 or 2. So, that didn't work.
Then I found this class of Getch and I implemented it. Long story short, it entered me into a never ending loop and my result is something like this now,
Welcome to Tic Tac Toe Game!!!
Enter 1 to Start Game
Enter 2 to Exit Game
Press Enter to Continue....
Welcome to Tic Tac Toe Game!!!
Enter 1 to Start Game
Enter 2 to Exit Game
Press Enter to Continue....
Welcome to Tic Tac Toe Game!!!
Enter 1 to Start Game
Enter 2 to Exit Game
Press Enter to Continue....
And it is a never ending loop... Even if I press any key like "1" or "2", it still doesn't stop and keep on performing this and don't enter any function.
What I want is a function similar to this,
It should work on PYCHARM Console (I am practicing and I don't want to practice on Terminal. I am used to using the console of the IDE I am working on)
It pauses and waits for the user to enter any input (like input does)
It accepts and stores the very first key entered by the user into the variable. Like in this case, if user presses "1" then it should store that character in "a" and simply move on. You don't have to Press "ENTER" to move on.
If the user presses any other button like "a" or "b" or anything like this, it will simply not do anything and keep on asking for the input until the required number "1" or "2" is entered (and I think that can very easily be handled in this while loop)
In other words, I just want an alternative to getch() command of C++ in Python. I have tried a lot to find it, but I couldn't. Please refer to me a question which provides a solution to this exact question or provide a solution here. Thank you.
Edit: Please note this isn't the complete code. I have only provided the code which is relevant. If anyone needs to see the whole code, I am happy to share that as well.
Complete code is as follows,
import os
import keyboard
def getch():
alphabet = list(map(chr, range(97, 123)))
while True:
for letter in alphabet: # detect when a letter is pressed
if keyboard.is_pressed(letter):
return letter
for num in range(10): # detect numbers 0-9
if keyboard.is_pressed(str(num)):
return str(num)
arr = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
playerturn = 1
def drawboard():
global playerturn
print("Player 1 (X) - Player 2 (O)\n")
print("Turn: Player " + str(playerturn))
print("\n")
for i in range(3):
print (" ", end='')
for j in range(3):
print(arr[i][j], end='')
if j == 2:
continue
print(" | ", end='')
if i == 2:
continue
print("")
print("____|____|____")
print(" | | ")
def playermove():
global playerturn
row = col = 0
correctmove = False
print("\n\nMake your Move!\n")
while not correctmove:
row = int(input("Enter Row: "))
col = int(input("Enter Col: "))
if (3 > row > -1) and (-1 < col < 3):
for i in range(3):
for j in range(3):
if arr[row][col] == 0:
correctmove = True
if playerturn == 1:
arr[row][col] = 1
else:
arr[row][col] = 2
playerturn += 1
if playerturn > 2:
playerturn = 1
if not correctmove:
print ("Wrong Inputs, please enter again, ")
def checkwin():
for player in range(1, 3):
for i in range(3):
if arr[i][0] == player and arr[i][1] == player and arr[i][2] == player: return player
if arr[0][i] == player and arr[1][i] == player and arr[2][i] == player: return player
if arr[0][0] == player and arr[1][1] == player and arr[2][2] == player: return player
if arr[0][2] == player and arr[1][1] == player and arr[2][0] == player: return player
return -1
def checkdraw():
for i in range(3):
for j in range(3):
if arr[i][j] == 0:
return False
return True
def checkresult():
check = checkwin()
if check == 1:
os.system('cls')
drawboard()
print("\n\nPlayer 1 has won the game!!\n")
elif check == 2:
os.system('cls')
drawboard()
print("\n\nPlayer 2 has won the game!!\n")
elif check == 3:
os.system('cls')
drawboard()
print("\n\nThe game has been drawn!!\n")
else:
return True
return False
def mainfun():
check = fh = True
while check:
os.system("cls")
fh = True
arr = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
print ("Welcome to Tic Tac Toe Game!!!\n\n")
print("Enter 1 to Start Game")
print("Enter 2 to Exit Game")
a = getch()
if a == "1":
while fh:
os.system("cls")
drawboard()
playermove()
fh = checkresult()
elif a == "2":
break
print ("Press any key to continue...")
getch()
mainfun()
EDIT2: Problem is resolved by using Keyboard module... The next issue here is how do I remove the data stored in input buffer after the getch() function is called? Because the data in buffer is getting displayed on the next input (when I am taking in the row and column) and I don't want that to happen. I fonud a solution for Linux but not for Windows (or for Pycharm)
It looks like this feature isn't in the standard python library but you can recreate it.
First, install the module 'keyboard'
$ pip3 install keyboard
Then you can use keyboard.is_pressed() to see if any one character is pressed.
import keyboard # using module keyboard
import string # use this to get the alphabet
print("Input a character")
def getch():
alphabet = list(string.ascii_lowercase)
while True:
for letter in alphabet: # detect when a letter is pressed
if keyboard.is_pressed(letter):
return letter
for num in range(10): # detect numbers 0-9
if keyboard.is_pressed(str(num)):
return str(num)
answer = getch()
print("you choose " + answer)
Edit: For unix you need to run with the script with sudo. This code should work fine on windows.
For EDIT-2:
Use below code to flush the screen:
sys.stdout.flush()
I'm using python 2.7 for this game. I have looked at other answers and questions similar to this but since I'm a python beginner with some experience with python I don't really understand some of the answers and some of the answers I saw weren't that clear. Because of the current code I have, it created a problem where when I got the item necessary to unlock the room it says the room has not been found. This is the code:
## checks which connecting rooms player.currentRoom has available and updates currentRoom on player choice.
def navigate(player,enemyToken):
os.system("clear")
# print available rooms to navigate to
i = 0
for room in player.currentRoom.connectingRooms:
print(str(i) + ": " + room.name)
i = i + 1
try:
navigate = input("Choose room to navigate to [type its number]: ")
# change players current room to selected room and contains the locking code after the "and".
if(navigate <= len(player.currentRoom.connectingRooms) and player.items[0].unlocks == room == True):
player.currentRoom = player.currentRoom.connectingRooms[navigate]
else:
print("room not found!")
time.sleep(1)
except NameError:
print("that was not a number!")
time.sleep(1)
except SyntaxError:
print("that was not a number!")
time.sleep(1)
except IndexError:
print("that was not an option!")
time.sleep(2)
how would I make a lock that would succesfully lock the player from accessing that room untill they have grabbed the object that is required to open this room. If you need more code to help me I would provide it.
Based on my comment, this code should word(Untested as I do not know where the locking mechanism should go)
Code:
x = True
while x = True:
if LockRoom != RoomUnlock:
Code here
else:
Code here when you unlock the room
x = False
player.items[0].unlocks == room == True
This part looks weird to me. player.items[0].unlocks == room should be sufficient to check if the two numbers match.
I am very inexperienced with any programming language. I decided for my first for-fun/leaning project to be creating a calculator to add different durations of time (ex. add the length of several songs to find how long an album is).
So far the user input method is pretty basic, and I'll work to fix that once the basics work, so bear with me on that. The calculator is currently capable of adding two times together and printing the correct answer.
My main problem is creating a functional Continue/Clear user prompt. I have a loop asking if the user wants to continue, clear, or exit. User input works correctly, but I don't know how to actually "continue or clear".
My idea: Upon hitting continue, the previous total will become firstNumber, and the user will only be prompted for the second number (nextNumber) and will be given a new sum and receive the same continue/clear/exit prompt. If the user hits clear, it will start at the very beginning and the user will be prompted for a new firstNumber.
Any help is greatly appreciated.
Below is the code:
import datetime
# holds first entry
print("Enter the first number")
seconds_1 = int(input("Seconds: "))
minutes_1 = int(input("Minutes: "))
hours_1 = int(input("Hours: "))
# holds second entry
print("Enter another number")
seconds_2 = int(input("Seconds: "))
minutes_2 = int(input("Minutes: "))
hours_2 = int(input("Hours: "))
# calculation
duration_1 = datetime.timedelta(hours=hours_1, minutes=minutes_1, seconds=seconds_1)
duration_2 = datetime.timedelta(hours=hours_2, minutes=minutes_2, seconds=seconds_2)
total = duration_1 + duration_2
print(total)
# continue, clear, or exit
contClear = input("Continue: Y | Clear: N | Exit: X: ")
cont = False
while cont == False:
if contClear.upper() == "Y" or contClear.upper() == "YES":
print("Next")
cont = True
elif contClear.upper() == "N" or contClear.upper() == "NO":
print("Cleared")
cont = True
elif contClear.upper() =="X" or contClear.upper() == "EXIT":
print("Exiting")
cont = True
else:
print("Invalid Entry")
contClear = input("Continue: Y | Clear: N | Exit: X: ")
print("DONE")
I am trying to write a program for an assignment where you input a specific command and you can play Rock-Paper-Scissors-Lizard-Spock against the computer.
It was done and working until I realized that the assignment instructions wanted me to make it so that you keep playing the game until one person gets five wins.
So I thought, no big deals, let's throw in a while loop and some variables to track the wins. But when I run the program, it only runs once still. I don't know what I am doing wrong - as this should work. This is my first time working with Python (version 3.3) and this IDE, so I really need some help. Usually I'd just debug but I can't figure out how to work the one in this IDE.
Here is my code. The trouble while-loop is at the way bottom. I am nearly positive everything inside the class works. I would like to note that I already tried while(computerWins < 5 and userWins < 5), so I don't think the condition is the problem.
import random
computerWins = 0
userWins = 0
print ('SELECTION KEY:\nRock = r\nPaper = p\nScissors = sc\nLizard = l\nSpock = sp')
class rockPaperScissorsLizardSpock:
#Two methods for converting from strings to numbers
#convert name to number using if/elif/else
#also converts abbreviated versions of the name
def convertName(name):
if(name == 'rock' or name == 'r'):
return 0
elif(name == 'Spock' or name == 'sp'):
return 1
elif(name == 'paper' or name == 'p'):
return 2
elif(name == 'lizard' or name == 'l'):
return 3
elif(name == 'scissors' or name == 'sc'):
return 4
else:
print ('Error: Invalid name')
#convert number to a name using if/elif/else
def convertNum(number):
if(number == 0):
return 'rock'
elif(number == 1):
return 'Spock'
elif(number == 2):
return 'paper'
elif(number == 3):
return 'lizard'
elif(number == 4):
return 'scissors'
else:
print ('Error: Invalid number')
#User selects an option, and their selection is saved in the 'choice' variable
#Using a while loop so that the user cannot input something other than one of the legal options
prompt = True
while(prompt):
i = input('\nEnter your selection: ')
if(i=='r' or i=='p' or i=='sc' or i=='l' or i=='sp'):
prompt = False
else:
print('Invalid input.')
prompt = True
#Convert the user's selection first to a number and then to its full string
userNum = convertName(i)
userChoice = convertNum(userNum)
#Generate random guess for the computer's choice using random.randrange()
compNum = random.randrange(0, 4)
#Convert the computer's choice to a string
compChoice = convertNum(compNum)
print ('You chose', userChoice)
print ('The computer has chosen', compChoice)
#Determine the difference between the players' number selections
difference = (compNum - userNum) % 5
#Use 'difference' to determine who the winner of the round is
if(difference == 1 or difference == 2):
print ('The computer wins this round.')
computerWins = computerWins+1
elif (difference == 4 or difference == 3):
print ('You win this round!')
userWins = userWins+1
elif(difference == 0):
print ('This round ended up being a tie.')
#Plays the game until someone has won five times
while(computerWins != 5 and userWins != 5):
rockPaperScissorsLizardSpock()
if(computerWins == 5 and userWins != 5):
print ('The computer wins.')
elif(computerWins != 5 and userWins == 5):
print ('You win!')
The essential problem is that rockpaperscissorslizardspock is a class, where you expect it to be a function. The code inside it runs exactly once, when the whole class definition is parsed, rather than each time you call the class as you seem to expect.
You could put the relevant code into an __init__ method - this is a fairly direct analogue of a Java constructor, and hence is is run each time you call the class. But in this case, you probably don't need it to be in a class at all - calling the class creates a new instance (like doing new MyClass() in Java), which you don't use. You would also in this case (or if you made it into a function) need to make some more modifications to make sure the game state persists properly.
The easiest actual solution is to:
delete the line class rockpaperscissorslizardspock: (and unindent everything below it)
Take all the code that was under the class but not in a function - everything from the player makes a selection to determining the winner of the round - and paste it in place of the call to rockpaperscissorslizardspock() in the bottom loop.
The first thing is that you are using a class where you should probably be using a function.
Your code initially runs because python is loading the class.
However, the line rockPaperScissorsLizardSpock() is creating new anonymous instances of your class which calls a constructor that you haven't defined so it does nothing.
One of the interesting things about python is that it allows nested functions so if you change the class to a def you're almost there.
After that, you'll run into trouble with global variables in a local context. That problem is already explained in another StackOverflow question: Using global variables in a function other than the one that created them.
Here is my suggestion for the skeleton to a more simple solution. Use some ideas from here if you like.
import random
legal_shapes = ['r', 'p', 'sc', 'sp', 'l']
scoreboard = [0, 0]
print('SELECTION KEY:\nRock = r\nPaper = p\nScissors = sc\nLizard = l\n'
'Spock = sp')
while(max(scoreboard) < 5):
print("\nScore is {}-{}".format(*scoreboard))
# pick shapes
p1_shape = input('Enter your selection: ')
if p1_shape not in legal_shapes:
print('Not legal selection!')
continue
p2_shape = random.choice(legal_shapes)
print('\np1 plays {} and p2 plays {}'.format(
p1_shape.upper(), p2_shape.upper()))
# determine int values and result indicator
p1_shape_int = legal_shapes.index(p1_shape)
p2_shape_int = legal_shapes.index(p2_shape)
res = (p1_shape_int - p2_shape_int) % 5
if res != 0:
res = abs((res % 2) - 2)
# Print winner
if res == 0:
print(' -> Draw!!')
else:
print(' -> p{} wins'.format(res))
scoreboard[res-1] += 1
print("\nThe game is over!!")
print("p{} won with score {}-{}".format(res, *scoreboard))
It outputs something like
(env)➜ tmp python3 rsp.py
SELECTION KEY:
Rock = r
Paper = p
Scissors = sc
Lizard = l
Spock = sp
Score is 0-0
Enter your selection: T
Not legal selection!
Score is 0-0
Enter your selection: l
p1 plays L and p2 plays SP
-> p2 wins
Score is 0-1
Enter your selection: l
p1 plays L and p2 plays SC
-> p2 wins
...
The game is over!!
p2 won with score 2-5
I have a feeling I've made a silly mistake somewhere but at nearly 2am I just can't see it...
Here's the code in question. It is part of a function:
running = True
while (running):
playerName = input("Please enter your first name \n").title()
print ("You have entered '%s' as your name. Is this correct?"%playerName)
playerNameChoice = input("Enter 'Y' for Yes or 'N' for No.\n").upper()
if(playerNameChoice == "Y"):
break
#The following randomly selects Card 1 for the computer
randomComputerCard = random.choice(availableCards)
if randomComputerCard in (Queen,King,Jack,Ace):
randomComputerCard = 10
else:
randomComputerCard = randomComputerCard
randomComputerCard2 = random.choice(availableCards)
if randomComputerCard2 in (Queen,King,Jack,Ace):
randomComputerCard2 = 10
else:
randomComputerCard2 = randomComputerCard2
print ("%i"%randomComputerCard)
print ("%i"%randomComputerCard2)
print ("TEST OVER")
elif(playerNameChoice == "N"):
continue
During testing when I enter Y when prompted to enter either Y or N nothing happens, it just continues the loop when it should actually break. However when I enter N it does exactly what it's meant to and continues the loop. Sorry if this is a waste of a question, but I actually have no idea what I've done incorrectly.
Thanks in advance as always! :)
EDIT: The variable availableCards has already been defined.
You need to remove the 'break' at line 7. That's causing your code to exit prematurely.