Advertisement
mirosh111000

PingPong(pr5)

Sep 13th, 2024 (edited)
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 16.41 KB | None | 0 0
  1. import numpy as np
  2. import pandas as pd
  3. import seaborn as sns
  4. import sys
  5. import pygame
  6. import matplotlib.pyplot as plt
  7. from sklearn.metrics import mean_squared_error
  8. from sklearn.datasets import load_breast_cancer, load_digits
  9. from sklearn.model_selection import train_test_split
  10. from sklearn.metrics import precision_score, recall_score, accuracy_score
  11. import random
  12.  
  13.  
  14. class MultiNeuralNetwork:
  15.     def __init__(self, type='reg', learning_rate=0.01, epochs=100000, hidden_layers=[10], C=1):
  16.         self.type = type # 'reg', 'binary', 'multi'
  17.         self.learning_rate = learning_rate
  18.         self.epochs = epochs
  19.         self.hidden_layers = hidden_layers
  20.         self.C = C
  21.         self.weights = []
  22.         self.biases = []
  23.         self.loss_ = []
  24.         self.epochs_ = []
  25.  
  26.     def sigmoid(self, z):
  27.         return 1 / (1 + np.exp(-z))
  28.  
  29.     def sigmoid_derivative(self, z):
  30.         s = self.sigmoid(z)
  31.         return s * (1 - s)
  32.  
  33.     def linear(self, z, C=1):
  34.         return z * C
  35.  
  36.     def softmax(self, z):
  37.         exp_values = np.exp(z - np.max(z))
  38.         return exp_values / np.sum(exp_values, axis=0)
  39.  
  40.     def initialize_parameters(self, input_size, output_size):
  41.             layers = [input_size] + self.hidden_layers + [output_size]
  42.             self.weights = [np.random.randn(layers[i], layers[i + 1]) * np.sqrt(1 / layers[i]) for i in range(len(layers) - 1)]
  43.             self.biases = [np.random.randn(layers[i + 1]) * 0.01 for i in range(len(layers) - 1)]
  44.  
  45.     def calc_out(self, x):
  46.         try:
  47.             input_size = x.shape[1]
  48.         except:
  49.             x = x.reshape(-1, 1)
  50.             input_size = x.shape[1]
  51.            
  52.         for epoch in range(self.epochs):
  53.             y_pred = []
  54.             for i, x_sample in enumerate(x):
  55.                 inputs, activations, outputs = [x_sample], [], []
  56.                 input = x_sample
  57.  
  58.                 len_ = len(self.weights)
  59.                 d_weights, d_biases = [None] * len_ , [None] * len_
  60.                
  61.                 for idx, _ in enumerate(zip(self.weights, self.biases)):
  62.                     w, b = _[0], _[1]
  63.                    
  64.                     activation = np.dot(input, w) + b
  65.                     activations.append(activation)
  66.                    
  67.                     if w.shape[1] == 1 and self.type == 'reg':
  68.                         output = self.linear(activation, C=self.C)
  69.                         outputs.append(output)
  70.                     elif w.shape[1] == 1 and self.type == 'binary':
  71.                         output = self.sigmoid(activation)
  72.                         outputs.append(output)
  73.                     elif idx == (len_-1) and self.type == 'multi':
  74.                         output = self.softmax(activation)
  75.                         outputs.append(output)
  76.                     else:
  77.                         input = self.sigmoid(activation)
  78.                         outputs.append(input)
  79.                         inputs.append(input)
  80.  
  81.                 y_pred.append(output)
  82.  
  83.             return np.array(y_pred), inputs, activations
  84.  
  85.     def learn(self, inputs, activations, expected_output, output):
  86.  
  87.         output_size = len(output) if self.type == 'multi' else 1
  88.         len_ = len(self.weights)
  89.         d_weights, d_biases = [None] * len_ , [None] * len_
  90.                
  91.         if self.type == 'multi':
  92.             delta = output - np.eye(output_size)[expected_output]
  93.         else:
  94.             delta = output - expected_output
  95.            
  96.         d_biases[len_-1] = delta * self.C
  97.         d_weights[len_-1] = np.dot(inputs[len_-1].reshape(-1, 1), d_biases[len_-1].reshape(-1, 1).T)
  98.  
  99.         for idx in reversed(range(len_ - 1)):
  100.             d_biases[idx] = np.dot(d_biases[idx+1], self.weights[idx+1].T * self.sigmoid_derivative(activations[idx]))
  101.             d_weights[idx] = np.dot(inputs[idx].reshape(-1, 1), d_biases[idx].reshape(-1, 1).T)
  102.  
  103.         for idx in (range(len_)):
  104.             self.weights[idx] -= self.learning_rate * d_weights[idx]
  105.             self.biases[idx] -= self.learning_rate * d_biases[idx]
  106.            
  107.     def predict(self, x):
  108.        
  109.         try:
  110.             _ = x.shape[1]
  111.         except:
  112.             x = x.reshape(-1, 1)
  113.        
  114.         y_pred = []
  115.         len_ = len(self.weights)
  116.         for x_sample in x:
  117.             input = x_sample
  118.             for idx, _ in enumerate(zip(self.weights, self.biases)):
  119.                 w, b = _[0], _[1]
  120.                 activation = np.dot(input, w) + b
  121.                
  122.                 if w.shape[1] == 1 and self.type == 'reg':
  123.                     output = self.linear(activation, C=self.C)
  124.                 elif w.shape[1] == 1 and self.type == 'binary':
  125.                     output = (self.sigmoid(activation) > 0.5).astype(int)
  126.                 elif idx == (len_-1) and self.type == 'multi':
  127.                     output = np.argmax(self.softmax(activation))
  128.                 else:
  129.                     input = self.sigmoid(activation)
  130.             y_pred.append(output)
  131.         return np.array(y_pred)
  132.  
  133.     def save_to_file(self, fname):
  134.         try:
  135.             with open(fname, "wb") as file:
  136.                 for w in self.weights:
  137.                     np.save(file, w)
  138.                 for b in self.biases:
  139.                     np.save(file, b)
  140.             print(f"Weights and biases saved to {fname}")
  141.         except Exception as e:
  142.             print(f"Error saving weights: {e}")
  143.  
  144.  
  145.     def load_from_file(self, fname):
  146.         try:
  147.             with open(fname, "rb") as file:
  148.                 self.weights = [np.load(file) for _ in range(len(self.weights))]
  149.                 self.biases = [np.load(file) for _ in range(len(self.biases))]
  150.             print(f"Weights and biases loaded from {fname}")
  151.         except Exception as e:
  152.             print(f"Error loading weights: {e}")
  153.  
  154.  
  155. def plot_results(y1, accuracy):
  156.     x1 = np.arange(1, len(y1) + 1)
  157.     plt.figure(figsize=(10, 5))
  158.     plt.xlabel('Number of Episodes', fontsize=18)
  159.     plt.ylabel('log(Number of Successes)', fontsize=18)
  160.     plt.xticks(fontsize=16)
  161.     plt.yticks(fontsize=16)
  162.     plt.plot(x1, np.log(y1), c='red')
  163.     plt.scatter(x1, np.log(y1), c='red')
  164.     plt.show()
  165.  
  166.     plt.figure(figsize=(10, 5))
  167.     plt.xlabel('Number of Episodes', fontsize=18)
  168.     plt.ylabel('Accuracy', fontsize=18)
  169.     plt.xticks(fontsize=16)
  170.     plt.yticks(fontsize=16)
  171.     plt.plot(x1, accuracy, c='red')
  172.     plt.scatter(x1, accuracy, c='red')
  173.     plt.show()
  174.  
  175.  
  176. class Ball:
  177.     def __init__(self, size):
  178.         self.step = 5
  179.         self.delta_x = random.randint(-10, 10)
  180.         self.pygame_object = pygame.Surface((size, size))
  181.         self.pygame_object.fill((255, 0, 0))
  182.         self.rect = self.pygame_object.get_rect()
  183.         self.rect.x = random.randint(0, window_w - size)
  184.         self.rect.y = 0
  185.  
  186.     def move(self):
  187.         self.rect.x += self.delta_x
  188.         self.rect.y += self.step
  189.  
  190.         if self.rect.x <= 0 or self.rect.x + self.rect.w >= window_w:
  191.             self.delta_x = -self.delta_x
  192.  
  193.         if self.rect.y <= 0:
  194.             self.step = abs(self.step)
  195.  
  196. class Player:
  197.     def __init__(self, width, height, x_pos, step, color=(180, 180, 0)):
  198.         self.step = step
  199.         self.width = width
  200.         self.height = height
  201.         self.x_pos = x_pos
  202.         self.pygame_object = pygame.Surface((width, height))
  203.         self.pygame_object.fill(color)
  204.         self.rect = self.pygame_object.get_rect()
  205.         self.rect.x = x_pos
  206.         self.rect.y = window_h - height
  207.  
  208.     def move(self, direction):
  209.         if direction == "->" and self.rect.x < window_w - self.width:
  210.             self.rect.x += self.step
  211.         elif direction == "<-" and self.rect.x > 0:
  212.             self.rect.x -= self.step
  213.         elif direction == "stay":
  214.             pass
  215.  
  216.  
  217. window_w = 400
  218. window_h = 400
  219. ball_size = 15
  220. player_width = 100
  221. player_height = 10
  222. player_step = 10
  223. filename = 'weights_temp.dat'
  224. player_x_pos = (window_w - player_width) / 2
  225.  
  226.  
  227. ball = Ball(ball_size)
  228. player = Player(player_width, player_height, player_x_pos, player_step)
  229. model = MultiNeuralNetwork(type='multi', learning_rate=0.1, epochs=1, hidden_layers=[5])
  230. model.initialize_parameters(input_size=2, output_size=3)
  231. epoches = 200
  232.  
  233. # pygame.init()
  234. # window = pygame.display.set_mode((window_w, window_h))
  235. time_delay = 10
  236.  
  237. actions = []
  238. num_of_successes_in_episode = 0
  239. num_of_episodes = 0
  240. y_true, y_pred = [], []
  241. accuracy_arr = []
  242.  
  243. while True:
  244.     # pygame.time.delay(time_delay)
  245.     input = np.array([[(player.rect.x + player.rect.w / 2) / window_w, (ball.rect.x + ball.rect.w / 2) / window_w]])
  246.    
  247.     temp = model.calc_out(input)
  248.     output, inputs, activations = temp[0][0], temp[1], temp[2]
  249.    
  250.     # for event in pygame.event.get():
  251.     #     if event.type == pygame.QUIT:
  252.     #         actions.append(num_of_successes_in_episode)
  253.     #         plot_results(actions, accuracy_arr)
  254.     #         pygame.quit()
  255.     #         sys.exit()
  256.    
  257.     if np.argmax(output) == 0:
  258.         move_to = "<-"
  259.     elif np.argmax(output) == 1:
  260.         move_to = "stay"
  261.     elif np.argmax(output) == 2:
  262.         move_to = "->"
  263.     player.move(move_to)
  264.    
  265.     ball.move()
  266.  
  267.     if ball.rect.colliderect(player.rect):
  268.         ball.step = -abs(ball.step)
  269.         num_of_successes_in_episode += 1  
  270.  
  271.     if ball.rect.x + ball.rect.w / 2 < player.rect.x + player.rect.x*0.3333:
  272.         expected_output = np.array([0])  # Вліво
  273.     elif ball.rect.x + ball.rect.w / 2 > player.rect.x + player.rect.w - player.rect.x*0.3333:
  274.         expected_output = np.array([2])  # Вправо
  275.     else:
  276.         expected_output = np.array([1])  # На місці
  277.  
  278.     y_true.append(expected_output[0])
  279.     y_pred.append(np.argmax(output))
  280.     model.learn(inputs=inputs, activations=activations, expected_output=expected_output[0], output=output)
  281.  
  282.     if (ball.rect.y + ball.rect.h >= window_h) or num_of_successes_in_episode >= 10000:
  283.         num_of_episodes += 1
  284.         actions.append(num_of_successes_in_episode)
  285.         num_of_successes_in_episode = 0
  286.         accuracy = accuracy_score(np.array(y_true), np.array(y_pred))*100
  287.         accuracy_arr.append(accuracy)
  288.         print(f'game{num_of_episodes}: accuracy={round(accuracy, 2)}%, num_of_successes_in_episode={actions[-1]}')
  289.         y_true, y_pred = [], []
  290.        
  291.         if num_of_episodes >= 30:
  292.             model.save_to_file(filename)
  293.             plot_results(actions, accuracy_arr)
  294.             # pygame.quit()
  295.             # sys.exit()
  296.             break
  297.  
  298.         ball.rect.y = 0
  299.         ball.rect.x = random.randint(0, window_w - ball_size)
  300.         player.x_pos = player_x_pos
  301.  
  302.     # window.fill((0, 0, 0))
  303.     # window.blit(player.pygame_object, player.rect)
  304.     # window.blit(ball.pygame_object, ball.rect)
  305.     # pygame.display.update()
  306.  
  307.  
  308.  
  309.  
  310. window_w = 400
  311. window_h = 400
  312. ball_size = 15
  313. player_width = 100
  314. player_height = 10
  315. player_step = 10
  316. filename = 'weights_temp.dat'
  317. winning_score = 5
  318.  
  319. black = (0, 0, 0)
  320. white = (255, 255, 255)
  321.  
  322. class Ball:
  323.     def __init__(self, size):
  324.         self.step = random.choice([-5, 5])
  325.         self.delta_x = random.randint(-10, 10)
  326.         self.pygame_object = pygame.Surface((size, size))
  327.         self.pygame_object.fill((255, 0, 0))
  328.         self.rect = self.pygame_object.get_rect()
  329.         self.rect.x = random.randint(0, window_w - size)
  330.         self.rect.y = window_h / 2 - size / 2
  331.  
  332. class Player:
  333.     def __init__(self, width, height, x_pos, y_pos, step, color=(180, 180, 0)):
  334.         self.step = step
  335.         self.width = width
  336.         self.height = height
  337.         self.pygame_object = pygame.Surface((width, height))
  338.         self.pygame_object.fill(color)
  339.         self.rect = self.pygame_object.get_rect()
  340.         self.rect.x = x_pos
  341.         self.rect.y = y_pos
  342.         self.score = 0
  343.        
  344.     def movement(self, distance):
  345.         self.rect.x += distance
  346.         if self.rect.x <= 0:
  347.             self.rect.x = 0
  348.         if self.rect.x >= window_w - self.width:
  349.             self.rect.x = window_w - self.width
  350.  
  351. ball = Ball(ball_size)
  352. player_horizontal_position = (window_w - player_width) / 2
  353. human = Player(player_width, player_height, player_horizontal_position, window_h - player_height, player_step, color=(0, 255, 0))
  354. comp = Player(player_width, player_height, player_horizontal_position, 0, player_step, color=(0, 0, 255))
  355. model.load_from_file(filename)
  356.  
  357. pygame.init()
  358. window = pygame.display.set_mode((window_w, window_h))
  359. font_winner = pygame.font.Font(None, 32)
  360. font_score = pygame.font.Font(None, 48)
  361.  
  362. time_delay = 10
  363. paused = True
  364. done = False
  365. distance = 0
  366.  
  367. while not done:
  368.     if paused:
  369.         for event in pygame.event.get():
  370.             if event.type == pygame.QUIT:
  371.                 done = True
  372.             if event.type == pygame.KEYDOWN:
  373.                 if event.key == pygame.K_RIGHT:
  374.                     distance = player_step
  375.                 if event.key == pygame.K_LEFT:
  376.                     distance = -player_step
  377.                 if event.key == pygame.K_SPACE:
  378.                     paused = not paused
  379.                 if event.key == pygame.K_ESCAPE:
  380.                     human.score = 0
  381.                     comp.score = 0
  382.                     paused = not paused
  383.             if event.type == pygame.KEYUP:
  384.                 if event.key in (pygame.K_RIGHT, pygame.K_LEFT):
  385.                     distance = 0
  386.     if not paused:
  387.         for event in pygame.event.get():
  388.             if event.type == pygame.QUIT:
  389.                 done = True
  390.             if event.type == pygame.KEYDOWN:
  391.                 if event.key == pygame.K_RIGHT:
  392.                     distance = player_step
  393.                 if event.key == pygame.K_LEFT:
  394.                     distance = -player_step
  395.             if event.type == pygame.KEYUP:
  396.                 if event.key in (pygame.K_RIGHT, pygame.K_LEFT):
  397.                     distance = 0
  398.  
  399.         human.movement(distance)
  400.         pygame.time.delay(time_delay)
  401.  
  402.         input = np.array([[(comp.rect.x + comp.rect.w / 2) / window_w, (ball.rect.x + ball.rect.w / 2) / window_w]])
  403.         output = model.predict(input)[0]
  404.         if output == 0: move_to = '<-'
  405.         elif output == 2: move_to = '->'
  406.         else: move_to == 'stay'
  407.  
  408.         if move_to == '->' and comp.rect.x < window_w - comp.width:
  409.             comp.rect.x += comp.step
  410.         elif move_to == '<-' and comp.rect.x > 0:
  411.             comp.rect.x -= comp.step
  412.  
  413.         ball.rect.x += ball.delta_x
  414.         ball.rect.y += ball.step
  415.         if ball.rect.x <= 0:
  416.             ball.delta_x = -ball.delta_x
  417.             ball.rect.x = 0
  418.         if ball.rect.x + ball.rect.w >= window_w:
  419.             ball.delta_x = -ball.delta_x
  420.             ball.rect.x = window_w - ball.rect.w
  421.         if ball.rect.y <= 0:
  422.             ball.step = -ball.step
  423.  
  424.         if ball.rect.colliderect(comp.rect):
  425.             ball.delta_x = random.randint(-9, 9)
  426.             ball.step = -ball.step
  427.  
  428.         if ball.rect.colliderect(human.rect):
  429.             ball.delta_x = random.randint(-9, 9)
  430.             ball.step = -ball.step
  431.  
  432.  
  433.         if ball.rect.y > window_h or ball.rect.y < 0:
  434.             if ball.rect.y > window_h:
  435.                 comp.score += 1
  436.             else:
  437.                 human.score += 1
  438.             ball.rect.y = window_h / 2 - ball_size / 2
  439.             ball.rect.x = random.randint(0, window_w - ball_size)
  440.             ball.step = random.choice([-5, 5])
  441.             human.rect.x = player_horizontal_position
  442.             comp.rect.x = player_horizontal_position
  443.             paused = True
  444.             distance = 0
  445.  
  446.         pygame.display.set_caption(f'Ping Pong Game | Comp ({comp.score}) : Human ({human.score})')
  447.  
  448.         if human.score >= winning_score or comp.score >= winning_score:
  449.             if human.score >= winning_score:
  450.                 winner = 'You win !!!'
  451.             else:
  452.                 winner = 'Computer wins !!!'
  453.             text_winner = font_winner.render(winner, True, white)
  454.             text_winner_rect = text_winner.get_rect()
  455.             text_winner_rect.center = (window_w // 2, window_h // 2)
  456.  
  457.             window.fill(black)
  458.             window.blit(text_winner, text_winner_rect)
  459.             pygame.display.update()
  460.             pygame.time.delay(3000)
  461.             done = True
  462.  
  463.     if not done:
  464.         window.fill(black)
  465.         window.blit(human.pygame_object, human.rect)
  466.         window.blit(comp.pygame_object, comp.rect)
  467.         window.blit(ball.pygame_object, ball.rect)
  468.         pygame.display.update()
  469.  
  470. pygame.quit()
  471. sys.exit()
  472.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement