Advertisement
here2share

# tk_attraction_vs_repulsion.py

Mar 7th, 2024
1,009
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.78 KB | None | 0 0
  1. # tk_attraction_vs_repulsion.py
  2.  
  3. import tkinter as tk
  4. import random
  5. import math
  6. from PIL import Image, ImageTk, ImageDraw
  7.  
  8. WINDOW_WIDTH = 600
  9. WINDOW_HEIGHT = 600
  10. CX, CY = WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2
  11. ROCK_COUNT = PAPER_COUNT = SCISSORS_COUNT = 100
  12. EDGE_AVOID_RADIUS = 20
  13. REPULSION_RADIUS = 20
  14. SPEED = 1
  15.  
  16. root = tk.Tk()
  17. root.title("tk_attraction_vs_repulsion")
  18. root.geometry("%dx%d+%d+%d" % (WINDOW_WIDTH, WINDOW_HEIGHT, 10, 10))
  19.  
  20. canvas = tk.Canvas(root, width=WINDOW_WIDTH, height=WINDOW_HEIGHT, bg="white")
  21. canvas.pack()
  22.  
  23. tribe_color = {
  24.     "rock": "red",
  25.     "paper": "lime",
  26.     "scissors": "black"
  27. }
  28.  
  29. chase = {
  30.     "rock": "scissors",
  31.     "scissors": "paper",
  32.     "paper": "rock",
  33. }
  34.  
  35. cxy = {
  36.     "rock": "",
  37.     "scissors": "",
  38.     "paper": ""
  39. }
  40.  
  41. food_chain = '{rock} > {scissors} > {paper} > {rock}'.format_map(tribe_color)
  42.  
  43. def offset(t=1.2):
  44.     return random.uniform(-t, t)
  45.  
  46. def avoid_edges():
  47.     x0 = min(WINDOW_WIDTH - EDGE_AVOID_RADIUS, max(x, EDGE_AVOID_RADIUS))
  48.     y0 = min(WINDOW_HEIGHT - EDGE_AVOID_RADIUS, max(y, EDGE_AVOID_RADIUS))
  49.     return x0, y0
  50.    
  51. def avoid_entities(x, y):
  52.     for j, (x2, y2, entity2) in enumerate(entities):
  53.         if i != j:
  54.             distance = distance_to(x, y, x2, y2)
  55.             if distance < REPULSION_RADIUS:
  56.                 angle = math.atan2(y - y2, x - x2)
  57.                 x += 5 * math.cos(angle)
  58.                 y += 5 * math.sin(angle)
  59.                 return x, y
  60.     return x, y
  61.  
  62. def movement(x, y, target_x, target_y):
  63.     angle = math.atan2(y - target_y, x - target_x) + if_rev
  64.     x += SPEED * math.cos(angle + offset())
  65.     y += SPEED * math.sin(angle + offset())
  66.     return x, y
  67.  
  68. def distance_to(x1, y1, x2, y2):
  69.     return math.sqrt((x1 - x2)**2 + (y1 - y2)**2)
  70.  
  71. def draw_entity(x, y, entity):
  72.     color = tribe_color[entity]
  73.     draw.ellipse((x - 2, y - 2, x + 2, y + 2), fill=color, outline=color)
  74.  
  75. def start(event=0):
  76.     global entities
  77.     entities = [(random.randint(0, WINDOW_WIDTH), random.randint(0, WINDOW_HEIGHT), "rock") for _ in range(ROCK_COUNT)]
  78.     entities += [(random.randint(0, WINDOW_WIDTH), random.randint(0, WINDOW_HEIGHT), "paper") for _ in range(PAPER_COUNT)]
  79.     entities += [(random.randint(0, WINDOW_WIDTH), random.randint(0, WINDOW_HEIGHT), "scissors") for _ in range(SCISSORS_COUNT)]
  80.     random.shuffle(entities)
  81.  
  82. start()
  83. root.bind("<space>", start)
  84.  
  85. while True:
  86.     pil_image = Image.new('RGB', (WINDOW_WIDTH, WINDOW_HEIGHT), color='white')
  87.     draw = ImageDraw.Draw(pil_image)
  88.  
  89.     for i, (x, y, entity) in enumerate(entities):
  90.         x0, y0 = CX, CY
  91.         if_rev = math.pi
  92.         x, y = movement(x, y, x0, y0)
  93.         x, y = avoid_edges()
  94.         x, y = avoid_entities(x, y)
  95.         draw_entity(x, y, entity)
  96.         entities[i] = (x, y, entity)
  97.  
  98.     photo_image = ImageTk.PhotoImage(pil_image)
  99.  
  100.     canvas.create_image(0, 0, anchor='nw', image=photo_image)
  101.     root.update()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement