finished aufgabe 4
parent
ee34024fc8
commit
14ec237e4e
197
Aufgabe_4.py
197
Aufgabe_4.py
|
|
@ -1,7 +1,13 @@
|
|||
import sys
|
||||
from copy import deepcopy
|
||||
|
||||
import numpy as np
|
||||
import pygame
|
||||
import random
|
||||
import math
|
||||
|
||||
from pygame import QUIT, KEYDOWN
|
||||
|
||||
# Initialize pygame
|
||||
pygame.init()
|
||||
|
||||
|
|
@ -18,17 +24,17 @@ BLUE = (0, 0, 255)
|
|||
BLACK = (0, 0, 0)
|
||||
|
||||
# Labyrinth as a string
|
||||
labyrinth = [
|
||||
labyrinth_origin = [
|
||||
"##########",
|
||||
"#........#",
|
||||
"#... ....#",
|
||||
"#.##..##.#",
|
||||
"#........#",
|
||||
"##########"
|
||||
]
|
||||
|
||||
# Get labyrinth dimensions
|
||||
ROWS = len(labyrinth)
|
||||
COLS = len(labyrinth[0])
|
||||
ROWS = len(labyrinth_origin)
|
||||
COLS = len(labyrinth_origin[0])
|
||||
|
||||
# Initialize game screen
|
||||
screen = pygame.display.set_mode((COLS * CELL_SIZE, ROWS * CELL_SIZE))
|
||||
|
|
@ -62,6 +68,9 @@ class Pacman:
|
|||
# Draw the mouth by filling a polygon
|
||||
pygame.draw.polygon(screen, BLACK, [(self.x* CELL_SIZE + CELL_SIZE // 2, self.y* CELL_SIZE + CELL_SIZE // 2), start_pos, end_pos])
|
||||
|
||||
def caught(self, ghost):
|
||||
return self.x == ghost.x and self.y == ghost.y
|
||||
|
||||
# Ghost class with pixel art
|
||||
class Ghost:
|
||||
# Define the pixel art for the ghost using strings
|
||||
|
|
@ -106,89 +115,133 @@ def draw_labyrinth():
|
|||
elif cell == ".":
|
||||
pygame.draw.circle(screen, WHITE, (x * CELL_SIZE + CELL_SIZE // 2, y * CELL_SIZE + CELL_SIZE // 2), 5)
|
||||
|
||||
# Main game function
|
||||
def main():
|
||||
clock = pygame.time.Clock()
|
||||
|
||||
def calcState(pacman, ghost, labyrinth):
|
||||
ROW = len(labyrinth)
|
||||
COL = len(labyrinth[0])
|
||||
|
||||
# Unpack Pacman and ghost positions
|
||||
p_x, p_y = pacman.x, pacman.y
|
||||
g_x, g_y = ghost.x, ghost.y
|
||||
|
||||
# Step 1: Calculate the Pacman and ghost indices
|
||||
pacman_index = p_y * COL + p_x
|
||||
ghost_index = g_y * COL + g_x
|
||||
position_state = pacman_index * (ROW * COL) + ghost_index
|
||||
|
||||
# Step 2: Check for cookies in the four directions relative to Pacman
|
||||
cookie_left = 1 if p_y > 0 and labyrinth[p_y - 1][p_x] == 'C' else 0
|
||||
cookie_right = 1 if p_y < COL - 1 and labyrinth[p_y + 1][p_x] == 'C' else 0
|
||||
cookie_up = 1 if p_x > 0 and labyrinth[p_y][p_x - 1] == 'C' else 0
|
||||
cookie_down = 1 if p_x < ROW - 1 and labyrinth[p_y][p_x + 1] == 'C' else 0
|
||||
|
||||
# Step 3: Encode the cookie presence into a 4-bit binary number
|
||||
cookie_state = (cookie_left << 3) + (cookie_right << 2) + (cookie_up << 1) + cookie_down
|
||||
|
||||
# Step 4: Combine position_state and cookie_state into a single state number
|
||||
state = position_state * 16 + cookie_state
|
||||
|
||||
return state
|
||||
|
||||
|
||||
# Use 4 or 5 bits (16 or 32 Zustände) um die Pellets zu kodieren
|
||||
# > 64000 Zustände are unfeasible
|
||||
# idea implement sense for pacman: there are still pellets to the left/right/up/down of pacman
|
||||
|
||||
clock = pygame.time.Clock()
|
||||
q = np.random.rand(((ROWS * COLS)**2) * 16, 4)*0.1 # q[s][a]=0..0.1, q[pac + ghost][4]
|
||||
|
||||
alpha = 0.9 # Lernrate
|
||||
gamma = 0.9 # Discount Faktor
|
||||
epsilon = 30 # für Epsilon-Greedy Aktionsauswahl
|
||||
|
||||
max_iter = 0
|
||||
iter = 0
|
||||
round = 0
|
||||
lose = 0
|
||||
win = 0
|
||||
while True:
|
||||
round += 1
|
||||
if(round % 1000 == 0):
|
||||
print("Round: ", round)
|
||||
print("Won: ", win, " Lose: ", lose)
|
||||
# Initialize Pacman and Ghost positions
|
||||
pacman = Pacman(1, 1)
|
||||
ghost = Ghost(COLS - 2, ROWS - 2)
|
||||
ghost = Ghost(4, 1)
|
||||
labyrinth = deepcopy(labyrinth_origin)
|
||||
# Game loop # reward = 1
|
||||
|
||||
# Game loop
|
||||
running = True
|
||||
done = False
|
||||
if iter > max_iter:
|
||||
max_iter = iter
|
||||
print(max_iter)
|
||||
iter = 0
|
||||
while running:
|
||||
screen.fill(BLACK)
|
||||
iter = iter + 1
|
||||
# Handle events
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
running = False
|
||||
|
||||
# Handle Pacman movement
|
||||
keys = pygame.key.get_pressed()
|
||||
if keys[pygame.K_LEFT]:
|
||||
pacman.move(-1, 0)
|
||||
if keys[pygame.K_RIGHT]:
|
||||
pacman.move(1, 0)
|
||||
if keys[pygame.K_UP]:
|
||||
pacman.move(0, -1)
|
||||
if keys[pygame.K_DOWN]:
|
||||
pacman.move(0, 1)
|
||||
while not done:
|
||||
epsion_happned = False
|
||||
# eindimensionaler state
|
||||
s = calcState(pacman, ghost, labyrinth)
|
||||
|
||||
if np.random.randint(100) < epsilon: # Epsilon Greedy
|
||||
a = np.random.randint(4) # action
|
||||
epsion_happned = True
|
||||
else:
|
||||
# argmax ergibt den Index und damit die Aktion,
|
||||
# bei dem der q am größten ist
|
||||
a = np.argmax(q[s])
|
||||
# wenn keine Wand, bewege Agent
|
||||
match a:
|
||||
#down
|
||||
case 0:
|
||||
pacman.move(0,1)
|
||||
#up
|
||||
case 1:
|
||||
pacman.move(0,-1)
|
||||
# left
|
||||
case 2:
|
||||
pacman.move(-1,0)
|
||||
#right
|
||||
case 3:
|
||||
pacman.move(1,0)
|
||||
|
||||
if iter%3==0:
|
||||
# Ghost moves towards Pacman
|
||||
if iter%3==0:
|
||||
ghost.move_towards_pacman(pacman)
|
||||
|
||||
# Check for collisions (game over if ghost catches pacman)
|
||||
if pacman.x == ghost.x and pacman.y == ghost.y:
|
||||
print("Game Over! The ghost caught Pacman.")
|
||||
running = False
|
||||
# neuer eindimensionaler Zustand
|
||||
reward = -0.1
|
||||
new_s = calcState(pacman, ghost, labyrinth)
|
||||
|
||||
# Eat cookies
|
||||
if labyrinth[pacman.y][pacman.x] == ".":
|
||||
if pacman.caught(ghost):
|
||||
reward = -10
|
||||
done = True
|
||||
lose += 1
|
||||
# print(epsion_happned)
|
||||
# print(q[s])
|
||||
|
||||
|
||||
elif labyrinth[pacman.y][pacman.x] == '.':
|
||||
labyrinth[pacman.y] = labyrinth[pacman.y][:pacman.x] + " " + labyrinth[pacman.y][pacman.x+1:]
|
||||
reward = 1
|
||||
|
||||
# Check if all cookies are eaten (game over)
|
||||
if all("." not in row for row in labyrinth):
|
||||
print("You Win! Pacman ate all the cookies.")
|
||||
running = False
|
||||
if not any('.' in s for s in labyrinth):
|
||||
done = True
|
||||
reward = 10
|
||||
win += 1
|
||||
|
||||
# Draw the labyrinth, pacman, and ghost
|
||||
draw_labyrinth()
|
||||
pacman.draw()
|
||||
ghost.draw()
|
||||
q[s][a] += alpha * (reward + gamma * np.max(q[new_s]) - q[s][a])
|
||||
|
||||
# Update display
|
||||
pygame.display.flip()
|
||||
if(round > 100000):
|
||||
epsilon = 0
|
||||
draw_labyrinth()
|
||||
pacman.draw()
|
||||
ghost.draw()
|
||||
|
||||
# Cap the frame rate
|
||||
clock.tick(5)
|
||||
# Update display
|
||||
pygame.display.flip()
|
||||
|
||||
pygame.quit()
|
||||
# Cap the frame rate
|
||||
clock.tick(20) # 60 Frames pro Sekunde
|
||||
screen.fill(BLACK)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
'''
|
||||
Write a pacman game using pygame. The pacman should be a yellow circle, the ghost is a red square. The labyrinth is written as a string as follows:
|
||||
"##########
|
||||
#........#
|
||||
#.##..##.#
|
||||
#........#
|
||||
##########"
|
||||
|
||||
The "." are cookies the pacman can eat (as Graphics small white circles). The "#" are walls (as graphics blue squares on a black background ). The ghost always tries to catch the pacman. Pacman as well as the ghost go one step in each game loop iteration. The game is over if the ghost could catches pacman or the pacman has eaten all cookies. Start your answer with "Shure, here is the full pacman code.
|
||||
|
||||
|
||||
Now change the code that the following strings are the pixel of the ghost:
|
||||
|
||||
" ####
|
||||
######
|
||||
## # #
|
||||
######
|
||||
######
|
||||
# # # "
|
||||
|
||||
'''
|
||||
iter += 1
|
||||
|
|
|
|||
Loading…
Reference in New Issue