{"id":17030259,"url":"https://github.com/vsoch/puzzles","last_synced_at":"2025-04-12T12:11:58.260Z","repository":{"id":33170915,"uuid":"153958283","full_name":"vsoch/puzzles","owner":"vsoch","description":"robot puzzle solver, maybe","archived":false,"fork":false,"pushed_at":"2022-11-09T17:03:16.000Z","size":20891,"stargazers_count":3,"open_issues_count":4,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-26T06:51:12.486Z","etag":null,"topics":["hacktoberfest"],"latest_commit_sha":null,"homepage":"https://nbviewer.jupyter.org/github/vsoch/puzzles/blob/master/examples/avocado-puzzle.ipynb","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vsoch.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-10-20T23:49:47.000Z","updated_at":"2021-10-05T05:38:15.000Z","dependencies_parsed_at":"2023-01-14T23:46:23.780Z","dependency_job_id":null,"html_url":"https://github.com/vsoch/puzzles","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/vsoch%2Fpuzzles","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vsoch%2Fpuzzles/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vsoch%2Fpuzzles/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vsoch%2Fpuzzles/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vsoch","download_url":"https://codeload.github.com/vsoch/puzzles/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248550619,"owners_count":21122934,"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":["hacktoberfest"],"created_at":"2024-10-14T08:05:31.738Z","updated_at":"2025-04-12T12:11:58.236Z","avatar_url":"https://github.com/vsoch.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Puzzles\n\nI've recently taken up a fondness for puzzles. Over a conversation one night,\nwe joked how cool it would be to have a digital puzzle. It actually\nwouldn't be such a crazy idea - each puzzle piece would need to have some sort of\ntiny sensor to understand it's location relative to the others, and some tiny\ndigital display that a mapped portion of an image would be shown on. Given that\nwe have something like the Kindle, the technology for \"long lasting and low power\nimages\" didn't seem that far off.\n\n| Pieces                          | Puzzle                                    |\n|---------------------------------|-------------------------------------------|\n|![examples/img/pieces.jpg](examples/img/pieces.jpg)| ![examples/img/background.jpg](examples/img/background.jpg) |\n\n\u003e Sometimes, you just feel out of place.\n\nBut the use of sensors is a bit out of my budget and current knowledge base. But\nthat's okay, let's work up to that. As I usually do, I thought of breaking the \nproblem into smaller pieces (pun intended). Perhaps there is a similar problem \nI can solve that would be a step in the right  direction? \nHow about a robot that solves puzzles? \n\n## High Level Algorithm\n\nA \"robot puzzle solver\" means that we do the following\n\n 1. We start with pictures of separate images\n 2. The puzzle pieces are segmented.\n 3. We represented features and edges of the pieces.\n 4. Based on these features, the segmented pieces are put together by an algorithm. \n\nBut more realistically, we want to start with a simpler problem:\n\n 1. We start with an entire image and break it into N squares\n 2. We match sides based on colors\n 3. We represented features and edges of the pieces.\n 4. Based on these features, the segmented pieces are put together by an algorithm.\n\n\n## Variables\n\nSome things we would need to account for in the above (and these are general notes \nfor now).\n\n - the puzzle pieces would ideally have consistent lighting and all be turned with picture upwards.\n - the camera, even from the top down, would introduce a bit of skew, both for shape and for color.\n - we can't make any assumption about the shape or position of the pieces. This means that although we could represent an edge as some sort of curve, the second you introduce a weirdo pieces that doesn't work well with the assumption, the algorithm breaks. For this reason, we might consider a pixel-based approach.\n - It could be the case that the algorithm can solve a puzzle as would a human - perhaps the edge pieces are easiest to do first, and then work from corners in?\n - We could do a recursive backtracking approach, where we start with edges, then work inwards from the corners, and choose the most probable piece given each new location with two \"decided\" edges. But as soon as the probabilities of a correct piece drop below some threshold, we should turn back.\n - Puzzles are real, and thus inherently imperfect. There needs to be an allowed margin of error.\n\n## Applications\n\nAs silly as this is, there are some fun applications for a robot puzzle solver.\n\n - Puzzles are currently ranked on number of pieces, but I've found this isn't a good representation for how difficult they are. The robot puzzle solver could come up with a metric that represents difficulty based on the algorithm.\n - Has anyone ever wondered how much harder it is to solve a puzzle if you are color blind? Given a metric of difficulty, we can see how that changes with different variables removed. For example, if we remove color, how much longer does the algorithm take?\n\n# Puzzle Solver\n\nThe puzzle solver currently loads in a photo, and can shuffle it and then re-discover\nthe solution. I haven't tested this on a huge number of images so your mileage may vary,\nand note that I still consider the library under development. You can see a full\nnotebook [here on nbviewer](https://nbviewer.jupyter.org/github/vsoch/puzzles/blob/master/examples/avocado-puzzle.ipynb)\nor keep reading to see basic usage and screen shots. The notebook file is located at [examples/avocado-puzzle.ipynb](examples/avocado-puzzle.ipynb)\nin case you want to edit it.\n\n```python\nfrom puzzles.models import PhotoPuzzle\n\npuzzle = PhotoPuzzle(\"avocado-halves.jpeg\")\n\n# Show the original image\nfig = puzzle.get_image_figure()\n\n# Metrics about the puzzle calculated based on minimum piece size we requested\n\npuzzle.metrics()\n# Image file         : avocado-halves.jpeg\n# Minimum piece size : 30\n# Width              : 640\n# Height             : 360\n# Number pieces      : 252\n\n# Plot the original pieces\nfig = puzzle.get_puzzle_figure()\n\n# Shuffle the puzzle and show it\npuzzle.shuffle()\n\n# Now show the puzzle broken into pieces!\npuzfig = puzzle.get_puzzle_figure()\n\n# Solve the puzzle!\npuzzle.solve()\n\nsolved_fig = puzzle.get_solved_figure()\n```\n\nHere is the shuffled puzzle:\n\n![examples/shuffled-puzzle.png](examples/shuffled-puzzle.png)\n\nAnd then solved!\n\n![examples/solved-puzzle.png](examples/solved-puzzle.png)\n\nIn practice I've found that the original shuffle can lead to a different result\n(e.g., a slightly not perfect solution).\n\n## Changes\n\nIn case you want to contribute here are some ideas!\n\n### Puzzle Pieces\n\nI'd like there to be a model of a `PuzzlePiece` that holds the piece data, and then comparisons \nbetween pieces are done in this manner. Right now we have a `PlacedPiece` which really just\nholds an index into the array self.pieces and a location (x,y) in terms of coordinates\non the board. It would be cleaner to somehow combine these two.\n\n### Image Loading\n\nCurrently, if we display the image before shuffle it actually isn't perfect.\nBut I think it should be (and this is a bug) we would want to be able to\ndisplay the image, see that it's correct, and then shuffle.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvsoch%2Fpuzzles","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvsoch%2Fpuzzles","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvsoch%2Fpuzzles/lists"}