refactored out Position
This commit is contained in:
parent
923e967056
commit
b83bb6b37a
12 changed files with 252 additions and 216 deletions
|
|
@ -1,6 +1,7 @@
|
|||
from __future__ import annotations
|
||||
from abc import ABC, abstractmethod
|
||||
from dataclasses import dataclass, field
|
||||
from advent.common.position import UNIT_NEG_X, UNIT_NEG_Y, UNIT_X, UNIT_Y, Position
|
||||
from enum import Enum
|
||||
|
||||
from typing import Iterator, Self
|
||||
|
|
@ -44,29 +45,17 @@ class Facing(Enum):
|
|||
case Facing.Left: return Facing.Up
|
||||
case Facing.Down: return Facing.Left
|
||||
|
||||
def as_position(self) -> Position2D:
|
||||
def as_position(self) -> Position:
|
||||
match self:
|
||||
case Facing.Right: return Position2D(1, 0)
|
||||
case Facing.Up: return Position2D(0, -1)
|
||||
case Facing.Left: return Position2D(-1, 0)
|
||||
case Facing.Down: return Position2D(0, 1)
|
||||
|
||||
|
||||
@dataclass(slots=True, frozen=True)
|
||||
class Position2D:
|
||||
x: int
|
||||
y: int
|
||||
|
||||
def __add__(self, other: Position2D) -> Position2D:
|
||||
return Position2D(self.x + other.x, self.y + other.y)
|
||||
|
||||
def __mul__(self, factor: int) -> Position2D:
|
||||
return Position2D(self.x * factor, self.y * factor)
|
||||
case Facing.Right: return UNIT_X
|
||||
case Facing.Up: return UNIT_NEG_Y
|
||||
case Facing.Left: return UNIT_NEG_X
|
||||
case Facing.Down: return UNIT_Y
|
||||
|
||||
|
||||
@dataclass(slots=True, frozen=True)
|
||||
class Player:
|
||||
position: Position2D
|
||||
position: Position
|
||||
facing: Facing
|
||||
|
||||
@property
|
||||
|
|
@ -113,35 +102,35 @@ class PasswordJungle(ABC):
|
|||
return val, start
|
||||
case _: raise Exception("Illegal char")
|
||||
|
||||
def start(self) -> tuple[Position2D, Facing]:
|
||||
def start(self) -> tuple[Position, Facing]:
|
||||
return self.start_column(0), Facing.Right
|
||||
|
||||
def start_column(self, row: int) -> Position2D:
|
||||
def start_column(self, row: int) -> Position:
|
||||
for col, char in enumerate(self.map[row]):
|
||||
if char != ' ':
|
||||
return Position2D(col, row)
|
||||
return Position(col, row)
|
||||
raise Exception("Empty row found")
|
||||
|
||||
def end_column(self, row: int) -> Position2D:
|
||||
def end_column(self, row: int) -> Position:
|
||||
for col in range(len(self.map[row]) - 1, -1, -1):
|
||||
if self.map[row][col] != ' ':
|
||||
return Position2D(col, row)
|
||||
return Position(col, row)
|
||||
raise Exception("Empty row found")
|
||||
|
||||
def start_row(self, col: int) -> Position2D:
|
||||
def start_row(self, col: int) -> Position:
|
||||
for row, line in enumerate(self.map):
|
||||
if col < len(line) and line[col] != ' ':
|
||||
return Position2D(col, row)
|
||||
return Position(col, row)
|
||||
raise Exception("Empty row found")
|
||||
|
||||
def end_row(self, col: int) -> Position2D:
|
||||
def end_row(self, col: int) -> Position:
|
||||
for row in range(len(self.map) - 1, -1, -1):
|
||||
line = self.map[row]
|
||||
if col < len(line) and line[col] != ' ':
|
||||
return Position2D(col, row)
|
||||
return Position(col, row)
|
||||
raise Exception("Empty row found")
|
||||
|
||||
def check_tile(self, pos: Position2D) -> str:
|
||||
def check_tile(self, pos: Position) -> str:
|
||||
if pos.y not in range(0, len(self.map)) or pos.x not in range(0, len(self.map[pos.y])):
|
||||
return ' '
|
||||
return self.map[pos.y][pos.x]
|
||||
|
|
@ -216,9 +205,9 @@ class CubePosition:
|
|||
@dataclass(slots=True)
|
||||
class PasswordCubeJungle(PasswordJungle):
|
||||
cube_width: int = field(default=50, init=False)
|
||||
sides: dict[Vector, tuple[Position2D, Vector]] = field(default_factory=dict, init=False)
|
||||
sides: dict[Vector, tuple[Position, Vector]] = field(default_factory=dict, init=False)
|
||||
|
||||
def _find_neighbors(self, map_position: Position2D, facing: Facing,
|
||||
def _find_neighbors(self, map_position: Position, facing: Facing,
|
||||
cube_position: CubePosition):
|
||||
match facing:
|
||||
case Facing.Right: facing_right = cube_position.facing
|
||||
|
|
@ -300,7 +289,7 @@ class PasswordCubeJungle(PasswordJungle):
|
|||
y = position.y
|
||||
x = position.x + self.cube_width - 1 - delta
|
||||
|
||||
result = Player(Position2D(x, y), facing)
|
||||
result = Player(Position(x, y), facing)
|
||||
return result
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from .solution import (
|
|||
PasswordCubeJungle,
|
||||
PasswordSimpleJungle,
|
||||
Player,
|
||||
Position2D,
|
||||
Position,
|
||||
Turn,
|
||||
Vector,
|
||||
day_num,
|
||||
|
|
@ -56,39 +56,39 @@ def test_positions():
|
|||
jungle = PasswordSimpleJungle.create(lines)
|
||||
|
||||
result = jungle.start_column(0)
|
||||
assert result == Position2D(8, 0)
|
||||
assert result == Position(8, 0)
|
||||
|
||||
result = jungle.start_row(0)
|
||||
assert result == Position2D(0, 4)
|
||||
assert result == Position(0, 4)
|
||||
|
||||
result = jungle.end_column(4)
|
||||
assert result == Position2D(11, 4)
|
||||
assert result == Position(11, 4)
|
||||
|
||||
result = jungle.end_row(4)
|
||||
assert result == Position2D(4, 7)
|
||||
assert result == Position(4, 7)
|
||||
|
||||
result = jungle.start_row(8)
|
||||
assert result == Position2D(8, 0)
|
||||
assert result == Position(8, 0)
|
||||
|
||||
|
||||
def test_step():
|
||||
lines = input.read_lines(day_num, 'example01.txt')
|
||||
jungle = PasswordSimpleJungle.create(lines)
|
||||
person = jungle.step(Player(Position2D(8, 0), Facing.Right), 10)
|
||||
assert person == Player(Position2D(10, 0), Facing.Right)
|
||||
person = jungle.step(Player(Position(8, 0), Facing.Right), 10)
|
||||
assert person == Player(Position(10, 0), Facing.Right)
|
||||
|
||||
person = jungle.step(Player(Position2D(10, 0), Facing.Down), 5)
|
||||
assert person == Player(Position2D(10, 5), Facing.Down)
|
||||
person = jungle.step(Player(Position(10, 0), Facing.Down), 5)
|
||||
assert person == Player(Position(10, 5), Facing.Down)
|
||||
|
||||
person = jungle.step(Player(Position2D(10, 5), Facing.Right), 5)
|
||||
assert person == Player(Position2D(3, 5), Facing.Right)
|
||||
person = jungle.step(Player(Position(10, 5), Facing.Right), 5)
|
||||
assert person == Player(Position(3, 5), Facing.Right)
|
||||
|
||||
|
||||
def test_walk():
|
||||
lines = input.read_lines(day_num, 'example01.txt')
|
||||
jungle = PasswordSimpleJungle.create(lines)
|
||||
person = jungle.walk()
|
||||
assert person == Player(Position2D(7, 5), Facing.Right)
|
||||
assert person == Player(Position(7, 5), Facing.Right)
|
||||
assert person.value == 6032
|
||||
|
||||
|
||||
|
|
@ -102,19 +102,19 @@ def test_cube_info():
|
|||
lines = input.read_lines(day_num, 'example01.txt')
|
||||
jungle = PasswordCubeJungle.create(lines)
|
||||
|
||||
person = Player(Position2D(14, 8), Facing.Up)
|
||||
person = Player(Position(14, 8), Facing.Up)
|
||||
result = jungle.get_cube_position(person)
|
||||
assert result == (CubePosition(Vector(0, 1, 0), Vector(0, 0, -1)), 2)
|
||||
|
||||
person = Player(Position2D(11, 5), Facing.Right)
|
||||
person = Player(Position(11, 5), Facing.Right)
|
||||
result = jungle.get_cube_position(person)
|
||||
assert result == (CubePosition(Vector(0, 0, -1), Vector(0, 1, 0)), 1)
|
||||
|
||||
person = Player(Position2D(1, 7), Facing.Down)
|
||||
person = Player(Position(1, 7), Facing.Down)
|
||||
result = jungle.get_cube_position(person)
|
||||
assert result == (CubePosition(Vector(0, 0, 1), Vector(-1, 0, 0)), 2)
|
||||
|
||||
person = Player(Position2D(10, 11), Facing.Down)
|
||||
person = Player(Position(10, 11), Facing.Down)
|
||||
result = jungle.get_cube_position(person)
|
||||
assert result == (CubePosition(Vector(-1, 0, 0), Vector(0, 0, 1)), 1)
|
||||
|
||||
|
|
@ -123,18 +123,18 @@ def test_cube_wrap():
|
|||
lines = input.read_lines(day_num, 'example01.txt')
|
||||
jungle = PasswordCubeJungle.create(lines)
|
||||
|
||||
person = Player(Position2D(14, 8), Facing.Up)
|
||||
person = Player(Position(14, 8), Facing.Up)
|
||||
result = jungle.wrap(person)
|
||||
assert result == Player(Position2D(11, 5), Facing.Left)
|
||||
assert result == Player(Position(11, 5), Facing.Left)
|
||||
|
||||
person = Player(Position2D(11, 5), Facing.Right)
|
||||
person = Player(Position(11, 5), Facing.Right)
|
||||
result = jungle.wrap(person)
|
||||
assert result == Player(Position2D(14, 8), Facing.Down)
|
||||
assert result == Player(Position(14, 8), Facing.Down)
|
||||
|
||||
person = Player(Position2D(1, 7), Facing.Down)
|
||||
person = Player(Position(1, 7), Facing.Down)
|
||||
result = jungle.wrap(person)
|
||||
assert result == Player(Position2D(10, 11), Facing.Up)
|
||||
assert result == Player(Position(10, 11), Facing.Up)
|
||||
|
||||
person = Player(Position2D(10, 11), Facing.Down)
|
||||
person = Player(Position(10, 11), Facing.Down)
|
||||
result = jungle.wrap(person)
|
||||
assert result == Player(Position2D(1, 7), Facing.Up)
|
||||
assert result == Player(Position(1, 7), Facing.Up)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue