0

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

Yahya
  • 1

1 Answers1

0

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)
Rabbid76
  • 202,892
  • 27
  • 131
  • 174