how can i center the numbers in the two grids? - python

this is the program of the game, it contains everything but i need help to center the numbers inside the grids, i did some attempts i put them in comments, please help me
imports of my program
import numpy as np
import random
import pygame
from pygame.locals import *
constructor of the class
class Py2048:
def __init__(self):
self.N = 4
self.grid1 = np.zeros((self.N, self.N), dtype=int) #initialiasation de la grid avec des 0
self.grid2 = np.zeros((self.N, self.N), dtype=int) #initialiasation
self.cellSize = 70
self.gap = 3
self.windowBgColor = (187, 173, 160)
self.blockSize = self.cellSize + self.gap * 2
self.W = 700
self.H = self.W
pygame.init()
pygame.display.set_caption("2048")
pygame.font.init()
self.myfont = pygame.font.SysFont('Comic Sans MS', 30)
self.screen = pygame.display.set_mode((self.W, self.H))
adding a new number to the grids
def new_number(self, k=1):
free_poss1 = list(zip(*np.where(self.grid1 == 0))) #position de la grid
free_poss2 = list(zip(*np.where(self.grid2 == 0)))
for pos in random.sample(free_poss1, k=k): #random 2 ou 4
if random.random() < .1:
self.grid1[pos] = 4
else:
self.grid1[pos] = 2
for pos in random.sample(free_poss2, k=k): #random 2 ou 4
if random.random() < .1:
self.grid2[pos] = 4
else:
self.grid2[pos] = 2
#staticmethod
def _get_nums(this):
this_n = this[this != 0]
this_n_sum = []
skip = False
for j in range(len(this_n)):
if skip:
skip = False
continue
if j != len(this_n) - 1 and this_n[j] == this_n[j + 1]:
new_n = this_n[j] * 2
skip = True
else:
new_n = this_n[j]
this_n_sum.append(new_n)
return np.array(this_n_sum)
def make_move(self, move): #move
for i in range(self.N):
if move in 'lr':
this1 = self.grid1[i, :]
this2 = self.grid2[i, :]
else:
this1 = self.grid1[:, i]
this2 = self.grid2[:, i]
flipped = False
if move in 'rd':
flipped = True
this1 = this1[::-1]
this2 = this2[::-1]
this_n1 = self._get_nums(this1)
this_n2 = self._get_nums(this2)
new_this1 = np.zeros_like(this1)
new_this1[:len(this_n1)] = this_n1
new_this2 = np.zeros_like(this2)
new_this2[:len(this_n2)] = this_n2
if flipped:
new_this1 = new_this1[::-1]
new_this2 = new_this2[::-1]
if move in 'lr':
self.grid1[i, :] = new_this1
self.grid2[i, :] = new_this2
else:
self.grid1[:, i] = new_this1
self.grid2[:, i] = new_this2
this is where i have the problem, when i draw the two grids i dont know how to center the numbers in them
def draw_game(self):
self.screen.fill(self.windowBgColor)
for i in range(self.N):
rectY = self.blockSize * i + self.gap
for j in range(self.N):
n1 = self.grid1[i][j]
n2 = self.grid2[i][j]
rectX = 200 + self.blockSize * j + self.gap
pygame.draw.rect(
self.screen,
(255, 255, 255),
pygame.Rect(rectX, 40 + rectY, self.cellSize, self.cellSize),
border_radius = 6
)
pygame.draw.rect(
self.screen,
(255, 255, 255),
pygame.Rect(rectX, 360 + rectY, self.cellSize, self.cellSize),
border_radius = 6
)
if n1 == 0 and n2 == 0:
continue
text_surface1 = self.myfont.render(f'{n1}', True, (0, 0, 0))
text_rect1 = text_surface1.get_rect(center=(rectX ,
rectY ))
self.screen.blit(text_surface1, text_rect1)
# text_surface2 = self.myfont.render(f'{n2}', True, (0, 0, 0))
# text_rect2 = text_surface2.get_rect(center=(rectX ,
# 360 + rectY ))
# self.screen.blit(text_surface2, text_rect2)
#staticmethod
def wait_for_key():
while True:
for event in pygame.event.get():
if event.type == QUIT:
return 'q'
if event.type == KEYDOWN:
if event.key == K_UP:
return 'u'
elif event.key == K_RIGHT:
return 'r'
elif event.key == K_LEFT:
return 'l'
elif event.key == K_DOWN:
return 'd'
elif event.key == K_q or event.key == K_ESCAPE:
return 'q'
def play(self):
self.new_number(k=2)
while True:
self.draw_game()
pygame.display.flip()
cmd = self.wait_for_key()
if cmd == 'q':
break
old_grid1 = self.grid1.copy()
old_grid2 = self.grid2.copy()
self.make_move(cmd)
print(game.grid1)
print(game.grid2)
if all((self.grid1 == old_grid1).flatten()) and all((self.grid2 == old_grid2).flatten()):
continue
self.new_number()
if __name__ == '__main__':
game = Py2048()
game.play()
this is the main code for the modified 2048 game that i wanna create

See How to Center Text in Pygame. When calculating the text rectangle, the center of the text rectangle must be set by the center of the grid. Store the tile rectangle in a variable and use it to set the center of the text rectangle:
for i in range(self.N):
rectY = self.blockSize * i + self.gap
for j in range(self.N):
n1 = self.grid1[i][j]
n2 = self.grid2[i][j]
rectX = 200 + self.blockSize * j + self.gap
tile_rect1 = pygame.Rect(rectX, 40 + rectY, self.cellSize, self.cellSize)
pygame.draw.rect(self.screen, (255, 255, 255), tile_rect1, border_radius = 6)
tile_rect2 = pygame.Rect(rectX, 360 + rectY, self.cellSize, self.cellSize),
pygame.draw.rect(self.screen, (255, 255, 255), tile_rect2, border_radius = 6)
if n1 == 0 and n2 == 0:
continue
text_surface1 = self.myfont.render(f'{n1}', True, (0, 0, 0))
text_rect1 = text_surface1.get_rect(center = tile_rect1.center)
self.screen.blit(text_surface1, text_rect1)
text_surface2 = self.myfont.render(f'{n2}', True, (0, 0, 0))
text_rect2 = text_surface2.get_rect(center = tile_rect2.center)
self.screen.blit(text_surface2, text_rect2)

Related

Mapping Grid Position To Matrix Position

I needed help, I was trying to map the position of a ghost in its current position such as (225, 175) to its position on the matrix (7,9), not sure what the math is to calculate its relative position, the reason why im asking is because it makes it easier to detect if theres a wall in matrix position as opposed to current position. I want to be able to do this so I can decide its next move at an intersection.
import pygame
import time
import random
import pickle
import math
pygame.init()
pygame.mixer.init()
pygame.display.set_caption("Pac-Man")
# Sets the size of the screen via (WIDTH, HEIGHT)
SCREEN_WIDTH = 478
SCREEN_HEIGHT = 608
# Speed of Characters
SPEED = 1
# Frames per second, how fast the game runs
FPS = 50
# Colors (RED,GREEN,BLUE)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
YELLOW = (255, 255, 0)
BLUE = (0, 0, 255)
# Sets the WIDTH and HEIGHT of the window
WINDOW = (SCREEN_WIDTH, SCREEN_HEIGHT)
# Displays the screen
SCREEN = pygame.display.set_mode(WINDOW)
CLOCK = pygame.time.Clock()
PacManStartSurface = pygame.transform.scale(pygame.image.load
("PacManStart.png"), (23, 23))
PacManStartSurface.convert()
PacManStartRect = PacManStartSurface.get_rect(topleft =
(((SCREEN_WIDTH - 25) // 2),
(SCREEN_HEIGHT + 144) // 2))
PacManSurface = pygame.transform.scale(pygame.image.load
("PacManRight.png"), (23, 23))
PacManSurface.convert()
PacManRect = PacManStartSurface.get_rect(topleft =
(((SCREEN_WIDTH - 125) // 2),
(SCREEN_HEIGHT + 144) // 2))
CurrentSurface = PacManStartSurface
CurrentRect = PacManStartRect
BackgroundSurface = pygame.image.load("Background.png").convert()
PinkGhostSurface = pygame.transform.scale(pygame.image.load("PinkGhost.png")
.convert(), (23, 23))
PinkGhostRect = PinkGhostSurface.get_rect()
YellowGhostSurface = pygame.transform.scale(pygame.image.load
("YellowGhost.png")
.convert(), (23, 23))
YellowGhostRect = YellowGhostSurface.get_rect()
RedGhostSurface = pygame.transform.scale(pygame.image.load("RedGhost.png")
.convert(), (23, 23))
RedGhostRect = RedGhostSurface.get_rect()
BlueGhostSurface = pygame.transform.scale(pygame.image.load("BlueGhost.png")
.convert(), (23, 23))
BlueGhostRect = BlueGhostSurface.get_rect()
pygame.mixer.music.load('power_pellet.wav')
Font = pygame.font.Font("emulogic.ttf", 15)
class PacMan():
def __init__(self):
self.LIVES = 3
class Maze():
def __init__(self):
self.DOTS = []
self.WALLS = []
self.ENERGIZER = []
self.GHOSTS = []
self.WALLS_XY = []
self.BLOCK_WIDTH = 25
self.BLOCK_HEIGHT = 25
self.MAZE_OFFSET_X = 0
self.MAZE_OFFSET_Y = 50
# 0 - Dots
# 1 - Walls
# 2 - Empty Spaces
# 3 - Energizers
# 4 - Ghosts
self.MATRIX = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], \
[1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1], \
[1,3,1,1,0,1,1,1,0,1,0,1,1,1,0,1,1,3,1], \
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], \
[1,0,1,1,0,1,0,1,1,1,1,1,0,1,0,1,1,0,1], \
[1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,1], \
[1,1,1,1,0,1,1,1,2,1,2,1,1,1,0,1,1,1,1], \
[2,2,2,1,0,1,2,2,2,4,2,2,2,1,0,1,2,2,2], \
[1,1,1,1,0,1,2,1,1,1,1,1,2,1,0,1,1,1,1], \
[0,0,0,0,0,2,2,1,4,4,4,1,2,2,0,0,0,0,0], \
[1,1,1,1,0,1,2,1,1,1,1,1,2,1,0,1,1,1,1], \
[2,2,2,1,0,1,2,2,2,2,2,2,2,1,0,1,2,2,2], \
[1,1,1,1,0,1,2,1,1,1,1,1,2,1,0,1,1,1,1], \
[1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1], \
[1,3,1,1,0,1,1,1,0,1,0,1,1,1,0,1,1,3,1], \
[1,0,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,0,1], \
[1,1,0,1,0,1,0,1,1,1,1,1,0,1,0,1,0,1,1], \
[1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,1], \
[1,0,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,0,1], \
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], \
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
# BackgroundImage(X, Y, WIDTH, HEIGHT)
self.MAZE_X = self.BLOCK_WIDTH * (len(self.MATRIX[0])
+ self.MAZE_OFFSET_X)
self.MAZE_Y = self.BLOCK_HEIGHT * (len(self.MATRIX)
+ self.MAZE_OFFSET_Y)
self.MAZE_WIDTH = self.BLOCK_WIDTH * len(self.MATRIX[0])
self.MAZE_HEIGHT = self.BLOCK_HEIGHT * len(self.MATRIX)
def DrawMaze(self, MazeSurface):
for ROW in range(len(self.MATRIX)):
for COLUMN in range(len(self.MATRIX[0])):
# Saves the position of each dot
if self.MATRIX[ROW][COLUMN] == 0:
self.DOTS.append([(self.BLOCK_WIDTH * COLUMN),
(self.BLOCK_HEIGHT * ROW), 4, 4])
# Saves the position of each wall
if self.MATRIX[ROW][COLUMN] == 1:
self.WALLS.append(pygame.draw.rect(MazeSurface, WHITE,
[((self.BLOCK_WIDTH) * COLUMN),
((self.BLOCK_HEIGHT) * ROW),
self.BLOCK_WIDTH, self.BLOCK_HEIGHT]))
# Saves the position of each Energizer
if self.MATRIX[ROW][COLUMN] == 3:
self.ENERGIZER.append([(self.BLOCK_WIDTH * COLUMN),
(self.BLOCK_HEIGHT * ROW), 14, 14])
if self.MATRIX[ROW][COLUMN] == 4:
self.GHOSTS.append([(self.BLOCK_WIDTH * COLUMN),
(self.BLOCK_HEIGHT * ROW), 23, 23])
for WALL in self.WALLS:
X, Y, WIDTH, HEIGHT = WALL
self.WALLS_XY.append((X, Y))
class Main(Maze):
def __init__(self):
# Inherits Maze class
Maze.__init__(self)
self.TimeBetweenBites = 0.1
self.LastBiteTime = time.time()
self.MouthOpen = False
self.PacManDirection = ""
self.GhostDirection = ""
self.SCORE = 0
self.HIGH_SCORE = 0
self.GridSizeX = SCREEN_HEIGHT // 19
self.GridSizeY = SCREEN_HEIGHT // 32
def PacManMovement(self):
key = pygame.key.get_pressed()
if key[pygame.K_LEFT] and not key[pygame.K_UP] \
and not key[pygame.K_DOWN]:
self.PacManDirection = "LEFT"
elif key[pygame.K_RIGHT] and not key[pygame.K_UP] \
and not key[pygame.K_DOWN]:
self.PacManDirection = "RIGHT"
elif key[pygame.K_UP] and not key[pygame.K_LEFT] \
and not key[pygame.K_RIGHT]:
self.PacManDirection = "UP"
elif key[pygame.K_DOWN] and not key[pygame.K_LEFT] \
and not key[pygame.K_RIGHT]:
self.PacManDirection = "DOWN"
def ContinuePacManMovement(self):
if self.PacManDirection == "LEFT":
CurrentRect.x -= SPEED
self.PacManWallDetection(-1, 0, CurrentRect)
if self.PacManDirection == "RIGHT":
CurrentRect.x += SPEED
self.PacManWallDetection(1, 0, CurrentRect)
if self.PacManDirection == "UP":
CurrentRect.y -= SPEED
self.PacManWallDetection(0, -1, CurrentRect)
if self.PacManDirection == "DOWN":
CurrentRect.y += SPEED
self.PacManWallDetection(0, 1, CurrentRect)
def ContinueGhostMovement(self):
if self.GhostDirection == "LEFT":
PinkGhostRect.x -= SPEED
self.GhostWallDetection(-1, 0, PinkGhostRect)
if self.GhostDirection == "RIGHT":
PinkGhostRect.x += SPEED
self.GhostWallDetection(1, 0, PinkGhostRect)
if self.GhostDirection == "UP":
PinkGhostRect.y -= SPEED
self.GhostWallDetection(0, -1, PinkGhostRect)
if self.GhostDirection == "DOWN":
PinkGhostRect.y += SPEED
self.GhostWallDetection(-1, 0, PinkGhostRect)
def PacManTeleport(self):
if CurrentRect.right < 0:
CurrentRect.right = SCREEN_WIDTH + 20
if CurrentRect.left > SCREEN_WIDTH:
CurrentRect.right = 0
def GhostTeleport(self, Intersection):
if PinkGhostRect.right < 0:
PinkGhostRect.right = SCREEN_WIDTH + 20
Intersection.append("LEFT")
if PinkGhostRect.left > SCREEN_WIDTH:
PinkGhostRect.right = 0
Intersection.append("RIGHT")
def PacManWallDetection(self, x, y, CurrentRect):
CurrentRect.right += x
for WALL in self.WALLS:
COLLIDE = CurrentRect.colliderect(WALL)
if COLLIDE:
if x < 0:
CurrentRect.left = WALL.right
CurrentSurface = pygame.transform.rotate(PacManSurface, 180)
MazeSurface.blit(CurrentSurface, CurrentRect)
if x > 0:
CurrentRect.right = WALL.left
break
CurrentRect.top += y
for WALL in self.WALLS:
COLLIDE = CurrentRect.colliderect(WALL)
if COLLIDE:
if y < 0:
CurrentRect.top = WALL.bottom
if y > 0:
CurrentRect.bottom = WALL.top
break
def GhostWallDetection(self, x, y, PinkGhostRect):
PinkGhostRect.right += x
for WALL in self.WALLS:
COLLIDE = PinkGhostRect.colliderect(WALL)
if COLLIDE:
if x < 0:
PinkGhostRect.left = WALL.right
if random.randrange(0, 100) <= 40:
self.GhostDirection = "RIGHT"
if x > 0:
PinkGhostRect.right = WALL.left
if random.randrange(0, 100) <= 40:
self.GhostDirection = "LEFT"
break
PinkGhostRect.top += y
for WALL in self.WALLS:
COLLIDE = PinkGhostRect.colliderect(WALL)
if COLLIDE:
if y < 0:
PinkGhostRect.top = WALL.bottom
if random.randrange(0, 100) <= 40:
self.GhostDirection = "DOWN"
if y > 0:
PinkGhostRect.bottom = WALL.top
if random.randrange(0, 100) <= 40:
self.GhostDirection = "UP"
break
def GetAvailableMoves(self):
Intersection = []
self.GhostTeleport(Intersection)
print(PinkGhostRect.topleft)
print(self.WALLS_XY)
if ((PinkGhostRect.x - 1, PinkGhostRect.y)) not in self.WALLS_XY:
Intersection.append("LEFT")
if ((PinkGhostRect.x + 1, PinkGhostRect.y)) not in self.WALLS_XY:
Intersection.append("RIGHT")
if ((PinkGhostRect.x, PinkGhostRect.y - 1)) not in self.WALLS_XY:
Intersection.append("UP")
if ((PinkGhostRect.x, PinkGhostRect.y + 1)) not in self.WALLS_XY:
Intersection.append("DOWN")
print(Intersection)
return Intersection
def EatDots(self):
for ROW in range(len(self.MATRIX)):
for COLUMN in range(len(self.MATRIX[0])):
for DOT in self.DOTS:
CHOMP = CurrentRect.colliderect(DOT)
if CHOMP:
Main.PlaySound(self, 0)
self.DOTS.remove(DOT)
self.MATRIX[ROW][COLUMN] = 3
self.SCORE += 10
if self.SCORE > self.HIGH_SCORE:
self.HIGH_SCORE = self.SCORE
return str(self.SCORE), str(self.HIGH_SCORE)
def EatEnergizer(self):
for ROW in range(len(self.MATRIX)):
for COLUMN in range(len(self.MATRIX[0])):
for POWERUP in self.ENERGIZER:
CHOMP = CurrentRect.colliderect(POWERUP)
if CHOMP:
self.ENERGIZER.remove(POWERUP)
self.MATRIX[ROW][COLUMN] = 3
self.SCORE += 50
Main.PlaySound(self, 1)
if self.SCORE > self.HIGH_SCORE:
self.HIGH_SCORE = self.SCORE
return str(self.SCORE), str(self.HIGH_SCORE)
def EatGhosts(self):
pass
def DrawDots(self):
for POSITION in self.DOTS:
X = POSITION[0] + 13
Y = POSITION[1] + 13
WIDTH = POSITION[2]
HEIGHT = POSITION[3]
pygame.draw.circle(MazeSurface, YELLOW, (X, Y),
WIDTH // 2, HEIGHT // 2)
def DrawEnergizer(self):
for POSITION in self.ENERGIZER:
X = POSITION[0] + 13
Y = POSITION[1] + 13
WIDTH = POSITION[2]
HEIGHT = POSITION[3]
pygame.draw.circle(MazeSurface, YELLOW, (X, Y),
WIDTH // 2, HEIGHT // 2)
def DrawGhosts(self):
MazeSurface.blit(PinkGhostSurface, PinkGhostRect)
MazeSurface.blit(YellowGhostSurface, YellowGhostRect)
MazeSurface.blit(RedGhostSurface, RedGhostRect)
MazeSurface.blit(BlueGhostSurface, BlueGhostRect)
def GhostStartPosition(self):
X, Y, WIDTH, HEIGHT = self.GHOSTS[0]
PinkGhostRect.x = X
PinkGhostRect.y = Y
X, Y, WIDTH, HEIGHT = self.GHOSTS[1]
YellowGhostRect.x = X
YellowGhostRect.y = Y
X, Y, WIDTH, HEIGHT = self.GHOSTS[2]
RedGhostRect.x = X
RedGhostRect.y = Y
X, Y, WIDTH, HEIGHT = self.GHOSTS[3]
BlueGhostRect.x = X
BlueGhostRect.y = Y
def PlaySound(self, Track):
if Track == 0:
Eat = pygame.mixer.Sound("pacman_chomp.wav")
Eat.play()
pygame.mixer.fadeout(400)
if Track == 1:
EatPellet = pygame.mixer.Sound("pacman_eatghost.wav")
EatPellet.play()
pygame.mixer.music.play(7)
pygame.mixer.fadeout(400)
def ShowScore(self):
global Font
OneUpText = Font.render("1UP", True, WHITE)
OneUpTextRect = OneUpText.get_rect(center = (70, 10))
# Displays current score
OneUpScoreText = Font.render(str(self.SCORE), True, WHITE)
OneUpScoreRect = OneUpScoreText.get_rect(center =
((SCREEN_WIDTH - 290)
// 2, 26))
HighScoreText = Font.render("High Score", True, WHITE)
HighScoreTextRect = HighScoreText.get_rect(center =
(SCREEN_WIDTH // 2, 10))
# Displays High Score
HighScoreNumber = Font.render(str(self.HIGH_SCORE), True, WHITE)
HighScoreNumberRect = HighScoreNumber.get_rect(center =
((SCREEN_WIDTH + 90)
// 2, 26))
SCREEN.blit(OneUpText, OneUpTextRect)
SCREEN.blit(OneUpScoreText, OneUpScoreRect)
SCREEN.blit(HighScoreText, HighScoreTextRect)
SCREEN.blit(HighScoreNumber, HighScoreNumberRect)
def PacManBite(self):
global CurrentSurface
CurrentTime = time.time()
if CurrentTime - self.LastBiteTime >= self.TimeBetweenBites:
self.LastBiteTime = CurrentTime
if self.MouthOpen:
CurrentSurface = PacManStartSurface
else:
CurrentSurface = PacManSurface
self.MouthOpen = not self.MouthOpen
if self.PacManDirection == "LEFT":
CurrentSurface = pygame.transform.rotate(CurrentSurface, 180)
if self.PacManDirection == "RIGHT":
CurrentSurface = CurrentSurface
if self.PacManDirection == "UP":
CurrentSurface = pygame.transform.rotate(CurrentSurface, 90)
if self.PacManDirection == "DOWN":
CurrentSurface = pygame.transform.rotate(CurrentSurface, 270)
def PacManLives(self):
pass
def Update(self):
Player.PacManTeleport()
Player.ContinuePacManMovement()
Player.ContinueGhostMovement()
Player.GetAvailableMoves()
MazeSurface.blit(BackgroundSurface, BackgroundRect)
Player.DrawDots()
Player.DrawEnergizer()
Player.DrawGhosts()
Player.EatDots()
Player.EatEnergizer()
MazeSurface.blit(CurrentSurface, CurrentRect)
Player.PacManBite()
SCREEN.blit(MazeSurface, MazeRect)
Player.ShowScore()
Player = Main()
BackgroundSurface = pygame.transform.scale(BackgroundSurface,
(Player.MAZE_WIDTH,
Player.MAZE_HEIGHT))
BackgroundRect = BackgroundSurface.get_rect()
MazeSurface = pygame.Surface((Player.MAZE_WIDTH, Player.MAZE_HEIGHT))
MazeRect = MazeSurface.get_rect(topleft = (Player.MAZE_OFFSET_X,
Player.MAZE_OFFSET_Y))
Player.DrawMaze(MazeSurface)
Player.GhostStartPosition()
'''
Before the game starts ...
pregame = True
while pregame:
if key button pressed:
pregame = False
run = True
'''
run = True
while run:
SCREEN.fill(BLACK)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
Player.PacManMovement()
Player.Update()
pygame.display.update()
CLOCK.tick(FPS)
pygame.quit()
You just need to divide the position in the grid by the size of a tile with the // (floor-division) operator:
pos_in_maze = (225, 175)
column = pos_in_maze[0] // Player.BLOCK_WIDTH
row = pos_in_maze[1] // Player.BLOCK_HEIGHT
Since the size of a tile is 25 the results are 9 for the column and 7 for the row.
screen_pos = (225, 175)
column = (screen_pos[0] - Player.MAZE_OFFSET_X) // Player.BLOCK_WIDTH
row = (screen_pos[1] - Player.MAZE_OFFSET_Y) // Player.BLOCK_HEIGHT
Since MAZE_OFFSET_X is 0 and MAZE_OFFSET_Y is 50 the results are 9 for the column and 5 for the row.

I need help troubelshotting why my buttons arent being detected properly

My game is a simple slot game that's based around a numpy grid system and is played with left click to spin and r to reset the board. Im trying to implement a point system to make it more exciting but i cant get the code to detect when im clicking the buttons correctly.
The part of the code that seems to be malfunctioning is the posCheckRight and posCheckLeft functions (close to the bottom part of the code, row 160 - 184). They work correctly sometimes but more than often not, to replicate my issues try clicking nearby the buttons and check the inputs
import pygame as pg
import sys
import numpy as np
import random as rand
pg.init()
width = 800
height = 800
lineWidth = 15
winLineWidth = 15
boardRows = 4
boardCols = 4
squareSize = 200
space = 55
windowName = "Slots"
windowNameInt = 0
cost = 50
costtxt = "Cost: {}".format(cost)
fontClr = (255,99,71)
player = 1
game_over = False
posCheckLvlR = 0
posCheckLvlL = 0
bgColor = (200, 200, 0)
lineColor = (0, 0, 180)
triangleColor = (255, 0, 0)
winLineColor = (220, 220, 220)
circleColor = (239, 231, 200)
crossColor = (66, 66, 66)
screen = pg.display.set_mode((width, height))
pg.display.set_caption(windowName)
screen.fill(bgColor)
board = np.zeros((boardRows, boardCols))
def drawLines() :
#Line 1 vert
pg.draw.line(screen, lineColor, (0, squareSize), (width, squareSize), lineWidth)
#Line 2 vert
pg.draw.line(screen, lineColor, (0, 2 * squareSize), (width, 2 * squareSize), lineWidth)
#Line 3 vert
pg.draw.line(screen, lineColor, (0, 3 * squareSize), (width, 3 * squareSize), lineWidth)
#Line 1 hori
pg.draw.line(screen, lineColor, (squareSize, 0), (squareSize, height), lineWidth)
#Line 2 hori
pg.draw.line(screen, lineColor, (2 * squareSize, 0), (2 * squareSize, height), lineWidth)
#Line 3 hori
pg.draw.line(screen, lineColor, (3 * squareSize, 0), (3 * squareSize, height - 60), lineWidth)
def drawPointSyst() :
#(rightest point)(top point)(bottom point)
pg.draw.polygon(screen, (triangleColor), ((790, 760), (760, 730), (760, 790)))
#(leftest point)(top point)(bottom point)
pg.draw.polygon(screen, (triangleColor), ((720, 760), (750, 730), (750, 790)))
#temp square
pg.draw.rect(screen, (triangleColor), (720, 730, 30, 60))
pg.draw.rect(screen, (triangleColor), (760, 730, 30, 60))
myFont = pg.font.SysFont(None, 50)
textSurface = myFont.render(costtxt, True, (fontClr))
#(x,y)
screen.blit(textSurface, (560, 750))
snake1 = pg.image.load("snake.png")
snake2 = pg.image.load("blackSnake.png")
def drawShapes():
for row in range(boardRows):
for col in range(boardCols):
if board[row][col] == 1:
screen.blit(snake2, (int( col * squareSize + squareSize//2 - 32), int( row * squareSize + squareSize//2 - 32)))
elif board[row][col] == 2:
screen.blit(snake1, (int( col * squareSize + squareSize//2 - 32), int( row * squareSize + squareSize//2 - 32)))
def markSquare(row, col):
shape = rand.randint(1,2)
board[row][col] = shape
def freeSquare(row, col):
return board[row][col] == 0
def boardCheck():
for row in range(boardRows):
for col in range(boardCols):
if board[row][col] == 0:
return False
return True
def checkWin(player):
global windowNameInt
#All vertical
for col in range(boardCols):
if board[0][col] == player and board[1][col] == player and board[2][col] == player and board[3][col] == player:
vertWinLine(col)
windowNameInt += 1
#All horizontal
for row in range(boardRows):
if board[row][0] == player and board[row][1] == player and board[row][2] == player and board[row][3] == player:
horiWinLine(row)
windowNameInt += 1
#From bottom right to top left
if board[3][0] == player and board[2][1] == player and board[1][2] == player and board[0][3] == player:
drawAscDiagonal()
windowNameInt += 1
#From top left to bottom right
if board[0][0] == player and board[1][1] == player and board[2][2] == player and board[3][3] == player:
drawDescDiagonal()
windowNameInt += 1
def vertWinLine(col):
posX = col * squareSize + squareSize//2
color = winLineColor
pg.draw.line(screen, color, (posX, 15), (posX, height - 15), lineWidth)
# print("verti win")
def horiWinLine(row):
posY = row * squareSize + squareSize//2
color = winLineColor
pg.draw.line(screen, color, (15, posY), (width - 15, posY), winLineWidth)
# print("hori win")
def drawAscDiagonal():
color = winLineColor
pg.draw.line(screen, color, (15, height - 15), (width - 15, 15), winLineWidth)
# print("asc win")
def drawDescDiagonal():
color = winLineColor
pg.draw.line(screen, color, (15, 15), (width - 15, height - 15), winLineWidth)
# print("diag win")
def restart():
screen.fill(bgColor)
drawLines()
drawPointSyst()
windowName = (str(windowNameInt))
pg.display.set_caption(windowName)
for row in range(boardRows):
for col in range(boardCols):
board[row][col] = 0
drawLines()
drawPointSyst()
def posCheckLeft(pos) :
global posCheckLvlL
for x in pos :
if posCheckLvlL % 2 == 0 :
if x > 720 and x < 750 :
posCheckLvlL += 1
pass
elif posCheckLvlL % 2 == 1 :
if x > 730 and x < 790 :
posCheckLvlL += 1
return True
return False
def posCheckRight(pos) :
global posCheckLvlR
for x in pos :
if posCheckLvlR % 2 == 0 :
if x > 760 and x < 790 :
posCheckLvlR += 1
pass
elif posCheckLvlR % 2 == 1 :
if x > 730 and x < 790 :
posCheckLvlR += 1
return True
return False
def game() :
for event in pg.event.get():
if event.type == pg.QUIT:
sys.exit()
if event.type == pg.MOUSEBUTTONDOWN:
pos = pg.mouse.get_pos()
print(pos)
if posCheckLeft(pos) :
print("left")
if posCheckRight(pos) :
print("right")
while not boardCheck() :
randMouseX = rand.randint(0, width - 1)
randMouseY = rand.randint(0, height - 1)
clickedRow = int(randMouseY // squareSize)
clickedCol = int(randMouseX // squareSize)
# print("Click ", pos, "Grid coordinates: ", clickedRow, clickedCol)
if freeSquare(clickedRow, clickedCol) :
markSquare(clickedRow, clickedCol)
drawShapes()
checkWin(1)
checkWin(2)
if event.type == pg.KEYDOWN:
if event.key == pg.K_r:
restart()
pg.display.update()
while True: game()
If you need to check the (x,y) position of the clicks, then you just need to check x and y. I believe this does what you want:
def posCheckLeft(pos) :
x,y = pos
return 720 < x < 750 and 730 < y < 790
def posCheckRight(pos) :
x,y = pos
return 760 < x < 790 and 730 < y < 790

Sliding image puzzle game - image not centered when game window is resized

I am working on a sliding puzzle game, but when I adjust the game window of the game the image with tiles is stock on the left side and it cannot go with center. I borrowed this code from GitHub. I am new with python and starting to explore new things. I want to learn more in python and thank you in advance. These are the codes:
import pygame as pg
import os.path
import random
import sys
class PuzzlerGame():
def init(self):
global BASICFONT
window_width = 1380
# window_width =700
window_height = 770
self.tile_width = 150
# self.tile_width = 75
self.tile_height = 150
# self.tile_height = 75
self.coloumn = 4
self.rows = 4
self.img_list = [0, "image1.jpg", "image2.jpg", "image3.jpg", "image4.jpg",
"image5.jpg", "image6.jpg", "image7.jpg", "image8.jpg",
"image9.jpg", "image10.jpg", ]
self.empty_tile = (3, 3)
global emptyc, emptyr
emptyc, emptyr = 3, 3
self.color = (255, 130, 130)
# white = (215,215,215)
self.yellow = (255, 255, 0)
self.red = (200, 15, 15)
self.black = (0, 0, 0)
self.tiles = {}
pg.init()
self.gameWindow = pg.display.set_mode((window_width, window_height))
# pg.display.set_caption("Puzzler")
pg.display.set_caption("Fun City slide puzzle")
# self.gameWindow.fill(white)
self.gameWindow.fill(self.red)
pg.display.update()
if (os.path.isfile('level.txt')):
lfile = open('level.txt', 'r')
# print(storefile)
self.level = int(lfile.read())
# self.level=str(lfile.read())
# print(self.highscore)
lfile.close()
else:
self.level = 1
# self.intro()
self.start(1)
def message(self, v1, u1, text):
rect_w = 70
rect_h = 70
font = pg.font.SysFont('comicsansms', 25)
TextSurf = font.render(text, True, self.black)
TextRect = TextSurf.get_rect()
TextRect.center = ((v1 * rect_w + ((rect_w - 3) / 2)),
(u1 * rect_h + (rect_h / 2)))
self.gameWindow.blit(TextSurf, TextRect)
pg.display.update()
def buttons(self, text):
# rect_w = 70
rect_w = 180
# rect_h = 70
rect_h = 180
color = self.color
# additional button
mouse_pos = pg.mouse.get_pos()
click = pg.mouse.get_pressed()
if (self.v * rect_w + rect_w - 3 > mouse_pos[0] > self.v * rect_w
and self.u * rect_h + rect_h - 3 > mouse_pos[1] > self.u * rect_h):
if int(text) <= self.level:
# if str(text)<=self.level:
color = (255, 30, 30)
if click[0] == 1:
self.start(int(text))
else:
pass
pg.draw.rect(self.gameWindow, color, [self.v * rect_w, self.u * rect_h,
rect_w - 100, rect_h - 3])
self.message(self.v, self.u, text)
# self.message(text)
pg.display.update()
def intro(self):
# additional for button
# NEW_SURF, NEW_RECT = self.makeText("New game", self.yellow, window_width - 120, window_height - 90)
while True:
self.v = 4
self.u = 5
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
sys.exit()
for rec in range(1, 2): # Level Number showing
# self.labels(300, 430, "Tap to Start", (0, 0, 255))
# self.buttons(str(rec))
# self.labels()
# self.message(self.v,self.u,str(rec))
self.v += 1
if self.v == 8:
self.v = 4
self.u += 1
#############################################################################
def labels(self, v1, u1, text, color, size=20):
font = pg.font.SysFont('comicsansms', size)
TextSurf = font.render(text, True, color)
TextRect = TextSurf.get_rect()
# print(TextRect)
TextRect.center = (v1, u1)
self.gameWindow.blit(TextSurf, TextRect)
pg.display.update()
def check(self):
global game_over
j, k = 0, 0
tag_list = []
for i in range(1, 17):
# print("checking ",i,tiles[(j,k)])
tag = "tag" + str(i)
# print(tag,j,k)
if self.tiles[(j, k)][1] == tag:
tag_list.append(tag)
j += 1
if j > 3:
k += 1
j = 0
else:
break
if i == 16:
print("GAME FINISHED")
game_over = True
def shift(self, c, r):
global emptyc, emptyr
rect_color = (255, 255, 255) # the square for suffling
# rect_color = (0,0,0)
self.gameWindow.blit(
self.tiles[(c, r)][0],
(emptyc * self.tile_width, emptyr * self.tile_height))
'''pg.draw.rect(gameWindow,black,[c*tile_width,r*tile_height,
tile_width-1,tile_height-1])'''
self.gameWindow.blit(
self.tiles[self.empty_tile][0],
(c * self.tile_width, r * self.tile_height))
# state[(emptyc, emptyr)] = state[(c, r)]
# state[(c, r)] = empty_tile
temp = self.tiles[(c, r)]
# print(temp,c,r)
self.tiles[(c, r)] = self.tiles[(emptyc, emptyr)]
self.tiles[(emptyc, emptyr)] = temp
emptyc, emptyr = c, r
# tiles[(emptyc, emptyr)].fill(black)
pg.draw.rect(self.gameWindow, rect_color, [c * self.tile_width, r * self.tile_height,
self.tile_width - 1, self.tile_height - 1])
self.empty_tile = (emptyc, emptyr)
# empty_tile.fill(0,0,0)
pg.display.flip()
def shuffle(self):
global emptyc, emptyr
# keep track of last shuffling direction to avoid "undo" shuffle moves
last_r = 0
for i in range(100):
# slow down shuffling for visual effect
pg.time.delay(50)
while True:
# pick a random direction and make a shuffling move
# if that is possible in that direction
r = random.randint(1, 4)
if (last_r + r == 5):
# don't undo the last shuffling move
continue
if r == 1 and (emptyc > 0):
self.shift(emptyc - 1, emptyr) # shift left
elif r == 4 and (emptyc < self.coloumn - 1):
self.shift(emptyc + 1, emptyr) # shift right
elif r == 2 and (emptyr > 0):
self.shift(emptyc, emptyr - 1) # shift up
elif r == 3 and (emptyr < self.rows - 1):
self.shift(emptyc, emptyr + 1) # shift down
else:
# the random shuffle move didn't fit in that direction
continue
last_r = r
break # a shuffling move was made
def start(self, l):
f = 1
imageX = 350
imageY = 50
global level, game_over
game_over = False
level = l
img = self.img_list[level]
self.image = pg.image.load("./Res/" + img)
button = pg.image.load("./efx/" + "button.jpg")
self.button = pg.image.load("./efx/" + "button.jpg")
self.gameWindow.fill((190, 190, 190)) # color of the window
for r in range(self.coloumn):
for c in range(self.rows):
tag = "tag" + str(f)
tile = self.image.subsurface(c * self.tile_width, r * self.tile_height,
self.tile_width - 1, self.tile_height - 1)
f += 1
self.tiles[(c, r)] = (tile, tag)
if (c, r) == self.empty_tile:
pg.draw.rect(self.gameWindow, (255, 255, 255),
# pg.draw.rect(self.gameWindow,(260,260,260),
[c * self.tile_width, r * self.tile_height,
self.tile_width - 1, self.tile_height - 1])#width and height of the white tile
break
self.gameWindow.blit(tile, (c * self.tile_width, r * self.tile_height)) # uploading the image through the window
#self.gameWindow.blit(tile,(imageX,imageY))
pg.display.update()
# print(tile)
# print(tiles)
# text = "Level "+str(level)
text = "Have fun!"
self.labels(350, 625, text, (0, 0, 255))
# self.labels(300,625,"Click to start Game",(0,0,255))
self.labels(700, 300, "Tap to start Game", (0, 0, 255))
self.gameWindow.blit(button, (640, 180))
pg.display.update()
self.gameloop()
def gameloop(self):
started = False
show_sol = False
global level
# self.gameWindow.fill((190,190,190),(150,610,300,40))
while True:
if game_over:
self.labels(300, 300, "Good job well played", (255, 100, 30), 50)
# self.labels(300,625,"Click to next Level",(0,0,255))
for event in pg.event.get():
# print(event)
if event.type == pg.QUIT:
pg.quit()
sys.exit()
if event.type == pg.MOUSEBUTTONDOWN:
# print(event.type)
# print(event.dict)
# shuffle()
if not started:
self.shuffle()
self.gameWindow.fill((190, 190, 190), (150, 610, 300, 40))
# self.labels(300,625,"Right click to see Solution",(0,0,255))
started = True
if game_over:
level += 1
# self.labels(300,300,"Good job well played",(255,100,30),50)
# self.labels(300,625,"Click to next Level",(0,0,255))
if self.level < level:
self.level += 1
file = open("level.txt", "w")
file.write(str(self.level))
file.close()
self.start(level)
if event.dict['button'] == 1:
mouse_pos = pg.mouse.get_pos()
c = mouse_pos[0] // self.tile_width
r = mouse_pos[1] // self.tile_height
# print("dot posn",emptyc,emptyr)
# print("mouse posn",c,r)
if c == emptyc and r == emptyr:
continue
elif c == emptyc and (r == emptyr - 1 or r == emptyr + 1):
self.shift(c, r)
self.check()
elif r == emptyr and (c == emptyc - 1 or c == emptyc + 1):
self.shift(c, r)
self.check()
# print(c,r)
elif event.dict['button'] == 3:
saved_image = self.gameWindow.copy()
# print(saved_image)
# gameWindow.fill(255,255,255)
self.gameWindow.blit(self.image, (0, 0))
pg.display.flip()
show_sol = True
elif show_sol and (event.type == pg.MOUSEBUTTONUP):
# stop showing the solution
self.gameWindow.blit(saved_image, (0, 0))
pg.display.flip()
show_sol = False
if name == "main":
PuzzlerGame()
The dest argument of pygame.Surface.blit() can also be a rectangle. To center an image on the screen get the bounding rectangle of the image with pygame.Surface.get_rect. Set the center of the rectangle by the center of the screen. Use the rectangle to blit the image:
game_window_rect = self.gameWindow.get_rect()
dest_rect = saved_image.get_rect(center = game_window_rect.center)
self.gameWindow.blit(saved_image, dest_rect)

Why is my program not decreasing a life if the answer is wrong?

For my program, I am making a game which involves multiple choice questions. Along with this, I have used three separate heart images to show the lives to the user.
In the code, I set conditions so that if the lives for example is 1, only one heart image is blitted on the screen. The number of lives will only decrease if the answer the user has chosen is incorrect.
Below shows the relevant part of my code:
class GameState:
def __init__(self, difficulty):
self.difficulty = difficulty
self.questions = [
("Q1: 4 _ 6 = 10?"),
("Q2: ___ = 1"),
("Q3: 1 * 3?")
]
self.answers = [4, 2, 2]
self.current_question = None
self.question_index = 0
def pop_question(self):
q = self.questions[0]
self.questions.remove(q)
self.current_question = q
self.question_index += 1
return q
def answer(self, answer):
lives = 3
if self.answers == self.current_question[1]:
lives = lives - 1
else:
lives = lives
if lives == 1:
screen.blit(Heart, (500, 10))
if lives == 2:
screen.blit(Heart, (500, 10))
screen.blit(Heart, (X // 2, 10))
if lives == 3:
screen.blit(Heart, (500, 10))
screen.blit(Heart1, (X // 2, 10))
screen.blit(Heart2, (775, 10))
class GameScene:
def __init__(self):
if SimpleScene.FONT == None:
SimpleScene.FONT = pygame.freetype.SysFont(None, 32)
self.rects = []
for n in range(4):
rect = pygame.Rect(420, (n * 70) + 300, 500, 50)
self.rects.append(rect)
self.choices = [['x', '-', '*', '+'], ["number", "fruit", "weather", "letter"], ["4", "3", "-2", "13"]]
def start(self, gamestate):
self.background = pygame.Surface((X, Y))
self.background.fill(pygame.Color("white"))
self.gamestate = gamestate
question = gamestate.pop_question()
SimpleScene.FONT.render_to(self.background, (20, 150), question, (blue))
def draw(self, screen):
screen.blit(self.background, (0, 0))
n = 0
for rect in self.rects:
if rect.collidepoint(pygame.mouse.get_pos()):
pygame.draw.rect(screen, pygame.Color('darkgrey'), rect)
pygame.draw.rect(screen, pygame.Color('darkgrey'),
rect, 5)
screen.blit(Heart, (500, 10))
screen.blit(Heart1, (X // 2, 10))
screen.blit(Heart2, (775, 10))
for i in range(len(self.choices)):
if self.gamestate.question_index == i + 1:
SimpleScene.FONT.render_to(screen, (rect.x + 30, rect. y + 20), str(self.choices[i][n]),
(green))
SimpleScene.FONT.render_to(screen, (rect.x + 29, rect.y + 19), str(self.choices [i][n]),
(green))
n += 1
def update(self, events, dt):
for event in events:
if event.type == pygame.MOUSEBUTTONDOWN:
n = 1
for rect in self.rects:
if rect.collidepoint(event.pos):
self.gamestate.answer(n)
if self.gamestate.questions:
return ('GAME', self.gamestate)
else:
quit()
n += 1
When I run the program, none of the hearts disappear. Is it because of a mistake I made while setting the condition of the lives to minus by one if the answer is wrong?
lives needs to be an attribute of GameState:
class GameState:
def __init__(self, difficulty):
# [...]
self.lives = 3
# [...]
def pop_question(self):
q = self.questions[0]
self.current_question = q
return q
def answer(self, answer):
if answer != self.answers[self.question_index]:
self.lives -= 1
else:
self.question_index += 1
self.questions.pop(0)
However you must draw the hearts in GameScene.draw, dependent on the value of self.gamestate.lives:
class GameScene:
# [...]
def draw(self, screen):
screen.blit(self.background, (0, 0))
if self.gamestate.lives >= 1:
screen.blit(Heart, (500, 10))
if self.gamestate.lives >= 2:
screen.blit(Heart1, (X // 2, 10))
if self.gamestate.lives >= 3:
screen.blit(Heart2, (775, 10))
n = 0
for rect in self.rects:
if rect.collidepoint(pygame.mouse.get_pos()):
pygame.draw.rect(screen, pygame.Color('darkgrey'), rect)
pygame.draw.rect(screen, pygame.Color('darkgrey'),
rect, 5)
for i in range(len(self.choices)):
if self.gamestate.question_index == i:
SimpleScene.FONT.render_to(screen, (rect.x + 30, rect. y + 20), str(self.choices[i][n]),
(green))
SimpleScene.FONT.render_to(screen, (rect.x + 29, rect.y + 19), str(self.choices [i][n]),
(green))
n += 1
End the game when
def main():
# [...]
while True:
# [...]
game = scene.update(events, dt)
if game:
next_scene, state = game
if next_scene:
scene = scenes[next_scene]
scene.start(state)
if state and state.lives == 0:
print("GAME OVER")
break

How to add bubble sort to my boxes in the code?

So first here is my code:
import pygame, sys, random
from pygame.locals import *
# Create the constants (go ahead and experiment with different values)
BOARDWIDTH = 4 # number of columns in the board
BOARDHEIGHT = 4 # number of rows in the board
TILESIZE = 80
WINDOWWIDTH = 640
WINDOWHEIGHT = 480
FPS = 30
BLANK = None
# R G B
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
BRIGHTBLUE = ( 0, 50, 255)
DARKTURQUOISE = ( 3, 54, 73)
GREEN = ( 0, 204, 0)
BGCOLOR = DARKTURQUOISE
TILECOLOR = GREEN
TEXTCOLOR = WHITE
BORDERCOLOR = BRIGHTBLUE
BASICFONTSIZE = 20
BUTTONCOLOR = WHITE
BUTTONTEXTCOLOR = BLACK
MESSAGECOLOR = WHITE
XMARGIN = int((WINDOWWIDTH - (TILESIZE * BOARDWIDTH + (BOARDWIDTH - 1))) / 2)
YMARGIN = int((WINDOWHEIGHT - (TILESIZE * BOARDHEIGHT + (BOARDHEIGHT - 1))) / 2)
UP = 'up'
DOWN = 'down'
LEFT = 'left'
RIGHT = 'right'
def main():
global FPSCLOCK, DISPLAYSURF, BASICFONT, RESET_SURF, RESET_RECT, NEW_SURF, NEW_RECT, SOLVE_SURF, SOLVE_RECT
pygame.init()
FPSCLOCK = pygame.time.Clock()
DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.set_caption('Slide Puzzle')
BASICFONT = pygame.font.Font('freesansbold.ttf', BASICFONTSIZE)
# Store the option buttons and their rectangles in OPTIONS.
RESET_SURF, RESET_RECT = makeText('Reset', TEXTCOLOR, TILECOLOR, WINDOWWIDTH - 120, WINDOWHEIGHT - 90)
NEW_SURF, NEW_RECT = makeText('New Game', TEXTCOLOR, TILECOLOR, WINDOWWIDTH - 120, WINDOWHEIGHT - 60)
SOLVE_SURF, SOLVE_RECT = makeText('Solve', TEXTCOLOR, TILECOLOR, WINDOWWIDTH - 120, WINDOWHEIGHT - 30)
mainBoard, solutionSeq = generateNewPuzzle(80)
SOLVEDBOARD = getStartingBoard() # a solved board is the same as the board in a start state.
allMoves = [] # list of moves made from the solved configuration
while True: # main game loop
slideTo = None # the direction, if any, a tile should slide
msg = 'Click tile or press arrow keys to slide.' # contains the message to show in the upper left corner.
if mainBoard == SOLVEDBOARD:
msg = 'Solved!'
drawBoard(mainBoard, msg)
checkForQuit()
for event in pygame.event.get(): # event handling loop
if event.type == MOUSEBUTTONUP:
spotx, spoty = getSpotClicked(mainBoard, event.pos[0], event.pos[1])
if (spotx, spoty) == (None, None):
# check if the user clicked on an option button
if RESET_RECT.collidepoint(event.pos):
resetAnimation(mainBoard, allMoves) # clicked on Reset button
allMoves = []
elif NEW_RECT.collidepoint(event.pos):
mainBoard, solutionSeq = generateNewPuzzle(80) # clicked on New Game button
allMoves = []
elif SOLVE_RECT.collidepoint(event.pos):
resetAnimation(mainBoard, solutionSeq + allMoves) # clicked on Solve button
allMoves = []
else:
# check if the clicked tile was next to the blank spot
blankx, blanky = getBlankPosition(mainBoard)
if spotx == blankx + 1 and spoty == blanky:
slideTo = LEFT
elif spotx == blankx - 1 and spoty == blanky:
slideTo = RIGHT
elif spotx == blankx and spoty == blanky + 1:
slideTo = UP
elif spotx == blankx and spoty == blanky - 1:
slideTo = DOWN
elif event.type == KEYUP:
# check if the user pressed a key to slide a tile
if event.key in (K_LEFT, K_a) and isValidMove(mainBoard, LEFT):
slideTo = LEFT
elif event.key in (K_RIGHT, K_d) and isValidMove(mainBoard, RIGHT):
slideTo = RIGHT
elif event.key in (K_UP, K_w) and isValidMove(mainBoard, UP):
slideTo = UP
elif event.key in (K_DOWN, K_s) and isValidMove(mainBoard, DOWN):
slideTo = DOWN
if slideTo:
slideAnimation(mainBoard, slideTo, 'Click tile or press arrow keys to slide.', 8) # show slide on screen
makeMove(mainBoard, slideTo)
allMoves.append(slideTo) # record the slide
pygame.display.update()
FPSCLOCK.tick(FPS)
def terminate():
pygame.quit()
sys.exit()
def checkForQuit():
for event in pygame.event.get(QUIT): # get all the QUIT events
terminate() # terminate if any QUIT events are present
for event in pygame.event.get(KEYUP): # get all the KEYUP events
if event.key == K_ESCAPE:
terminate() # terminate if the KEYUP event was for the Esc key
pygame.event.post(event) # put the other KEYUP event objects back
def getStartingBoard():
# Return a board data structure with tiles in the solved state.
# For example, if BOARDWIDTH and BOARDHEIGHT are both 3, this function
# returns [[1, 4, 7], [2, 5, 8], [3, 6, BLANK]]
counter = 1
board = []
for x in range(BOARDWIDTH):
column = []
for y in range(BOARDHEIGHT):
column.append(counter)
counter += BOARDWIDTH
board.append(column)
counter -= BOARDWIDTH * (BOARDHEIGHT - 1) + BOARDWIDTH - 1
board[BOARDWIDTH-1][BOARDHEIGHT-1] = BLANK
return board
def getBlankPosition(board):
# Return the x and y of board coordinates of the blank space.
for x in range(BOARDWIDTH):
for y in range(BOARDHEIGHT):
if board[x][y] == BLANK:
return (x, y)
def makeMove(board, move):
# This function does not check if the move is valid.
blankx, blanky = getBlankPosition(board)
if move == UP:
board[blankx][blanky], board[blankx][blanky + 1] = board[blankx][blanky + 1], board[blankx][blanky]
elif move == DOWN:
board[blankx][blanky], board[blankx][blanky - 1] = board[blankx][blanky - 1], board[blankx][blanky]
elif move == LEFT:
board[blankx][blanky], board[blankx + 1][blanky] = board[blankx + 1][blanky], board[blankx][blanky]
elif move == RIGHT:
board[blankx][blanky], board[blankx - 1][blanky] = board[blankx - 1][blanky], board[blankx][blanky]
def isValidMove(board, move):
blankx, blanky = getBlankPosition(board)
return (move == UP and blanky != len(board[0]) - 1) or \
(move == DOWN and blanky != 0) or \
(move == LEFT and blankx != len(board) - 1) or \
(move == RIGHT and blankx != 0)
def getRandomMove(board, lastMove=None):
# start with a full list of all four moves
validMoves = [UP, DOWN, LEFT, RIGHT]
# remove moves from the list as they are disqualified
if lastMove == UP or not isValidMove(board, DOWN):
validMoves.remove(DOWN)
if lastMove == DOWN or not isValidMove(board, UP):
validMoves.remove(UP)
if lastMove == LEFT or not isValidMove(board, RIGHT):
validMoves.remove(RIGHT)
if lastMove == RIGHT or not isValidMove(board, LEFT):
validMoves.remove(LEFT)
# return a random move from the list of remaining moves
return random.choice(validMoves)
def getLeftTopOfTile(tileX, tileY):
left = XMARGIN + (tileX * TILESIZE) + (tileX - 1)
top = YMARGIN + (tileY * TILESIZE) + (tileY - 1)
return (left, top)
def getSpotClicked(board, x, y):
# from the x & y pixel coordinates, get the x & y board coordinates
for tileX in range(len(board)):
for tileY in range(len(board[0])):
left, top = getLeftTopOfTile(tileX, tileY)
tileRect = pygame.Rect(left, top, TILESIZE, TILESIZE)
if tileRect.collidepoint(x, y):
return (tileX, tileY)
return (None, None)
def drawTile(tilex, tiley, number, adjx=0, adjy=0):
# draw a tile at board coordinates tilex and tiley, optionally a few
# pixels over (determined by adjx and adjy)
left, top = getLeftTopOfTile(tilex, tiley)
pygame.draw.rect(DISPLAYSURF, TILECOLOR, (left + adjx, top + adjy, TILESIZE, TILESIZE))
textSurf = BASICFONT.render(str(number), True, TEXTCOLOR)
textRect = textSurf.get_rect()
textRect.center = left + int(TILESIZE / 2) + adjx, top + int(TILESIZE / 2) + adjy
DISPLAYSURF.blit(textSurf, textRect)
def makeText(text, color, bgcolor, top, left):
# create the Surface and Rect objects for some text.
textSurf = BASICFONT.render(text, True, color, bgcolor)
textRect = textSurf.get_rect()
textRect.topleft = (top, left)
return (textSurf, textRect)
def drawBoard(board, message):
DISPLAYSURF.fill(BGCOLOR)
if message:
textSurf, textRect = makeText(message, MESSAGECOLOR, BGCOLOR, 5, 5)
DISPLAYSURF.blit(textSurf, textRect)
for tilex in range(len(board)):
for tiley in range(len(board[0])):
if board[tilex][tiley]:
drawTile(tilex, tiley, board[tilex][tiley])
left, top = getLeftTopOfTile(0, 0)
width = BOARDWIDTH * TILESIZE
height = BOARDHEIGHT * TILESIZE
pygame.draw.rect(DISPLAYSURF, BORDERCOLOR, (left - 5, top - 5, width + 11, height + 11), 4)
DISPLAYSURF.blit(RESET_SURF, RESET_RECT)
DISPLAYSURF.blit(NEW_SURF, NEW_RECT)
DISPLAYSURF.blit(SOLVE_SURF, SOLVE_RECT)
def slideAnimation(board, direction, message, animationSpeed):
#This function does not check if the move is valid.
blankx, blanky = getBlankPosition(board)
if direction == UP:
movex = blankx
movey = blanky + 1
elif direction == DOWN:
movex = blankx
movey = blanky - 1
elif direction == LEFT:
movex = blankx + 1
movey = blanky
elif direction == RIGHT:
movex = blankx - 1
movey = blanky
# prepare the base surface
drawBoard(board, message)
baseSurf = DISPLAYSURF.copy()
# draw a blank space over the moving tile on the baseSurf Surface.
moveLeft, moveTop = getLeftTopOfTile(movex, movey)
pygame.draw.rect(baseSurf, BGCOLOR, (moveLeft, moveTop, TILESIZE, TILESIZE))
for i in range(0, TILESIZE, animationSpeed):
# animate the tile sliding over
checkForQuit()
DISPLAYSURF.blit(baseSurf, (0, 0))
if direction == UP:
drawTile(movex, movey, board[movex][movey], 0, -i)
if direction == DOWN:
drawTile(movex, movey, board[movex][movey], 0, i)
if direction == LEFT:
drawTile(movex, movey, board[movex][movey], -i, 0)
if direction == RIGHT:
drawTile(movex, movey, board[movex][movey], i, 0)
pygame.display.update()
FPSCLOCK.tick(FPS)
def generateNewPuzzle(numSlides):
# From a starting configuration, make numSlides number of moves (and
# animate these moves).
sequence = []
board = getStartingBoard()
drawBoard(board, '')
pygame.display.update()
pygame.time.wait(500) # pause 500 milliseconds for effect
lastMove = None
for i in range(numSlides):
move = getRandomMove(board, lastMove)
slideAnimation(board, move, 'Generating new puzzle...', animationSpeed=int(TILESIZE / 3))
makeMove(board, move)
sequence.append(move)
lastMove = move
return (board, sequence)
def resetAnimation(board, allMoves):
# make all of the moves in allMoves in reverse.
revAllMoves = allMoves[:] # gets a copy of the list
revAllMoves.reverse()
for move in revAllMoves:
if move == UP:
oppositeMove = DOWN
elif move == DOWN:
oppositeMove = UP
elif move == RIGHT:
oppositeMove = LEFT
elif move == LEFT:
oppositeMove = RIGHT
slideAnimation(board, oppositeMove, '', animationSpeed=int(TILESIZE / 2))
makeMove(board, oppositeMove)
if __name__ == '__main__':
main()
Here is the bubble sort code:
def shortBubbleSort(alist):
exchanges = True
passnum = len(alist)-1
while passnum > 0 and exchanges:
exchanges = False
for i in range(passnum):
if alist[i]>alist[i+1]:
exchanges = True
temp = alist[i]
alist[i] = alist[i+1]
alist[i+1] = temp
passnum = passnum-1
alist=[20,30,40,90,50,60,70,80,100,110]
shortBubbleSort(alist)
print(alist)
I am not sure how to select the numbers I have and arrange them using bubble sort method.
Oh - I found your code very complex for python and bubble-sort.
Here is the my view:
def bubbleSort(alist):
for passnum in range(len(alist)-1, 0, -1):
for i in range(passnum):
if alist[i] > alist[i+1]:
alist[i] , alist[i+1] = alist[i+1] , alist[i]
alist = [54,26,93,17,77,31,44,55,20]
bubbleSort(alist)
print(alist)
You do not need any flags or temp variables - this is the python, the language of magic! :) :) :) abracadabra!!!

Categories