diff --git a/DIRECTORY.md b/DIRECTORY.md
index ab3259b9a766..fb1788a18d96 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -878,6 +878,7 @@
   * [Casimir Effect](physics/casimir_effect.py)
   * [Center Of Mass](physics/center_of_mass.py)
   * [Centripetal Force](physics/centripetal_force.py)
+  * [Collision Detection](physics/collision_detection.py)
   * [Coulombs Law](physics/coulombs_law.py)
   * [Doppler Frequency](physics/doppler_frequency.py)
   * [Grahams Law](physics/grahams_law.py)
diff --git a/physics/collision_detection.py b/physics/collision_detection.py
new file mode 100644
index 000000000000..29e96b9b7dac
--- /dev/null
+++ b/physics/collision_detection.py
@@ -0,0 +1,91 @@
+"""
+Title : AABB Collision Detection and Counter
+
+Description : This program simulates two moving boxes that bounce back when they
+collide with each other or with the edges of the screen. A collision counter
+increments each time the boxes collide, except when they touch the edges of the
+screen, where they rebound without increasing the counter. The motion and
+collision logic demonstrate axis-aligned bounding box (AABB) collision detection.
+
+The program is implemented using Pygame and features:
+- Two boxes moving towards each other
+- Collision detection between the boxes
+- Edge collision handling (without counter increment)
+- A visual counter displaying the number of collisions
+
+Source :
+- https://en.wikipedia.org/wiki/Bounding_volume
+- https://www.pygame.org/docs/
+"""
+
+import pygame
+
+# Initialize Pygame
+pygame.init()
+
+# Constants for screen dimensions and box properties
+WIDTH, HEIGHT = 500, 300  # Screen width and height
+BOX_SIZE = 50  # Size of each box
+SPEED = 3  # Speed of movement
+
+# Colors
+WHITE = (255, 255, 255)  # Background color
+RED = (255, 0, 0)  # Box 1 color
+BLUE = (0, 0, 255)  # Box 2 color
+
+# Create display window
+screen = pygame.display.set_mode((WIDTH, HEIGHT))
+pygame.display.set_caption("AABB Collision Detection")
+
+# Initial positions of the boxes
+box1_x, box1_y = 50, HEIGHT // 2 - BOX_SIZE // 2
+box2_x, box2_y = WIDTH - 100, HEIGHT // 2 - BOX_SIZE // 2
+
+# Movement directions
+box1_dir = SPEED
+box2_dir = -SPEED
+
+# Collision counter
+collision_count = 0
+
+# Main game loop
+running = True
+while running:
+    pygame.time.delay(20)  # Controls the frame rate
+    screen.fill(WHITE)  # Clear screen before drawing
+
+    # Move the boxes
+    box1_x += box1_dir
+    box2_x += box2_dir
+
+    # Collision detection between the two boxes
+    if box1_x + BOX_SIZE > box2_x:
+        # Only increase the counter if they overlap beyond just touching edges
+        if box1_x + BOX_SIZE > box2_x + 1 or box2_x > box1_x + 1:
+            collision_count += 1
+        box1_dir *= -1  # Reverse direction
+        box2_dir *= -1  # Reverse direction
+
+    # Edge collision detection (bouncing without increasing counter)
+    if box1_x <= 0 or box1_x + BOX_SIZE >= WIDTH:
+        box1_dir *= -1
+    if box2_x <= 0 or box2_x + BOX_SIZE >= WIDTH:
+        box2_dir *= -1
+
+    # Draw the boxes
+    pygame.draw.rect(screen, RED, (box1_x, box1_y, BOX_SIZE, BOX_SIZE))
+    pygame.draw.rect(screen, BLUE, (box2_x, box2_y, BOX_SIZE, BOX_SIZE))
+
+    # Display the collision count
+    font = pygame.font.Font(None, 36)
+    text = font.render("Collisions: " + str(collision_count), True, (0, 0, 0))
+    screen.blit(text, (10, 10))
+
+    # Event handling
+    for event in pygame.event.get():
+        if event.type == pygame.QUIT:
+            running = False
+            print("Number of collisions occurred are", collision_count)
+    pygame.display.update()
+# Quit Pygame
+pygame.quit()
diff --git a/requirements.txt b/requirements.txt
index b104505e01bc..d52e5d155ce3 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -8,6 +8,7 @@ numpy
 opencv-python
 pandas
 pillow
+pygame
 requests
 rich
 scikit-learn
diff --git a/uv.lock b/uv.lock
index 077288f041a1..c36e09f0a1d6 100644
--- a/uv.lock
+++ b/uv.lock
@@ -1,9 +1,10 @@
 version = 1
+revision = 1
 requires-python = ">=3.13"
 resolution-markers = [
-    "platform_system == 'Darwin'",
-    "platform_machine == 'aarch64' and platform_system == 'Linux'",
-    "(platform_machine != 'aarch64' and platform_system != 'Darwin') or (platform_system != 'Darwin' and platform_system != 'Linux')",
+    "sys_platform == 'darwin'",
+    "platform_machine == 'aarch64' and sys_platform == 'linux'",
+    "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')",
 ]
 
 [[package]]
@@ -87,15 +88,6 @@ wheels = [
     { url = "https://files.pythonhosted.org/packages/bf/9b/08c0432272d77b04803958a4598a51e2a4b51c06640af8b8f0f908c18bf2/charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", size = 49446 },
 ]
 
-[[package]]
-name = "codespell"
-version = "2.3.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/a0/a9/98353dfc7afcdf18cffd2dd3e959a25eaaf2728cf450caa59af89648a8e4/codespell-2.3.0.tar.gz", hash = "sha256:360c7d10f75e65f67bad720af7007e1060a5d395670ec11a7ed1fed9dd17471f", size = 329791 }
-wheels = [
-    { url = "https://files.pythonhosted.org/packages/0e/20/b6019add11e84f821184234cea0ad91442373489ef7ccfa3d73a71b908fa/codespell-2.3.0-py3-none-any.whl", hash = "sha256:a9c7cef2501c9cfede2110fd6d4e5e62296920efe9abfb84648df866e47f58d1", size = 329167 },
-]
-
 [[package]]
 name = "colorama"
 version = "0.4.6"
@@ -476,7 +468,7 @@ name = "ml-dtypes"
 version = "0.5.0"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
