-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathvisual-pygame.py
145 lines (109 loc) · 3.65 KB
/
visual-pygame.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
from adversary import RandomAdversary
from arguments import parser
from board import Board, Direction, Rotation
from constants import BOARD_WIDTH, BOARD_HEIGHT, DEFAULT_SEED, INTERVAL
from player import Player, SelectedPlayer
import pygame
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
CELL_WIDTH = 20
CELL_HEIGHT = 20
EVENT_FORCE_DOWN = pygame.USEREVENT + 1
FRAMES_PER_SECOND = 60
class Square(pygame.sprite.Sprite):
def __init__(self, color, x, y):
super().__init__()
self.image = pygame.Surface([CELL_WIDTH, CELL_HEIGHT])
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.x = x * CELL_WIDTH
self.rect.y = y * CELL_HEIGHT
def render(screen, board):
screen.fill(BLACK)
sprites = pygame.sprite.Group()
# Add the cells already on the board for drawing.
for (x, y) in board:
sprites.add(Square(pygame.Color(board.cellcolor[x, y]), x, y))
if board.falling is not None:
# Add the cells of the falling block for drawing.
for (x, y) in board.falling:
sprites.add(Square(pygame.Color(board.falling.color), x, y))
if board.next is not None:
for (x, y) in board.next:
sprites.add(
Square(
pygame.Color(board.next.color),
x + board.width + 2,
y+1
)
)
sprites.draw(screen)
pygame.draw.line(
screen,
BLUE,
(board.width * CELL_WIDTH + 2, 0),
(board.width * CELL_WIDTH + 2, board.height * CELL_HEIGHT)
)
# Update window title with score.
pygame.display.set_caption(f'Score: {board.score}')
class UserPlayer(Player):
"""
A simple user player that reads moves from the command line.
"""
key_to_move = {
pygame.K_RIGHT: Direction.Right,
pygame.K_LEFT: Direction.Left,
pygame.K_DOWN: Direction.Down,
pygame.K_SPACE: Direction.Drop,
pygame.K_UP: Rotation.Clockwise,
pygame.K_z: Rotation.Anticlockwise,
pygame.K_x: Rotation.Clockwise,
}
def choose_action(self, board):
while True:
event = pygame.event.wait()
if event.type == pygame.QUIT:
raise SystemExit
elif event.type == pygame.KEYUP:
if event.key in self.key_to_move:
return self.key_to_move[event.key]
elif event.key == pygame.K_ESCAPE:
raise SystemExit
elif event.type == EVENT_FORCE_DOWN:
return None
def check_stop():
for event in pygame.event.get():
if event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE:
raise SystemExit
elif event.type == pygame.QUIT:
raise SystemExit
def run():
board = Board(BOARD_WIDTH, BOARD_HEIGHT)
adversary = RandomAdversary(DEFAULT_SEED)
args = parser.parse_args()
if args.manual:
player = UserPlayer()
else:
player = SelectedPlayer()
pygame.init()
screen = pygame.display.set_mode([
(BOARD_WIDTH + 6) * CELL_WIDTH,
BOARD_HEIGHT * CELL_HEIGHT
])
clock = pygame.time.Clock()
# Set timer to force block down when no input is given.
pygame.time.set_timer(EVENT_FORCE_DOWN, INTERVAL)
for move in board.run(player, adversary):
render(screen, board)
pygame.display.flip()
# If we are not playing manually, clear the events.
if not args.manual:
check_stop()
clock.tick(FRAMES_PER_SECOND)
while True:
check_stop()
if __name__ == '__main__':
run()