Why is my while/if statement not working? - python

Im making my own Hangman Python program, im still a newbie to python programming, so i dont quite understand what im doing wrong. I have specified that the lives are limited to 6, but when inputing a wrong input, the lives can go down to -2 as the console says..
import random
words = ["stone"]
word = words[random.randint(0, (len(words)) - 1)]
wordToLetters = list(word)
gaps = ["_"] * len(word)
lives = 6
gameOver = False
while not gameOver:
for num, x in enumerate(wordToLetters):
print(lives)
print(gaps)
eingabe = input("Buchstaben eingeben: ")
if lives < 0:
gameOver = True
print("spiel verloren...\n")
if gaps == wordToLetters:
print("Spiel gewonnen!\n")
print("Das Wort war: " + word)
gameOver = True
if eingabe in wordToLetters:
if eingabe in gaps:
lives -= 1
print("Buchstabe schon geraten!")
else:
gaps[num] = eingabe
print("Buchstabe vorhanden!\n")
else:
lives -= 1
print("Buchstabe nicht vorhanden! :(\n")

you must use elif to not test the other conditions when one of them is true:
import random
words = ["stone"]
word = words[random.randint(0, (len(words)) - 1)]
wordToLetters = list(word)
gaps = ["_"] * len(word)
lives = 6
gameOver = False
while not gameOver:
for num, x in enumerate(wordToLetters):
print(lives)
print(gaps)
eingabe = input("Buchstaben eingeben: ")
if lives < 0:
gameOver = True
print("spiel verloren...\n")
elif gaps == wordToLetters:
print("Spiel gewonnen!\n")
print("Das Wort war: " + word)
gameOver = True
elif eingabe in wordToLetters:
if eingabe in gaps:
lives -= 1
print("Buchstabe schon geraten!")
else:
gaps[num] = eingabe
print("Buchstabe vorhanden!\n")
else:
lives -= 1
print("Buchstabe nicht vorhanden! :(\n")
here if the first "if" is true then we will not check the others.

Related

Python tic tac toe program closes on "3 1" input

My problem: Python tab closes on "3 1" input.
This code is heavily inspired by Hafeezul Kareem Shaik's tic-tac-toe game on geekflare.
My code:
import random
class TicTacToe:
def __init__(self):
self.board = []
def create_board(self):
for r0w in range(3):
row = []
for c0l in range(3):
row.append('-')
self.board.append(row)
def get_random_first_player(self):
return random.randint(0,1)
def fix_spot(self, row, col, player):
self.board[row][col] = player
def is_player_win(self, player):
win = None
n = len(self.board)
#checking rows
for r0w in range(n):
win = True
for c0l in range(n):
if self.board[r0w][c0l] != player:
win = False
break
if win:
return win
#checking columns
for r0w in range(n):
win = True
for c0l in range(n):
if self.board[c0l][r0w] != player:
win = False
break
if win:
return win
#checking diagonals
win = True
for i in range (n):
if self.board[i][i] != player:
win = False
break
if win:
return win
win = True
for i in range(n):
if self.board[r0w][n - 1 - r0w] != player:
win = False
break
if win:
return win
return False
for row in self.board:
for item in row:
if item == '-':
return False
return True
def is_board_filled(self):
for row in self.board:
for item in row:
if item == "-":
return False
return True
def swap_player_turn(self, player):
return 'X' if player =='O' else 'O'
def show_board(self):
for row in self.board:
for item in row:
print(item, end=" ")
print()
def start(self):
self.create_board()
player = 'X' if self.get_random_first_player() == 1 else 'O'
while True:
print(f"Player {player} turn")
self.show_board()
# user input
row, col = list(
map(int, input("Enter row and column numbers to fix spot: ").split()))
print()
#fixing spot
self.fix_spot(row - 1, col - 1, player)
#has current player won
if self.is_player_win(player):
print(f"{player} Wins!")
break
#is game a draw
if self.is_board_filled():
print("Draw!")
break
#swapping turn
player = self.swap_player_turn(player)
#final board
print()
self.show_board()
tic_tac_toe = TicTacToe()
tic_tac_toe.start()
The Tic_Tac-Toe Game worked up until I typed "3 1". I tested multiple games and it would always close after that input.
I have tried editing the scope of the following, as I believe that is what is causing it to malfunction
if win:
return win
return False
Unfortunately that has not fixed the problem. Any ideas or suggestions?
This code is so badly written that I wouldn't take it as an example for anything.
But if you really want to know why it ends on 3 1 as input, you should look here:
win = True
for i in range(n):
if self.board[r0w][n - 1 - r0w] != player:
win = False
break
if win:
return win
return False
Here r0w is not reset, it has the last value from the for loop, which is 2, and it's not changing in the loop, so there's only one check made, which is 3 1, translated to 2 0, which is the current player, so that's an instant win.
I assume this was supposed to be a loop to check the other diagonal, but it's clearly flawed.

