How to create a memory puzzle game with Python and Pygame (#005)

First look at the following code:

import time
# create Font object
text_font = pygame.font.SysFont('arial', 50)

# create a list that stores two pos that going to compare to each other
pos_to_compare_list = []
# create a list that stores all the pos that matched
pos_matched = []

# set backgroud color to white
while True:
      
      for event in pygame.event.get():
            if event.type == QUIT:
                  pygame.quit()
                  sys.exit()
            elif event.type == MOUSEBUTTONDOWN:
                  (x,y) = pygame.mouse.get_pos()
                  pos = check_click(x,y, square_pos)
                  if pos:
                        text_surface = text_font.render(board[pos[0]][pos[1]], True, WHITE)
                        if len(pos_to_compare_list) < 2:
                              if pos not in pos_to_compare_list:
                                    pos_to_compare_list.append(pos)
                              if len(pos_to_compare_list) == 2:
                                    res = compare_two_pos(pos_to_compare_list[0], pos_to_compare_list[1], board)
                                    if res:
                                          pos_matched.extend(pos_to_compare_list)
                                    
      draw_pos_matched(pos_matched, pos_to_compare_list, square_pos, board)
    pygame.display.update()
   if len(pos_to_compare_list) == 2: time.sleep(1) pos_to_compare_list = []

First, we need to create a Font object to render the 36 letters used for patterns.

text_font = pygame.font.SysFont('arial', 50)

We are gonna render our letters into "arial" font with size of 50.

Second, we create two lists.

# create a list that stores two pos that going to compare to each other
pos_to_compare_list = []
# create a list that stores all the pos that matched
pos_matched = []

The pos_to_compare_list is for storing two positions for compareing equality.  Once the two patterns at the two positions are matched, those two positions will be extended to pos_matched list. And then we empty the pos_compare_list for next comparing process.

Third, we have to handle mouse click event like the following.

while True:
      
      for event in pygame.event.get():
            if event.type == QUIT:
                  pygame.quit()
                  sys.exit()
            elif event.type == MOUSEBUTTONDOWN:
                  (x,y) = pygame.mouse.get_pos()
                  pos = check_click(x,y, square_pos)
                  if pos:
                        text_surface = text_font.render(board[pos[0]][pos[1]], True, WHITE)
                        if len(pos_to_compare_list) < 2:
                              if pos not in pos_to_compare_list:
                                    pos_to_compare_list.append(pos)
                              if len(pos_to_compare_list) == 2:
                                    res = compare_two_pos(pos_to_compare_list[0], pos_to_compare_list[1], board)
                                    if res:
                                    pos_matched.extend(pos_to_compare_list) 

If we click on the main game screen, we have satisfied the elif condition: 

 event.type == MOUSEBUTTONDOWN

The statement is evaluated to True.

And then we get the click point position by using:

(x,y) = pygame.mouse.get_pos()

After we got the mouse click point, we could use this point to check if the player has clicked on the green square. For now, we could just abstract this process by using a imaginary function (which will be developed in a moment) check_click()

The check_click() method will take three arguments, the x, y are the coordinates of the click position; and the third one is the list of center point coordinates of all the green squares.

It returns the board position of the green square (such as (0,0), (3,4), notice that it does not return coordinates e.g.(170, 90)) when the player clicks right on the square.  If the player does not click on the board area, it returns None.

pos = check_click(x,y, square_pos)

If the pos returned is not None, so we can render its corresponding letter beneath the board position by using:

text_surface = text_font.render(board[pos[0]][pos[1]], True, WHITE)

Remember, our pos_to_compare_list could at most have 2 elements. So before we add elements to this list, we must ensure there are less than 2 elements already in the list. So do this extra safeguarding process:

if len(pos_to_compare_list) < 2:

After this, we need to do another if statement to ensure clicking the same square twice does not end up with being compared to equal. All the positions in the pos_to_compare_list must be deifferent. So we do the following:

if pos not in pos_to_compare_list:
    pos_to_compare_list.append(pos)

Then next, if there are two elements in side the pos_to_compare_list, we should really do the comparison by abstracting a function called compare_two_pos().  Later we will develop this method aslo.

The compare_two_pos function takes three arguments, the first two are the two positions in the pos_to_compare_list; and the third one is  board data structure for retrieving its letter patterns.

The compare_two_pos function returns True if positions matched otherwise returns False.

If two positions are  matched, the two positions will be extended to pos_matched list.

if res:
    pos_matched.extend(pos_to_compare_list)

As the logic goes, we should empty the pos_to_compare_list in the code sinppet above, but we wil do this later elsewhere.

After all this, we should draw all the changes on the main screen. By now we should just abstract this process by using an imaginary function draw_pos_matched().

draw_pos_matched(pos_matched, pos_to_compare_list, square_pos, board)

It is simple, the fucntion will draw all the letters at positions of both pos_matched and pos_to_compare_list lists. The drawing coordinates will be fetched through square_pos list. 

In the end of the game loop,

if len(pos_to_compare_list) == 2:

            time.sleep(1)

            pos_to_compare_list = []

After update the screen, we need to check whether pos_to_compare_list is full or not, if there are already two positions inside, after displaying it for 1 second by using time.sleep(1) we empty the list before the next game loop iteration.

Next, we are gonna develop all the missing functions.


Comments

Popular posts from this blog

How to write a slide puzzle game with Python and Pygame (2020 tutorial)

Introduction to multitasking with Python #001 multithreading (2020 tutorial)