Hangman troubles with drawing and replacing dashlist - python

I'm having a slight issue figuring out how to replace the dashed list on my hangman game. What I want it to do is replace itself into the word the player guesses, like in the actual hangman. In addition, my program is not able to draw the head or body of the hangman. Could you guys help me out? Thanks.
I tried using .replace but I'm either too incompetent or have no idea how to use it despite going through other sources. Ditto with the turtle drawing.
Here is the code if it helps out.
import random
import os
import turtle as t
#declare variables
alphaList = list("abcdefghijklmnopqrstuvwxyz")
wordlist = ['penguin', 'pengalin', 'ability', 'absense', 'academy', 'swordman']
chosenList = []
dashedList = []
Newlist = list (random.choice (wordlist))
# make the cls() method
def cls():
os.system('cls' if os.name=='nt' else 'clear')
# call the cls method
def circle(x, y, rad, col):
t.color ("black", col)
t.goto (x,y)
t.pendown ()
t.begin_fill ()
t.circle (rad)
t.end_fill ()
t.penup ()
def rectangle(x, y, hor, vert, col):
t.color ("black", col)
t.goto (x,y)
t.pendown ()
t.begin_fill ()
#trace out rectangle
for x in range (2):
t.forward (hor)
t.right (90)
t.forward (vert)
t.right (90)
t.end_fill ()
t.penup ()
def setup():
#randomly choose word and make a list
Newlist = list (random.choice (wordlist))
for i in range (0, len(Newlist)):
dashedList.append ("_")
def display ():
print ("Available letters: ")
print ("".join (alphaList))
print ()
print ("Mystery Word: ")
print (dashedList)
#main logic
def hangman():
points = 6
guessed_letters = []
print(Newlist, "ChosenList")
while points > 0:
print(guessed_letters)
userguess = input("Tell me a letter: ").lower()
if points < 6:
return circle
if points < 5:
return rectangle
if len(userguess) != 1:
print("Try using only 1 letter next time.")
if userguess in guessed_letters:
print("You have already chosen", userguess, ",friend.")
elif userguess in Newlist:
print("You got a correct letter!")
guessed_letters.append(userguess)
else:
guessed_letters.append(userguess)
print("Uh oh ",userguess, " not in the word")
points -= 1
print(points, "Tries left. ")
#main logic
setup ()
display ()
hangman()
circle(x, y, rad, col)
rectangle(x, y, hor, vert, col)

Related

List value being overwritten even though I am checking for it

I'm new to python and writing my first project. I'm trying to implement a check that if a space is already occupied, not to move there. I can't seem to figure out why my move_player method overwrites the index value of the board even though I am explicitly checking it (If it is O's turn and X has already been placed in the index O is trying to move to, it just overwrites it). I have tried hard coding the check for 'X' and 'O' instead of player.player as well but can't seem to figure it out. Does it have to do something with how Python works or am I implementing it wrong?
class Player:
def __init__(self, player):
self.player = player
class Board:
def __init__(self):
self.board = [[' ' for i in range(3)] for j in range(3)]
def display_board(self):
print('---------')
for row in self.board:
print('| ', end='')
for col in row:
print(f'{col} ', end='')
print('|')
print('---------')
def move_player(self, player):
try:
p1 = Player('X')
p2 = Player('O')
coordinates = [int(i) for i in input("Enter coordinates for move: ").split()]
xCoordinate = coordinates[0]
yCoordinate = coordinates[1]
if ((self.board[xCoordinate][yCoordinate] == p1.player) or
(self.board[xCoordinate][yCoordinate] == p2.player)):
print("That space is occupied, please choose another one.")
self.move_player(player)
else:
self.board[xCoordinate - 1][yCoordinate - 1] = player.player
except (ValueError, IndexError):
print("Please only enter numbers between 1 and 3.")
self.move_player(player)
def has_won(self, player):
if self.check_diagonal(player):
return True
elif self.check_across(player):
return True
elif self.check_down(player):
return True
return False
if __name__ == '__main__':
board = Board()
player1 = Player('X')
player2 = Player('O')
player = player1
while True:
board.display_board()
board.move_player(player)
if board.has_won(player):
board.display_board()
print(f'{player.player} wins!!!')
break
if player == player1:
player = player2
else:
player = player1
The code is very convoluted but from what I can see:
if ((self.board[xCoordinate][yCoordinate] == p1.player) or
(self.board[xCoordinate][yCoordinate] == p2.player)):
...
self.board[xCoordinate - 1][yCoordinate - 1] = player.player
You are checking [x,y] but assigning to [x-1,y-1].

How to use variable of function for another one? (Python)

I am a beginner in Python. I started to write some code for a game called 'Tic tac toe'.
For that I created some functions below:
import random
def choose_first():
random.randint(1, 2)
if random.randint(1,2) == 1:
print('Player 1 is first to play')
player1_input()
elif random.randint(1,2) == 2:
print('Player 2 is first to play')
player2_input()
def player1_input():
player1=''
marker=''
while marker !='X' and marker !='O':
marker=input('Player 1, choose X or O: ')
return marker
player1==marker
if player1=='X':
player2='O'
else:
player2='X'
return (player1,player2,marker)
def player_choice(board):
position = int(input('Which position you want to choose? '))
if space_check is True:
return position
def place_marker(board, marker, position):
board[position] = marker
Here is piece of code that using those functions:
def game_on():
board = ['#','','','','','','','','','']
choose_first()
while not full_board_check(board):
player_choice(board)
place_marker(board, marker, position)
display_board(board)
while full_board_check(board):
if win_check(board, mark):
print('Player using', marker, 'won')
else:
print("It's a tie!")
When I choosing position it returns this error:
<ipython-input-117-d37edecdd743> in game_on()
5 while not full_board_check(board):
6 player_choice(board)
----> 7 place_marker(board, marker, position)
8 display_board(board)
9 while full_board_check(board):
NameError: name 'marker' is not defined
It seems that the 'marker' variable doesn't return from player_input() but I need to use him at another function (in this situation for placing marker). How to do that? Please help if you can.
I think what you should do is to put global marker before getting the input:
global marker
marker=input('Player 1, choose X or O: ')

Store User Values in Python Game Using Class Methods