Minimax implementation in tic tac toe (Python) not working - no idea why

I am currently trying to make a Tic Tac Toe game with minimax implemented in Python. Another feature that I'm trying to implement is different board sizes. But overall, unfortunately, the algorithm is not working.
As a beginner, this is not a surprise for me, but this case seems hopeless. I tried tweaking quite a lot of things (may seem like a lot just to me) just to end up with the same result - the computer filling up the fields from top left to bottom right.
#Sprawdzenie czy ktos wygral w poziomie lub pionie / straight line check
def winLine(line, letter):
return all(n == letter for n in line)
#Utworzenie nowej listy z elementow przekatnych / diagonal check
def winDiagonal(board, letter):
arr = []
tArr = []
for n in range(boardSize):
arr.append(board[n][n])
tArr.append(board[n][boardSize-n-1])
if winLine(arr, letter):
return True
elif winLine(tArr, letter):
return True
else:
return False
def checkWinner (board):
#Liczenie wolnych pol / checking the available fields
openSpots = 9
for n in range(boardSize):
for m in range(boardSize):
if board[n][m] == '0':
openSpots += 1
#Transpozycja planszy, by mozna bylo latwo zastosowac winLine na kolumach / transposition of the board
for letter in (person, ai):
transPos = list(zip(*board))
#Sprawdzanie w poziomie / horizontal check
if any(winLine(row, letter) for row in board):
#print('winline horizontal')
return letter
#Sprawdzanie w pionie / vertical check
elif any (winLine(col, letter) for col in transPos):
#print('winline vertical')
return letter
#Sprawdzanie po przekatnych / diagonal check
elif winDiagonal(board, letter):
return letter
elif openSpots == 0: return 'tie'
else: return 'none'
#Funkcja sprawdzajaca czy dane pole jest wolne / checks whether the field is available
def available (row, col):
global board
#Sprawdzenie czy pole jest wolne
if board[row][col] == '0':
return True
else:
return False
#Stale dla algorytmu minimax / minimax initial scores to compare against
minTarget = float('inf')
maxTarget = float('-inf')
#Slownik z wartosciami liczbowi dla wynikow, komputer maksymalizuje / a dictionary with scores for particular results
scores = {
'X': 10,
'O': -10,
'tie': 0
}
#Algorytm minimax
def minimax(myBoard, depth, maximizes):
#Sprawdzenie czy zaszla wygrana lub remis / Checking whether there is a win or tie
res = checkWinner(myBoard)
if (res != 'none'):
return scores[res]
#Gracz maksymalizujacy/ Maximizing player
elif maximizes == True:
bestScoreMax = maxTarget
for n in range(boardSize):
for m in range(boardSize):
if board[n][m] == '0':
board[n][m] = person
score = minimax(board, depth + 1, False)
board[n][m] = '0'
bestScoreMax = max([score, bestScoreMax])
return bestScoreMax
#Gracz minimalizujacy / minimizing player
elif maximizes == False:
bestScoreMin = minTarget
for n in range(boardSize):
for m in range(boardSize):
if board[n][m] == '0':
board[n][m] = ai
score = minimax(board, depth + 1, True)
board[n][m] = '0'
bestScoreMin = min([score, bestScoreMin])
return bestScoreMin
def makeMove(row, col):
global board
board[row][col] = ai
def computedMove():
global board
myBoard = board
computedTarget = maxTarget
moveX = 2
moveY = 2
for n in range(boardSize):
for m in range(boardSize):
if myBoard[n][m] == '0':
score = minimax(myBoard, 0, True)
if score > computedTarget:
computedTarget = score
moveX = n
moveY = m
makeMove(moveX, moveY)
#print(str(move.x) + ' ' + str(move.y))
# Funkcja pobierajaca ruch uzytkownika / player input for the move
def getPlayerMove():
global board
res = input('Please type in your move on the form \"x y\", x being the number of the row and y the number of the column of your choosing.\n')
col, row = res.split(" ")
row = int(row)
col = int(col)
if available(row-1, col-1):
board[row-1][col-1] = person
else:
print('You cannot make that move')
getPlayerMove()
def drawBoard():
global board
for n in range(boardSize):
for m in range(boardSize):
if board[n][m] == '0':
print(' - ', end='')
else:
print(' '+board[n][m]+' ', end='')
print('\n')
#Zmienna powiadamiajaca o stanie rozgrywki / variable indicating the state of the game
playing = False
# initializing the variable
boardSize = 0
# initializing the players
person = 'X'
ai = 'O'
#Gracz posiadajacy ruch (a takze rozpoczynajacy) / player who is playing at the moment
currentPlayer = ''
while True:
currentPlayer = person
boardSize = int(input("Please enter the size of the board. (one side)\n"))
global board
board = [['0' for i in range(boardSize)] for i in range(boardSize)]
print("You go first.")
playing = True
while playing:
if currentPlayer == person:
drawBoard()
getPlayerMove()
if checkWinner(board) == person:
drawBoard()
print("Yaay, you won!")
playing = False
else:
if checkWinner(board) == 'tie':
drawBoard()
print('It\'s a tie!')
break
else:
currentPlayer = ai
elif currentPlayer == ai:
computedMove()
if checkWinner(board) == ai:
drawBoard()
print('You lose!')
playing = False
else:
if checkWinner(board) == 'tie':
drawBoard()
print('It\'s a tie!')
break
else:
currentPlayer = person
if not input('Do you want to play again?').lower().startswith('y'):
break
In computedMove, you should first play the ai move then check the scores.
def computedMove():
global board
myBoard = board
computedTarget = maxTarget
moveX = 2
moveY = 2
for n in range(boardSize):
for m in range(boardSize):
if myBoard[n][m] == '0':
myBoard[n][m] = ai #This is added
score = minimax(myBoard, 0, True)
if score > computedTarget:
computedTarget = score
moveX = n
moveY = m
makeMove(moveX, moveY)
Also in minimax function, you should use same variable for myBoard and board.

Mastermind Python coding

Ok I have a feeling that this is a simple simple issue but I have been staring at this code for about 10 hours now.
The issue I am having is in mastermind is that once I get it to recognize that I have the correct colors in the right spot I can get it to display the right spots with X and the wrong spots with O. I need to be able to convert that so instead of X and O I need it to tell the user that he/she has 2 blacks and one white
For example: The secret code is RGYB The user enters RGOY so then Python relays "You have 2 blacks(The R and G spots) and one 1 White (The Y because it's the right color just in the wrong index) As of right now I got it to display X for the right color in the right spot and anything else it is an O
I will post what I have been working with now but today I am at my wit's end
https://pastebin.com/HKK0T7bQ
if correctColor != "XXXX":
for i in range(4):
if guess[i] == tempCode[i]:
correctColor += "X"
if guess[i] != tempCode[i] in tempCode:
correctColor += "O"
print (correctColor + "\n")
if correctColor == "XXXX":
if attempts == 1:
print ("You think you are sweet because you got it right on the first try? Play me again!")
else:
print ("Well done... You needed " + str(attempts) + " attempts to guess.")
game = False
A few comments
X and O
you use X and 0 to denote the success, it will be easier and faster to use a list or tuple or booleans for this, that way you can use sum() to count how many colors and locations were correct. Then whether you represent that with X and O or red and white pins is a matter for later
compartmentalization
Your game logic (guess input, input validation, do you want to continue, etc) is mixed with the comparison logic, so it would be best to separate the different functions of your program into different methods.
This is an fineexample to introduce object oriented programming, but is so simple it doesn't need OO, but it can help. What you need is a method which takes a series of colours and compares it to another series of colours
Standard library
Python has a very extended standard library, so a lot of stuff you want to do probably already exists
Correct colours
to count the number of letters which occur in 2 strings, you can use collections.Counter
guess = "RGOY "
solution = "RGYB"
a = collections.Counter(guess)
b = collections.Counter(solution)
a & b
Counter({'G': 1, 'R': 1, 'Y': 1})
correct_colours = sum((a & b).values())
3
So the user guessed 3 colours correctly
Correct locations
can be solved with an easy list comprehension
[g == s for g, s in zip(guess, solution)]
[True, True, False, False]
sum(g == s for g, s in zip(guess, solution))
2
so the used put 2 colours on the correct location
This is a MasterMind I made in Python. Hope you like it and it helped you! :)
import random
import time
from tkinter import *
def select_level():
global level
level = level_selector.get()
root.destroy()
root = Tk()
level_selector = Scale(root, from_=1, to=3, tickinterval=1)
level_selector.set(0)
level_selector.pack()
Button(root, text="Select a difficulty level", command=select_level).pack()
mainloop()
cpc_1_digit = 0
cpc_2_digit = 0
cpc_3_digit = 0
cpc_4_digit = 0
p_1_digit = 0
p_2_digit = 0
p_3_digit = 0
p_4_digit = 0
correct_correct = 0
correct_wrong = 0
chances = 0
if level == 1:
chances = 15
elif level == 2:
chances = 10
else:
chances = 7
cpc_1_digit = random.randint(0, 9)
while cpc_2_digit == cpc_1_digit or cpc_2_digit == cpc_3_digit or cpc_2_digit ==
cpc_4_digit:
cpc_2_digit = random.randint(0, 9)
while cpc_3_digit == cpc_1_digit or cpc_3_digit == cpc_2_digit or cpc_3_digit ==
cpc_4_digit:
cpc_3_digit = random.randint(0, 9)
while cpc_4_digit == cpc_1_digit or cpc_4_digit == cpc_2_digit or cpc_4_digit ==
cpc_3_digit:
cpc_4_digit = random.randint(0, 9)
while chances > 0:
correct_correct = 0
correct_wrong = 0
answer = input("Enter a four-digit number with different digits (e.g 1476): ")
p_1_digit = int(answer[0])
p_2_digit = int(answer[1])
p_3_digit = int(answer[2])
p_4_digit = int(answer[3])
if p_1_digit == cpc_1_digit:
correct_correct = int(correct_correct) + 1
elif p_1_digit == cpc_2_digit or p_1_digit == cpc_3_digit or p_1_digit ==
cpc_4_digit:
correct_wrong = int(correct_wrong) + 1
else:
pass
if p_2_digit == cpc_2_digit:
correct_correct = correct_correct + 1
elif p_2_digit == cpc_1_digit or p_2_digit == cpc_3_digit or p_2_digit ==
cpc_4_digit:
correct_wrong = int(correct_wrong) + 1
else:
pass
if p_3_digit == cpc_3_digit:
correct_correct = int(correct_correct) + 1
elif p_3_digit == cpc_1_digit or p_3_digit == cpc_2_digit or p_3_digit ==
cpc_4_digit:
correct_wrong = int(correct_wrong) + 1
else:
pass
if p_4_digit == cpc_4_digit:
correct_correct = int(correct_correct) + 1
elif p_4_digit == cpc_1_digit or p_4_digit == cpc_3_digit or p_4_digit ==
cpc_2_digit:
correct_wrong = int(correct_wrong) + 1
else:
pass
print("")
if int(correct_correct) == 4:
print("Congratsulations! You found the computer's number!")
break
elif int(correct_wrong) > 0 or int(correct_correct) >= 1 and int(correct_correct)
< 4:
print("You got " + str(correct_correct) + " correct digit(s) in the correct
place, and " + str(correct_wrong) + " correct digit(s) but in wrong place.")
elif int(correct_correct) == 0 and int(correct_wrong) == 0:
print("You didn't guess any number, try again!")
else:
raise Exception("CheckError: line 69, something went wrong with the
comparings.")
exit()
print("")
chances = chances - 1
if chances == 0:
print("You lost... The secret number was " + str(cpc_1_digit) + str(cpc_2_digit)
+ str(cpc_3_digit) + str(cpc_4_digit) + ". Try again by rerunning the program.")
time.sleep(4)

Curses snake game not removing cells in linux os

It's code from a curses tutorial that I've been using to get a grasp of it but even though I've checked the code multiple times, it's still not removing the old cells. The guy that wrote the code is on a mac and I'm using linux so would that be a problem?
import curses
import time
import random
screen = curses.initscr()
dims = screen.getmaxyx()
def game():
screen.nodelay(1)
head = [1, 1]
body = [head[:]]*5
screen.border()
direction = 0 # 0:right, 1:down, 2:left, 3:up
gameover = False
while not gameover:
deadcell = body[-1][:]
if deadcell not in body:
screen.addch(deadcell[0], deadcell[1], ' ')
screen.addch(head[0], head[1], 'X')
if direction == 0:
head[1] += 1
elif direction == 2:
head[1] -= 1
elif direction == 1:
head[0] += 1
elif direction == 3:
head[0] -= 1
deadcell = body[-1][:]
for z in range(len(body)-1, 0, -1):
body[z] = body[z-1][:]
body[0] = head[:]
if screen.inch(head[0], head[1]) != ord(' '):
gameover = True
screen.move(dims[0]-1, dims[1]-1)
screen.refresh()
time.sleep(0.1)
game()
curses.endwin()
The problem seems to be near the lines:
while not gameover:
deadcell = body[-1][:]
if deadcell not in body:
screen.addch(deadcell[0], deadcell[1], ' ')
deadcell is always going to be in body, so no cells will ever get cleared.
Try this instead:
deadcell = body[-1][:]
while not gameover:
if deadcell not in body:
screen.addch(deadcell[0], deadcell[1], ' ')

List object occurrence checker python

I was working on a small project, and I've run across a little error in my programming. It's a basic battleship game, and so far I have two "ships" set, and I have the game to end when both on either my side or the enemy side is hit.
def enemy_board():
global enemy_grid
enemy_grid = []
for i in range (0,10):
enemy_grid.append(["="] * 10)
def random_row_one(enemy_grid):
return randint(0, len(enemy_grid) - 1)
def random_col_one(enemy_grid):
return randint(0, len(enemy_grid) - 1)
def random_row_two(enemy_grid):
return randint(0, len(enemy_grid) - 1)
def random_col_two(enemy_grid):
return randint(0, len(enemy_grid) - 1)
global x_one
x_one = random_row_one(enemy_grid)
global y_one
y_one = random_col_one(enemy_grid)
global x_two
x_two = random_row_two(enemy_grid)
global y_two
y_two = random_col_two(enemy_grid)
print(x_one)
print(y_one)
print(x_two)
print(y_two)
So that's the basis of my list, but later on in the code is where it's giving me a little trouble.
elif enemy_grid.count("H") == 2:
print("\nYou got them all!\n")
break
Update
Sorry I was a little unclear about what I meant.
def my_board():
global my_grid
my_grid = []
for i in range (0,10):
my_grid.append(["O"] * 10)
def my_row_one(my_grid):
int(input("Where do you wish to position your first ship on the x-axis? "))
def my_col_one(my_grid):
int(input("Where do you wish to position your first ship on the y-axis? "))
global x_mio
x_mio = my_row_one(my_grid)
global y_mio
y_mio = my_col_one(my_grid)
def my_row_two(my_grid):
int(input("\nWhere do you wish to position your other ship on the x-axis? "))
def my_col_two(my_grid):
int(input("Where do you wish to position your other ship on the y-axis? "))
global x_mit
x_mit = my_row_two(my_grid)
global y_mit
y_mit = my_col_two(my_grid)
def enemy_board():
global enemy_grid
enemy_grid = []
for i in range (0,10):
enemy_grid.append(["="] * 10)
def random_row_one(enemy_grid):
return randint(0, len(enemy_grid) - 1)
def random_col_one(enemy_grid):
return randint(0, len(enemy_grid) - 1)
def random_row_two(enemy_grid):
return randint(0, len(enemy_grid) - 1)
def random_col_two(enemy_grid):
return randint(0, len(enemy_grid) - 1)
global x_one
x_one = random_row_one(enemy_grid)
global y_one
y_one = random_col_one(enemy_grid)
global x_two
x_two = random_row_two(enemy_grid)
global y_two
y_two = random_col_two(enemy_grid)
print(x_one)
print(y_one)
print(x_two)
print(y_two)
title()
my_board()
enemy_board()
m = 20
guesses = m
while guesses > 0:
def printmi_board(my_grid):
for row in my_grid:
print(" ".join(row))
def printyu_board(enemy_grid):
for row in enemy_grid:
print (" ".join(row))
print(printmi_board(my_grid))
print(printyu_board(enemy_grid))
try:
guess_x = int(input("Take aim at the x-xalue: "))
except ValueError:
print("\nI SAID TAKE AIM!\n")
guess_x = int(input("Take aim at the x-xalue: "))
try:
guess_y = int(input("Take aim at the y-value: "))
except ValueError:
print("\nDo you have wax in your ears?? AIM!\n")
guess_y = int(input("Take aim at the y-value: "))
comp_x = randint(0, len(my_grid) - 1)
comp_y = randint(0, len(my_grid) - 1)
if x_one == guess_x and y_one == guess_y:
print("\nYou hit one! \n")
enemy_grid[guess_x - 1][guess_y - 1] = "H"
continue
elif x_two == guess_x and y_two == guess_y:
enemy_grid[guess_x - 1][guess_y - 1] = "H"
print("\nYou hit one! \n")
continue
elif enemy_grid[guess_x - 1][guess_y - 1] == "O":
print("\nYou've tried there before! Here's another round.\n")
print("You have " + str(guesses) + " rounds left, cadet.\n\n")
continue
elif enemy_grid.count("H") == 2:
print("\nYou got them all!\n")
break
else:
if guess_x not in range(10) or guess_y not in range(10):
print("\nThat's not even in the OCEAN!! Take another free round then.\n")
print("You have " + str(guesses) + " rounds left, cadet.\n\n")
continue
elif enemy_grid[guess_x][guess_y] == "O":
print("\nYou've tried there before! Here's another round.\n")
print("You have " + str(guesses) + " rounds left, cadet.\n\n")
continue
else:
print("\nYou missed, soldier!\n")
guesses = guesses - 1
print("You have " + str(guesses) + " rounds left, cadet.\n\n")
enemy_grid[guess_x - 1][guess_y - 1] = "O"
if comp_x == x_mio and comp_y == y_mio:
my_grid[comp_x - 1][comp_y - 1] = "H"
print("\nThe enemy hit you! \n")
continue
elif comp_x == x_mit and comp_y == y_mit:
my_grid[comp_x - 1][comp_y - 1] = "H"
print("\nThe enemy hit you! \n")
continue
elif my_grid.count("H") == 2:
print("We have to retreat! They've sunken all of your ships...")
break
else:
my_grid[comp_x - 1][comp_y - 1] = "="
continue
I'm using python 3 if that makes any difference. So it's that if the player hits the correct spot on the grid, then it'll show as "H" and not as "=" or "O". So I was just wondering about if I could count those "H"'s to use to end the IF loop.
You haven't really explained the problem, and so much of the code is missing that it's very hard to tell you what's wrong, I'm going to guess at it though.
My guess is that you create an '=' grid to represent a player's board, and then if their ship is 'hit' you replace the '=' in that position with an 'H'.
The structure you create (enemy_grid) seems to look something like:
[[====]
[====]
[====]
[....]]
in which case your test, enemy_grid.count("H") doesn't make sense as enemy_grid is a list that contains other lists (so the count of Hs will always be 0 - they're deeper down in the 2nd layer of lists).
You probably want a test more along the lines of:
[cell for row in enemy_grid for cell in row].count('H')

Categories

Resources