https://github.com/mikyll/gosnek
Go CLI implementation of Snake 🐍 game, using channels
https://github.com/mikyll/gosnek
channels cli go message-passing snake
Last synced: 10 months ago
JSON representation
Go CLI implementation of Snake 🐍 game, using channels
- Host: GitHub
- URL: https://github.com/mikyll/gosnek
- Owner: mikyll
- License: mit
- Created: 2022-02-07T16:38:14.000Z (almost 4 years ago)
- Default Branch: main
- Last Pushed: 2024-03-04T09:28:08.000Z (almost 2 years ago)
- Last Synced: 2024-03-04T10:48:27.336Z (almost 2 years ago)
- Topics: channels, cli, go, message-passing, snake
- Language: Go
- Homepage:
- Size: 1.5 MB
- Stars: 7
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[![GPL-3.0 License][license-shield]][license-url]
[![Size][size-shield]][size-url]
[![Issues][issues-shield]][issues-url]
[![Stars][stars-shield]][stars-url]\
[![Go][go-shield]][go-url]
[![VS Code][vs-code-shield]][vs-code-url]
# GoSnek 🐍
Go CLI implementation of Snake game, using channels.
NB: this code works only with ANSI terminals.
Demo

Resize the terminal window to change the "difficulty".
### Fruit Spawn Algorithm
To 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.
If 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```.
At each cycle we check if the new location is still occupied by the snake:
- If not we've found our fruit coordinates;
- otherwise we increase ```f.x``` by one (or ```f.y```, for the external loop).
When 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```).
This 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.
```go
f.x = rand.Intn(BL-2) + 1
f.y = rand.Intn(BH-2) + 1
if b.xy[f.x][f.y] == HEAD || b.xy[f.x][f.y] == BODY {
if f.x == 1 || f.x == BL-1 {
f.x = BL / 2
}
if f.y == 1 || f.y == BH-1 {
f.y = BH / 2
}
found := false
j := f.y
i := f.x
for f.y += 1; f.y != j; f.y++ {
for f.x += 1; f.x != i; f.x++ {
if b.xy[f.x][f.y] != HEAD && b.xy[f.x][f.y] != BODY && b.xy[f.x][f.y] != BORDER {
found = true
break
}
if f.x == BL-1 {
f.x = 1
}
}
if found {
break
}
if f.y == BH-1 {
f.y = 1
}
}
}
```
### References
- [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)
- [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code)
[![LinkedIn][linkedin-shield]][linkedin-url]
[![GitHub followers][github-shield]][github-url]
[downloads-shield]: https://img.shields.io/github/downloads/mikyll/GoSnek/total
[downloads-url]: https://github.com/mikyll/GoSnek/releases/latest
[license-shield]: https://img.shields.io/github/license/mikyll/GoSnek
[license-url]: https://github.com/mikyll/GoSnek/blob/main/LICENSE
[size-shield]: https://img.shields.io/github/repo-size/mikyll/GoSnek
[size-url]: https://github.com/mikyll/GoSnek
[issues-shield]: https://img.shields.io/github/issues/mikyll/GoSnek
[issues-url]: https://github.com/mikyll/GoSnek/issues
[stars-shield]: https://custom-icon-badges.herokuapp.com/github/stars/mikyll/GoSnek?logo=star&logoColor=yellow&style=flat
[stars-url]: https://github.com/mikyll/GoSnek/stargazers
[go-shield]: https://img.shields.io/badge/Go-%2300ADD8.svg?logo=go&logoColor=white
[go-url]: https://go.dev/
[vs-code-shield]: https://img.shields.io/badge/VS%20Code-0078d7.svg?logo=visual-studio-code&logoColor=white
[vs-code-url]: https://code.visualstudio.com/
[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?logo=linkedin&colorB=0077B5
[linkedin-url]: https://www.linkedin.com/in/michele-righi/?locale=en_US
[github-shield]: https://img.shields.io/github/followers/mikyll.svg?style=social&label=Follow
[github-url]: https://github.com/mikyll