Python beginner here--working on a Battleship project for a class. My program will loop through the first player to place their ships. The grid does successfully print the visual ships on the board, but once i get to player two, the ships are overlapping with player one. (also note there is some validation work that still needs to be done).
I think the issue is that maybe I'm storing both coordinates for each player in the same list. So my question is how do I store the values for each player so that I can get the board to print ships only applicable to each player?
Here are my classes:
BOARD_SIZE = 10
class Ship:
def __init__(self, ship_name, size, coords, player, direction):
self.ship_name = ship_name
self.size = size
self.player = player
self.coords = coords
self.direction = direction
class Board:
def __init__(self):
self.board = []
self.guesses = []
board = [['O']*BOARD_SIZE for _ in range(BOARD_SIZE)]
def add_ship(self, name, size, player, coords, direction):
for coord in coords:
# convert string like "a1" to x,y coordinates
y = ord(coord[0])-ord('a')
x = int(coord[1:])-1
# update the board at this position
self.board = board[x][y]
print(" " + " ".join([chr(c) for c in range(ord('A'), ord('A') + BOARD_SIZE)]))
row_num = 1
for row in board:
print(str(row_num).rjust(2) + " " + (" ".join(row)))
row_num += 1
self.board.append(Ship(coords,player,name,size,direction))
def print_board_heading(self):
print(" " + " ".join([chr(c) for c in range(ord('A'), ord('A') + BOARD_SIZE)]))
def print_board(self):
board = [['O']*BOARD_SIZE for _ in range(BOARD_SIZE)]
print_board_heading()
row_num = 1
for row in board:
print(str(row_num).rjust(2) + " " + (" ".join(row)))
row_num += 1
def print_updated_board(coords, direction, board, player):
for coord in coords:
# convert string like "a1" to x,y coordinates
y = ord(coord[0])-ord('a')
x = int(coord[1:])-1
# update the board at this position
board[x][y] = '|' if direction == 'v' else '-'
print(" " + " ".join([chr(c) for c in range(ord('A'), ord('A') + BOARD_SIZE)]))
row_num = 1
for row in board:
print(str(row_num).rjust(2) + " " + (" ".join(row)))
row_num += 1
class Player():
def __init__(self,name):
self.name = name
self.board = Board()
self.ships = []
self.guesses = []
And the battleship game file:
from ship import Ship, Player, Board
SHIP_INFO = [
("Aircraft Carrier", 5),
("Battleship", 4),
("Submarine", 3),
("Cruiser", 3),
("Patrol Boat", 2)
]
BOARD_SIZE = 10
VERTICAL_SHIP = '|'
HORIZONTAL_SHIP = '-'
EMPTY = 'O'
MISS = '.'
HIT = '*'
SUNK = '#'
board = [['O']*BOARD_SIZE for _ in range(BOARD_SIZE)]
def print_board_heading():
print(" " + " ".join([chr(c) for c in range(ord('A'), ord('A') + BOARD_SIZE)]))
def print_board():
board = [['O']*BOARD_SIZE for _ in range(BOARD_SIZE)]
print_board_heading()
row_num = 1
for row in board:
print(str(row_num).rjust(2) + " " + (" ".join(row)))
row_num += 1
def print_updated_board(coords, direction,board):
# create an empty board
# board = [['O']*BOARD_SIZE for _ in range(BOARD_SIZE)]
# at each coordinate, draw a ship
for coord in coords:
# convert string like "a1" to x,y coordinates
y = ord(coord[0])-ord('a')
x = int(coord[1:])-1
# update the board at this position
board[x][y] = '|' if direction == 'v' else '-'
print_board_heading()
row_num = 1
for row in board:
print(str(row_num).rjust(2) + " " + (" ".join(row)))
row_num += 1
def clear_screen():
print("\033c", end="")
def get_coordinates(ship):
while True:
print("\n")
coordinate = input("Where do you want the " + ship + "(example: A1)?: ")
coords_strip = coordinate.strip()
coords_lower = coords_strip.lower()
x = coords_lower[0]
y = coords_lower[1:]
if (len(x)+len(y)) in range(2,4):
if x not in 'abcdefghij' or y not in '1,2,3,4,5,6,7,8,9,10':
print("Oops! That was not a valid entry. Try again...")
continue
else:
return x, y
else:
if len(coords_lower) < 2 or len(coords_lower) > 3:
print("Oops! That's too not the right amount of characters. Please try again...")
continue
def get_direction():
while True:
dir = input("[H]orizontal or [V]ertical?: ")
dir_strip = dir.strip()
direction = dir_strip.lower()
if direction not in 'hv':
print("Oops! That was not a valid entry. Try again...")
continue
else:
return direction
def create_ship_coordinates(x, y, size, direction):
ship_col = ord(x)
ship_row = int(y)
if direction == 'v':
# ship runs vertically DOWN from coordinate
coords = [chr(ship_col) + str(r) for r in range(ship_row, ship_row + size)]
return coords
else:
# ship runs horizontally RIGHT from coordinate
coords = [chr(col) + str(ship_row) for col in range(ship_col, ship_col + size)]
return coords
def place_user_ships(player):
ships = []
print_board()
print("\n")
print("Let's go " + player + " !")
for ship, size in SHIP_INFO:
while True:
# ask for starting coordinate
x, y = get_coordinates(ship)
# ask for vertical or horizontal direction
direction = get_direction()
# create the coordinates for the ship placement
coords = create_ship_coordinates(x, y, size, direction)
# validate the
# new_ship = Board().add_ship(ship, size, coords, direction, player)
# update = Board.print_updated_board(coords,direction,board,player)
break
# create ship from data
# add the ship from above to a player list
# player = Player(board)
# place the ship on the game board
# print out the board to reflect the shp placement
clear_screen()
print("\n")
input("All ships placed for {}. Please hit ENTER to continue....".format(player))
player1 = input("What's Player 1's Name? ")
player2 = input("What's Player 2's Name? ")
# define player one's fleet
place_user_ships(player1)
place_user_ships(player2)
IIRC, in battleship there are really four boards. One is managed by each player with their shots at the enemy, and the other is the player's own ships and incoming shots from the enemy.
The "shot" process is one of notifying the enemy where the shot was taken, the enemy responding with "hit" or "miss", and recording the result on the local player's outgoing-shots board.
The "notification" process is one of receiving a location where an enemy shot was made, looking up the result on the local-ships board, returning "hit" or "miss", and updating the local ships board to indicate the enemy shot.
So you have a Player, with a pair of Boards. You might also have a Game class to marry the two players.
Inputting the ships is going to depend a lot on your actual user interface. Are you doing graphics with a mouse? Are you doing text with a mouse? Text with arrow keys via curses or some such? Simple coordinate inputs?
If you're doing coordinates, you probably want something simple, like x,y,{up,down,left,right} to eliminate having to position every block of the ship.
Again, there is a Board method here - placing a ship. The board can enforce whatever rules you have about placement (ex: can two ships be directly adjacent? Or must there be a one-space gap between?) and reject the inappropriate attempts.
If you put all the wisdom in your Board class, then the Player classes can be simple, with just links to the boards. And the game can manage the players in turn:
def play(self):
p1 = self.player[0]
p2 = self.player[1]
try:
while True:
self.attack(p1, p2)
self.attack(p2, p1)
except Victory v:
print("The winner is", v.player.name)
I notice you doing things like player1 = input("What is player 1's name?"). This is something that should be pushed into the player classes.
Try to design from the top down: game, player, board. And try following the rule, "Tell, don't ask." That is, if something needs to be done, you tell a class to do it, instead of asking the class for data and doing it yourself.
Instead of this:
move = player1.get_move()
if valid_move(move):
...
Do this:
player1.make_move()
And push the logic downwards. Eventually, you get to the place where the knowledge "should be". The player "should" make moves. The board "should" know what is a valid move or not. And every method "should" be given enough data to do its job. ;-)

