예제 #1
0
파일: board.py 프로젝트: m-nez/tetroll
    def __init__(self):
        self.width = 11
        self.height = 24
        self.visible_height = 21
        self.guide_on = False
        self.dot_spawn_troll = False
        self.reset_matrix()
        self.win_functions = [
            self.win_func1
            ]
        self.loss_functions = [
            self.loss_func1
            ]
        self.win_conditions = [self.win_func1]
        self.loss_conditions = [self.loss_func1]
        self.forfeit = False
        self.send_multi = False
        self.multi_msg = ""

        self.active_block = blocks.block()
        self.pos = [5, 20]
        self.end_count = 0
        self.end_count_pos = [20, 380]
        self.end_count_matrix = [[]]

        self.last_game_step = time()
        self.curr_game_step = 0.0

        self.dot_meter = 0
        self.troll_meter = 0
        self.troll_meter_to_send = 0

        self.bo_pos = [200, 200]
        self.level = 0
        self.game_turn_time = 1.0
        self.end_time_increase = 0.5
        self.red_block_reward = 0.04
        self.turn_time_decrease = 0.83
        self.defill_time_decrease = True
        self.troll_time_decrease = False
        self.troll_time_modifier = 1.0
        self.troll_counter = 0 # Number of troll blocks spawned
        self.troll_time_counter = 0 # Number of time decreases

        self.init_images(1)

        self.scale = 1.0
        self.sp_level = 0

        self.last_landed = [5, 0]
        self.ai = AI(self)
