Skip to content

Instantly share code, notes, and snippets.

@mnguyenngo
Created May 28, 2026 18:00
Show Gist options
  • Select an option

  • Save mnguyenngo/8e960f2c12d12174d5a03ce433d6e61b to your computer and use it in GitHub Desktop.

Select an option

Save mnguyenngo/8e960f2c12d12174d5a03ce433d6e61b to your computer and use it in GitHub Desktop.
from typing import List, Tuple, Dict, Any
import math
class Room:
"""
Represents a room as a logical constraint boundary.
Supports composition of adjacent rooms (e.g., bathrooms and closets).
"""
def __init__(self, name: str, x: float, y: float, center: Tuple[float, float] = (0.0, 0.0)):
if x <= 0 or y <= 0:
raise ValueError("Dimensions must be positive.")
self.name = name
self.x = x # width (feet)
self.y = y # depth (feet)
self.center = center
self.sub_rooms: List['Room'] = []
@property
def calculated_area(self) -> float:
return self.x * self.y
@property
def total_suite_area(self) -> float:
"""Returns the total area of the room and all its sub-rooms."""
return self.calculated_area + sum(r.total_suite_area for r in self.sub_rooms)
def add_bathroom(self, target_area: float, bathroom_type: str = "standard") -> 'Room':
"""Attaches a bathroom to this room adjacent to its right side."""
# Standard width of 5.0 ft for standard layout, or 8.0 ft for custom
width = 5.0 if bathroom_type == "standard" else 8.0
depth = target_area / width
# Position bathroom adjacent to the right side of the main room
bath_center = (self.center[0] + (self.x + width) / 2.0, self.center[1])
bath = Room(f"{self.name} Bathroom", x=width, y=depth, center=bath_center)
self.sub_rooms.append(bath)
return bath
def add_closet(self, target_area: float, closet_type: str = "walk_in") -> 'Room':
"""Attaches a closet to this room adjacent to its top side."""
# Standard depth of 4.0 ft for walk-in layout, or 3.0 ft for reach-in
depth = 4.0 if closet_type == "walk_in" else 3.0
width = target_area / depth
# Position closet adjacent to the top side of the main room
closet_center = (self.center[0], self.center[1] + (self.y + depth) / 2.0)
closet = Room(f"{self.name} Closet", x=width, y=depth, center=closet_center)
self.sub_rooms.append(closet)
return closet
def _calculate_vertices(self) -> List[Tuple[float, float]]:
cx, cy = self.center
x_min, x_max = cx - self.x / 2.0, cx + self.x / 2.0
y_min, y_max = cy - self.y / 2.0, cy + self.y / 2.0
return [
(x_min, y_min),
(x_max, y_min),
(x_max, y_max),
(x_min, y_max)
]
@property
def vertices(self) -> List[Tuple[float, float]]:
return self._calculate_vertices()
def serialize(self) -> Dict[str, Any]:
return {
"name": self.name,
"dimensions": (self.x, self.y),
"center": self.center,
"calculated_area": self.calculated_area,
"vertices": self.vertices,
"sub_rooms": [r.serialize() for r in self.sub_rooms]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment