I have been trying to solve this code from the past few days where if I by mistake place my symbol("x" or "o") in the index already containing symbol, then it should display message "index already filled!", the problem is that it is showing that message even for the indexes which aren't filled. I am a beginner, please help me with this code and please answer my question with your code since i'm kind of bad at English.
import numpy
board=numpy.array([["-","-","-"],["-","-","-"],["-","-","-"]])
numpy.matrix(board)
def pos(row,col,symbol,altr):
while(board[row][col]==symbol or board[row][col]==altr):
print("index already filled")
place(symbol,altr)
board[row][col]=symbol
return board
def place(symbol,altr):
c=int(input("enter index: "))
if(c==1):
return pos(0,0,symbol,altr)
elif(c==2):
return pos(0,1,symbol,altr)
elif(c==3):
return pos(0,2,symbol,altr)
elif(c==4):
return pos(1,0,symbol,altr)
elif(c==5):
return pos(1,1,symbol,altr)
elif(c==6):
return pos(1,2,symbol,altr)
elif(c==7):
return pos(2,0,symbol,altr)
elif(c==8):
return pos(2,1,symbol,altr)
elif(c==9):
return pos(2,2,symbol,altr)
def won(symbol):
return check_rows(symbol) or check_cols(symbol) or check_diagnols(symbol)
def check_rows(symbol):
for i in range(3):
count=0
for j in range(3):
if(board[i][j]==symbol):
count+=1
if(count==3):
return True
else:
return False
def check_cols(symbol):
for j in range(3):
count=0
for i in range(3):
if(board[i][j]==symbol):
count+=1
if(count==3):
return True
else:
return False
def check_diagnols(symbol):
if(board[0][0]==board[1][1] and board[1][1]==board[2][2] and board[2][2]==symbol):
return True
if(board[0][2]==board[1][1] and board[1][1]==board[2][0] and board[2][0]==symbol):
return True
return False
def play():
p1=input("player1,enter your name: ")
p2=input("player2,enter your name: ")
pl1="x"
pl2="o"
i=0
while(i<9):
if(i%2==0):
print(board)
print(p1,"your turn")
place(pl1,pl2)
if(won(pl1)):
print(board)
print(p1,"you won")
break
else:
if(i%2==1):
print(board)
print(p2,"your turn")
place(pl2,pl1)
if(won(pl2)):
print(board)
print(p2,"you won")
break
i+=1
if not won(pl1) and not won(pl2):
print(board)
print("draw")
The while is not appropriate: the condition's result will never change, no matter how many times you loop. So effectively it is an infinite loop: once you get in, you never get out again.
It should be an if. And secondly, when the if condition is true, you don't want the execution of board[row][col]=symbol with those values of row and col. You should let that assignment happen through the recursive call of place. That execution will come to this function with (hopefully) better values of row and col, and will take care of putting the value in the board. So, ... you need to put that assignment in an else block, so it only happens when the location is fine.
if (board[row][col]==symbol or board[row][col]==altr):
print("index already filled")
place(symbol,altr)
else:
board[row][col]=symbol
Remark: Even though it works like this, I would not have chosen for the recursive solution. You may want to look at an alternative where you have no recursion, but a while loop in the place function.
I think the problem is place call pos, and pos call place, again and again. It's not necessary to return board in both functions.
def pos(row,col,symbol,altr):
if board[row][col]==symbol or board[row][col]==altr:
print("index already filled")
return False
else:
board[row][col]=symbol
return True
def place(symbol,altr):
while True
c=int(input("enter index: "))
if 1 <= c <= 9:
c = c-1
if pos(c//3, c%3, symbol, alter):
return
I explained this with pseudo code
def pos(row, column, player_symbol, another_player_sumbol):
# Check (row, cell) if not occupied
if selected_cell not with blank syambol:
message('Cell occupied')
return input_is_NG
else:
set cell occupied
return input_is_OK
def place(symbol,altr):
while True (until position_is_OK):
input position of cell
if position is from 1 to 9:
position -= 1
if pos(position//3, position%3, symbol, alter) is OK:
return # exit from place, and next turn for another player
user_input_is_NG, while loop again
Related
I'm trying to get the user to input a number from 1 to 9. The code is supposed to check if the number is in the list "board" or already taken. If it's not taken the number is turned into "O". If the number is not in the list or already taken the loop is supposed to re-ask the user for input. However, even if the number is in the list and not taken, the function asks the user for input twice. If I move the else statement on line with the if statement, I get an infinite loop asking for input.
Here's the code:
# ask the unser to make a move
def userMove():
move = int(input("Please make your move: "))
check = True
# check if move is already taken
while check:
for i in range(len(board)):
for j in range(len(board[i])):
if board[i][j] == move:
board[i][j] = "O"
check = False
else:
print("This field is either already taken or not on the board")
move = int(input("Please choose another move: "))
You can use any() to check if value is in 2D list:
if any(move in sublist for sublist in board):
Your problem is caused by the else clause being executed always. The posted code can be fixed as follows.
With for/else statements, the else clause executes after the loop completes normally.
A break statement can be used to prevent normal completion.
Revised Code
# ask the unser to make a move
def userMove():
move = int(input("Please make your move: "))
check = True
# check if move is already taken
while check:
for i in range(len(board)):
for j in range(len(board[i])):
if board[i][j] == move:
board[i][j] = "O"
check = False
break
if not check:
break
else:
# only executes if break not encountered in for i loop
print("This field is either already taken or not on the board")
move = int(input("Please choose another move: "))
I just learned about break and return in Python.
In a toy code that I wrote to get familiar with the two statements, I got stuck in a loop, but I don't know why. Here is my code:
def break_return():
while True:
for i in range(5):
if i < 2:
print(i)
if i == 3:
break
else:
print('i = ', i)
return 343
break_return()
I'm new to programming, any suggestions will be appreciated.
With the for-else construct you only enter the else block if the for loop does not break, which your for loop always does because i inevitably becomes 3 with your range generator. Your infinite while loop is therefore never able to reach the return statement, which is only in the said else block.
nvm I'm super wrong here
First of all, when you define a function in Python, any code that belongs in the function should be in the same indentation block. With this in mind, your code would look like this:
def break_return():
while True:
for i in range(5):
if i < 2:
print(i)
if i == 3:
break
else:
print('i = ', i)
return 343
break_return()
The next problem I see is that your else statement isn't correctly formatted with an if statement. If you mean for it to go on the 2nd if statement, your code would look like this:
def break_return():
while True:
for i in range(5):
if i < 2:
print(i)
if i == 3:
break
else:
print('i = ', i)
return 343
break_return()
This is only formatting. But in this example, the code would only run once because it immediately returns and exits the function.
I think this may be a better example of using both break and return:
def break_return(value):
for i in range(5):
print(i)
if i == 3:
break #This exits the for loop
if i == 4:
print("This won't print!")
#Won't print because the loop "breaks" before i ever becomes 4
return value * 2 #Returns the input value x 2
print(break_return(30)) #Display the return value of break_return()
This demonstrates how break exits a for loop and how return can return a value from the function.
The output of the code above is:
0 #Value of i
1 #Value of i
2 #Value of i
3 #Value of i
60 #The value returned by the function
Glad to hear you're learning Python! It's a lot of fun, and super useful.
I have this program:
def validateNumber(number):
if (count > 10) :
print('Invalid number')
return -1
elif (count < 10):
print('Invalid number')
return -1
while True:
count = 0
num = int(input('Number:'))
while num > 0:
num = num//10
count = count+1
if (count == 10) :
break
But I can't print the print('Invalid number') and it turn out to be like this:
Number:122344
Number:123442
Number:1234567890
>>>
I want it to print the print('Invalid number') when the number is less or more than 10.
Number:122344
Invalid number
Number:123442088080989098
Invalid number
Number:1234567890
>>>
Help please. Thanks
The return -1 is for if the number is missing or invalid
Firstly, you could condense your if check to one statement. Note that the easiest way to count the number of digits is to convert it to a string and check its length.
def validateNumber(number):
if len(str(number)) != 10:
return -1
Unfortunately, you do not return a legitimate value if the number is valid. Why not return a boolean value instead?
def validateNumber(number):
if len(str(number)):
return True
return False
You can further reduce this to:
def validateNumber(number):
return len(str(number)) == 10
Note that all the validation logic has now been moved to the function. You'll see how this simplifies the loop code.
Next, you have defined two loops. When you break from the inner, the outer will continue, so you come back to the inner, thus restarting the process.
As a fix, I'd recommend doing this with one loop only, like this:
while True:
x = int(input('...'))
if validateNumber(x):
break
else:
print('Invalid Number')
Since validateNumber returns a bool result, simply have the if query the return value, and break if the number is valid, otherwise the loop repeats.
The good thing about having all your validation code inside the function is that you don't have to modify your loop code if your validation logic changes.
I am currently working on a battleship game to practice my programming skills. I have functional code but was wondering if anyone can help me break my code down into a for loop?
import random
def main():
board = []
for i in range(0,5):
board.append(random.randint(1,50))
print(board) #test purposes
guess=int(input("enter number between 1-50"))
if guess == board[0]:
print("hit")
board[0]="hit"
elif guess != board[0]:
print("miss")
board[0]="miss"
Note i want to carry out the if statement multiple times to check for board[0-5].
Instead of repeating it 5 times I was thinking of doing something like this:
for x in range(0,5):
if guess == board[x]:
print("hit")
board[x]="hit"
else:
print("miss")
board[x]="miss"
But this is not working as it takes just 1 input whereas I want it to take 5. For each input it has to check if input is equal to board[0-5]
Thank You in advance for any help.
write guess in a for loop,be careful about indentation
import random
def main():
board = []
for i in range(0, 5):
board.append(random.randint(1, 50))
guess = int(input("enter number between 1-50 : "))
print(board) # test purposes
if guess == board[0]:
print("hit")
board[0] = "hit"
elif guess != board[0]:
print("miss")
board[0] = "miss"
I'm not quite sure what you are trying to achieve, but I believe it to be this:
import random
def main():
board = []
for i in range(0,5):
board.append(random.randint(1,50))
print(board) #test purposes
guesses = []
try_nr = 0
while try_nr < 5:
try_nr += 1
guess = int(input("enter number between 1-50"))
guesses.append(guess)
for i in enumerate(guesses):
i = i[0]
if guesses[i] in board:
print("hit")
# board[0]="hit" --> not quite sure what you want to achieve here?
else:
print("miss")
# board[0]="miss" --> not quite sure what you want to achieve here?
NB1: There are other more neat/dense ways to code this, but this helps you to get going. See if you can perfect it for yourself if needed.
NB2: I have changed your elif statement into else. Your equation can only have two possible answers (either a hit or a miss). By using elif you are forcing python to reconsider/re-calculate your if-statement fully while using else it only considers the if-statement once.
You can use the enumerate() function to add a counter to your for loop. This will be useful.
board = [12, 4, 76, 2]
for index, number in enumerate(board):
print index, number
#output
# 0 12
# 1 4
# 2 76
# 3 2
You said you want to take 5 guesses? You could do something like this:
for i in range(5):
guess=int(input("enter number between 1-50"))
for index, number in enumerate(board):
if guess == number
print("hit")
board[index] = "hit"
else:
print("miss")
board[index] = "miss"
I'm trying to make a function, which recursively checks for palindromes in a given range. The range is sent to "is_palindrome_multi", which then calls "is_palindrome".
However, it doesn't work with numbers higher then 10, so the limiting step seems to be:
elif data[0]==data[-1]:
statement. Why it doesn't return true for the numbers like 11, 22 and so on? I will be grateful for explanation.
def is_palindorme_multi(beg, end):
for i in range(beg, end):
i = str(i)
if is_palindrome(i) == True:
print "Palindrome"
else:
print "Not palindrome"
def is_palindrome(data):
print data,
if len(data)==1 or len(data)==0:
return True
elif data[0]==data[-1]:
is_palindrome(data[1:-1])
else:
return False
You are not returning the result of the recursive call.
Change your elif:
elif data[0]==data[-1]:
is_palindrome(data[1:-1])
to:
elif data[0]==data[-1]:
return is_palindrome(data[1:-1])
However, I would simply change your is_palindrome method to:
def is_palindrome(data):
return data == data[::-1]
Really, no need to use recursion here.