Advertisement
pinguy

QSnake: Quantum Snake Game with Quantum Noise

Oct 5th, 2024
226
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.72 KB | Science | 0 0
  1. #!/usr/bin/python
  2.  
  3. from qiskit import QuantumCircuit, Aer, execute, transpile
  4. import tkinter as tk
  5. import random
  6.  
  7. # Define the size of the grid (10x10 grid using 100 qubits)
  8. grid_size = 100 # 10x10 grid
  9. qc = QuantumCircuit(grid_size, grid_size)
  10.  
  11. # Player snake body, represented as a list of positions (initially just the head)
  12. snake_body = [0] # Start with the snake having just one segment (head)
  13. direction = "Right" # Default direction
  14.  
  15. # Food (red block) initial random position
  16. food_position = random.randint(0, grid_size - 1)
  17.  
  18. # Counter for food eaten
  19. food_eaten_count = 0 # Start with zero food eaten
  20.  
  21. # Random toggle state
  22. random_enabled = False # Start with randomness disabled
  23.  
  24. # Noise simulation state
  25. simulate_noise = False # Start with noise simulation disabled
  26.  
  27. # Function to toggle randomness on and off
  28. def toggle_randomness(event):
  29. global random_enabled
  30. random_enabled = not random_enabled # Toggle between True and False
  31. if random_enabled:
  32. print("Randomness Enabled")
  33. else:
  34. print("Randomness Disabled")
  35.  
  36. # Function to toggle noise simulation on and off
  37. def toggle_noise_simulation(event):
  38. global simulate_noise
  39. simulate_noise = not simulate_noise
  40. if simulate_noise:
  41. print("Noise Simulation Enabled")
  42. log_noise_event("Noise Simulation Enabled")
  43. else:
  44. print("Noise Simulation Disabled")
  45. log_noise_event("Noise Simulation Disabled")
  46.  
  47. # Function to apply quantum noise simulation
  48. def apply_quantum_noise():
  49. if simulate_noise:
  50. # 10% chance of random direction change
  51. if random.random() < 0.1:
  52. new_direction = random.choice(["Left", "Right", "Up", "Down"])
  53. event_message = f"Quantum Noise! Random direction change to {new_direction}."
  54. print(event_message)
  55. log_noise_event(event_message) # Log the event
  56. return new_direction
  57. # 5% chance of teleporting snake to a random grid position (quantum glitch!)
  58. if random.random() < 0.05:
  59. event_message = "Quantum Glitch! Snake teleported."
  60. print(event_message)
  61. log_noise_event(event_message) # Log the event
  62. return 'teleport'
  63. return None
  64.  
  65. # Function to clear the grid
  66. def clear_grid(circuit):
  67. """Clears the entire grid by resetting all qubits to 0."""
  68. for qubit in range(grid_size):
  69. circuit.reset(qubit) # Reset all qubits to |0⟩ state
  70.  
  71. # Function to move the snake
  72. def move_snake(circuit, direction):
  73. global snake_body, food_position, food_eaten_count
  74.  
  75. # Calculate the new head position based on the direction
  76. head = snake_body[0]
  77. if direction == 'Right' and head % 10 != 9:
  78. new_head = head + 1
  79. elif direction == 'Left' and head % 10 != 0:
  80. new_head = head - 1
  81. elif direction == 'Up' and head >= 10:
  82. new_head = head - 10
  83. elif direction == 'Down' and head < 90:
  84. new_head = head + 10
  85. else:
  86. # Snake has hit the wall, end the game
  87. print("Game Over! Hit the wall.")
  88. root.quit()
  89. return
  90.  
  91. # Check for collision with itself
  92. if new_head in snake_body:
  93. print("Game Over! Hit itself.")
  94. root.quit()
  95. return
  96.  
  97. # Move the snake: add new head and remove the tail unless it just ate food
  98. snake_body.insert(0, new_head)
  99.  
  100. if new_head == food_position:
  101. # Snake has eaten the food
  102. food_position = random.randint(0, grid_size - 1)
  103. food_eaten_count += 1
  104. food_counter_label.config(text=f"Food Eaten: {food_eaten_count}")
  105. else:
  106. # Remove the last segment (tail) if no food was eaten
  107. snake_body.pop()
  108.  
  109. # Update the quantum circuit to reflect the new snake position
  110. update_grid(circuit)
  111.  
  112. # Function to randomly change direction with 70% probability
  113. def random_change_direction():
  114. if random_enabled and random.random() < 0.7: # 70% chance to change direction randomly
  115. return random.choice(["Left", "Right", "Up", "Down"])
  116. else:
  117. return None # No change if randomness is disabled
  118.  
  119. # Function to log noise events to the secondary window
  120. def log_noise_event(event):
  121. log_textbox.insert(tk.END, event + '\n') # Insert event into the text box
  122. log_textbox.see(tk.END) # Scroll to the end to always show the latest event
  123.  
  124. # Set up the main game GUI to visualize the grid
  125. root = tk.Tk()
  126. root.title("Quantum Snake Game with Food Eaten Counter and Grid State")
  127.  
  128. # Define grid dimensions (10x10)
  129. rows = 10
  130. cols = 10
  131. cell_size = 50 # Size of each cell in pixels
  132.  
  133. # Create a canvas to draw the grid
  134. canvas = tk.Canvas(root, width=cols * cell_size, height=rows * cell_size)
  135. canvas.pack()
  136.  
  137. # Create a label to display the grid state
  138. grid_state_label = tk.Label(root, text="Grid State: ")
  139. grid_state_label.pack()
  140.  
  141. # Create a label to display the food eaten counter
  142. food_counter_label = tk.Label(root, text=f"Food Eaten: {food_eaten_count}")
  143. food_counter_label.pack()
  144.  
  145. # Draw the grid on the canvas
  146. cells = []
  147. for row in range(rows):
  148. row_cells = []
  149. for col in range(cols):
  150. x1 = col * cell_size
  151. y1 = row * cell_size
  152. x2 = x1 + cell_size
  153. y2 = y1 + cell_size
  154. cell = canvas.create_rectangle(x1, y1, x2, y2, fill="white")
  155. row_cells.append(cell)
  156. cells.append(row_cells)
  157.  
  158. # Create the secondary window for logging quantum noise events
  159. log_window = tk.Toplevel(root)
  160. log_window.title("Quantum Noise Log")
  161. log_textbox = tk.Text(log_window, width=50, height=10)
  162. log_textbox.pack()
  163.  
  164. # Function to update the grid based on the quantum circuit results
  165. def update_grid(circuit):
  166. clear_grid(circuit) # Clear the quantum circuit grid
  167.  
  168. # Draw the snake body (blue)
  169. for segment in snake_body:
  170. circuit.x(segment)
  171.  
  172. # Draw the food block (red)
  173. circuit.x(food_position)
  174.  
  175. # Measure all qubits to see the final state of the grid
  176. qc.measure([i for i in range(grid_size)], [i for i in range(grid_size)])
  177.  
  178. # Use the QASM simulator to run the circuit
  179. simulator = Aer.get_backend('qasm_simulator')
  180. job = execute(qc, simulator, shots=1) # One shot to measure the final state
  181. result = job.result()
  182.  
  183. # Get the results
  184. counts = result.get_counts(qc)
  185. bitstring = list(counts.keys())[0] # Get the measured bitstring (grid state)
  186.  
  187. # Update the GUI grid based on the bitstring
  188. for i, bit in enumerate(bitstring):
  189. row = i // 10
  190. col = i % 10
  191. if i in snake_body:
  192. canvas.itemconfig(cells[row][col], fill="blue") # Snake (blue)
  193. elif i == food_position:
  194. canvas.itemconfig(cells[row][col], fill="red") # Food (red)
  195. else:
  196. canvas.itemconfig(cells[row][col], fill="white") # Empty cell
  197.  
  198. # Update the label with the current grid state (bitstring)
  199. grid_state_label.config(text=f"Grid State: {bitstring}")
  200.  
  201. # Print the grid state to the console (optional)
  202. print(f"Grid State: {bitstring}")
  203.  
  204. # Function to automatically move the snake in the current direction
  205. def auto_move():
  206. global direction
  207.  
  208. # Apply noise simulation to see if a random event occurs
  209. noise_event = apply_quantum_noise()
  210. if noise_event == 'teleport':
  211. # Quantum glitch: teleport the snake's head to a random grid position
  212. snake_body[0] = random.randint(0, grid_size - 1)
  213. elif noise_event:
  214. # Apply random direction change due to noise
  215. direction = noise_event
  216.  
  217. # Randomly change direction with a 70% chance if randomness is enabled
  218. new_direction = random_change_direction()
  219. if new_direction:
  220. direction = new_direction # Update direction to a random one
  221.  
  222. move_snake(qc, direction) # Move the snake according to the current direction
  223. root.after(500, auto_move) # Repeat every 500ms to keep moving
  224.  
  225. # Keyboard event handlers to change direction
  226. def on_key_press(event):
  227. global direction
  228. if event.keysym == 'Right':
  229. direction = 'Right'
  230. elif event.keysym == 'Left':
  231. direction = 'Left'
  232. elif event.keysym == 'Up':
  233. direction = 'Up'
  234. elif event.keysym == 'Down':
  235. direction = 'Down'
  236.  
  237. # Bind the spacebar to toggle randomness
  238. root.bind("<space>", toggle_randomness)
  239.  
  240. # Bind 'n' key to toggle noise simulation
  241. root.bind("<n>", toggle_noise_simulation)
  242.  
  243. # Bind arrow keys to change the snake movement direction
  244. root.bind("<KeyPress>", on_key_press)
  245.  
  246. # Initialize the snake on the grid and start the auto-move loop
  247. update_grid(qc) # Display the initial grid
  248. auto_move() # Start the automatic movement
  249.  
  250. # Run the Tkinter main loop
  251. root.mainloop()
  252.  
  253. # Transpile the circuit for optimization and inspection
  254. transpiled_circuit = transpile(qc, optimization_level=1)
  255.  
  256. # Get the number of qubits and gates
  257. num_qubits = transpiled_circuit.num_qubits
  258. num_gates = transpiled_circuit.size()
  259.  
  260. # Print out the number of qubits and the number of gates in the terminal
  261. print(f"Number of qubits: {num_qubits}")
  262. print(f"Number of gates: {num_gates}")
  263.  
  264. # Get the text representation of the quantum circuit as a string
  265. circuit_text_representation = transpiled_circuit.draw(output='text').__str__() # Convert to string
  266.  
  267. # Save the quantum circuit, qubit, and gate info to a text file
  268. file_path = './quantum_circuit_diagram.txt' # Specify the file path
  269. with open(file_path, 'w') as file:
  270. # Write the qubit and gate information at the top of the file
  271. file.write(f"Number of qubits: {num_qubits}\n")
  272. file.write(f"Number of gates: {num_gates}\n\n")
  273.  
  274. # Write the circuit diagram to the file
  275. file.write(circuit_text_representation)
  276.  
  277. print(f"Quantum circuit diagram and stats saved to {file_path}")
  278.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement