Board logo

標題: Google Gemini 新模型 2.5 Pro 處理複雜問題 [打印本頁]

作者: javacomhk    時間: 2025-4-1 13:00     標題: Google Gemini 新模型 2.5 Pro 處理複雜問題

本帖最後由 javacomhk 於 2025-4-1 11:10 編輯

[attach]2471820[/attach]

編碼能力領先 OpenAI 、 Claude 及 Grok3
[attach]2471821[/attach]

測試 Google Gemini Programming task 的 tetrasnake.py
Comparing it with Grok 3 code at https://x.ai/news/grok-3
Prompt:
Create a game that is a mixture of two classic games. Make it in pygame with sound effects and make it look pretty.
  1. import pygame
  2. import random
  3. import sys # Needed for sys.exit()

  4. # --- Constants ---
  5. SCREEN_WIDTH = 400
  6. SCREEN_HEIGHT = 600
  7. GRID_SIZE = 30
  8. GRID_WIDTH = SCREEN_WIDTH // GRID_SIZE # Grid dimensions in cells
  9. GRID_HEIGHT = SCREEN_HEIGHT // GRID_SIZE

  10. # Center the grid horizontally
  11. BOARD_WIDTH = 10 # Width of the playable Tetris area
  12. BOARD_HEIGHT = 20 # Height of the playable Tetris area (visible)
  13. BOARD_X_OFFSET = (GRID_WIDTH - BOARD_WIDTH) // 2
  14. BOARD_Y_OFFSET = (GRID_HEIGHT - BOARD_HEIGHT) # Keep board aligned to bottom for snake

  15. # Colors (Can be customized for a prettier look)
  16. WHITE = (255, 255, 255)
  17. BLACK = (0, 0, 0)
  18. GRAY = (128, 128, 128)
  19. CYAN = (0, 255, 255)
  20. BLUE = (0, 0, 255)
  21. ORANGE = (255, 165, 0)
  22. YELLOW = (255, 255, 0)
  23. GREEN = (0, 255, 0)
  24. PURPLE = (128, 0, 128)
  25. RED = (255, 0, 0)
  26. SNAKE_HEAD_COLOR = (200, 200, 0) # Distinct color for snake head
  27. SNAKE_BODY_COLOR = YELLOW # Use Tetris yellow for consistency

  28. # Tetromino Shapes (coordinates relative to top-left pivot)
  29. SHAPES = [
  30.     [[1, 1, 1, 1]], # I
  31.     [[1, 1], [1, 1]], # O
  32.     [[0, 1, 0], [1, 1, 1]], # T
  33.     [[1, 0, 0], [1, 1, 1]], # L
  34.     [[0, 0, 1], [1, 1, 1]], # J
  35.     [[0, 1, 1], [1, 1, 0]], # S
  36.     [[1, 1, 0], [0, 1, 1]]  # Z
  37. ]

  38. SHAPE_COLORS = [CYAN, YELLOW, PURPLE, ORANGE, BLUE, GREEN, RED] # Colors corresponding to SHAPES

  39. # Game Settings
  40. INITIAL_FALL_SPEED = 500 # Milliseconds per grid step down
  41. SPEED_INCREMENT = 20 # Speed increase per line clear
  42. MIN_FALL_SPEED = 100 # Fastest speed
  43. INITIAL_SNAKE_LENGTH = 3

  44. # --- Sound Effect Placeholders ---
  45. # Replace 'None' with loaded sound objects using pygame.mixer.Sound('path/to/sound.wav')
  46. # You'll need to find or create these sound files (.wav or .ogg recommended)
  47. try:
  48.     pygame.mixer.init()
  49.     # move_sound = pygame.mixer.Sound('sounds/move.wav') # Example
  50.     # rotate_sound = pygame.mixer.Sound('sounds/rotate.wav') # Example
  51.     lock_sound = pygame.mixer.Sound('sounds/lock.wav') if pygame.mixer.get_init() else None
  52.     clear_sound = pygame.mixer.Sound('sounds/clear.wav') if pygame.mixer.get_init() else None
  53.     grow_sound = pygame.mixer.Sound('sounds/grow.wav') if pygame.mixer.get_init() else None
  54.     game_over_sound = pygame.mixer.Sound('sounds/game_over.wav') if pygame.mixer.get_init() else None
  55.     # Background music?
  56.     # pygame.mixer.music.load('sounds/background.ogg')
  57.     # pygame.mixer.music.play(-1) # Loop indefinitely
  58. except pygame.error as e:
  59.     print(f"Warning: Could not initialize mixer or load sounds: {e}")
  60.     lock_sound, clear_sound, grow_sound, game_over_sound = None, None, None, None

  61. def play_sound(sound):
  62.     """Safely plays a sound effect if it's loaded."""
  63.     if sound:
  64.         sound.play()

  65. # --- Classes ---
  66. class Tetromino:
  67.     def __init__(self, x, y, shape_index):
  68.         self.x = x
  69.         self.y = y
  70.         self.shape_index = shape_index
  71.         self.shape = SHAPES[shape_index]
  72.         self.color = SHAPE_COLORS[shape_index]
  73.         self.rotation = 0 # Not implementing rotation for falling pieces in this version yet

  74.     def draw(self, surface, grid_x_offset, grid_y_offset):
  75.         for r_idx, row in enumerate(self.shape):
  76.             for c_idx, cell in enumerate(row):
  77.                 if cell:
  78.                     pygame.draw.rect(
  79.                         surface,
  80.                         self.color,
  81.                         (
  82.                             (self.x + c_idx + grid_x_offset) * GRID_SIZE,
  83.                             (self.y + r_idx + grid_y_offset) * GRID_SIZE,
  84.                             GRID_SIZE - 1, # -1 for grid lines
  85.                             GRID_SIZE - 1
  86.                         )
  87.                     )
  88.                     # Add a slightly darker border for definition
  89.                     pygame.draw.rect(
  90.                         surface,
  91.                         tuple(max(0, c-50) for c in self.color), # Darker color
  92.                         (
  93.                             (self.x + c_idx + grid_x_offset) * GRID_SIZE,
  94.                             (self.y + r_idx + grid_y_offset) * GRID_SIZE,
  95.                             GRID_SIZE - 1,
  96.                             GRID_SIZE - 1
  97.                         ), 1 # Border width
  98.                     )

  99.     def move(self, dx, dy):
  100.         self.x += dx
  101.         self.y += dy

  102.     def get_block_positions(self):
  103.         """Returns list of (x, y) grid coordinates for each block in the piece."""
  104.         positions = []
  105.         for r_idx, row in enumerate(self.shape):
  106.             for c_idx, cell in enumerate(row):
  107.                 if cell:
  108.                     positions.append((self.x + c_idx, self.y + r_idx))
  109.         return positions

  110. class Snake:
  111.     def __init__(self, initial_x, initial_y, length):
  112.         self.segments = [(initial_x - i, initial_y) for i in range(length)] # Head is at index 0
  113.         self.direction = (1, 0) # Initial movement (not used for player control here)
  114.         self.head_color = SNAKE_HEAD_COLOR
  115.         self.body_color = SNAKE_BODY_COLOR

  116.     def move(self, dx):
  117.         """Moves the entire snake horizontally."""
  118.         new_segments = []
  119.         can_move = True
  120.         for i, (sx, sy) in enumerate(self.segments):
  121.             new_x = sx + dx
  122.             # Basic boundary check (adjust if needed for board offset)
  123.             if not (0 <= new_x < BOARD_WIDTH):
  124.                  can_move = False
  125.                  break
  126.             new_segments.append((new_x, sy))

  127.         if can_move:
  128.             self.segments = new_segments
  129.             # play_sound(move_sound) # Sound for snake move

  130.     def grow(self, amount=1):
  131.         """Adds segments to the tail."""
  132.         if not self.segments: return # Cannot grow if snake doesn't exist

  133.         # Determine tail direction to add new segment logically
  134.         # (Simplification: always add to the 'left' based on current list order)
  135.         last_x, last_y = self.segments[-1]
  136.         # We'll just add it conceptually off-screen left, it'll correct position on next move?
  137.         # Or better: find the leftmost segment and add left of that.
  138.         min_x = min(x for x, y in self.segments)
  139.         new_segment_pos = (min_x - 1, last_y) # Add left of the leftmost block
  140.         
  141.         # Check if new segment position is valid (within bounds) - It might initially be outside!
  142.         # We rely on the next player move to bring it potentially back into bounds.
  143.         # A better approach might be needed if snake wraps or complex growth is desired.
  144.         
  145.         for _ in range(amount):
  146.              self.segments.append(new_segment_pos) # Add multiple segments if needed
  147.              new_segment_pos = (new_segment_pos[0] - 1, new_segment_pos[1]) # Continue left
  148.         play_sound(grow_sound)

  149.     def draw(self, surface, grid_x_offset, grid_y_offset):
  150.         for i, (x, y) in enumerate(self.segments):
  151.              # Only draw segments within the visible board area
  152.              if 0 <= x < BOARD_WIDTH and 0 <= y < BOARD_HEIGHT :
  153.                 color = self.head_color if i == 0 else self.body_color
  154.                 # Draw slightly smaller rects for grid effect
  155.                 pygame.draw.rect(
  156.                     surface,
  157.                     color,
  158.                     (
  159.                         (x + grid_x_offset) * GRID_SIZE,
  160.                         (y + grid_y_offset) * GRID_SIZE,
  161.                         GRID_SIZE - 1,
  162.                         GRID_SIZE - 1
  163.                     )
  164.                 )
  165.                 # Border
  166.                 pygame.draw.rect(
  167.                     surface,
  168.                     tuple(max(0, c-50) for c in color),
  169.                     (
  170.                         (x + grid_x_offset) * GRID_SIZE,
  171.                         (y + grid_y_offset) * GRID_SIZE,
  172.                         GRID_SIZE - 1,
  173.                         GRID_SIZE - 1
  174.                     ), 1
  175.                 )


  176.     def get_head_pos(self):
  177.         return self.segments[0] if self.segments else None

  178.     def get_body_positions(self):
  179.         return self.segments[1:] if len(self.segments) > 1 else []
  180.    
  181.     def get_all_positions(self):
  182.         return self.segments

  183. # --- Game Functions ---

  184. def create_grid(locked_positions={}):
  185.     """Create the board grid structure."""
  186.     grid = [[BLACK for _ in range(BOARD_WIDTH)] for _ in range(BOARD_HEIGHT)] # Visible grid

  187.     # Fill grid with colors of locked pieces
  188.     for y in range(BOARD_HEIGHT):
  189.         for x in range(BOARD_WIDTH):
  190.             if (x, y) in locked_positions:
  191.                 color = locked_positions[(x, y)]
  192.                 grid[y][x] = color
  193.     return grid

  194. def draw_grid(surface, grid, grid_x_offset, grid_y_offset):
  195.     """Draw the grid lines."""
  196.     for y in range(BOARD_HEIGHT):
  197.         for x in range(BOARD_WIDTH):
  198.              # Draw cell background (already done by filling 'grid' in create_grid)
  199.              pygame.draw.rect(
  200.                  surface,
  201.                  grid[y][x],
  202.                  (
  203.                      (x + grid_x_offset) * GRID_SIZE,
  204.                      (y + grid_y_offset) * GRID_SIZE,
  205.                      GRID_SIZE,
  206.                      GRID_SIZE
  207.                  ),
  208.                  0 # Fill the cell
  209.              )
  210.              # Draw border for the cell
  211.              pygame.draw.rect(
  212.                  surface,
  213.                  GRAY, # Grid line color
  214.                  (
  215.                      (x + grid_x_offset) * GRID_SIZE,
  216.                      (y + grid_y_offset) * GRID_SIZE,
  217.                      GRID_SIZE,
  218.                      GRID_SIZE
  219.                  ),
  220.                  1 # Border width
  221.              )

  222. def draw_window(surface, grid, score=0, snake=None, current_piece=None, next_piece=None):
  223.     """Draws all elements onto the screen."""
  224.     surface.fill(BLACK) # Background

  225.     # Title
  226.     font = pygame.font.SysFont('comicsans', 40)
  227.     label = font.render('TetraSnake', 1, WHITE)
  228.     surface.blit(label, (SCREEN_WIDTH / 2 - label.get_width() / 2, 15))

  229.     # Draw the Play Area Grid and locked pieces
  230.     draw_grid(surface, grid, BOARD_X_OFFSET, BOARD_Y_OFFSET)

  231.     # Draw the falling piece
  232.     if current_piece:
  233.         current_piece.draw(surface, BOARD_X_OFFSET, BOARD_Y_OFFSET)

  234.     # Draw the snake
  235.     if snake:
  236.         snake.draw(surface, BOARD_X_OFFSET, BOARD_Y_OFFSET)

  237.     # Draw Score
  238.     score_label = font.render(f'Score: {score}', 1, WHITE)
  239.     sx = SCREEN_WIDTH - score_label.get_width() - 20
  240.     sy = 50 # Position score top right
  241.     surface.blit(score_label, (sx, sy))

  242.     # Draw Next Piece (optional - needs UI space)
  243.     if next_piece:
  244.         nx_label = pygame.font.SysFont('comicsans', 25).render('Next:', 1, WHITE)
  245.         nx_x = SCREEN_WIDTH - nx_label.get_width() - 40
  246.         nx_y = 100
  247.         surface.blit(nx_label, (nx_x, nx_y))
  248.         # Adjust position for drawing the small preview piece
  249.         preview_piece = Tetromino(0, 0, next_piece.shape_index) # Temp piece for drawing
  250.         preview_piece.draw(surface, (nx_x // GRID_SIZE) + 1, (nx_y // GRID_SIZE) + 1)


  251.     # Update the display
  252.     # pygame.display.update() # Use flip() at end of main loop instead for full screen update

  253. def get_new_piece():
  254.     """Returns a new random Tetromino at the top center."""
  255.     shape_idx = random.randint(0, len(SHAPES) - 1)
  256.     # Start piece above the visible grid
  257.     start_x = BOARD_WIDTH // 2 - len(SHAPES[shape_idx][0]) // 2
  258.     start_y = 0 # Start at the very top row
  259.     return Tetromino(start_x, start_y, shape_idx)

  260. def is_valid_position(piece, grid, locked_positions, snake):
  261.     """Checks if the piece is in a valid position (within bounds, not overlapping)."""
  262.     accepted_pos = [[(x, y) for x in range(BOARD_WIDTH) if y >= 0] for y in range(BOARD_HEIGHT)]
  263.     accepted_pos = [item for sublist in accepted_pos for item in sublist] # Flatten

  264.     formatted = piece.get_block_positions()

  265.     for pos in formatted:
  266.         x, y = pos
  267.         if x < 0 or x >= BOARD_WIDTH or y >= BOARD_HEIGHT: # Check bounds (allow y<0 initially)
  268.             return False
  269.         if y >= 0: # Only check grid/locked if within visible area
  270.              # Check collision with locked pieces
  271.              if (x, y) in locked_positions:
  272.                  return False
  273.              # Check collision with snake's body (not head)
  274.              if snake and pos in snake.get_body_positions():
  275.                  return False # Cannot land on snake body yet (becomes locked)


  276.     return True

  277. def check_lost(locked_positions, snake):
  278.     """Checks if the game is over."""
  279.     # 1. Block reached the top
  280.     for x, y in locked_positions:
  281.         if y < 1: # Piece locked in the topmost row (or above)
  282.             return True
  283.             
  284.     # 2. Falling piece collided with snake head (handled during locking) - Implicitly checked below

  285.     # 3. Snake collided with itself (not implemented)

  286.     return False

  287. def clear_lines(grid, locked_positions):
  288.     """Checks for and clears completed lines, returns number of lines cleared."""
  289.     lines_cleared = 0
  290.     full_rows = []

  291.     # Check from bottom up
  292.     for y in range(BOARD_HEIGHT - 1, -1, -1):
  293.         row_full = True
  294.         for x in range(BOARD_WIDTH):
  295.             if (x, y) not in locked_positions:
  296.                 row_full = False
  297.                 break
  298.         if row_full:
  299.             lines_cleared += 1
  300.             full_rows.append(y)
  301.             play_sound(clear_sound)
  302.             # Mark row for clearing visually (optional flashing effect could go here)
  303.             for x in range(BOARD_WIDTH):
  304.                  # Temporarily change color? Or handle in draw loop
  305.                  pass


  306.     if lines_cleared > 0:
  307.         # Remove cleared rows from locked_positions
  308.         new_locked = {}
  309.         rows_to_shift = sorted(full_rows) # Sort ascending for correct shifting

  310.         for (x, y), color in locked_positions.items():
  311.             if y not in rows_to_shift:
  312.                  # Calculate how many cleared rows were below this position
  313.                  shift_down = sum(1 for cleared_y in rows_to_shift if cleared_y > y)
  314.                  new_locked[(x, y + shift_down)] = color # Add shifted block to new dict
  315.         
  316.         return lines_cleared, new_locked

  317.     return 0, locked_positions # No lines cleared, return original


  318. def draw_text_middle(surface, text, size, color):
  319.     font = pygame.font.SysFont('comicsans', size, bold=True)
  320.     label = font.render(text, 1, color)
  321.     surface.blit(label, (SCREEN_WIDTH / 2 - label.get_width() / 2, SCREEN_HEIGHT / 2 - label.get_height() / 2))

  322. # --- Main Game Loop ---
  323. def main():
  324.     pygame.init()
  325.     screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
  326.     pygame.display.set_caption("TetraSnake")

  327.     locked_positions = {} # (x, y): color
  328.     grid = create_grid(locked_positions)

  329.     change_piece = False
  330.     run = True
  331.     current_piece = get_new_piece()
  332.     next_piece = get_new_piece()
  333.     clock = pygame.time.Clock()
  334.     fall_time = 0
  335.     fall_speed = INITIAL_FALL_SPEED
  336.     level_time = 0 # Could be used for speed increase over time too
  337.     score = 0

  338.     # Initialize Snake at the bottom center
  339.     snake_start_y = BOARD_HEIGHT - 1 # Last row
  340.     snake_start_x = BOARD_WIDTH // 2
  341.     player_snake = Snake(snake_start_x, snake_start_y, INITIAL_SNAKE_LENGTH)

  342.     game_over = False

  343.     while run:
  344.         grid = create_grid(locked_positions) # Update grid based on locked pieces
  345.         fall_time += clock.get_rawtime() # Time since last frame
  346.         level_time += clock.get_rawtime()
  347.         clock.tick() # Control FPS (let Pygame manage it)

  348.         # --- Automatic Falling ---
  349.         if not game_over and fall_time / 1000 * (1000 / fall_speed) >= 1: # Time based fall
  350.             fall_time = 0
  351.             current_piece.move(0, 1) # Move down one step
  352.             
  353.             # Check if landed
  354.             if not is_valid_position(current_piece, grid, locked_positions, player_snake):
  355.                 current_piece.move(0, -1) # Move back up
  356.                
  357.                 # Check for collision with Snake Head -> Game Over
  358.                 piece_blocks = current_piece.get_block_positions()
  359.                 snake_head = player_snake.get_head_pos()
  360.                 if snake_head and any(block == snake_head for block in piece_blocks):
  361.                      game_over = True
  362.                      play_sound(game_over_sound)
  363.                      # Optional: Show piece overlapping head briefly
  364.                      draw_window(screen, grid, score, player_snake, current_piece, next_piece)
  365.                      pygame.display.flip()
  366.                      pygame.time.wait(500) # Short pause
  367.                
  368.                 if not game_over:
  369.                     # Lock the piece
  370.                     for pos in piece_blocks:
  371.                         x, y = pos
  372.                         if y >= 0: # Only lock blocks within the visible grid
  373.                            locked_positions[(x, y)] = current_piece.color
  374.                     play_sound(lock_sound)
  375.                     change_piece = True # Signal to get a new piece


  376.         # --- Event Handling ---
  377.         for event in pygame.event.get():
  378.             if event.type == pygame.QUIT:
  379.                 run = False
  380.                 pygame.quit()
  381.                 sys.exit()

  382.             if event.type == pygame.KEYDOWN:
  383.                  if not game_over:
  384.                      if event.key == pygame.K_LEFT:
  385.                          player_snake.move(-1)
  386.                          # Check snake collision with locked pieces after move (optional for difficulty)
  387.                          # If head hits a locked piece? Maybe game over?

  388.                      elif event.key == pygame.K_RIGHT:
  389.                           player_snake.move(1)
  390.                           # Check snake collision...

  391.                      # Tetris Controls (Apply to falling piece) - Can be complex with snake
  392.                      # For simplicity, let's *not* allow player control of falling piece for now
  393.                      # Focus on snake movement first.

  394.                      # elif event.key == pygame.K_DOWN: # Soft drop
  395.                      #     current_piece.move(0, 1)
  396.                      #     if not is_valid_position(current_piece, grid, locked_positions, player_snake):
  397.                      #         current_piece.move(0, -1) # Undo if invalid
  398.                      
  399.                      # elif event.key == pygame.K_UP: # Rotate (Harder to implement correctly)
  400.                      #     # Add rotation logic here
  401.                      #     pass # play_sound(rotate_sound)

  402.                      # elif event.key == pygame.K_SPACE: # Hard drop
  403.                      #      while is_valid_position(current_piece, grid, locked_positions, player_snake):
  404.                      #          current_piece.move(0, 1)
  405.                      #      current_piece.move(0, -1) # Move back one step
  406.                      #      # Lock piece immediately after hard drop (similar logic to landing)
  407.                      #      piece_blocks = current_piece.get_block_positions()
  408.                      #      if snake_head and any(block == snake_head for block in piece_blocks):
  409.                      #          game_over = True
  410.                      #          play_sound(game_over_sound)
  411.                      #      else:
  412.                      #          for pos in piece_blocks:
  413.                      #               x,y = pos
  414.                      #               if y >=0: locked_positions[(x,y)] = current_piece.color
  415.                      #          play_sound(lock_sound)
  416.                      #          change_piece = True


  417.                  if game_over and event.key == pygame.K_RETURN: # Restart game
  418.                      main() # Call main again to reset everything


  419.         # --- Piece Locking and New Piece ---
  420.         if change_piece and not game_over:
  421.             # Check for cleared lines BEFORE getting the new piece
  422.             lines_cleared, locked_positions = clear_lines(grid, locked_positions)
  423.             
  424.             if lines_cleared > 0:
  425.                  score += lines_cleared * 10 # Simple scoring
  426.                  player_snake.grow(lines_cleared * 4) # Grow snake by blocks cleared (4 per line avg?)
  427.                  # Increase speed
  428.                  fall_speed = max(MIN_FALL_SPEED, fall_speed - (SPEED_INCREMENT * lines_cleared))


  429.             # Get the next piece
  430.             current_piece = next_piece
  431.             next_piece = get_new_piece()
  432.             change_piece = False

  433.             # Check if the new piece immediately causes a loss (spawn overlap)
  434.             if not is_valid_position(current_piece, grid, locked_positions, player_snake):
  435.                 game_over = True
  436.                 play_sound(game_over_sound)

  437.         # --- Game Over Check ---
  438.         if not game_over:
  439.             # Check loss condition based on locked pieces height (redundant with spawn check?)
  440.              if check_lost(locked_positions, player_snake):
  441.                 game_over = True
  442.                 play_sound(game_over_sound)


  443.         # --- Drawing ---
  444.         draw_window(screen, grid, score, player_snake, current_piece, next_piece)

  445.         if game_over:
  446.             draw_text_middle(screen, "GAME OVER!", 80, RED)
  447.             draw_text_middle(screen, f"Score: {score}", 50, WHITE, y_offset=50) # Offset score display
  448.             draw_text_middle(screen, "Press ENTER to Play Again", 30, WHITE, y_offset=100)


  449.         pygame.display.flip() # Update the full screen

  450. # Function to draw text with offset easily
  451. def draw_text_middle(surface, text, size, color, y_offset=0):
  452.     font = pygame.font.SysFont('comicsans', size, bold=True)
  453.     label = font.render(text, 1, color)
  454.     text_rect = label.get_rect(center=(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2 + y_offset))
  455.     surface.blit(label, text_rect)


  456. if __name__ == "__main__":
  457.     main()
複製代碼





歡迎光臨 電腦領域 HKEPC Hardware (https://h2.hkepc.com/forum/) Powered by Discuz! 7.2