So, i have been working on a snake game made in Pygame. So far, everything is fine, except for one problem: When the snake eats the fruit, the fruit (that randomly spawns) sometimes appears inside the snake's body. So, to avoid this, i made this function:
def random_fruit(body_pos):
global general_fruit_x, general_fruit_y # Fruit rectangle coordinates
while True:
general_fruit_x = randrange(window[0] // snake.w) * snake.w # (Snake is a pygame.Rect)
general_fruit_y = randrange(window[1] // snake.h) * snake.h
if len(list(filter(lambda z: body_pos == (general_fruit_x, general_fruit_y), body_pos))) > 0:
continue # If the spawning position of the fruit is the same as the snake's body, we continue the loop
else:
break # If not, we are done
set_obj_coordinates(general_fruit, general_fruit_x, general_fruit_y) # set fruit random position
And implemented it in the main game loop:
if fruit_eated:
random_ind1 = random_ind2
snake_len += 1
apple_sound.play()
random_fruit(snake_pos) # snake_pos is a list of tuples with all snake's body coordinates
for m in range(3):
snake_imgs[random_ind1][m] = img("snake_" + snake_colors[random_ind1] + str(m + 1)) # Reset snake image
random_ind2 = randint(0, 3)
if x_move < 0:
rotate_imgs(90, random_ind1)
if x_move > 0:
rotate_imgs(-90, random_ind1)
if y_move > 0:
rotate_imgs(180, random_ind1)
if y_move < 0:
pass
But it seems that the random_fruit function ignores the condition of the snake's body.
Here is the complete code: https://github.com/n4tm/PySnake/tree/main/snake
You have to check if any position of the body is equal to the new random position of the fruit:
if len(list(filter(lambda z: body_pos == (general_fruit_x, general_fruit_y), body_pos))) > 0:`
if any(pos == (general_fruit_x, general_fruit_y) for pos in body_pos):
random_fruit function:
def random_fruit(body_pos):
global general_fruit_x, general_fruit_y
while True:
general_fruit_x = randrange(window[0] // snake.w) * snake.w
general_fruit_y = randrange(window[1] // snake.h) * snake.h
if not any(pos == (general_fruit_x, general_fruit_y) for pos in body_pos):
break
set_obj_coordinates(general_fruit, general_fruit_x, general_fruit_y)
Related
I'm trying to make a chess game, and I've encountered a problem:
I'm trying to update the display for every 'tick' by using pygame.Surface.fill(black_sc).
But as a result, it seems I'm not able to draw anything on top of the now black screen:
#GAME LOOP
while True:
screen.fill(black_sc)
#SQUARE DRAWING LOOP
s_draw_loop()
#DRAW THE PIECES
draw_pieces()
m_pos = pygame.mouse.get_pos()
for x in pygame.event.get():
if x.type == pygame.QUIT or pygame.key.get_pressed()[pygame.K_ESCAPE] == True:
exit()
if x.type == pygame.MOUSEBUTTONDOWN:
for space in range(len(rect_database)):
if rect_database[space].collidepoint(m_pos) == True:
print(space)
pygame.display.flip()
Here's the s_draw_loop():
class s_draw_loop():
s_posx = 0
s_posy = 0
s_w = size[0] / 8
s_h = size[1] / 8
row = 0
i = 0
while i < 64:
if i % 2 == 0:
if row % 2 == 0:
current_rect = pygame.Rect(s_posx, s_posy, s_w, s_h)
screen.fill(white, current_rect)
else:
current_rect = pygame.Rect(s_posx, s_posy, s_w, s_h)
screen.fill(black,current_rect)
s_posx += s_w
i += 1
else:
if row % 2 == 0:
current_rect = pygame.Rect(s_posx, s_posy, s_w, s_h)
screen.fill(black,current_rect)
else:
current_rect = pygame.Rect(s_posx, s_posy, s_w, s_h)
screen.fill(white,current_rect)
s_posx += s_w
i += 1
if i % 8 == 0:
s_posx = 0
s_posy += s_h
row += 1
I'll spare you from the entire function drawing the pieces, unless you need it, but it's basically just using pygame.Surface.blit() to draw the pictures onto the display.
I've tried including the 'drawing functions' into the game-loop itself, but it seems to make no difference.
Here's the output when including 'screen.fill(black_sc)'
And here it is when commenting 'screen.fill(black_sc)' out
It's because s_draw_loop is a class, not a function.
The drawing code inside s_draw_loop is only executed once, before entering the game loop, when the python runtime reads the code of the class.
Calling s_draw_loop() inside your game loop does actually nothing (except creating an useless instace of that class that does nothing).
Simply change
class s_draw_loop():
...
to
def s_draw_loop():
...
so the code inside s_draw_loop gets executed every frame.
I am trying to make a game of checkers in pygame, and can't think of a way to do the logic for killing a checker once I jump over it. If you need any more information let me know. Here is the function in the checker sprite class:
# Determine if move is valid, and if so snap to the grid
# and tell the game logic that there is a checker there
def snap_to_grid(self):
global turn
x, y = self.rect.topleft
coord_x = round(x / square_size)
coord_y = round(y / square_size)
new_x = coord_x * square_size + 5
new_y = coord_y * square_size + 5
# get all valid moves from the starting position
valid_moves = self.valid_moves()
# check if it is valid, or if it is going back to the same spot. If either is true,
# then reset. If not, move to that spot.
if [new_x, new_y] == self.location or not [coord_x, coord_y] in valid_moves:
self.set_pos(self.location, 'topleft')
else:
# move to new position
self.set_pos((new_x, new_y), 'topleft')
# tell game data that the checker moved from the old square
board[self.coords[1]][self.coords[0]] = None
# the next few lines are to determine if the checker jumped or not
old_x, old_y = self.coords
self.location = [new_x, new_y]
self.coords = [int(self.location[0]//square_size), int(self.location[1]//square_size)]
distance = abs((old_x - self.coords[0])^2 + (old_y - self.coords[1])*2)
# check if checker jumped
if not distance == 1 and not distance == 5:
print("jumped")
"""
this code here should trigger when a jump happens.
I need to kill the checker it jumped over
"""
# tell game data the checker moved to the new square
board[self.coords[1]][self.coords[0]] = self
# set to be the next turn
if self.color == white:
turn = dark_gray
else:
turn = white
ok I think I figured it out, if there is a better way let me know (the distances in the if statements are the output if it is a jump in a specific direction):
old_x, old_y = self.coords
self.location = [new_x, new_y]
self.coords = [int(self.location[0]//square_size), int(self.location[1]//square_size)]
distance = (old_x - self.coords[0])^2 + (old_y - self.coords[1])*2
# check if checker jumped top right
if distance == -8:
board[self.coords[1]+1][self.coords[0]-1].kill()
# check if checker jumped top left
elif distance == 4:
board[self.coords[1]+1][self.coords[0]+1].kill()
# check if checker jumped bottom right
elif distance == 0:
board[self.coords[1]-1][self.coords[0]-1].kill()
# check if checker jumped bottom left
elif distance == -4:
board[self.coords[1]-1][self.coords[0]+1].kill()
I just currently finished making the game 'snake' as a practice to learn how to program, as I am new to programming for about 3 months.
Although the game is completed and runs the way I intended, I want to try to simplify my code and reduce the amount of lines as much as possible, and possibly make the script tidier as the current majority of my codes are cluster in the while loop.
Until now I haven't touched upon class objects, and I want everything in the while loop to go into individual classes that get called out from the while loop to reduce the amount of lines in it.
off-topic: by reading through the script, how else can I improve it to be run more efficiently, including simplifying some code as I may have over-complicated it?
I looked up how class object is used from w3school and other programming tutorials, but I still don't fully understand it as it only shows examples in using print. I did play around and experimented with class object examples and attempted to call them without using print, but I lack the knowledge of how to use them properly.
from graphics import *
from threading import Timer
import keyboard, random, time
# configurations
width = 400
gridHeight = width
height = 470
timer = False
game = True
score = 0
bonus = 0
x = 70
y = 30
radius = 10
length = radius * 2
playerLength = 3
poisonLength = playerLength
i = 0
k = 0
pointRadius = 5
points = False
cherryPoints = False
key = "Right"
countDown = 0
# set coordinations
cX = 90
cY = 30
coordX = [10]
coordY = [10]
while coordX[len(coordX)-1] != width-10:
cX+=20
coordX.append(cX)
while coordY[len(coordY)-1] != 390:
cY+=20
coordY.append(cY)
randomX = random.choice(coordX)
randomY = random.choice(coordY)
cherryRandomX = random.choice(coordX)
cherryRandomY = random.choice(coordY)
poisonRandomX = random.choice(coordX)
poisonRandomY = random.choice(coordY)
# window set up
win = GraphWin("SNAKE", width, height, autoflush = False)
win.setBackground(color_rgb(15,15,15))
# grid
lineX = 20
while lineX < width:
gridX = Line(Point(lineX,0),Point(lineX,gridHeight))
gridX.setOutline(color_rgb(25,25,25))
gridX.draw(win)
lineX += 20
lineY = 20
while lineY <= gridHeight:
gridX = Line(Point(0,lineY),Point(width,lineY))
gridX.setOutline(color_rgb(25,25,25))
gridX.draw(win)
lineY += 20
# snake banner
UI = Rectangle(Point(0,400),Point(width,height))
UI.setFill(color_rgb(102,51,0))
UI.setOutline(color_rgb(102,51,0))
UI.draw(win)
snakeTitle = Text(Point(width/2,420),"SNAKE")
snakeTitle.setTextColor("green")
snakeTitle.setSize(20)
snakeTitle.draw(win)
scoreTitle = Text(Point(320,424),"SCORE")
scoreTitle.setTextColor("white")
scoreTitle.setSize(10)
scoreTitle.draw(win)
scoreUI = Text(Point(320,435),score)
scoreUI.setTextColor("white")
scoreUI.setSize(10)
scoreUI.draw(win)
# make player
player = {}
player[0] = Rectangle(Point(x-20-radius,y-radius), Point(x-20+radius, y+radius))
player[1] = Rectangle(Point(x-40-radius,y-radius), Point(x-40+radius, y+radius))
player[2] = Rectangle(Point(x-60-radius,y-radius), Point(x-60+radius, y+radius))
# make poison
poison = {}
def main():
global timer, scoreUI, score, bonus, playerLength, poisonLength, x, y, points, cherryPoints, randomX, randomY, cherryRandomX, cherryRandomY, poisonRandomX, poisonRandomY, key, countDown, k, game
while(game==True):
# score update
scoreUI.undraw()
scoreUI = Text(Point(320,435),score)
scoreUI.setTextColor("white")
scoreUI.setSize(10)
scoreUI.draw(win)
# generating new body blocks
if len(player) < playerLength:
i+=1
player[i] = player[i-1].clone()
# body following player
player[0].undraw()
for i in range(1,len(player)):
player[len(player)-i].undraw()
player[len(player)-i] = player[len(player)-i-1].clone()
player[len(player)-i].draw(win)
# update player's head coordinate
player[0] = Rectangle(Point(x-radius,y-radius), Point(x+radius,y+radius))
player[0].setFill("green")
player[0].setWidth(2)
player[0].draw(win)
# player movement
if keyboard.is_pressed("Up") and key != "Down":
key = "Up"
elif keyboard.is_pressed("Left") and key != "Right":
key = "Left"
elif keyboard.is_pressed("Down") and key != "Up":
key = "Down"
elif keyboard.is_pressed("Right") and key != "Left":
key = "Right"
if key == "Up":
y -= length
elif key == "Left":
x -= length
elif key == "Down":
y += length
elif key == "Right":
x += length
# point
if points == False: # generates new point when eaten
point = Rectangle(Point(randomX-pointRadius,randomY-pointRadius),Point(randomX+pointRadius,randomY+pointRadius))
point.setFill("white")
point.setWidth(2)
point.draw(win)
points = True
if player[0].getCenter().getX() == point.getCenter().getX() and player[0].getCenter().getY() == point.getCenter().getY(): # when player eats the point
point.undraw()
playerLength += 1
poisonLength += 1
score += 200+bonus
randomX = random.choice(coordX)
randomY = random.choice(coordY)
for i in range(len(player)):
if (point.getCenter().getX() == player[i].getCenter().getX() and point.getCenter().getY() == player[i].getCenter().getY()) or (cherryPoints == True and cherryPoint.getCenter().getX() == point.getCenter().getX() and cherryPoint.getCenter().getY() == point.getCenter().getY()): # regenerate x and y coordinate if they share the same coordinate as player and cherry
randomX = random.choice(coordX)
randomY = random.choice(coordY)
for i in range(len(poison)): # regenerate x and y coordinate if point shares the same coordinate to other array of poisons
if point.getCenter().getX() == poison[i].getCenter().getX() and point.getCenter().getY() == poison[i].getCenter().getY():
cherryRandomX = random.choice(coordX)
cherryRandomY = random.choice(coordY)
points = False
# cherry
if countDown == 150:
countDown = 0
if cherryPoints == False: # generates new cherry from countdown
cherryPoint = Rectangle(Point(cherryRandomX-pointRadius,cherryRandomY-pointRadius),Point(cherryRandomX+pointRadius,cherryRandomY+pointRadius))
cherryPoint.setFill(color_rgb(213,0,50))
cherryPoint.setWidth(2)
cherryPoint.draw(win)
cherryPoints = True
if cherryPoints == True:
for i in range(2, 6): # cherry blinks between countdown 40 to 100
if countDown == 20*i:
cherryPoint.undraw()
elif countDown == 10+(20*i):
cherryPoint.draw(win)
if countDown >= 100: # when countdown becomes 100, remove cherry and reset count down
cherryPoints = False
countDown = 0
cherryRandomX = random.choice(coordX)
cherryRandomY = random.choice(coordY)
if cherryPoints==True and player[0].getCenter().getX() == cherryPoint.getCenter().getX() and player[0].getCenter().getY() == cherryPoint.getCenter().getY(): # when player eats the cherry
cherryPoint.undraw()
score += 500
cherryRandomX = random.choice(coordX)
cherryRandomY = random.choice(coordY)
for i in range(len(player)):
if (cherryPoint.getCenter().getX() == player[i].getCenter().getX() and cherryPoint.getCenter().getY() == player[i].getCenter().getY()) or (cherryPoint.getCenter().getX() == point.getCenter().getX() and cherryPoint.getCenter().getY() == point.getCenter().getY()): # regenerate x and y coordinate if they share the same coordinate as player and point
cherryRandomX = random.choice(coordX)
cherryRandomY = random.choice(coordY)
for i in range(len(poison)): # regenerate x and y coordinate if cherry shares the same coordinate to other array of poisons
if cherryPoint.getCenter().getX() == poison[i].getCenter().getX() and cherryPoint.getCenter().getY() == poison[i].getCenter().getY():
cherryRandomX = random.choice(coordX)
cherryRandomY = random.choice(coordY)
cherryPoints = False
# poison
if poisonLength % 5 == 0: # generates a poison block each time the player size reaches the multiple of 5
poison[k] = Rectangle(Point(poisonRandomX-pointRadius,poisonRandomY-pointRadius),Point(poisonRandomX+pointRadius,poisonRandomY+pointRadius))
poison[k].setFill("green")
poison[k].setWidth(2)
poison[k].draw(win)
poisonRandomX = random.choice(coordX)
poisonRandomY = random.choice(coordY)
for i in range(len(player)):
if (poison[k].getCenter().getX() == player[i].getCenter().getX() and poison[k].getCenter().getY() == player[i].getCenter().getY()) or (poison[k].getCenter().getX() == point.getCenter().getX() and poison[k].getCenter().getY() == point.getCenter().getY()) or (cherryPoints==True and poison[k].getCenter().getX() == cherryPoint.getCenter().getX() and poison[k].getCenter().getY() == cherryPoint.getCenter().getY()): # regenerate x and y coordinate if they share the same coordinate as player and point and cherry
poisonRandomX = random.choice(coordX)
poisonRandomY = random.choice(coordY)
for i in range(len(poison)):
if poison[k].getCenter().getX() == poison[i].getCenter().getX() and poison[k].getCenter().getY() == poison[i].getCenter().getY(): # regenerate x and y coordinate if new poison shares the same coordinate to other array of poisons
poisonRandomX = random.choice(coordX)
poisonRandomY = random.choice(coordY)
bonus+=50
k+=1
poisonLength+=1
# game over requirements
for i in range(len(poison)): # if player touches poison
if player[0].getCenter().getX() == poison[i].getCenter().getX() and player[0].getCenter().getY() == poison[i].getCenter().getY():
game = False
for i in range(2, len(player)): # if player touches its own body or reach out of window
if (player[0].getCenter().getX() == player[i].getCenter().getX() and player[0].getCenter().getY() == player[i].getCenter().getY()) or x < 0 or x > width or y < 0 or y > gridHeight:
game = False
# FPS
update(10)
countDown += 1
# GAME OVER
gameOver = Text(Point(width/2,200), "GAME OVER")
gameOver.setTextColor("red")
gameOver.setSize(30)
gameOver.draw(win)
update()
time.sleep(2)
win.close()
main()
Ideally the result should replace each code in the while loop with individual classes outside of the function to reduce the amount of lines in the main() function and make the script easier to read.
Classes are essentially just bundles of code that contain various attributes and methods.
A Snake class might have a list of coordinates for each section of the body (the first is the head).
class Snake:
def __init__(self, x, y):
self.positions = [(x, y)]
def get_head(self):
return self.positions[0]
def move_forward(self):
self.positions.pop()
self.positions.insert(0, self.get_head()[1] + 1)
def move_backward(self):
self.positions.pop()
self.positions.insert(0, self.get_head()[1] - 1)
...
And so on. Classes, at this level, let you think of objects as concrete entities, distinct from each other but easily manipulated.
first time poster here.
Ill try to keep this as simple as possible. I am trying to make a game in pygame but it seems my collision detection is acting up. I have a player class that detects whether or not the player is colliding with the ground or any other objects in the environment list, and I have an enemy class that collides with anything in the same list. The enemies work out what direction they need to travel in in order to try and hit the player. There is gravity which is very likely to play a major part in the problem.
The problem is that when the 'flies' are placed in and fall to the ground, they immediately jump off screen, even though their X and Y values seem (according to logs of items on the screen) to not move at all?
As clarification, the two 'flies' are placed into a secondary list to allow for collision detection. Also, as a side note, the 'glitch' doesn't occur if there is no left and right collide detection... Thanks to anyone who can provide help :)
def collisions():
#Detection Working as intended
for fly in Fly.List:
fly_proj = pygame.sprite.spritecollide(fly, Projectile.List, True)
if len(fly_proj) > 0:
for hit in fly_proj:
fly.health -= 100
X = pygame.sprite.spritecollide(fly, current_level.object_list, False)
if len(X) == 0: #Gravity here:
if (fly.vspeed == 0):
fly.vspeed = 1
print("Gravity")
else:
fly.vspeed += 0.35
if len(X) > 1:
for hit in X:
if fly.vspeed > 0:
fly.rect.bottom = hit.rect.top +1
fly.vspeed = 0
elif fly.vspeed < 0:
fly.rect.top = hit.rect.bottom -1
elif fly.hspeed > 0:
fly.rect.right = hit.rect.left
fly.hspeed = 0
elif fly.hspeed < 0:
fly.rect.left = hit.rect.right
fly.hspeed = 0
print(len(X),framecounter, fly.vspeed, fly.hspeed)
#Kill fly if health reaches 0
if fly.health <= 0:
fly.destroy(Fly)
#Detect where the player is
if window_rect.contains(fly.rect):
fly.playersnapshot = player.rect.x
if fly.rect.x - player.rect.x >= -10:
#print("LEFTING")
fly.hspeed = -2
if fly.rect.x - player.rect.x <= 10:
fly.hspeed = 2
fly.truefalse = True
event = None
fly.rect.y += fly.vspeed
fly.rect.x += fly.hspeed
I think your if/else is incorrect.
Probably when fly touch ground you set vspeed to zero and then if/else checks hspeed and it use ground left/right to change fly left/right.
I know one method.
move fly vertically
check collision and use if/else with vspeed
move fly horizontally
check collision and use if/else with hspeed
--
EDIT:
# move horizontally only
fly.rect.x += fly.hspeed
X = pygame.sprite.spritecollide( ... )
for hit in X:
if fly.hspeed > 0:
fly.rect.right = hit.rect.left
else:
fly.rect.left = hit.rect.right
# move vertically only
fly.rect.y += fly.vspeed
X = pygame.sprite.spritecollide( ... )
for hit in X:
if fly.vspeed > 0:
fly.rect.bottom = hit.rect.top
else:
fly.rect.top = hit.rect.bottom
# on_ground = True
I found this method in source code of "Platform Jumper" on ProgramArcadeGames.com
see page with: platform_jumper.py
I have made a sonar finding game and some functions for it. I have put these functions into a class and now I want to call them so I can play the game, however when I define the class call it now returns things to me like game.getNewBoard() takes 0 positional arguments and tells me I have given it one when I have not and so on. Any help would be appreciated.
# Sonar
import random
import sys
class OceanTreasure:
def drawBoard(board):
# Draw the board data structure.
hline = ' ' # initial space for the numbers down the left side of the board
for i in range(1, 6):
hline += (' ' * 9) + str(i)
# print the numbers across the top
print(hline)
print(' ' + ('0123456789' * 6))
print()
# print each of the 15 rows
for i in range(15):
# single-digit numbers need to be padded with an extra space
if i < 10:
extraSpace = ' '
else:
extraSpace = ''
print('%s%s %s %s' % (extraSpace, i, getRow(board, i), i))
# print the numbers across the bottom
print()
print(' ' + ('0123456789' * 6))
print(hline)
def getRow(board, row):
# Return a string from the board data structure at a certain row.
boardRow = ''
for i in range(60):
boardRow += board[i][row]
return boardRow
def getNewBoard():
# Create a new 60x15 board data structure.
board = []
for x in range(60): # the main list is a list of 60 lists
board.append([])
for y in range(15): # each list in the main list has 15 single-character strings
# I thought about using different char to make it more readble?? Admit it, it looks dull with just these ~
if random.randint(0, 1) == 0:
board[x].append('~')
else:
board[x].append('~')
return board
def getRandomChests(numChests):
# Create a list of chest data structures (two-item lists of x, y int coordinates)
chests = []
for i in range(numChests):
chests.append([random.randint(0, 59), random.randint(0, 14)])
return chests
def isValidMove(x, y):
# Return True if the coordinates are on the board, otherwise False.
return x >= 0 and x <= 59 and y >= 0 and y <= 14
def makeMove(board, chests, x, y):
# Change the board data structure with a sonar device character. Remove treasure chests
# from the chests list as they are found. Return False if this is an invalid move.
# Otherwise, return the string of the result of this move.
if not isValidMove(x, y):
return False
smallestDistance = 100 # any chest will be closer than 100.
for cx, cy in chests:
if abs(cx - x) > abs(cy - y):
distance = abs(cx - x)
else:
distance = abs(cy - y)
if distance < smallestDistance: # we want the closest treasure chest.
smallestDistance = distance
if smallestDistance == 0:
# xy is directly on a treasure chest!
chests.remove([x, y])
return 'You have found a sunken treasure chest!'
else:
if smallestDistance < 10:
board[x][y] = str(smallestDistance)
return 'Treasure detected at a distance of %s from the sonar device.' % (smallestDistance)
else:
board[x][y] = 'O'
return 'Sonar did not detect anything. All treasure chests out of range.'
def enterPlayerMove():
# Let the player type in her move. Return a two-item list of int xy coordinates.
print('Where do you want to drop the next sonar device? (0-59 0-14) (or type quit)')
while True:
move = input()
if move.lower() == 'quit':
print('Thanks for playing!')
sys.exit()
move = move.split()
if len(move) == 2 and move[0].isdigit() and move[1].isdigit() and isValidMove(int(move[0]), int(move[1])):
return [int(move[0]), int(move[1])]
print('Enter a number from 0 to 59, a space, then a number from 0 to 14.')
def playAgain():
# This function returns True if the player wants to play again, otherwise it returns False.
print('Do you want to play again? (yes or no)')
return input().lower().startswith('y')
print('S O N A R !')
print()
while True:
# game setup
game=OceanTreasure()
sonarDevices = 20
theBoard = game.getNewBoard()
theChests = getRandomChests(3)
drawBoard(theBoard)
previousMoves = []
while sonarDevices > 0:
# Start of a turn:
# sonar device/chest status
if sonarDevices > 1: extraSsonar = 's'
else: extraSsonar = ''
if len(theChests) > 1: extraSchest = 's'
else: extraSchest = ''
print('You have %s sonar device%s left. %s treasure chest%s remaining.' % (sonarDevices, extraSsonar, len(theChests), extraSchest))
x, y = enterPlayerMove()
previousMoves.append([x, y]) # we must track all moves so that sonar devices can be updated.
moveResult = makeMove(theBoard, theChests, x, y)
if moveResult == False:
continue
else:
if moveResult == 'You have found a sunken treasure chest!':
# update all the sonar devices currently on the map.
for x, y in previousMoves:
makeMove(theBoard, theChests, x, y)
drawBoard(theBoard)
print(moveResult)
if len(theChests) == 0:
print('You have found all the sunken treasure chests! Congratulations and good game!')
break
sonarDevices -= 1
if sonarDevices == 0:
print('We\'ve run out of sonar devices! Now we have to turn the ship around and head')
print('for home with treasure chests still out there! Game over.')
print(' The remaining chests were here:')
for x, y in theChests:
print(' %s, %s' % (x, y))
if not playAgain():
sys.exit() #I thought this is a better way than just break or make false, correct me if I am wrong
Every class method in Python receives the instance it is called from as the first parameter automatically. That means, that the first parameter is always self:
def drawBoard(self, board):