The Python content practiced today is Python Day 14 – Snake Game.Reference link:https://mp.weixin.qq.com/s/_Ww9sXfxoMIfHfVafu7HCAUsing the arcade library to set up the framework – pip install arcade
import arcade # Import the arcade library for graphics rendering and game development
import random # Import the random library for generating random numbers
# Define a 2D vector class to represent position and direction
class Vector2:
def __init__(self, x, y):
self.x = x # x coordinate
self.y = y # y coordinate
# Define vector addition to allow direct addition of two Vector2 objects
def __add__(self, other):
return Vector2(self.x + other.x, self.y + other.y)
# Define equality operation to compare two Vector2 objects
def __eq__(self, other):
return self.x == other.x and self.y == other.y
# Direction dictionary storing unit vectors for up, down, left, right movement
DIRECTIONS = {
"up": Vector2(0, 1), # Move up
"down": Vector2(0, -1), # Move down
"left": Vector2(-1, 0), # Move left
"right": Vector2(1, 0), # Move right
}
# Game state class storing the snake's position, direction, food, etc.
class GameState:
def __init__(self, width=20, height=20):
self.snake = [Vector2(5, 5)] # Initialize snake position, initial length is 1
self.direction = DIRECTIONS["right"] # Initial direction is right
self.food = self._generate_food() # Generate food
self.score = 0 # Score
self.game_over = False # Flag indicating if the game is over
# Generate food ensuring it does not appear on the snake's body
def _generate_food(self):
while True:
new_food = Vector2(random.randint(0, 19), random.randint(0, 19)) # Randomly generate food position in the range 0-19
if new_food not in self.snake: # Ensure food does not appear on the snake's body
return new_food
# Snake game window class, inheriting from arcade.Window
class SnakeGame(arcade.Window):
def __init__(self):
super().__init__(width=400, height=400, title="Snake Game") # Set window size and title
self.cell_size = 20 # Size of each cell
self.game = GameState() # Create game state object
arcade.set_background_color(arcade.color.BLACK) # Set background color to black
# Control snake's movement speed (in seconds)
self.move_interval = 0.2 # Move every 0.2 seconds
self.time_since_last_move = 0.0 # Record time since last move
# Draw game content
def on_draw(self):
self.clear() # Clear the screen
# Draw each segment of the snake
for segment in self.game.snake:
arcade.draw_rect_filled(
arcade.rect.XYWH(
segment.x * self.cell_size + 1, # Calculate x coordinate for drawing
segment.y * self.cell_size + 1, # Calculate y coordinate for drawing
self.cell_size - 2, # Width
self.cell_size - 2 # Height
),
arcade.color.GREEN # Set snake color to green
)
# Draw food
arcade.draw_circle_filled(
self.game.food.x * self.cell_size + self.cell_size // 2, # Calculate food's x coordinate
self.game.food.y * self.cell_size + self.cell_size // 2, # Calculate food's y coordinate
self.cell_size // 2 - 2, # Calculate food's radius
arcade.color.RED # Set food color to red
)
# Display score
arcade.draw_text(
f"Score: {self.game.score}", # Text content
10, self.height - 30, # Text position (top left)
arcade.color.WHITE, # Text color
16 # Text size
)
# Game logic update, called once per frame
def on_update(self, delta_time):
if not self.game.game_over: # Only update if the game is not over
self.time_since_last_move += delta_time # Accumulate time
# Move only if accumulated time exceeds move interval
if self.time_since_last_move >= self.move_interval:
self.time_since_last_move = 0.0 # Reset timer
self._move_snake() # Move snake
self._check_collisions() # Check for collisions
# Move snake
def _move_snake(self):
new_head = self.game.snake[-1] + self.game.direction # Calculate new head position
self.game.snake.append(new_head) # Add new head to snake
if new_head == self.game.food: # If snake eats food
self.game.score += 1 # Increase score by 1
self.game.food = self.game._generate_food() # Generate new food
else:
self.game.snake.pop(0) # If not eating food, remove tail (maintain length)
# Check if snake hits wall or bites itself
def _check_collisions(self):
head = self.game.snake[-1] # Get head position
if not (0 <= head.x < 20 and 0 <= head.y < 20): # Check if out of bounds
self.game.game_over = True # End game
if head in self.game.snake[:-1]: # Check if bites itself
self.game.game_over = True # End game
# Handle keyboard input
def on_key_press(self, key, modifiers):
# Up arrow key, prevent direct reversal
if key == arcade.key.UP and self.game.direction != DIRECTIONS["down"]:
self.game.direction = DIRECTIONS["up"]
# Down arrow key, prevent direct reversal
elif key == arcade.key.DOWN and self.game.direction != DIRECTIONS["up"]:
self.game.direction = DIRECTIONS["down"]
# Left arrow key, prevent direct reversal
elif key == arcade.key.LEFT and self.game.direction != DIRECTIONS["right"]:
self.game.direction = DIRECTIONS["left"]
# Right arrow key, prevent direct reversal
elif key == arcade.key.RIGHT and self.game.direction != DIRECTIONS["left"]:
self.game.direction = DIRECTIONS["right"]
# Run the game
if __name__ == "__main__":
game = SnakeGame() # Create game window
arcade.run() # Run game
The actual running effect is:Today’s CTF content practiced isSimpleRev
Problem-solving reference link:https://www.cnblogs.com/murasame520/p/18519135
Key Points: Big-endian, Little-endian, Analyzing Pseudocode
As usual, first check the shell, 64-bit program:
Analyze in IDA64, shift+f12:
Enter the key strings:
Ctrl+x cross-reference:
View disassembled code:
This problem examines the judgment of big-endian and little-endian, but the author is not very familiar with this part of knowledge. Therefore, the content from the reference link is quoted here.
Write a script
text = 'killshadow'
key = 'adsfkndcls'
flag = ''
v5 = len(key)
for i in range(10): # Input ten characters, so loop ten times
for j in range(ord('A'), ord('z')+1): # Try all letters to find characters that can make the if condition succeed
str2 = (j -39 - ord(key[i % v5]) +97) % 26 + 97 # Directly copy the original encryption here, ord(key[i % v5]) is needed because python cannot directly convert strings to ascii codes
if chr(str2) == text[i]: # Compare the calculated ascii code chr() with the text content
flag += chr(j) break # The break here means if the if condition succeeds once, end this inner loop and start the second outer loop, if there is no break, it will output many other characters that satisfy the condition
print(flag)
The output result is KLDQCUDFZO, therefore flag{KLDQCUDFZO}.
The problem-solving is correct, solved, time to get off work!