{"id":26550158,"url":"https://github.com/mikyll/gosnek","last_synced_at":"2025-03-22T07:32:30.086Z","repository":{"id":108931115,"uuid":"456589787","full_name":"mikyll/GoSnek","owner":"mikyll","description":"Go CLI implementation of Snake 🐍 game, using channels","archived":false,"fork":false,"pushed_at":"2024-03-04T09:28:08.000Z","size":1576,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-03-04T10:48:27.336Z","etag":null,"topics":["channels","cli","go","message-passing","snake"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mikyll.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2022-02-07T16:38:14.000Z","updated_at":"2023-03-01T01:56:25.000Z","dependencies_parsed_at":null,"dependency_job_id":"fdd1c3c7-6b3d-42eb-8e53-096f82179aad","html_url":"https://github.com/mikyll/GoSnek","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikyll%2FGoSnek","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikyll%2FGoSnek/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikyll%2FGoSnek/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikyll%2FGoSnek/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mikyll","download_url":"https://codeload.github.com/mikyll/GoSnek/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244924774,"owners_count":20532872,"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":["channels","cli","go","message-passing","snake"],"created_at":"2025-03-22T07:30:37.422Z","updated_at":"2025-03-22T07:32:30.078Z","avatar_url":"https://github.com/mikyll.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n  [![GPL-3.0 License][license-shield]][license-url]\n  [![Size][size-shield]][size-url]\n  [![Issues][issues-shield]][issues-url]\n  [![Stars][stars-shield]][stars-url]\\\n  [![Go][go-shield]][go-url]\n  [![VS Code][vs-code-shield]][vs-code-url]\n\n# GoSnek 🐍\n\u003cp\u003e\n  Go CLI implementation of Snake game, using channels.\u003cbr/\u003e\n  NB: this code works only with ANSI terminals.\n\n\u003c/div\u003e\n          \n\u003ch2 align=\"center\"\u003eDemo\u003c/h2\u003e\n\u003cp align=\"center\"\u003e\n  \u003cimg alt=\"Demo\" src=\"https://github.com/mikyll/GoSnek/blob/main/gfx/cli-snake.gif\"/\u003e\u003cbr/\u003e\n  Resize the terminal window to change the \"difficulty\".\n\u003c/p\u003e\n\n### Fruit Spawn Algorithm\nTo prevent the fruit from spawning over the snake, we first get a pair of random indexes ```f.x``` and ```f.y``` and we check if that location is already occupied by the snake.\nIf so, we save those indexes and iterate over the columns (```f.y```) and rows (```f.x```) of the board, starting from ```f.y+1``` and ```f.x+1```.\nAt each cycle we check if the new location is still occupied by the snake:\n- If not we've found our fruit coordinates;\n- otherwise we increase ```f.x``` by one (or ```f.y```, for the external loop).\nWhen the index reaches the border (```BL``` or ```BH```), we reset it to 1, so it can make a complete cycle, and stop when they get to ```f.x``` or ```f.y``` (remember we started from ```f.x+1``` and ```f.y+1```).\n\nThis way we got a random starting point for our fruit spawn location and, in case it's not valid, we iteratively check for free coordinates.\n```go\nf.x = rand.Intn(BL-2) + 1\nf.y = rand.Intn(BH-2) + 1\n\nif b.xy[f.x][f.y] == HEAD || b.xy[f.x][f.y] == BODY {\n  if f.x == 1 || f.x == BL-1 {\n    f.x = BL / 2\n  }\n  if f.y == 1 || f.y == BH-1 {\n    f.y = BH / 2\n  }\n  found := false\n  j := f.y\n  i := f.x\n  for f.y += 1; f.y != j; f.y++ {\n    for f.x += 1; f.x != i; f.x++ {\n      if b.xy[f.x][f.y] != HEAD \u0026\u0026 b.xy[f.x][f.y] != BODY \u0026\u0026 b.xy[f.x][f.y] != BORDER {\n        found = true\n        break\n      }\n      if f.x == BL-1 {\n        f.x = 1\n      }\n    }\n    if found {\n      break\n    }\n    if f.y == BH-1 {\n      f.y = 1\n    }\n  }\n}\n```\n\n### References\n- [Read character from stdin without pressing enter](https://stackoverflow.com/questions/15159118/read-a-character-from-standard-input-in-go-without-pressing-enter/): [Windows](https://stackoverflow.com/a/70627571), [UNIX](https://stackoverflow.com/a/17278776)\n- [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code)\n\n\u003cdiv align=\"center\"\u003e\n\n[![LinkedIn][linkedin-shield]][linkedin-url]\n[![GitHub followers][github-shield]][github-url]\n  \n\u003c/div\u003e\n\n[downloads-shield]: https://img.shields.io/github/downloads/mikyll/GoSnek/total\n[downloads-url]: https://github.com/mikyll/GoSnek/releases/latest\n[license-shield]: https://img.shields.io/github/license/mikyll/GoSnek\n[license-url]: https://github.com/mikyll/GoSnek/blob/main/LICENSE\n[size-shield]: \thttps://img.shields.io/github/repo-size/mikyll/GoSnek\n[size-url]: https://github.com/mikyll/GoSnek\n[issues-shield]: https://img.shields.io/github/issues/mikyll/GoSnek\n[issues-url]: https://github.com/mikyll/GoSnek/issues\n[stars-shield]: https://custom-icon-badges.herokuapp.com/github/stars/mikyll/GoSnek?logo=star\u0026logoColor=yellow\u0026style=flat\n[stars-url]: https://github.com/mikyll/GoSnek/stargazers\n\n[go-shield]: https://img.shields.io/badge/Go-%2300ADD8.svg?logo=go\u0026logoColor=white\n[go-url]: https://go.dev/\n[vs-code-shield]:  https://img.shields.io/badge/VS%20Code-0078d7.svg?logo=visual-studio-code\u0026logoColor=white\n[vs-code-url]: https://code.visualstudio.com/\n\n[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?logo=linkedin\u0026colorB=0077B5\n[linkedin-url]: https://www.linkedin.com/in/michele-righi/?locale=en_US\n[github-shield]: https://img.shields.io/github/followers/mikyll.svg?style=social\u0026label=Follow\n[github-url]: https://github.com/mikyll\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikyll%2Fgosnek","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmikyll%2Fgosnek","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikyll%2Fgosnek/lists"}