예제 #2
0
파일: board.py 프로젝트: m-nez/tetroll
class board:
    def __init__(self):
        self.width = 11
        self.height = 24
        self.visible_height = 21
        self.guide_on = False
        self.dot_spawn_troll = False
        self.reset_matrix()
        self.win_functions = [
            self.win_func1
            ]
        self.loss_functions = [
            self.loss_func1
            ]
        self.win_conditions = [self.win_func1]
        self.loss_conditions = [self.loss_func1]
        self.forfeit = False
        self.send_multi = False
        self.multi_msg = ""

        self.active_block = blocks.block()
        self.pos = [5, 20]
        self.end_count = 0
        self.end_count_pos = [20, 380]
        self.end_count_matrix = [[]]

        self.last_game_step = time()
        self.curr_game_step = 0.0

        self.dot_meter = 0
        self.troll_meter = 0
        self.troll_meter_to_send = 0

        self.bo_pos = [200, 200]
        self.level = 0
        self.game_turn_time = 1.0
        self.end_time_increase = 0.5
        self.red_block_reward = 0.04
        self.turn_time_decrease = 0.83
        self.defill_time_decrease = True
        self.troll_time_decrease = False
        self.troll_time_modifier = 1.0
        self.troll_counter = 0 # Number of troll blocks spawned
        self.troll_time_counter = 0 # Number of time decreases

        self.init_images(1)

        self.scale = 1.0
        self.sp_level = 0

        self.last_landed = [5, 0]
        self.ai = AI(self)
    def send(self, b1, b2):
        """
        If multiplayer is enabled send two bytes to the other player.
        First byte is an unsigned integer, second byte is a signed integer.
        b1 <0, 255>
        b2 <-128, 127>
        If multiplayer is not enabled does nothing.
        """

        if self.send_multi:
            self.connection.send([b1, b2 + 128])
    def send_state(self):
        """
        Send elements necessary to recreate the board state.
        Pcket should be 512 bytes.
        """
        msg = []
        msg.append(self.level)
        msg.append(self.width) # Height doesn't change
        msg.append(self.active_block.identifier)
        msg.append(self.active_block.rotation)
        msg.append(self.active_block.colour)
        msg.append(self.pos[0])
        msg.append(self.pos[1])
        msg.append(self.forfeit)
        
        for l in self.matrix:
            msg.extend(l)
        msg.extend([0]*(512-len(msg)))

        self.connection.send(msg)
    def recreate_state(self, msg):
        """
        Recreate state from bytearry.
        """
        
        if (len(msg) - 8) % self.height != 0:
            print(msg)
        self.level = ord(msg[0]) # Python2 so msg is a string
        prev_width = self.width
        self.width = ord(msg[1])

        self.active_block.from_int(ord(msg[2]))
        self.active_block.rotation = ord(msg[3])
        self.active_block.colour = ord(msg[4])
        self.pos[0] = ord(msg[5])
        self.pos[1] = ord(msg[6])
        self.forfeit = ord(msg[7])

        mat = []
        for i in range(self.height):
            mat.append([ord(j) for j in msg[8 + i * self.width : 8 + (i+1) * self.width]])
        self.matrix = mat

    def try_recreate_state(self):
        """
        Receive 512 bytes encoding the board state
        """
        msg = self.connection.receive()
        if msg != 0:
            self.multi_msg += msg
            if len(msg) >= 512:
                index = (len(msg) // 512 - 1) * 512
                self.recreate_state(self.multi_msg[index:index+512])
                self.multi_msg = self.multi_msg[index+512:]
    def print_matrix(self):
        print(10*"*")
        self.add_block(self.pos, self.active_block.current_sqares())
        for i in reversed(range(self.visible_height)):
            for j in range(self.width):
                stdout.write(str(self.matrix[i][j]))
            print()
        self.erase_block(self.pos, self.active_block.current_sqares())
    def reset_matrix(self):
        self.matrix = []

        for i in range(self.height):
            self.matrix.append([])
            for j in range(self.width):
                self.matrix[i].append(0)

    def add_block(self, pos, sqares):
        for sq in sqares:
            self.matrix[pos[1]+sq[1]][pos[0]+sq[0]] = self.active_block.colour
    def check_block(self, pos, sqares):
        for sq in sqares:
            if (pos[0] + sq[0]) < 0 or (pos[0] + sq[0]) > self.width - 1:
                return 1
            if (pos[1] + sq[1]) < 0 or (pos[1] + sq[1]) > self.height - 1:
                return 1
            if self.matrix[pos[1]+sq[1]][pos[0]+sq[0]] >= 1:
                return 1
        return 0
    def erase_block(self, pos, sqares):
        for sq in sqares:
            self.matrix[pos[1]+sq[1]][pos[0]+sq[0]] = 0
    def spawn_block(self, seed=-1):
        self.pos = [5, 19]

        if seed != -1:
            self.active_block.from_int(seed)
        else:
            if self.dot_meter > 0:
                self.active_block.from_int(16)
                self.dot_meter -= 1
            elif self.troll_meter > 0:
                self.spawn_troll_block()
                self.troll_meter -= 1
            else:
                self.active_block.from_int(randint(0, 6))
        if self.check_block(self.pos, self.active_block.current_sqares()):
            self.end()
    def spawn_troll_block(self):
        self.troll_counter += 1
        if self.dot_spawn_troll:
            self.active_block.from_int(16)
        else:
            self.active_block.from_int(randint(7, 11))

    def advance_turn(self):
        if self.check_block([self.pos[0], self.pos[1] - 1], self.active_block.current_sqares()):
            self.last_landed = list(self.pos)
            self.add_block(self.pos, self.active_block.current_sqares())
            self.defill()
            self.spawn_block()
            self.last_game_step = time()
            return 1
        else:
            self.pos[1] -= 1
            return 0
    def dry_advance(self):
        if self.check_block([self.pos[0], self.pos[1] - 1], self.active_block.current_sqares()):
            self.add_block(self.pos, self.active_block.current_sqares())
            levels_cleared = self.dry_defill()
            self.erase_block(self.pos, self.active_block.current_sqares())
            return [True, levels_cleared]
        else:
            self.pos[1] -= 1
            return [False, 0]
    def dry_defill(self):
        counter = 0
        for i in range(self.height):
            counter += self.matrix[i].count(0) == 0
        return counter
    def try_move(self, x):
        if not self.check_block([self.pos[0] + x, self.pos[1]], self.active_block.current_sqares()):
            self.pos[0] += x
            return 1
        return 0
    def try_rotate(self, x):
        self.active_block.rotate(x)
        if self.check_block(self.pos, self.active_block.current_sqares()):
            self.active_block.rotate(-x)
            return 0
        return 1
    def defill(self):
        for i in reversed(range(self.height)):
            if self.matrix[i].count(0) == 0:
                if self.matrix[i].count(2) != 0:
                    self.dot_meter += 1
                    self.game_turn_time += self.red_block_reward
                self.bring_down(i)
                self.level += 1
                if self.defill_time_decrease:
                    self.game_turn_time *= self.turn_time_decrease
                self.troll_meter_to_send += 1
                if self.troll_time_decrease:
                    self.troll_time_modifier *= self.turn_time_decrease
    def bring_down(self, line):
        for i in range(line + 1, self.height):
            self.matrix[i-1] = deepcopy(self.matrix[i])
    def advance_to_bottom(self):
        while not self.advance_turn():
            pass
    def draw(self, screen):
        self.add_block(self.pos, self.active_block.current_sqares())
        for i in range(self.visible_height):
            for j in range(self.width):
                b_pos = (
                    self.bo_pos[0] + self.block_image.get_width() * j,
                    self.bo_pos[1] + self.block_image.get_height() * (self.visible_height - i))
                if self.matrix[i][j] == 1:
                    if i < self.level:
                        screen.blit(self.green_block_image, b_pos)
                    else:
                        screen.blit(self.block_image, b_pos)
                elif self.matrix[i][j] == 2:
                    screen.blit(self.red_block_image, b_pos)
                elif self.matrix[i][j] == 0:
                    screen.blit(self.gray_grid_image, b_pos)
        self.erase_block(self.pos, self.active_block.current_sqares())
        #draw_border
        self.draw_border(screen)
        self.draw_end_count(screen)
        if self.guide_on:
            self.draw_guidelines(screen)

    def draw_border(self, screen):
        for i in range(-1, self.width + 1):
            b_pos = (self.bo_pos[0] + self.block_image.get_width()*i,self.bo_pos[1] + self.block_image.get_height()*(0))
            screen.blit(self.brown_block_image, b_pos)
            b_pos = (self.bo_pos[0] + self.block_image.get_width()*i,self.bo_pos[1] + self.block_image.get_height()*(self.visible_height+1))
            screen.blit(self.brown_block_image, b_pos)
        for i in range(self.visible_height+1):
            b_pos = (self.bo_pos[0] + self.block_image.get_width()*(-1),self.bo_pos[1] + self.block_image.get_height()*(i))
            screen.blit(self.brown_block_image, b_pos)
            b_pos = (self.bo_pos[0] + self.block_image.get_width()*(self.width),self.bo_pos[1] + self.block_image.get_height()*(i))
            screen.blit(self.brown_block_image, b_pos)
    def draw_matrix(self, screen, matrix, pos, image):
        for i in range(len(matrix)):
            for j in range(len(matrix[i])):
                if matrix[i][j] == 1:
                    b_pos = (pos[0]+image.get_width()*j,pos[1]+image.get_height()*i)
                    screen.blit(image, b_pos)
    def draw_end_count(self, screen):
        pos = [0,0]
        pos[0] = self.bo_pos[0] + self.end_count_pos[0]
        pos[1] = self.bo_pos[1] + self.end_count_pos[1]
        self.draw_matrix(screen, self.end_count_matrix, pos, self.green_block_image)
    def draw_guidelines(self, screen):
            guide_pos = deepcopy(self.pos)
            while not self.check_block(guide_pos, self.active_block.current_sqares()):
                guide_pos[1] -= 1
            guide_pos[1] += 1
            for sq in self.active_block.current_sqares():
                b_pos = (self.bo_pos[0] +self.blue_guidelines_image.get_width()*(guide_pos[0]+sq[0]),self.bo_pos[1] + self.blue_guidelines_image.get_height()*(self.visible_height - (guide_pos[1]+sq[1])))
                screen.blit(self.blue_guidelines_image, b_pos)
    def end(self):
        if self.matrix[self.visible_height-1].count(0) != self.width:
            self.end_count += 1
            self.end_count_matrix[0].append(1)
            self.width += 1
            self.reset_matrix()
            self.game_turn_time += self.end_time_increase
            self.spawn_block()
            return True
        else:
            return False
    def time_advance(self):
        self.curr_game_step = time()
        if self.curr_game_step - self.last_game_step >= self.game_turn_time:
            self.last_game_step = self.curr_game_step
            self.advance_turn()
            return True
        else:
            return False
    def change_enemy_board(self, enemy_board):
        self.send_troll(enemy_board)
    def send_troll(self, enemy_board):
        enemy_board.troll_meter = self.level - enemy_board.troll_counter
        if enemy_board.troll_time_decrease:
            power = max(0, self.level - enemy_board.troll_time_counter)
            enemy_board.game_turn_time *= self.turn_time_decrease**power
            enemy_board.troll_time_counter += power
    def init_images(self, scale):
        pos = int(16 * scale)
        pos = (pos, pos)
        self.block_image = pygame.transform.scale(pygame.image.load("images/block.png"), pos)
        self.red_block_image = pygame.transform.scale(pygame.image.load("images/red_block.png"), pos)
        self.green_block_image = pygame.transform.scale(pygame.image.load("images/green_block.png"), pos)
        self.yellow_block_image = pygame.transform.scale(pygame.image.load("images/yellow_block.png"), pos)
        self.brown_block_image = pygame.transform.scale(pygame.image.load("images/brown_block.png"), pos)
        self.blue_block_image = pygame.transform.scale(pygame.image.load("images/blue_block.png"), pos)
        self.purple_block_image = pygame.transform.scale(pygame.image.load("images/purple_block.png"), pos)
        self.blue_guidelines_image = pygame.transform.scale(pygame.image.load("images/blue_guidelines.png"), pos)
        self.gray_grid_image = pygame.transform.scale(pygame.image.load("images/gray_grid.png"), pos)

        self.scale = scale
    def draw_win(self, screen):
        win_mat = [
                [1,0,0,0,1,0,1,0,1,1,0,1,0,0],
                [1,0,1,0,1,0,1,0,1,0,1,1,0,0],
                [0,1,0,1,0,0,1,0,1,0,0,1,0,0],
                ]
        pos = [self.bo_pos[0], self.bo_pos[1] + 16*(self.visible_height/2)*self.scale]
        self.draw_matrix(screen, win_mat, pos, self.blue_block_image)
    def draw_level(self, screen):
        mat = str_to_matrix(str(self.level))
        pos = [self.bo_pos[0], self.bo_pos[1] + 16*(self.visible_height/2)*self.scale]
        self.draw_matrix(screen, mat, pos, self.blue_block_image)
    def sp_level_win(self):
        if self.level >= 10:
            self.width += 1
            self.reset_matrix()
            self.game_turn_time += self.end_time_increase
            self.sp_level += 1
            self.level = 0
            return True
        else:
            return False
    def sp_win(self):
        if self.sp_level == 5:
            return True
        else:
            return False
    def AI_move(self):
        choice = self.ai.move()
    def win_func1(self):
        return self.level >= self.visible_height
    def loss_func1(self):
        return self.end_count >= 3
    def outcome(self):
        for win_con in self.win_conditions:
            if win_con():
                return 1
        for loss_con in self.loss_conditions:
            if loss_con():
                self.forfeit = True
                return 2
        if self.forfeit:
            return 2
        return 0
    def set_win_cons(self, func_str):
        self.win_conditions = []
        for i, val in enumerate(func_str):
            if val != "0":
                self.win_conditions.append(self.win_functions[i])
    def set_loss_cons(self, func_str):
        self.loss_conditions = []
        for i, val in enumerate(func_str):
            if val != "0":
                self.loss_conditions.append(self.loss_functions[i])
    def set_game_cons(self, win_cons, loss_cons):
        self.set_win_cons(win_cons)
        self.set_loss_cons(loss_cons)
    def set_forfeit(self, value):
        self.forfeit = value
    def set_level(self, level):
        self.level = level
    def add_troll(self, value):
        self.troll_meter_to_send += value
    def add_wait_connection(self, ip):
        self.connection = Connection(self, ip, send=False)
    def add_send_connection(self, ip):
        self.connection = Connection(self, ip, send=True)