Пример #1
0
    def render(self):
        matrix = self.matrix
        w = self.width
        h = self.height

        #draw held piece
        for x in range(w):
            for y in range(1, int(h / 2)):
                pygame.draw.rect(
                    self.screen, (200, 200, 200),
                    pygame.Rect((TOTAL_PIECE_WIDTH) * x,
                                (TOTAL_PIECE_HEIGHT) * y, PIECE_W, PIECE_H))

        #locate held_piece
        held_piece = self.board.get_held()
        if held_piece != None:
            color = block_color(held_piece)
            piece = Block(held_piece)
            hx = piece.get_spawn(w)
            hy = int(h / 4)

            for x in range(piece.get_width()):
                for y in range(piece.get_height()):
                    if piece.loc_mat[x][y] == 1:
                        pygame.draw.rect(
                            self.screen, color,
                            pygame.Rect((TOTAL_PIECE_WIDTH) * (hx + x),
                                        (TOTAL_PIECE_HEIGHT) * (hy + y),
                                        PIECE_W, PIECE_H))

        #draw game board
        cp = self.board.get_current()

        for x in range(w):
            for y in range(1, h):
                piece = matrix.lookup(x, y)

                if cp.intersects(x, y):
                    color = cp.get_color()
                else:
                    color = block_color(piece) if piece != 0 else GRAY

                pygame.draw.rect(
                    self.screen, color,
                    pygame.Rect((TOTAL_PIECE_WIDTH) * (w + x),
                                (TOTAL_PIECE_HEIGHT) * y, PIECE_W, PIECE_H))

        #draw next pieces
        for x in range(2 * w, 3 * w):
            for y in range(1, h):
                pygame.draw.rect(
                    self.screen, (200, 200, 200),
                    pygame.Rect((TOTAL_PIECE_WIDTH) * x,
                                (TOTAL_PIECE_HEIGHT) * y, PIECE_W, PIECE_H))

        q = list(self.board.next_queue)

        ny = 2
        for next_piece in q[:5]:
            color = block_color(next_piece + 1)
            piece = Block(next_piece)
            nx = piece.get_spawn(w)

            for x in range(piece.get_width()):
                for y in range(piece.get_height()):
                    if piece.loc_mat[x][y] == 1:
                        pygame.draw.rect(
                            self.screen, color,
                            pygame.Rect((TOTAL_PIECE_WIDTH) * (2 * w + nx + x),
                                        (TOTAL_PIECE_HEIGHT) * (ny + y),
                                        PIECE_W, PIECE_H))
            ny += 4
Пример #2
0
def generate_successor_states(board, piece_type):
	# number of unique rotations per piece
	r = valid_rotations(piece_type)

	# store all possible positions in a queue
	pos = Queue()
	# 3D memo for later ;)
	memo = [[[0 for z in range(r)] for y in range(board.get_height())] for x in range(board.get_width())]

	# for each unique rotation
	for rotation in range(r):
		# construct a temporary piece
		temp_piece = Block(piece_type)
		temp_piece.set_rotation(board, rotation)


		# get the next offset after rotating
		sx = temp_piece.get_offset()[0]

		# for each horizontal position
		for x in range(board.get_width() - temp_piece.get_width() + 1):

			# shift the piece horizontally
			temp_piece.set_offset(x, 0)
			if temp_piece.collides(board):
				continue

			# drop
			temp_piece.drop(board)

			# get final position
			tx, ty = temp_piece.get_offset()

			# memoize
			memo[tx][ty][rotation] = 1

			#print(str(tx) + ", " + str(ty) + ", " + str(rotation))

			# encode moves
			moves = [encode_move('crot') for i in range(rotation)] + [encode_move('left') if x - sx < 0 else encode_move('right') for i in range(abs(x-sx))] + [encode_move('drop')]

			# enqueue
			pos.put((tx, ty, rotation, moves))

	# the final set to return
	children = []

	# while the queue still contains positions
	while not pos.empty():

		child = pos.get()

		# add to final bag
		children.append(child)

		x, y, rot, moves = child

		# make a block and put it into the correct place
		test_piece = Block(piece_type)
		test_piece.execute_moves(moves, board)

		o_off_x, o_off_y = test_piece.get_offset()

		# generate partial movements from this position, i.e. left, right, and all rotations
		# stored in tuples like so (dx, dy, nr)
		next_positions = [(1, 0, rot), (-1, 0, rot)] + [(0,0,i) for i in range(r)]

		# for each partial movement
		for npos in next_positions:
			# quick access variables
			dx, dy, nr = npos

			# rotate the piece for the new rotation, if possibe, else its invalid so skip
			if not test_piece.set_rotation(board, nr):
				continue

			offset = test_piece.get_offset()

			# translate the piece right or left or skip if invalid
			if (dx > 0 and not test_piece.r_translate(board)) or (dx < 0 and not test_piece.l_translate(board)):
				continue

			# apply gravity
			down = test_piece.drop(board)

			# get updated locations
			nx, ny = test_piece.get_offset()

			# check that the move was not already encoded
			if memo[nx][ny][nr] == 1:
				test_piece.dirty_reset_position(o_off_x, o_off_y, rot)
				continue

			# now encode additional movements
			# copy moves and convert drops to down movements because this is more meticulous

			nmoves = deepcopy(moves)

			# convert drops to down moves
			l = len(moves) - 1
			if moves[l] == encode_move('drop'):
				nmoves = nmoves[:l] + [encode_move('down') for i in range(y)]

			# generate additional horizontal movements
			if dx != 0:
				nmoves.append(encode_move('left') if dx == -1 else encode_move('right'))

			# generate rotation movements
			dr = nr - rot
			#print("rotations:",dr)
			if rot == 3 and nr == 0:
				nmoves += [encode_move('crot')]
			elif dr != 0:
				nmoves += [encode_move('crot') if dr > 0 else encode_move('ccrot') for i in range(abs(dr))]

			# generate additional down movements
			nmoves += [encode_move('down') for i in range(down)]

			# enqueue
			pos.put((nx, ny, nr, nmoves))

			# mark this new space as visited, too
			memo[nx][ny][nr] = 1

			# undo moves
			test_piece.dirty_reset_position(o_off_x, o_off_y, rot)

	return children