Python game logic: "coins" variable is not incrementing

I am working on a game where the player is in search of treasure. Everything works perfectly, although my money system does not work. I need my code to work so that if the user lands on a treasure chest, they gain 10 extra coins. However, their number of coins is being set to 10 instead of adding 10.
import easygui
import time
from random import *
# Set up Initial Variables
Money = 0
grid = []
character = "X"
# player_loc will hold the x, y location of the player
player_loc = (0, 0)
# These are a mapping of direction
NORTH = "N"
SOUTH = "S"
EAST = "E"
WEST = "W" #All variables used for Later on
Treasure = "T"
Goblin = "G"
def menu(): #function
msg = "Would you like to...?" #Users choice to start game
buttons = ["start", "quit"]
while True:
title = "Menu"
selection = easygui.buttonbox(msg, title , buttons)
if selection == "quit":
exit()
elif selection == "start": #If users input is to start the game the all of this appears("Welcome to the treasure hunt game!")
easygui.msgbox("These are the rules! You have a choice of a grid ranging from a 3x3 choice to a 20x20 choice")
easygui.msgbox("In these grids, bandits and treasure chests will spawn at random locations, hidden to you.")
easygui.msgbox("You will have a choice of the amount of goblins and treasures you would like to spawn in, ranging from 1-2")
easygui.msgbox("You will move around the map, in search of treasures which will give you 10 gold. Although landing on a goblin would deduct the amount of gold to 0.")
easygui.msgbox("Furthurmore, just deciding on a position you would like to move to, would give you an extra 1 piece of gold.")
easygui.msgbox("You can only find the same treasure chest two times before it's replaced by a bandit.")
easygui.msgbox("To check the amount of gold you have and the amount of bandits and treasure chests in the grid. Simply type 'status'")
easygui.msgbox("Don't forget! If you have collected all the treasure chests and you don't have 100 gold, you lose the game!")
easygui.msgbox("Good luck, you will now be entered into the game")
easygui.msgbox("Ok! let's jump into the game!")
setupGrid()
Chests_and_Goblins()
def setupGrid(): #New function for creating grid
global grid #Adding/creating global variables
global row
global N
N = easygui.integerbox("How big would you like the grid to be?") #User input
while int(N) > 20: #Changing N to an integer so computer understamds
N = easygui.intergerbox("That number is too high, The grid has to be at a size of under 20x20")
else:
while int(N) < 3 : # Asking the user to input again as number is too high or low
N = easygui.integerbox("That number is too low, the grid has to be a size of over 3x3. Please try again")
for x in range(0, (int(N))):#For everything in range N
row = [] #The N amount of rows are created
for y in range(0, (int(N))): #For everything in range N
if x == player_loc[0] and y == player_loc[1]: #If the positions is equal to th player location
row.append(character) # Add the character in
else:
row.append('O') #Add the same amount of 0's as N
grid.append(row)
def Chests_and_Goblins(): #Function used for adding the treasures and goblins in the grid
global grid
global row
global Treasure
B = easygui.enterbox(" How many chests would you like in the grid? The amount of chests you like is given by the amount of C's")
F = easygui.enterbox(" How many Bandits would you like in the grid? The amount of bandits you like is given by the amount of B's")
for each in B:
grid[randint(0, int(N)-1)][randint(0, int(N)-1)] = Treasure
for each in F:
grid[randint(0, int(N)-1)][randint(0, int(N)-1)] = Goblin
gridRunner()
def moveSouth(n):
global player_loc
grid[player_loc[0]][player_loc[1]] = "O"
grid[player_loc[0] + n][player_loc[1]] = character
player_loc = (player_loc[0] + n, player_loc[1])
money()
def moveNorth(n):
global player_loc
grid[player_loc[0]][player_loc[1]] = "O"
grid[player_loc[0] - n][player_loc[1]] = character
player_loc = (player_loc[0] - n, player_loc[1])
money()
def moveEast(n):
global player_loc
grid[player_loc[0]][player_loc[1]] = "O"
grid[player_loc[0]][player_loc[1] + n] = character
player_loc = (player_loc[0], player_loc[1] + n)
money()
def moveWest(n):
global player_loc
grid[player_loc[0]][player_loc[1]] = "O"
grid[player_loc[0]][player_loc[1] - n] = character
player_loc = (player_loc[0], player_loc[1] - n)
money()
def gridRunner():
while True:
for row in grid:
print (row)
switch = {NORTH : moveNorth,
SOUTH : moveSouth,
EAST : moveEast,
WEST : moveWest }
print (" ")
P = easygui.enterbox("What direction would you like to move in? North (N), South(S), East(E) or West(W)?")
if P not in switch:
easygui.msgbox("invalid move")
continue
distance = easygui.integerbox("How far would you like to move in this direction? (blocks are the units)")
switch[P](distance)
def money():
global player_loc
global character
global Treasure
if player_loc == Treasure:
print("Well done, You have gained coins")
money = 10
else:
print ("You got nothing")
money = 0
menu()
In this part here:
if player_loc == Treasure:
print("Well done, You have gained coins")
money = 10
You are setting the money to 10, not adding 10. All you need to do is:
money += 10
Also make sure def money(): isn't indented; it won't work as it currently is indented.
It looks like you have to indent the code under your money() function first:
def money():
global player_loc
global character
global Treasure
if player_loc == Treasure:
print("Well done, You have gained coins")
money = 10
else:
print ("You got nothing")
money = 0

