{"id":16154787,"url":"https://github.com/idorobots/fullstack-challenge-obstacle-course-solver","last_synced_at":"2026-05-03T18:33:59.781Z","repository":{"id":55100608,"uuid":"276883342","full_name":"Idorobots/fullstack-challenge-obstacle-course-solver","owner":"Idorobots","description":"A FE and BE challenge I submited as part of a hiring process. TypeScript and Scala, runnable in Docker.","archived":false,"fork":false,"pushed_at":"2021-01-10T18:02:18.000Z","size":202,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-13T06:18:15.155Z","etag":null,"topics":["backend","docker","frontend","full-stack","react","scala","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Idorobots.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-07-03T11:26:33.000Z","updated_at":"2021-01-10T18:02:16.000Z","dependencies_parsed_at":"2022-08-14T12:00:37.395Z","dependency_job_id":null,"html_url":"https://github.com/Idorobots/fullstack-challenge-obstacle-course-solver","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Idorobots%2Ffullstack-challenge-obstacle-course-solver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Idorobots%2Ffullstack-challenge-obstacle-course-solver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Idorobots%2Ffullstack-challenge-obstacle-course-solver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Idorobots%2Ffullstack-challenge-obstacle-course-solver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Idorobots","download_url":"https://codeload.github.com/Idorobots/fullstack-challenge-obstacle-course-solver/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247574088,"owners_count":20960495,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backend","docker","frontend","full-stack","react","scala","typescript"],"created_at":"2024-10-10T01:18:53.237Z","updated_at":"2026-05-03T18:33:54.753Z","avatar_url":"https://github.com/Idorobots.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# obstacle-course-solver\nA full-stack-ish technical challenge for a company.\n\nThe goal of the challenge was to create an obstactle course solver that works on a grid of interconnected fields with various, well obstacles on it. Additional task was to add support for \"wormholes\" - fields that connect to another, distant field - and ensure that the solver can handle these.\nThe solution is an implementation of the field editor along with a backend A*-based solver. Two heuristics are provided, \"distance\" and \"zero\" that handles the wormhole use case.\n\nHere's how it looks:\n\n![](./ui.png)\n\n## Testing, building \u0026 running\n### Backend part\nTo run the included tests (hopefuly I wrote some ¯\\\\\\_(ツ)\\_/¯) run either of the following commands:\n\n```\nsbt clean-test\n```\n\nTo build \u0026 package the project:\n\n```\nsbt clean-compile\nsbt docker:publishLocal\n```\n\nEnsure that the Docker daemon is up an running in order to create an image. The image will be based on `openjdk:8` so it'll download a bit of crap on the first run. To then run the backend execute either command:\n\n```\nsbt run\ndocker run -p 8081:1234 -e REST_HOST=0.0.0.0 -e REST_PORT=1234 -e LOG_LEVEL=DEBUG obstacle-course-be:latest\n```\n\n### Frontend part\nTo run the tests:\n\n```\nnpm run test # Runs the tests inside of Firefox \u0026 Chrome.\nnpm run test:ci # Runs tests inside of a headless browser.\nnpm run test:watch # Runs the tests in an interactive mode - suitable for development.\n```\n\nTo build the project:\n\n```\nnpm run build # Builds a debug version of the project.\nnpm run build:release # Builds a \"release\" \"optimized\" version of the project.\nnpm run build:watch # Rebuilds the project automatically on any source changes.\n```\n\nTo package the project with Docker ensure that the Docker daemon is running and run:\n\n```\nnpm run package\n```\n\nTo run the project after building the image simply execute:\n\n```\ndocker run -p 8080:80 -e BACKEND_URL=\"localhost:8081\" obstacle-course-fe:latest\n```\n\nAlternatively, you can start a static file server inside of the `dist` directory instead of building a Docker image for the frontend.\n\n## Description of the solution\n### Frontend part\nThe frontend was written in TypeScript using Preact \u0026 Mobx. Mobx was chosen because of how minimalistic it is as compared to other implementations of Flux storage - instead of large amount of boilerplate I could focus entirely on delivering features without complicating their implementation needlessly. Preact was chosen due to smaller size than some of the alternatives (the whole app takes only 132k with assets, without gzipping). The app consists of a main store \u0026 user actions, backend API service, several containers (a.k.a. smart-componnents) and a few layout components. Unfortunately time was shor, so I did not include a diagram of how it all works.\n\n### Backend part\nThe backend part was written in Scala mostly in functional style although there were very few spots where that could be taken advantage of. The solver and A* implementation is unfortunately written in imperative style - functional version would be too time consuming for this challenge.\n\n## Caveats\nSome liberties were taken during the development:\n\n- Frontend isn't responsive nor follows any coherent desings - I'm not much of a UI designer, so I didn't bother with the looks as much as with the inner workings down the stack.\n\n- Field \u0026 board configuration is served by the backend and can be changed fairly easily without changing the frontend client.\n\n- The A* implementation on the backend is written in an imperative way making it pretty ugly.\n\n- The default heuristic for the A* algorithm is not addmissible in presence of Worm Holes making it find sub-optimal paths. A second, \"zero-distance\" heuristic was provided, turning the A* into a Dijkstra variant searching for optimal paths (turned on with `HEURISTIC=zero` env parameter).\n\n- Sometimes paths look weird even though they are optimal - there is no penalty for moving diagonally.\n\n- The code is missing a lot of tests, that's mostly because of lack of time for this assignment.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fidorobots%2Ffullstack-challenge-obstacle-course-solver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fidorobots%2Ffullstack-challenge-obstacle-course-solver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fidorobots%2Ffullstack-challenge-obstacle-course-solver/lists"}