ผลต่างระหว่างรุ่นของ "Prg2/pacman (applying design patterns)"

จาก Theory Wiki
ไปยังการนำทาง ไปยังการค้นหา
แถว 6: แถว 6:
 
[[Image:Prg2-pacman-2players.png]]
 
[[Image:Prg2-pacman-2players.png]]
  
=== Understanding the current code ===
+
== Understanding the current code ==
  
 
There are three main classes:
 
There are three main classes:
แถว 13: แถว 13:
 
* Pacman
 
* Pacman
 
* Maze
 
* Maze
 +
 +
=== PacmanGame ===
  
 
'''PacmanGame''' is the main class.  It creates a Maze and 2 Pacman's.  It feeds two Pacman's with user inputs.  The following is its <tt>on_key_pressed</tt> method, which looks pretty ugly.
 
'''PacmanGame''' is the main class.  It creates a Maze and 2 Pacman's.  It feeds two Pacman's with user inputs.  The following is its <tt>on_key_pressed</tt> method, which looks pretty ugly.
แถว 35: แถว 37:
 
         elif event.char.upper() == 'L':
 
         elif event.char.upper() == 'L':
 
             self.pacman2.set_next_direction(DIR_RIGHT)
 
             self.pacman2.set_next_direction(DIR_RIGHT)
 +
</syntaxhighlight>
 +
 +
=== Pacman ===
 +
 +
A '''Pacman''' is the key object.  It works with the Maze to navigate (to avoid running into walls) and eats dots from the Maze.  It also handles movement control.  The Pacman would continue moving under the recent direction until it hits the walls or a new directional key is pressed.  The Pacman does not change directly immediately, but it waits until it arrives at the centers of the "blocks".
 +
 +
Its main functionality can be understood with the following body of its <tt>update</tt> method.
 +
 +
<syntaxhighlight lang="python">
 +
    def update(self):
 +
        if self.maze.is_at_center(self.x, self.y):
 +
            r, c = self.maze.xy_to_rc(self.x, self.y)
 +
 +
            if self.maze.has_dot_at(r, c):
 +
                self.maze.eat_dot_at(r, c)
 +
           
 +
            if self.maze.is_movable_direction(r, c, self.next_direction):
 +
                self.direction = self.next_direction
 +
            else:
 +
                self.direction = DIR_STILL
 +
 +
        self.x += PACMAN_SPEED * DIR_OFFSET[self.direction][0]
 +
        self.y += PACMAN_SPEED * DIR_OFFSET[self.direction][1]
 
</syntaxhighlight>
 
</syntaxhighlight>
  

รุ่นแก้ไขเมื่อ 16:43, 17 มีนาคม 2564

This is part of Programming 2 2563

Overview

In this assignment, you and your friend will apply design patterns to the provided Pacman code. This version of the Pacman game is a 2-player game, where each player tries to score as many points as possible. The first Pacman is controlled by WASD keys, while the other Pacman is controlled by IJKL keys.

Prg2-pacman-2players.png

Understanding the current code

There are three main classes:

  • PacmanGame
  • Pacman
  • Maze

PacmanGame

PacmanGame is the main class. It creates a Maze and 2 Pacman's. It feeds two Pacman's with user inputs. The following is its on_key_pressed method, which looks pretty ugly.

    def on_key_pressed(self, event):
        if event.char.upper() == 'A':
            self.pacman1.set_next_direction(DIR_LEFT)
        elif event.char.upper() == 'W':
            self.pacman1.set_next_direction(DIR_UP)
        elif event.char.upper() == 'S':
            self.pacman1.set_next_direction(DIR_DOWN)
        elif event.char.upper() == 'D':
            self.pacman1.set_next_direction(DIR_RIGHT)

        if event.char.upper() == 'J':
            self.pacman2.set_next_direction(DIR_LEFT)
        elif event.char.upper() == 'I':
            self.pacman2.set_next_direction(DIR_UP)
        elif event.char.upper() == 'K':
            self.pacman2.set_next_direction(DIR_DOWN)
        elif event.char.upper() == 'L':
            self.pacman2.set_next_direction(DIR_RIGHT)

Pacman

A Pacman is the key object. It works with the Maze to navigate (to avoid running into walls) and eats dots from the Maze. It also handles movement control. The Pacman would continue moving under the recent direction until it hits the walls or a new directional key is pressed. The Pacman does not change directly immediately, but it waits until it arrives at the centers of the "blocks".

Its main functionality can be understood with the following body of its update method.

    def update(self):
        if self.maze.is_at_center(self.x, self.y):
            r, c = self.maze.xy_to_rc(self.x, self.y)

            if self.maze.has_dot_at(r, c):
                self.maze.eat_dot_at(r, c)
            
            if self.maze.is_movable_direction(r, c, self.next_direction):
                self.direction = self.next_direction
            else:
                self.direction = DIR_STILL

        self.x += PACMAN_SPEED * DIR_OFFSET[self.direction][0]
        self.y += PACMAN_SPEED * DIR_OFFSET[self.direction][1]

Dev 1: Observer pattern

Dev 2: Command pattern

Dev 1: Flyweight pattern

Dev 2: State pattern

Optional work