Little assistance with my tic-tac-toe program

I need some help with my tic-tac-toe game that I created in Python 3. Have a look at my fun program and try it out. After that, please help me creating a while statement in my program. That is while the user choice of square if filled, you should continue to ask them until they choose an empty square. When the choose an empty square, the program continues as before. I am not used to the while statements, please help me on this!
Here is my program:
from turtle import *
def setUp():
#Set up the screen and turtle
win = Screen()
tic = Turtle()
tic.speed(10)
#Change the coordinates to make it easier to tranlate moves to screen coordinates:
win.setworldcoordinates(-0.5,-0.5,3.5, 3.5)
#Draw the vertical bars of the game board:
for i in range(1,3):
tic.up()
tic.goto(0,i)
tic.down()
tic.forward(3)
#Draw the horizontal bars of the game board:
tic.left(90) #Point the turtle in the right direction before drawing
for i in range(1,3):
tic.up()
tic.goto(i,0)
tic.down()
tic.forward(3)
tic.up() #Don't need to draw any more lines, so, keep pen up
#Set up board:
board = [["","",""],["","",""],["","",""]]
return(win,tic,board)
def playGame(tic,board):
#Ask the user for the first 8 moves, alternating between the players X and O:
for i in range(4):
x,y = eval(input("Enter x, y coordinates for X's move: "))
tic.goto(x+.25,y+.25)
tic.write("X",font=('Arial', 90, 'normal'))
board[x][y] = "X"
x,y = eval(input("Enter x, y coordinates for O's move: "))
tic.goto(x+.25,y+.25)
tic.write("O",font=('Arial', 90, 'normal'))
board[x][y] = "O"
# The ninth move:
x,y = eval(input("Enter x, y coordinates for X's move: "))
tic.goto(x+.25,y+.25)
tic.write("X",font=('Arial', 90, 'normal'))
board[x][y] = "X"
def checkWinner(board):
for x in range(3):
if board[x][0] != "" and (board[x][0] == board[x][1] == board[x][2]):
return(board[x][0]) #we have a non-empty row that's identical
for y in range(3):
if board[0][y] != "" and (board[0][y] == board[1][y] == board[2][y]):
return(board[0][y]) #we have a non-empty column that's identical
if board[0][0] != "" and (board[0][0] == board[1][1] == board[2][2]):
return(board[0][0])
if board[2][0] != "" and (board[2][0] == board[1][1] == board[2][0]):
return(board[2][0])
return("No winner")
def cleanUp(tic,win):
#Display an ending message:
tic.goto(-0.25,-0.25)
tic.write("Thank you for playing!",font=('Arial', 20, 'normal'))
win.exitonclick()#Closes the graphics window when mouse is clicked
def main():
win,tic,board = setUp() #Set up the window and game board
playGame(tic,board) #Ask the user for the moves and display
print("\nThe winner is", checkWinner(board)) #Check for winner
cleanUp(tic,win) #Display end message and close window
main()
You're probably looking for something like this:
x,y = None,None
while x == None or y == None or board[x][y] != "";
x,y = eval(input("Enter x, y coordinates for X's move: "))
This will keep asking the user for input as long as x and y do not indicate an empty tile on the board.
By the way, you might consider changing the way you process the input. Right now you are using eval, which can be dangerous as any input can be executed. It might be better to process the input manually, something like this:
x,y = map(int,input("Enter coordinates").split(','))
This splits the input at the comma, turning it into a list of strings. map then applies the function int to each element in the list, turning them into integers. These are then unpacked into x and y.
for i in range(4):
while True:
move = input("Enter x, y coordinates for X's move: ")
x,y = int(move[0]), int(move[-1]) # don't use eval()
if board[x][y] not in ('X', 'O') # if valid
tic.goto(x+.25,y+.25)
tic.write("X",font=('Arial', 90, 'normal'))
board[x][y] = "X"
break # break out of loop after doing stuff
You might want to use a validation function taking the whole input string and parse it in the validation function, like the code below:
def isUserInputValid (s):
cordinate=s.split(',')
...... # Your validation logic goes here
while not isUserInputValid(input("Please put your cell cordinate x, y:")):
print("Your choice is not valid!")

Categories

Resources