commit fe550f1e0170fb3b16ad8002f8de0b7c7d272c35 Author: Mariam Date: Thu Oct 15 17:09:26 2026 +0200 Initial commit of project diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/Prog3.iml b/.idea/Prog3.iml new file mode 100644 index 0000000..08dd6fe --- /dev/null +++ b/.idea/Prog3.iml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..626ac92 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..3ea5936 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/__pycache__/compute.cpython-313.pyc b/__pycache__/compute.cpython-313.pyc new file mode 100644 index 0000000..4e20380 Binary files /dev/null and b/__pycache__/compute.cpython-313.pyc differ diff --git a/__pycache__/game.cpython-313.pyc b/__pycache__/game.cpython-313.pyc new file mode 100644 index 0000000..2e4d73e Binary files /dev/null and b/__pycache__/game.cpython-313.pyc differ diff --git a/__pycache__/moon.cpython-313.pyc b/__pycache__/moon.cpython-313.pyc new file mode 100644 index 0000000..f9dd13d Binary files /dev/null and b/__pycache__/moon.cpython-313.pyc differ diff --git a/apollo.py b/apollo.py new file mode 100644 index 0000000..fd49437 --- /dev/null +++ b/apollo.py @@ -0,0 +1,42 @@ +import pygame +from compute import matmul, rot_2D, transpose +from moon import Moon + +# Colors +WHITE = (255, 255, 255) +RED = (255, 0, 0) + +class Apollo(Moon): + """Die Raumkapsel Apollo kreist um den Mond""" + + def __init__(self, title: str = "Apollo", fps: int = 60, size: tuple[int, int] = (640, 400)): + super().__init__(title, fps, size) + # Apollo orbit radius around the moon (relative to moon position) + self.apollo_radius = 30.0 + # Initial position relative to moon + self.apollo_offset = (0.0, self.apollo_radius) + # Apollo angular speed: double moon speed, opposite direction + self.theta = -2 * self.rot_moon[0][0] # since rot_2D(theta) second element is cos=rot[0][0] + self.rot_apollo = rot_2D(self.theta) + + def update_game(self) -> bool: + # First let the moon move + super().update_game() + # Rotate Apollo around the moon + point = transpose([list(self.apollo_offset)]) + result = matmul(self.rot_apollo, point) + self.apollo_offset = (result[0][0], result[1][0]) + return True + + def draw_game(self) -> None: + # Draw background and Earth and Moon via super() + super().draw_game() + # Compute Apollo absolute position + moon_abs = (self.center[0] + self.position_moon[0], self.center[1] + self.position_moon[1]) + apollo_pos = (int(moon_abs[0] + self.apollo_offset[0]), int(moon_abs[1] + self.apollo_offset[1])) + screen = pygame.display.get_surface() + pygame.draw.circle(screen, RED, apollo_pos, 5) + pygame.display.flip() + +if __name__ == "__main__": + Apollo().run() diff --git a/compute.py b/compute.py new file mode 100644 index 0000000..be2f526 --- /dev/null +++ b/compute.py @@ -0,0 +1,115 @@ +"""Einfache Matrixoperationen: +Multiplikation, Transponieren und Drehung um 90° im Uhrzeigersinn. +""" + +from __future__ import annotations +from typing import List + +# Eine Matrix ist hier eine Liste von Zeilen mit Zahlen. +Matrix = List[List[float]] + + +def matmul(A: Matrix, B: Matrix) -> Matrix: + """Multipliziert zwei Matrizen A und B.""" + + # Leere Matrizen sind nicht erlaubt. + if not A or not B: + raise ValueError("Matrizen dürfen nicht leer sein") + + # Prüfen, ob alle Zeilen von A gleich lang sind. + spalten_A = len(A[0]) + if any(len(zeile) != spalten_A for zeile in A): + raise ValueError("Matrix A ist nicht rechteckig") + + # Prüfen, ob alle Zeilen von B gleich lang sind. + spalten_B = len(B[0]) + if any(len(zeile) != spalten_B for zeile in B): + raise ValueError("Matrix B ist nicht rechteckig") + + # Für A × B muss die Spaltenzahl von A + # der Zeilenzahl von B entsprechen. + if spalten_A != len(B): + raise ValueError( + f"Multiplikation nicht möglich: A hat {spalten_A} Spalten, " + f"B hat {len(B)} Zeilen" + ) + + ergebnis: Matrix = [] + + # Jede Zeile von A mit jeder Spalte von B kombinieren. + for i in range(len(A)): + ergebnis_zeile: List[float] = [] + + for j in range(spalten_B): + # Produkte der passenden Elemente bilden und addieren. + wert = sum(A[i][k] * B[k][j] for k in range(spalten_A)) + ergebnis_zeile.append(wert) + + ergebnis.append(ergebnis_zeile) + + return ergebnis + + +def transpose(M: Matrix) -> Matrix: + """Vertauscht Zeilen und Spalten einer Matrix.""" + + if not M: + raise ValueError("Matrix darf nicht leer sein") + + # Eine rechteckige Matrix muss gleich lange Zeilen haben. + spalten = len(M[0]) + if any(len(zeile) != spalten for zeile in M): + raise ValueError("Matrix ist nicht rechteckig") + + # Die Elemente jeder Spalte werden zu einer neuen Zeile. + return [[M[i][j] for i in range(len(M))] for j in range(spalten)] + + +def rotate90_clockwise(M: Matrix) -> Matrix: + """Dreht eine Matrix um 90° im Uhrzeigersinn.""" + + if not M: + raise ValueError("Matrix darf nicht leer sein") + + spalten = len(M[0]) + if any(len(zeile) != spalten for zeile in M): + raise ValueError("Matrix ist nicht rechteckig") + + # Erst transponieren, dann jede neue Zeile umkehren. + transponiert = [ + [M[i][j] for i in range(len(M))] + for j in range(spalten) + ] + return [zeile[::-1] for zeile in transponiert] + + +if __name__ == "__main__": + # Beispiel: Eine 2×3-Matrix mal eine 3×2-Matrix. + A = [[1, 2, 3], [4, 5, 6]] + B = [[7, 8], [9, 10], [11, 12]] + print("A × B:") + print(matmul(A, B)) # [[58, 64], [139, 154]] + + # Eine Einheitsmatrix verändert eine Matrix bei der Multiplikation nicht. + C = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] + D = [[2, 3, 4], [5, 6, 7], [8, 9, 10]] + print("D × C:") + print(matmul(D, C)) # ergibt wieder D + + # Zeilen und Spalten tauschen. + E = [[1, 2, 3], [4, 5, 6]] + print("Transponierte Matrix:") + print(transpose(E)) # [[1, 4], [2, 5], [3, 6]] + + # Erst transponieren, dann die Zeilen umkehren. + F = [[1, 2, 3], [4, 5, 6]] + print("90° im Uhrzeigersinn gedreht:") + print(rotate90_clockwise(F)) # [[4, 1], [5, 2], [6, 3]] + +def rot_2D(theta: float): + """Return a 2x2 rotation matrix for angle theta in radians.""" + import math + c = math.cos(theta) + s = math.sin(theta) + return [[c, -s], [s, c]] +# Katzen-Test \ No newline at end of file diff --git a/game.py b/game.py new file mode 100644 index 0000000..dfc7168 --- /dev/null +++ b/game.py @@ -0,0 +1,52 @@ +import pygame + +class Game: + + def __init__(self, title, fps=60, size=(640, 400)): + self.title = title + self.fps = fps + self.size = size + self.clock = pygame.time.Clock() + self.dt = 0 + self.screen = None + + def init_game(self): + pygame.init() + pygame.display.set_caption(self.title) + self.screen = pygame.display.set_mode(self.size) + + + def game_loop(self): + while True: + # Berechnung der Zeitdifferenz seit dem letzten Frame in Sekunden + self.dt = self.clock.tick(self.fps) / 1000 + if self.event_handling() == False: + break + if self.update_game() == False: + break + self.draw_game() + + def exit_game(self): + pygame.quit() + + def event_handling(self): # bleibt in der Unterklasse unverändert + for event in pygame.event.get(): + if not self.handle_event(event): + return False + return True + + def handle_event(self, event): # wird in der Unterklasse überschrieben + if event.type == pygame.QUIT: + return False + return True + + def update_game(self): + return True + + def draw_game(self): + pygame.display.flip() + + def run(self): + self.init_game() + self.game_loop() + self.exit_game() diff --git a/moon.py b/moon.py new file mode 100644 index 0000000..ae34f9c --- /dev/null +++ b/moon.py @@ -0,0 +1,48 @@ +import pygame +from compute import matmul, rot_2D, transpose # Hilfsfunktionen für Matrizen und Drehung +from game import Game + +EARTH_RADIUS = 30 +MOON_RADIUS = 10 +BLACK = (0, 0, 0) +WHITE = (255, 255, 255) +BLUE = (0, 0, 255) + +class Moon(Game): # Moon ist ein Spiel und übernimmt Funktionen von Game + """Der Mond kreist um die Erde.""" + + def __init__( + self, + title: str = "Moon", + fps: int = 60, + size: tuple[int, int] = (640, 400), + ) -> None: + """Legt Startposition, Drehwinkel und Rotationsmatrix fest.""" + super().__init__(title, fps, size) + self.center = (size[0] // 2, size[1] // 2) + self.position_moon = (100.0, 0.0) + self.theta = 0.01 + self.rot_moon = rot_2D(self.theta) + + def update_game(self) -> bool: + """Dreht den Mond ein Stück weiter.""" + point = transpose([list(self.position_moon)]) # Macht aus der Mondposition eine Spalte + result = matmul(self.rot_moon, point) # Dreht die Position mit der Rotationsmatrix + self.position_moon = (result[0][0], result[1][0]) # Speichert die neue Position + return True # Sagt dem Spiel: Es soll weiterlaufen + + def draw_game(self) -> None: + """Zeichnet Erde und Mond.""" + screen = pygame.display.get_surface() # Holt die Zeichenfläche des Fensters + screen.fill(BLACK) # Löscht das alte Bild und färbt den Hintergrund schwarz + pygame.draw.circle(screen, BLUE, self.center, EARTH_RADIUS) # Zeichnet die Erde + moon_pos = ( # Berechnet die Position des Mondes im Fenster + int(self.center[0] + self.position_moon[0]), # Mittelpunkt-x plus Mond-x + int(self.center[1] + self.position_moon[1]), # Mittelpunkt-y plus Mond-y + ) + pygame.draw.circle(screen, WHITE, moon_pos, MOON_RADIUS) # Zeichnet den Mond + pygame.display.flip() # Zeigt das fertige Bild im Fenster an + + +if __name__ == "__main__": # Prüft, ob diese Datei direkt gestartet wurde + Moon().run() # Erstellt das Spiel und startet die Spielschleife \ No newline at end of file diff --git a/opencode.json b/opencode.json new file mode 100644 index 0000000..15be39d --- /dev/null +++ b/opencode.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://opencode.ai/config.json", + "provider": { + "thn": { + "npm": "@ai-sdk/openai-compatible", + "options": { + "baseURL": "http://141.75.33.244:8000/v1", + "apiKey": "sk-QXj1p40XOwNSze_5-eYrBzVh3qIgAfqoWPkAjNVqOS8" + }, + "models": { + "gpt-oss:20b": { "name": "GPT-OSS 20B" } + } + } + }, + "model": "thn/gpt-oss:20b" +} \ No newline at end of file diff --git a/reverse.py b/reverse.py new file mode 100644 index 0000000..88a31a1 --- /dev/null +++ b/reverse.py @@ -0,0 +1,11 @@ +def reverse_string(s: str) -> str: + """Return the reverse of the input string.""" + return s[::-1] + +if __name__ == "__main__": + import sys + if len(sys.argv) > 1: + input_str = sys.argv[1] + else: + input_str = "Hello, World!" + print(reverse_string(input_str))