-    { name = "numpy", marker = "python_full_version >= '3.13'" },
+    { name = "numpy" },
 ]
 sdist = { url = "https://files.pythonhosted.org/packages/ab/79/717c5e22ad25d63ce3acdfe8ff8d64bdedec18914256c59b838218708b16/ml_dtypes-0.5.0.tar.gz", hash = "sha256:3e7d3a380fe73a63c884f06136f8baa7a5249cc8e9fdec677997dd78549f8128", size = 699367 }
 wheels = [
@@ -581,7 +573,7 @@ name = "opencv-python"
 version = "4.10.0.84"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
-    { name = "numpy", marker = "python_full_version >= '3.13'" },
+    { name = "numpy" },
 ]
 sdist = { url = "https://files.pythonhosted.org/packages/4a/e7/b70a2d9ab205110d715906fc8ec83fbb00404aeb3a37a0654fdb68eb0c8c/opencv-python-4.10.0.84.tar.gz", hash = "sha256:72d234e4582e9658ffea8e9cae5b63d488ad06994ef12d81dc303b17472f3526", size = 95103981 }
 wheels = [
@@ -638,7 +630,7 @@ name = "pandas"
 version = "2.2.3"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
-    { name = "numpy", marker = "python_full_version >= '3.13'" },
+    { name = "numpy" },
     { name = "python-dateutil" },
     { name = "pytz" },
     { name = "tzdata" },
@@ -833,31 +825,6 @@ wheels = [
     { url = "https://files.pythonhosted.org/packages/19/71/39c7c0d87f8d4e6c020a393182060eaefeeae6c01dab6a84ec346f2567df/rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90", size = 242424 },
 ]
 
-[[package]]
-name = "ruff"
-version = "0.8.1"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/95/d0/8ff5b189d125f4260f2255d143bf2fa413b69c2610c405ace7a0a8ec81ec/ruff-0.8.1.tar.gz", hash = "sha256:3583db9a6450364ed5ca3f3b4225958b24f78178908d5c4bc0f46251ccca898f", size = 3313222 }
-wheels = [
-    { url = "https://files.pythonhosted.org/packages/a2/d6/1a6314e568db88acdbb5121ed53e2c52cebf3720d3437a76f82f923bf171/ruff-0.8.1-py3-none-linux_armv6l.whl", hash = "sha256:fae0805bd514066f20309f6742f6ee7904a773eb9e6c17c45d6b1600ca65c9b5", size = 10532605 },
-    { url = "https://files.pythonhosted.org/packages/89/a8/a957a8812e31facffb6a26a30be0b5b4af000a6e30c7d43a22a5232a3398/ruff-0.8.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8a4f7385c2285c30f34b200ca5511fcc865f17578383db154e098150ce0a087", size = 10278243 },
-    { url = "https://files.pythonhosted.org/packages/a8/23/9db40fa19c453fabf94f7a35c61c58f20e8200b4734a20839515a19da790/ruff-0.8.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:cd054486da0c53e41e0086e1730eb77d1f698154f910e0cd9e0d64274979a209", size = 9917739 },
-    { url = "https://files.pythonhosted.org/packages/e2/a0/6ee2d949835d5701d832fc5acd05c0bfdad5e89cfdd074a171411f5ccad5/ruff-0.8.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2029b8c22da147c50ae577e621a5bfbc5d1fed75d86af53643d7a7aee1d23871", size = 10779153 },
-    { url = "https://files.pythonhosted.org/packages/7a/25/9c11dca9404ef1eb24833f780146236131a3c7941de394bc356912ef1041/ruff-0.8.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2666520828dee7dfc7e47ee4ea0d928f40de72056d929a7c5292d95071d881d1", size = 10304387 },
-    { url = "https://files.pythonhosted.org/packages/c8/b9/84c323780db1b06feae603a707d82dbbd85955c8c917738571c65d7d5aff/ruff-0.8.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:333c57013ef8c97a53892aa56042831c372e0bb1785ab7026187b7abd0135ad5", size = 11360351 },
-    { url = "https://files.pythonhosted.org/packages/6b/e1/9d4bbb2ace7aad14ded20e4674a48cda5b902aed7a1b14e6b028067060c4/ruff-0.8.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:288326162804f34088ac007139488dcb43de590a5ccfec3166396530b58fb89d", size = 12022879 },
-    { url = "https://files.pythonhosted.org/packages/75/28/752ff6120c0e7f9981bc4bc275d540c7f36db1379ba9db9142f69c88db21/ruff-0.8.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b12c39b9448632284561cbf4191aa1b005882acbc81900ffa9f9f471c8ff7e26", size = 11610354 },
-    { url = "https://files.pythonhosted.org/packages/ba/8c/967b61c2cc8ebd1df877607fbe462bc1e1220b4a30ae3352648aec8c24bd/ruff-0.8.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:364e6674450cbac8e998f7b30639040c99d81dfb5bbc6dfad69bc7a8f916b3d1", size = 12813976 },
-    { url = "https://files.pythonhosted.org/packages/7f/29/e059f945d6bd2d90213387b8c360187f2fefc989ddcee6bbf3c241329b92/ruff-0.8.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b22346f845fec132aa39cd29acb94451d030c10874408dbf776af3aaeb53284c", size = 11154564 },
-    { url = "https://files.pythonhosted.org/packages/55/47/cbd05e5a62f3fb4c072bc65c1e8fd709924cad1c7ec60a1000d1e4ee8307/ruff-0.8.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b2f2f7a7e7648a2bfe6ead4e0a16745db956da0e3a231ad443d2a66a105c04fa", size = 10760604 },
-    { url = "https://files.pythonhosted.org/packages/bb/ee/4c3981c47147c72647a198a94202633130cfda0fc95cd863a553b6f65c6a/ruff-0.8.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:adf314fc458374c25c5c4a4a9270c3e8a6a807b1bec018cfa2813d6546215540", size = 10391071 },
-    { url = "https://files.pythonhosted.org/packages/6b/e6/083eb61300214590b188616a8ac6ae1ef5730a0974240fb4bec9c17de78b/ruff-0.8.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a885d68342a231b5ba4d30b8c6e1b1ee3a65cf37e3d29b3c74069cdf1ee1e3c9", size = 10896657 },
-    { url = "https://files.pythonhosted.org/packages/77/bd/aacdb8285d10f1b943dbeb818968efca35459afc29f66ae3bd4596fbf954/ruff-0.8.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d2c16e3508c8cc73e96aa5127d0df8913d2290098f776416a4b157657bee44c5", size = 11228362 },
-    { url = "https://files.pythonhosted.org/packages/39/72/fcb7ad41947f38b4eaa702aca0a361af0e9c2bf671d7fd964480670c297e/ruff-0.8.1-py3-none-win32.whl", hash = "sha256:93335cd7c0eaedb44882d75a7acb7df4b77cd7cd0d2255c93b28791716e81790", size = 8803476 },
-    { url = "https://files.pythonhosted.org/packages/e4/ea/cae9aeb0f4822c44651c8407baacdb2e5b4dcd7b31a84e1c5df33aa2cc20/ruff-0.8.1-py3-none-win_amd64.whl", hash = "sha256:2954cdbe8dfd8ab359d4a30cd971b589d335a44d444b6ca2cb3d1da21b75e4b6", size = 9614463 },
-    { url = "https://files.pythonhosted.org/packages/eb/76/fbb4bd23dfb48fa7758d35b744413b650a9fd2ddd93bca77e30376864414/ruff-0.8.1-py3-none-win_arm64.whl", hash = "sha256:55873cc1a473e5ac129d15eccb3c008c096b94809d693fc7053f588b67822737", size = 8959621 },
-]
-
 [[package]]
 name = "scikit-learn"
 version = "1.5.2"
@@ -955,7 +922,7 @@ name = "sphinx-autoapi"
 version = "3.4.0"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
-    { name = "astroid", marker = "python_full_version >= '3.13'" },
+    { name = "astroid" },
     { name = "jinja2" },
     { name = "pyyaml" },
     { name = "sphinx" },
@@ -1092,10 +1059,6 @@ dependencies = [
 ]
 
 [package.dev-dependencies]
-dev = [
-    { name = "pytest" },
-    { name = "pytest-cov" },
-]
 docs = [
     { name = "myst-parser" },
     { name = "sphinx-autoapi" },
@@ -1103,13 +1066,11 @@ docs = [
 ]
 euler-validate = [
     { name = "numpy" },
-    { name = "pytest" },
-    { name = "pytest-cov" },
     { name = "requests" },
 ]
-lint = [
-    { name = "codespell" },
-    { name = "ruff" },
+test = [
+    { name = "pytest" },
+    { name = "pytest-cov" },
 ]
 
 [package.metadata]
@@ -1136,24 +1097,18 @@ requires-dist = [
 ]
 
 [package.metadata.requires-dev]
-dev = [
-    { name = "pytest", specifier = ">=8.3.4" },
-    { name = "pytest-cov", specifier = ">=6" },
-]
 docs = [
-    { name = "myst-parser", specifier = ">=4.0.0" },
-    { name = "sphinx-autoapi", specifier = ">=3.4.0" },
-    { name = "sphinx-pyproject", specifier = ">=0.3.0" },
+    { name = "myst-parser", specifier = ">=4" },
+    { name = "sphinx-autoapi", specifier = ">=3.4" },
+    { name = "sphinx-pyproject", specifier = ">=0.3" },
 ]
 euler-validate = [
     { name = "numpy", specifier = ">=2.1.3" },
-    { name = "pytest", specifier = ">=8.3.4" },
-    { name = "pytest-cov", specifier = ">=6.0.0" },
     { name = "requests", specifier = ">=2.32.3" },
 ]
-lint = [
-    { name = "codespell", specifier = ">=2.3" },
-    { name = "ruff", specifier = ">=0.8.1" },
+test = [
+    { name = "pytest", specifier = ">=8.3.4" },
+    { name = "pytest-cov", specifier = ">=6" },
 ]
 
 [[package]]
@@ -1231,7 +1186,7 @@ version = "2.1.3"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "numpy" },
-    { name = "nvidia-nccl-cu12", marker = "platform_machine != 'aarch64' and platform_system == 'Linux'" },
+    { name = "nvidia-nccl-cu12", marker = "platform_machine != 'aarch64' and sys_platform == 'linux'" },
     { name = "scipy" },
 ]
 sdist = { url = "https://files.pythonhosted.org/packages/48/b0/131ffc4a15fd3acee9be3a7baa6b2fa6faa479799c51b880de9fc3ddf550/xgboost-2.1.3.tar.gz", hash = "sha256:7699ec4226156887d3afc665c63ab87469db9d46e361c702ba9fccd22535730c", size = 1090326 }