codigojogo1.py

mail@pastecode.io avatar
unknown
python
2 months ago
21 kB
1
Indexable
Never
import pygame
import random
import sys

# Constantes
WIDTH = 700
HEIGHT = 700
ROWS = 7
COLS = 7
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
BLACK_HOLES = 5
pedra_branca = pygame.image.load('Imagens/pedrabranca.png')
pedra_preta = pygame.image.load('Imagens/pedrapreta.png')
fundo_inicio = pygame.image.load('Imagens/Fundonovo.jpg')
fundo_tabuleiro = pygame.image.load('Imagens/fundo_tabuleiro.jpg')
fundo_dificuldade = pygame.image.load('Imagens/fundo_dificuldade2.jpg')
fundo_liso = pygame.image.load('Imagens/fundo2.jpg')
pedra_branca_resize = pygame.transform.scale(pedra_branca, (70, 70))
pedra_preta_resize = pygame.transform.scale(pedra_preta, (70, 70))

# Inicializa o pygame
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("PahTum")

# Carrega uma fonte para exibir o texto
pygame.font.init()
font = pygame.font.Font("Crang.ttf", 10)


# Função para desenhar o botão
def draw_button(text, color, rect, font):
    pygame.draw.rect(screen, color, rect, border_radius=10)
    pygame.draw.circle(screen, color, (rect.left + 10, rect.top + 10), 10)
    pygame.draw.circle(screen, color, (rect.right - 10, rect.top + 10), 10)
    pygame.draw.circle(screen, color, (rect.left + 10, rect.bottom - 10), 10)
    pygame.draw.circle(screen, color, (rect.right - 10, rect.bottom - 10), 10)
    text_surface = font.render(text, True, WHITE)
    text_rect = text_surface.get_rect(center=rect.center)
    screen.blit(text_surface, text_rect)


# Função para exibir o menu de seleção de modo de jogo
def game_mode_selection():
    screen.blit(fundo_inicio, (0,0))

    # Botões de modo de jogo
    button_font = pygame.font.Font("Crang.ttf", 30)
    button_rects = [
        pygame.Rect(175, HEIGHT // 2 - 50, 350 , 55),
        pygame.Rect(125, HEIGHT // 2 +50, 450, 55),
        pygame.Rect(75, HEIGHT // 2 + 150, 550, 55),
        pygame.Rect(500, 600, 150, 55)
    ]
    button_texts = ["Humano vs Humano", "Humano vs Computador", "Computador vs Computador", "QUIT"]

    for rect, text in zip(button_rects, button_texts):
        draw_button(text, BLACK, rect, button_font)

    pygame.display.update()

    # Espera até que um botão seja pressionado
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                for i, rect in enumerate(button_rects):
                    if rect.collidepoint(event.pos):
                        return i  # Retorna o índice do botão pressionado


# Função para exibir o menu de seleção de dificuldade
def choose_difficulty():
    screen.blit(fundo_dificuldade, (0,0))

    # Botões de dificuldade
    button_font = pygame.font.Font('Crang.ttf', 45)
    button_rects = [
        pygame.Rect(240, HEIGHT // 2 - 50, 220, 73),
        pygame.Rect(240, HEIGHT // 2 + 50, 220, 73),
        pygame.Rect(240, HEIGHT // 2 + 150, 220, 73)
    ]
    button_texts = ["fácil", "médio", "difícil"]

    for rect, text in zip(button_rects, button_texts):
        draw_button(text, BLACK, rect, button_font)

    pygame.display.update()

    # Espera até que um botão seja pressionado
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                for i, rect in enumerate(button_rects):
                    if rect.collidepoint(event.pos):
                        return button_texts[i].lower()  # Retorna a dificuldade selecionada em minúsculas


# Função para desenhar o tabuleiro
def draw_board():
    screen.blit(fundo_tabuleiro, (0, 0))
    for row in range(ROWS):
        for col in range(COLS):
            pygame.draw.rect(screen, WHITE,
                             (col * (WIDTH // COLS), row * (HEIGHT // ROWS), WIDTH // COLS, HEIGHT // ROWS), 1)


# Função para gerar os buracos negros aleatórios
def generate_black_holes():
    black_holes = set()
    while len(black_holes) < 5:
        row = random.randint(0, ROWS - 1)
        col = random.randint(0, COLS - 1)
        black_holes.add((row, col))
    return black_holes


# Função para desenhar as pedras
def draw_stones(stones, black_holes):
    for color, positions in stones.items():
        for position in positions:
            if color == WHITE:
                stone_image = pedra_branca_resize
            else:
                stone_image = pedra_preta_resize
            stone_rect = stone_image.get_rect()
            stone_rect.center = (position[1] * (WIDTH // COLS) + (WIDTH // (2 * COLS)),
                                 position[0] * (HEIGHT // ROWS) + (HEIGHT // (2 * ROWS)))
            screen.blit(stone_image, stone_rect)

    for hole in black_holes:
        pygame.draw.rect(screen, BLACK,
                         (hole[1] * (WIDTH // COLS), hole[0] * (HEIGHT // ROWS), WIDTH // COLS, HEIGHT // ROWS))


# Função para verificar se uma jogada é válida
def is_valid_move(row, col, stones, black_holes):
    if (row, col) in stones or (row, col) in black_holes:
        return False
    return True


# Função para verificar a condição de vitória
def check_win(stones):
    white_points = 0
    black_points = 0
    for color, positions in stones.items():
        for position in positions:
            row, col = position
            # Verifica na horizontal
            count = 0
            for i in range(0, 7):
                if (row, col + i) in positions:
                    count += 1
                else:
                    break
            if count == 3:
                if color == WHITE:
                    white_points += 3
                else:
                    black_points += 3
            if count == 4:
                if color == WHITE:
                    white_points += 7
                else:
                    black_points += 7
            if count == 5:
                if color == WHITE:
                    white_points += 15
                else:
                    black_points += 15
            if count == 6:
                if color == WHITE:
                    white_points += 31
                else:
                    black_points += 31
            if count == 7:
                if color == WHITE:
                    white_points += 63
                else:
                    black_points += 63  
            # Verifica na vertical
            count = 0
            for i in range(0, 7):
                if (row + i, col) in positions:
                    count += 1
                else:
                    break
            if count == 3:
                if color == WHITE:
                    white_points += 3
                else:
                    black_points += 3
            if count == 4:
                if color == WHITE:
                    white_points += 7
                else:
                    black_points += 7
            if count == 5:
                if color == WHITE:
                    white_points += 15
                else:
                    black_points += 15
            if count == 6:
                if color == WHITE:
                    white_points += 31
                else:
                    black_points += 31
            if count == 7:
                if color == WHITE:
                    white_points += 63
                else:
                    black_points += 63                        

    return white_points, black_points


# Função para exibir texto na tela
def draw_text(text, color, x, y, font_size):
    font = pygame.font.Font("Crang.ttf", font_size)
    text_surface = font.render(text, True, color)
    text_rect = text_surface.get_rect()
    text_rect.center = (x, y)
    screen.blit(text_surface, text_rect)


# Lógica para bot aleatório
def easy_bot(stones, black_holes, player_turn):
    return minimax(stones, black_holes, depth=1, maximizing_player=True, player_turn=player_turn)[1]


# Lógica para bot de dificuldade média usando Minimax
def medium_bot(stones, black_holes, player_turn):
    return minimax(stones, black_holes, depth=3, maximizing_player=True, player_turn=player_turn) [1]



def execute_minimax_move_aux(game):
        # updates the game state to the best possible move (uses minimax to determine it)
        # your code here
        #--------------------------------------------------#
        best_move = None
        best_eval = float('-inf')
        for move in game.state.available_moves:
            new_state = game.state.move(move)
            # maximizing = False because we are checking for the best moves for the opponent after this move
            new_state_eval = minimax(new_state, depth - 1, float('-inf'), float('+inf'), False, game.state.player, evaluate_func)
            if new_state_eval > best_eval:
                best_move = new_state
                best_eval = new_state_eval
        game.state = best_move
        
        return best_move

def minimax(state, depth, alpha, beta, maximizing, player, evaluate_func):
    if depth == 0 or state.winner != -1:
        return evaluate_func(state) * (1 if player == 1 else -1)
    
    if maximizing:
        max_eval = float('-inf')
        for move in state.available_moves:
            new_state = state.move(move)
            eval = minimax(new_state, depth - 1, alpha, beta, False, player, evaluate_func)
            max_eval = max(max_eval, eval)
            alpha = max(alpha, eval)
            if beta <= alpha:
                break
        return max_eval
    else:
        min_eval = float('inf')
        for move in state.available_moves:
            new_state = state.move(move)
            eval = minimax(new_state, depth - 1, alpha, beta, True, player, evaluate_func)
            min_eval = min(min_eval, eval)
            beta = min(beta, eval)
            if beta <= alpha:
                break
        return min_eval
    
def evaluate_f1(state):
    
    return state.count_lines(4, 1) - state.count_lines(4, 2)
    

def evaluate_f2(state):
   
    return (state.count_lines(4, 1) - state.count_lines(4, 2)) * 100 + state.count_lines(3, 1) - state.count_lines(3, 2)
   

def evaluate_f3(state):
   
    return 100 * evaluate_f1(state) + state.central(1) - state.central(2)
  

def evaluate_f4(state):
   
    return 5 * evaluate_f2(state) + evaluate_f3(state)  


# Lógica para bot de dificuldade difícil usando Minimax
def hard_bot(stones, black_holes, player_turn):
    return minimax(stones, black_holes, depth=5, maximizing_player=True, player_turn=player_turn)[1]


# Função de avaliação da posição
def evaluate_position(stones, black_holes):
    score = 0
    for stone in stones[WHITE]:
        row, col = stone
        if row == 0 or row == 6:
            score += 5
        if col == 0 or col == 6:
            score += 5
        for other_stone in stones[WHITE]:
            if stone != other_stone:
                distance = abs(stone[0] - other_stone[0]) + abs(stone[1] - other_stone[1])
                if distance == 1:
                    score += 10
                elif distance == 2:
                    score += 5
        for hole in black_holes:
            if stone == hole:
                score -= 10
    for stone in stones[BLACK]:
        row, col = stone
        if row == 0 or row == 6:
            score -= 5
        if col == 0 or col == 6:
            score -= 5
        for other_stone in stones[BLACK]:
            if stone != other_stone:
                distance = abs(stone[0] - other_stone[0]) + abs(stone[1] - other_stone[1])
                if distance == 1:
                    score -= 10
                elif distance == 2:
                    score -= 5
        for hole in black_holes:
            if stone == hole:
                score += 10
    return score


# Algoritmo Minimax
def minimax(stones, black_holes, depth, maximizing_player, player_turn):
    if depth == 0 or len(stones[WHITE]) + len(stones[BLACK]) == ROWS * COLS - BLACK_HOLES:
        return evaluate_position(stones, black_holes), None

    if maximizing_player:
        max_eval = float('-inf')
        best_move = None
        for row in range(ROWS):
            for col in range(COLS):
                if (row, col) not in stones[WHITE] and (row, col) not in stones[BLACK] and (
                row, col) not in black_holes:
                    new_stones = {color: positions[:] for color, positions in stones.items()}
                    new_stones[player_turn].append((row, col))
                    eval, _ = minimax(new_stones, black_holes, depth - 1, False, player_turn)
                    if eval > max_eval:
                        max_eval = eval
                        best_move = (row, col)
        return max_eval, best_move
    else:
        min_eval = float('inf')
        best_move = None
        for row in range(ROWS):
            for col in range(COLS):
                if (row, col) not in stones[WHITE] and (row, col) not in stones[BLACK] and (
                row, col) not in black_holes:
                    new_stones = {color: positions[:] for color, positions in stones.items()}
                    new_stones[player_turn].append((row, col))
                    eval, _ = minimax(new_stones, black_holes, depth - 1, True, player_turn)
                    if eval < min_eval:
                        min_eval = eval
                        best_move = (row, col)
        return min_eval, best_move


# Loop principal do jogo
def main():
    mode = game_mode_selection()

    # Define as variáveis do jogo
    stones = {WHITE: [], BLACK: []}
    black_holes = generate_black_holes()
    game_over = False

    # Define o jogador atual dependendo do modo de jogo
    if mode == 0:  # Humano vs Humano
        player_turn = WHITE
    elif mode == 1:  # Humano vs Computador
        player_turn = WHITE
        difficulty = choose_difficulty()
    elif mode ==2:  # Computador vs Computador
        player_turn = WHITE
        bot_difficulty = choose_difficulty()
    else:
        pygame.quit()
        sys.exit()
    while not game_over:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            if mode == 0:  # Humano vs Humano
                if event.type == pygame.MOUSEBUTTONDOWN:
                    col = event.pos[0] // (WIDTH // COLS)
                    row = event.pos[1] // (HEIGHT // ROWS)
                    if is_valid_move(row, col, stones[WHITE] + stones[BLACK], black_holes):
                        stones[player_turn].append((row, col))
                        white_points, black_points = check_win(stones)
                        draw_board()
                        draw_stones(stones, black_holes)
                        pygame.display.update()
                        if len(stones[WHITE]) + len(stones[BLACK]) == ROWS * COLS - BLACK_HOLES:
                            game_over = True
                        if player_turn == WHITE:
                            player_turn = BLACK
                        else:
                            player_turn = WHITE
            elif mode == 1:  # Humano vs Computador
                if player_turn == WHITE:
                    if event.type == pygame.MOUSEBUTTONDOWN:
                        col = event.pos[0] // (WIDTH // COLS)
                        row = event.pos[1] // (HEIGHT // ROWS)
                        if is_valid_move(row, col, stones[WHITE] + stones[BLACK], black_holes):
                            stones[player_turn].append((row, col))
                            white_points, black_points = check_win(stones)
                            draw_board()
                            draw_stones(stones, black_holes)
                            pygame.display.update()
                            if len(stones[WHITE]) + len(stones[BLACK]) == ROWS * COLS - BLACK_HOLES:
                                game_over = True
                            player_turn = BLACK
                else:
                    if difficulty == "fácil":
                        row, col = easy_bot(stones, black_holes, player_turn)
                    elif difficulty == "médio":
                        row, col = medium_bot(stones, black_holes, player_turn)
                    else:
                        row, col = hard_bot(stones, black_holes, player_turn)
                    if is_valid_move(row, col, stones[WHITE] + stones[BLACK], black_holes):
                        stones[player_turn].append((row, col))
                        white_points, black_points = check_win(stones)
                        draw_board()
                        draw_stones(stones, black_holes)
                        pygame.display.update()
                        if len(stones[WHITE]) + len(stones[BLACK]) == ROWS * COLS - BLACK_HOLES:
                            game_over = True
                        player_turn = WHITE if player_turn == BLACK else BLACK
            else:  # Computador vs Computador
                if player_turn == WHITE:
                    if bot_difficulty == "fácil":
                        row, col = easy_bot(stones, black_holes)
                    elif bot_difficulty == "médio":
                        row, col = medium_bot(stones, black_holes, player_turn)
                    else:
                        row, col = hard_bot(stones, black_holes, player_turn)
                    if is_valid_move(row, col, stones[WHITE] + stones[BLACK], black_holes):
                        stones[player_turn].append((row, col))
                        white_points, black_points = check_win(stones)
                        draw_board()
                        draw_stones(stones, black_holes)
                        pygame.display.update()
                        if len(stones[WHITE]) + len(stones[BLACK]) == ROWS * COLS - BLACK_HOLES:
                            game_over = True
                        player_turn = BLACK
                else:
                    if bot_difficulty == "fácil":
                        row, col = easy_bot(stones, black_holes)
                    elif bot_difficulty == "médio":
                        row, col = medium_bot(stones, black_holes, player_turn)
                    else:
                        row, col = hard_bot(stones, black_holes, player_turn)
                    if is_valid_move(row, col, stones[WHITE] + stones[BLACK], black_holes):
                        stones[player_turn].append((row, col))
                        white_points, black_points = check_win(stones)
                        draw_board()
                        draw_stones(stones, black_holes)
                        pygame.display.update()
                        if len(stones[WHITE]) + len(stones[BLACK]) == ROWS * COLS - BLACK_HOLES:
                            game_over = True
                        player_turn = WHITE

        draw_board()
        draw_stones(stones, black_holes)
        pygame.display.update()

    white_points, black_points = check_win(stones)
    if white_points > black_points:
        winner_text = "White wins!"
        normal_text = "White: {} Black: {}".format(white_points, black_points)
    elif black_points > white_points:
        winner_text = "Black wins!"
        normal_text = "White: {} Black: {}".format(white_points, black_points)
    else:
        winner_text = "It's a draw!"
        normal_text = "White: {} Black: {}".format(white_points, black_points)

    # Remove o tabuleiro da tela
    screen.blit(fundo_liso, (0,0))
    # Exibe o texto do vencedor na tela
    draw_text(winner_text, BLACK, WIDTH // 2, HEIGHT // 2 - 150 , 80)
    draw_text(normal_text, BLACK, WIDTH // 2, HEIGHT // 2 - 70  , 44 )
    draw_text(winner_text, WHITE, WIDTH // 2 - 5, HEIGHT // 2 - 155 , 80)
    draw_text(normal_text, WHITE, WIDTH // 2 - 5, HEIGHT // 2 - 75  , 44 )
    
    # Cria os botões "QUIT" e "MAIN MENU"
    quit_button_rect = pygame.Rect(275, 500, 150, 55)
    main_menu_button_rect = pygame.Rect(190, 400, 320 , 55)
    # Exibe os botões
    draw_button("QUIT", BLACK, quit_button_rect, pygame.font.Font("Crang.ttf", 30))
    draw_button("MAIN MENU", BLACK, main_menu_button_rect, pygame.font.Font("Crang.ttf", 30))

    pygame.display.update()

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if quit_button_rect.collidepoint(event.pos):
                    pygame.quit()
                    sys.exit()
                elif main_menu_button_rect.collidepoint(event.pos):
                    main()


if __name__ == "__main__":
    main()
Leave a Comment