I'm working on making a battleship game for a school project using Pythons Tkinter, and I made these classes to have the player place their ships. The idea is that you can click on one of the ships in an area off to the side, and then click on a button on the board to place the ship. Problem is, the buttons place in a diagonal, and clicking on them brings the initial menu screen back up, which is odd
This is my first time working with Tk so I don't even know where to start
class ShipCreator:
global board, BOARD_OFFSET
ShipHolder = Frame(board)
ShipHolder.place(x=800, y=BOARD_OFFSET)
shipNum = 5
activeShip = None
def __init__(self, length, image, direction):
# Length is the length integer, image an image, direction is 0 for facing up/down, 1 for facing left/right
self.length = length
self.imageTk = ImageTk.PhotoImage(image)
self.direction = direction
self.button = Button(ShipCreator.ShipHolder, image=self.imageTk, command=self.start_place)
self.button.pack()
def start_place(self):
actionLabel.configure(text="Click where you'd like the bottom/left of the ship to be:")
ShipCreator.activeShip = self
def check_place(self, xcoord, ycoord):
import Main
can_place = True
for i in range(self.length + 1):
if self.direction == 0 and xcoord < len(Main.playerBoard):
if ycoord + i < len(Main.playerBoard[xcoord]) and Main.playerBoard[xcoord][ycoord + i] != " ":
can_place = False
break
elif ycoord < len(Main.playerBoard[xcoord + self.length]):
if xcoord + i < len(Main.playerBoard) and Main.playerBoard[xcoord + i][ycoord] == " ":
can_place = False
break
return can_place
def place(self, xcoord, ycoord):
import Main
global playerBoard
if self.check_place(xcoord, ycoord):
playerBoard.create_image(78 * xcoord + 8, 78 * xcoord + 8 + BOARD_OFFSET, image=self.imageTk, anchor=NW)
for i in range(self.length + 1):
if self.direction == 0:
Main.playerBoard[xcoord][ycoord + i] = "S"
else:
Main.playerBoard[xcoord + i][ycoord] = "S"
del self.button
ShipCreator.shipNum -= 1
if ShipCreator.shipNum == 0:
for i in range(10):
for j in range(10):
exec("del button" + str(i) + str(j))
del ship1, ship2, ship3, ship4, ship5
# TODO: Start actual game flow here
else:
ShipCreator.activeShip = None
actionLabel.configure(text="Cannot place a ship there!")
class PlaceButton:
def __init__(self, xcoord, ycoord):
global BOARD_OFFSET
self.xcoord = xcoord
self.ycoord = ycoord
self.button = Button(playerBoard, image=backgroundImageTK, command=self.place)
self.button.place(x=78 * xcoord + 8, y=78 * xcoord + 8 + BOARD_OFFSET, anchor=NW, height=78, width=78)
def place(self):
if ShipCreator.activeShip is not None:
ShipCreator.activeShip.place(self.xcoord, self.ycoord)
def open_game(): # Initializes the game, making the grid buttons for the players ships
global shipImg1, shipImg2, shipImg3, shipImg4, shipImg5, ship1, ship2, ship3, ship4, ship5
menu.pack_forget()
board.pack(expand=True, fill=BOTH)
for i in range(10):
for j in range(10):
exec("button" + str(i) + str(j) + " = PlaceButton(" + str(i + 1) + "," + str(j + 1) + ")")
ship1 = ShipCreator(5, shipImg1, 0)
ship2 = ShipCreator(4, shipImg2, 0)
ship3 = ShipCreator(3, shipImg3, 0)
ship4 = ShipCreator(4, shipImg4, 1)
ship5 = ShipCreator(5, shipImg5, 1)
I expect the ships to be placed on top of the buttons, and instead they are placed under the buttons, and bring the initial menu sreen back up