diff options
Diffstat (limited to 'src/2022/day22/aoc.cpp')
-rw-r--r-- | src/2022/day22/aoc.cpp | 112 |
1 files changed, 108 insertions, 4 deletions
diff --git a/src/2022/day22/aoc.cpp b/src/2022/day22/aoc.cpp index 101b604..69a3c9f 100644 --- a/src/2022/day22/aoc.cpp +++ b/src/2022/day22/aoc.cpp @@ -118,20 +118,124 @@ char cube_get(person* p, cube_map* cm) { return *(r.line.line + x - r.start); } -void cube_up(int s, person* p, cube_map** pcm) { +// p->x [0, cube_map::size) +// p->y [0, cube_map::size) +person wrap(person* p, cube_map** pcm, cube_map* cm, facing f) { + person p0{p->x, p->y, p->f}; + return p0; +} +void cube_up(int s, person* p, cube_map** pcm); +void cube_down(int s, person* p, cube_map** pcm); +void cube_left(int s, person* p, cube_map** pcm); +void cube_right(int s, person* p, cube_map** pcm); + +void cube_up(int s, person* p, cube_map** pcm) { + if (s > 0) { + if (p->y > 0) { + person p0{p->x, p->y - 1, p->f}; + if (cube_get(&p0, *pcm) == '.') { + p->y -= 1; + cube_up(s - 1, p, pcm); + } + } + else { // wrap to up + cube_map* cm = (*pcm)->sides[facing::up].m; + facing f = (*pcm)->sides[facing::up].f; + person p0 = wrap(p, pcm, cm, f); + if (cube_get(&p0, cm) == '.') { + *p = p0; + *pcm = cm; + switch(p->f) { + case right: cube_right(s - 1, p, pcm); break; + case down: cube_down(s - 1, p, pcm); break; + case left: cube_left(s - 1, p, pcm); break; + case up: cube_up(s - 1, p, pcm); break; + } + } + } + } } void cube_down(int s, person* p, cube_map** pcm) { - + if (s > 0) { + if (p->y < cube_map::size - 1) { + person p0{p->x, p->y + 1, p->f}; + if (cube_get(&p0, *pcm) == '.') { + p->y += 1; + cube_down(s - 1, p, pcm); + } + } + else { // wrap to down + cube_map* cm = (*pcm)->sides[facing::down].m; + facing f = (*pcm)->sides[facing::down].f; + person p0 = wrap(p, pcm, cm, f); + if (cube_get(&p0, cm) == '.') { + *p = p0; + *pcm = cm; + switch(p->f) { + case right: cube_right(s - 1, p, pcm); break; + case down: cube_down(s - 1, p, pcm); break; + case left: cube_left(s - 1, p, pcm); break; + case up: cube_up(s - 1, p, pcm); break; + } + } + } + } } void cube_left(int s, person* p, cube_map** pcm) { - + if (s > 0) { + if (p->x > 0) { + person p0{p->x - 1, p->y, p->f}; + if (cube_get(&p0, *pcm) == '.') { + p->x -= 1; + cube_left(s - 1, p, pcm); + } + } + else { // wrap to left + cube_map* cm = (*pcm)->sides[facing::left].m; + facing f = (*pcm)->sides[facing::left].f; + person p0 = wrap(p, pcm, cm, f); + if (cube_get(&p0, cm) == '.') { + *p = p0; + *pcm = cm; + switch(p->f) { + case right: cube_right(s - 1, p, pcm); break; + case down: cube_down(s - 1, p, pcm); break; + case left: cube_left(s - 1, p, pcm); break; + case up: cube_up(s - 1, p, pcm); break; + } + } + } + } } void cube_right(int s, person* p, cube_map** pcm) { - + if (s > 0) { + if (p->x < cube_map::size - 1) { + person p0{p->x + 1, p->y, p->f}; + if (cube_get(&p0, *pcm) == '.') { + p->x += 1; + cube_right(s - 1, p, pcm); + } + } + else { // wrap to right + cube_map* cm = (*pcm)->sides[facing::right].m; + facing f = (*pcm)->sides[facing::right].f; + person p0 = wrap(p, pcm, cm, f); + if (cube_get(&p0, cm) == '.') { + *p = p0; + *pcm = cm; + switch(p->f) { + case right: cube_right(s - 1, p, pcm); break; + case down: cube_down(s - 1, p, pcm); break; + case left: cube_left(s - 1, p, pcm); break; + case up: cube_up(s - 1, p, pcm); break; + } + } + } + } } void travel_cube(person* p, cube_map** pcm, const route& r) { |