-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
497 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# GoMaze | ||
|
||
*GoMaze* is a simple maze generator and solver written in *Go*. It randomly generate the maze and uses *Dijkstra algorithm* to find the minimum path between 2 points. | ||
|
||
The library used to render the maze and manage inputs is [ebitengine](https://ebitengine.org/), a simple 2D game engine written in Go. | ||
The minimum path is calculated using the [graph](https://pkg.go.dev/github.com/dominikbraun/graph#readme-getting-started) library. | ||
|
||
 | ||
|
||
# How to use | ||
|
||
## How to run | ||
|
||
```bash | ||
go run cmd/main.go | ||
``` | ||
|
||
```bash | ||
Flags: | ||
-h int | ||
height of the maze (cells number) (default 20) | ||
-w int | ||
width of the maze (cells number) (default 20) | ||
``` | ||
|
||
## How to play | ||
|
||
- *Click* on the maze with the *left mouse button* to set the *start* and the *ending* point. | ||
- Press *R* on the keyboard to *generate* a new maze. | ||
|
||
# How it works | ||
|
||
To find the minimum path between 2 points, the program uses the *Dijkstra algorithm*. Every walkable cell of the matrix (representing the maze), have been added to a graph. The weight of the edges is the distance between 2 cells, which is always 1. The algorithm will find the shortest path between the 2 points by exploring the graph. | ||
|
||
This is an example of the generated graph: | ||
|
||
 | ||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package main | ||
|
||
import ( | ||
"flag" | ||
"log" | ||
|
||
"github.com/cheina97/gomaze/pkg/game" | ||
"github.com/hajimehoshi/ebiten/v2" | ||
) | ||
|
||
func main() { | ||
w := flag.Int("w", 20, "width of the maze (cells number)") | ||
h := flag.Int("h", 20, "height of the maze (cells number)") | ||
flag.Parse() | ||
game, err := game.NewGame(*w, *h) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
if err := ebiten.RunGame(game); err != nil { | ||
log.Fatal(err) | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
module github.com/cheina97/gomaze | ||
|
||
go 1.22.1 | ||
|
||
require ( | ||
github.com/dominikbraun/graph v0.23.0 | ||
github.com/hajimehoshi/ebiten/v2 v2.6.7 | ||
) | ||
|
||
require ( | ||
github.com/ebitengine/purego v0.6.0 // indirect | ||
github.com/jezek/xgb v1.1.0 // indirect | ||
golang.org/x/exp/shiny v0.0.0-20230817173708-d852ddb80c63 // indirect | ||
golang.org/x/image v0.12.0 // indirect | ||
golang.org/x/mobile v0.0.0-20230922142353-e2f452493d57 // indirect | ||
golang.org/x/sync v0.3.0 // indirect | ||
golang.org/x/sys v0.12.0 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
github.com/dominikbraun/graph v0.23.0 h1:TdZB4pPqCLFxYhdyMFb1TBdFxp8XLcJfTTBQucVPgCo= | ||
github.com/dominikbraun/graph v0.23.0/go.mod h1:yOjYyogZLY1LSG9E33JWZJiq5k83Qy2C6POAuiViluc= | ||
github.com/ebitengine/purego v0.6.0 h1:Yo9uBc1x+ETQbfEaf6wcBsjrQfCEnh/gaGUg7lguEJY= | ||
github.com/ebitengine/purego v0.6.0/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= | ||
github.com/hajimehoshi/ebiten/v2 v2.6.7 h1:rxlMxu487wZN/JteykmuGdO1qotOolL8vJDU85lPh7A= | ||
github.com/hajimehoshi/ebiten/v2 v2.6.7/go.mod h1:gKgQI26zfoSb6j5QbrEz2L6nuHMbAYwrsXa5qsGrQKo= | ||
github.com/jezek/xgb v1.1.0 h1:wnpxJzP1+rkbGclEkmwpVFQWpuE2PUGNUzP8SbfFobk= | ||
github.com/jezek/xgb v1.1.0/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk= | ||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= | ||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= | ||
golang.org/x/exp/shiny v0.0.0-20230817173708-d852ddb80c63 h1:3AGKexOYqL+ztdWdkB1bDwXgPBuTS/S8A4WzuTvJ8Cg= | ||
golang.org/x/exp/shiny v0.0.0-20230817173708-d852ddb80c63/go.mod h1:UH99kUObWAZkDnWqppdQe5ZhPYESUw8I0zVV1uWBR+0= | ||
golang.org/x/image v0.12.0 h1:w13vZbU4o5rKOFFR8y7M+c4A5jXDC0uXTdHYRP8X2DQ= | ||
golang.org/x/image v0.12.0/go.mod h1:Lu90jvHG7GfemOIcldsh9A2hS01ocl6oNO7ype5mEnk= | ||
golang.org/x/mobile v0.0.0-20230922142353-e2f452493d57 h1:Q6NT8ckDYNcwmi/bmxe+XbiDMXqMRW1xFBtJ+bIpie4= | ||
golang.org/x/mobile v0.0.0-20230922142353-e2f452493d57/go.mod h1:wEyOn6VvNW7tcf+bW/wBz1sehi2s2BZ4TimyR7qZen4= | ||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= | ||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= | ||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | ||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= | ||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= | ||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= | ||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= | ||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= | ||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= | ||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= | ||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= | ||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= | ||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= | ||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= | ||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= | ||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
strict graph { | ||
|
||
|
||
"1/2" [ weight=0 ]; | ||
|
||
"1/2" -- "2/2" [ weight=0 ]; | ||
|
||
"1/2" -- "1/3" [ weight=0 ]; | ||
|
||
"1/2" -- "1/1" [ weight=0 ]; | ||
|
||
"2/5" [ weight=0 ]; | ||
|
||
"2/5" -- "2/4" [ weight=0 ]; | ||
|
||
"2/0" [ weight=0 ]; | ||
|
||
"2/4" [ weight=0 ]; | ||
|
||
"2/4" -- "2/5" [ weight=0 ]; | ||
|
||
"2/4" -- "1/4" [ weight=0 ]; | ||
|
||
"0/5" [ weight=0 ]; | ||
|
||
"0/5" -- "0/4" [ weight=0 ]; | ||
|
||
"1/1" [ weight=0 ]; | ||
|
||
"1/1" -- "0/1" [ weight=0 ]; | ||
|
||
"1/1" -- "1/2" [ weight=0 ]; | ||
|
||
"0/1" [ weight=0 ]; | ||
|
||
"0/1" -- "0/0" [ weight=0 ]; | ||
|
||
"0/1" -- "1/1" [ weight=0 ]; | ||
|
||
"0/3" [ weight=0 ]; | ||
|
||
"0/3" -- "0/4" [ weight=0 ]; | ||
|
||
"0/3" -- "1/3" [ weight=0 ]; | ||
|
||
"0/0" [ weight=0 ]; | ||
|
||
"0/0" -- "0/1" [ weight=0 ]; | ||
|
||
"0/4" [ weight=0 ]; | ||
|
||
"0/4" -- "1/4" [ weight=0 ]; | ||
|
||
"0/4" -- "0/5" [ weight=0 ]; | ||
|
||
"0/4" -- "0/3" [ weight=0 ]; | ||
|
||
"2/2" [ weight=0 ]; | ||
|
||
"2/2" -- "1/2" [ weight=0 ]; | ||
|
||
"1/3" [ weight=0 ]; | ||
|
||
"1/3" -- "0/3" [ weight=0 ]; | ||
|
||
"1/3" -- "1/2" [ weight=0 ]; | ||
|
||
"1/3" -- "1/4" [ weight=0 ]; | ||
|
||
"1/4" [ weight=0 ]; | ||
|
||
"1/4" -- "0/4" [ weight=0 ]; | ||
|
||
"1/4" -- "1/3" [ weight=0 ]; | ||
|
||
"1/4" -- "2/4" [ weight=0 ]; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package game | ||
|
||
import ( | ||
"os" | ||
|
||
"github.com/cheina97/gomaze/pkg/grid" | ||
"github.com/cheina97/gomaze/pkg/matrix" | ||
"github.com/dominikbraun/graph/draw" | ||
"github.com/hajimehoshi/ebiten/v2" | ||
"github.com/hajimehoshi/ebiten/v2/inpututil" | ||
) | ||
|
||
type lastPosSet string | ||
|
||
const ( | ||
start lastPosSet = "start" | ||
end lastPosSet = "end" | ||
) | ||
|
||
type Game struct { | ||
w, h int | ||
Matrix *matrix.Matrix | ||
nextPosToSet lastPosSet | ||
startFinding bool | ||
} | ||
|
||
func NewGame(w int, h int) (*Game, error) { | ||
ebiten.SetWindowSize(w*grid.CellSize, h*grid.CellSize) | ||
ebiten.SetWindowTitle("GoMaze") | ||
m := matrix.NewMatrix(h, w) | ||
if err := m.GenerateRandomWalls(); err != nil { | ||
return nil, err | ||
} | ||
if err := m.InitEdges(); err != nil { | ||
return nil, err | ||
} | ||
file, _ := os.Create("./mygraph.gv") | ||
_ = draw.DOT(m.Graph, file) | ||
|
||
return &Game{ | ||
w: w, | ||
h: h, | ||
Matrix: m, | ||
nextPosToSet: start, | ||
startFinding: false, | ||
}, nil | ||
} | ||
|
||
func (g *Game) Update() error { | ||
if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft) { | ||
mx, my := ebiten.CursorPosition() | ||
i, j := grid.GetGridCellFromCoords(mx, my) | ||
|
||
p := g.Matrix.Get(j, i) | ||
if p == matrix.Invalid || p == matrix.Wall { | ||
return nil | ||
} | ||
|
||
switch g.nextPosToSet { | ||
case end: | ||
g.Matrix.CleanAllValues(matrix.End) | ||
g.Matrix.Set(j, i, matrix.End) | ||
g.Matrix.End = &matrix.Point{X: j, Y: i} | ||
g.nextPosToSet = start | ||
g.startFinding = true | ||
case start: | ||
g.Matrix.CleanAllValues(matrix.Start) | ||
g.Matrix.Set(j, i, matrix.Start) | ||
g.Matrix.Start = &matrix.Point{X: j, Y: i} | ||
g.nextPosToSet = end | ||
g.startFinding = true | ||
} | ||
} | ||
if inpututil.IsKeyJustPressed(ebiten.KeyR) { | ||
g.Matrix = matrix.NewMatrix(g.h, g.w) | ||
if err := g.Matrix.GenerateRandomWalls(); err != nil { | ||
return err | ||
} | ||
if err := g.Matrix.InitEdges(); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
if g.Matrix.Start != nil && g.Matrix.End != nil && g.startFinding { | ||
g.Matrix.CleanAllValues(matrix.Path) | ||
if err := g.Matrix.FindMinimumPath(); err != nil { | ||
return err | ||
} | ||
g.startFinding = false | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (g *Game) Draw(screen *ebiten.Image) { | ||
grid.DrawGrid(screen, g.Matrix) | ||
} | ||
|
||
func (g *Game) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) { | ||
return outsideWidth, outsideHeight | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package grid | ||
|
||
import "image/color" | ||
|
||
const ( | ||
CellSize = 30 | ||
BorderOffset = 20 | ||
) | ||
|
||
var ( | ||
emptyColor = color.RGBA{255, 255, 255, 0} | ||
wallColor = color.RGBA{0, 0, 0, 0} | ||
startColor = color.RGBA{75, 162, 71, 0} | ||
endColor = color.RGBA{255, 20, 87, 0} | ||
pathColor = color.RGBA{255, 219, 87, 0} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package grid | ||
|
||
import ( | ||
"image/color" | ||
|
||
"github.com/cheina97/gomaze/pkg/matrix" | ||
"github.com/hajimehoshi/ebiten/v2" | ||
"github.com/hajimehoshi/ebiten/v2/vector" | ||
) | ||
|
||
func DrawGrid(dst *ebiten.Image, m *matrix.Matrix) { | ||
for x := 0; x < m.Cols; x++ { | ||
for y := 0; y < m.Rows; y++ { | ||
switch m.Get(x, y) { | ||
case matrix.Empty: | ||
DrawGridCell(dst, x, y, emptyColor) | ||
case matrix.Wall: | ||
DrawGridCell(dst, x, y, wallColor) | ||
case matrix.Start: | ||
DrawGridCell(dst, x, y, startColor) | ||
case matrix.End: | ||
DrawGridCell(dst, x, y, endColor) | ||
case matrix.Path: | ||
DrawGridCell(dst, x, y, pathColor) | ||
} | ||
} | ||
} | ||
} | ||
|
||
func DrawGridCell(dst *ebiten.Image, x, y int, cl color.Color) { | ||
vector.DrawFilledRect(dst, float32(x*CellSize), float32(y*CellSize), float32(CellSize), float32(CellSize), cl, false) | ||
} | ||
|
||
func GetGridCellFromCoords(x, y int) (int, int) { | ||
return y / (CellSize), x / (CellSize) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package matrix | ||
|
||
const ( | ||
Wall = 1 | ||
Empty = 0 | ||
Start = 2 | ||
End = 3 | ||
Path = 4 | ||
Invalid = -1 | ||
) |
Oops, something went wrong.