From d17d31b2936d16e8f22b977e5bd48e0726e73a01 Mon Sep 17 00:00:00 2001 From: deva Date: Sat, 13 Jul 2024 19:45:54 -0400 Subject: [PATCH] initialize git --- .env | 1 + commands/commands.go | 40 ++++++++++++++ go.mod | 12 +++++ go.sum | 16 ++++++ libsnake/libsnake.go | 121 +++++++++++++++++++++++++++++++++++++++++++ snake-go.go | 63 ++++++++++++++++++++++ 6 files changed, 253 insertions(+) create mode 100644 .env create mode 100644 commands/commands.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 libsnake/libsnake.go create mode 100644 snake-go.go diff --git a/.env b/.env new file mode 100644 index 0000000..35ff38f --- /dev/null +++ b/.env @@ -0,0 +1 @@ +DISCORD_TOKEN=MTI1OTI5MTk0MDE4MTI1MDExOA.G0ITLo.zvPPQ6LHaxPg3FNZjaBDxkQjOHYrgebetdcrhU \ No newline at end of file diff --git a/commands/commands.go b/commands/commands.go new file mode 100644 index 0000000..4fc2cb1 --- /dev/null +++ b/commands/commands.go @@ -0,0 +1,40 @@ +package commands + +import "github.com/bwmarrin/discordgo" + +type Command struct { + Name string + Handler func(s *discordgo.Session, m *discordgo.MessageCreate) + Aliases []string +} + +var Commands = []Command{ + { + Name: "ping", + Handler: PingPong("ping"), + }, + { + Name: "pong", + Handler: PingPong("pong"), + }, + { + Name: "start", + Handler: MainGame, + }, +} + +func MainGame(s *discordgo.Session, m *discordgo.MessageCreate) { + +} + +func PingPong(which string) func(s *discordgo.Session, m *discordgo.MessageCreate) { + if which == "ping" { + return func(s *discordgo.Session, m *discordgo.MessageCreate) { + _, _ = s.ChannelMessageSend(m.ChannelID, "pong") + } + } else { + return func(s *discordgo.Session, m *discordgo.MessageCreate) { + _, _ = s.ChannelMessageSend(m.ChannelID, "ping") + } + } +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..1362fde --- /dev/null +++ b/go.mod @@ -0,0 +1,12 @@ +module github.com/devawaves/snake-go + +go 1.22.3 + +require ( + github.com/bwmarrin/discordgo v0.28.1 // indirect + github.com/gorilla/websocket v1.4.2 // indirect + github.com/joho/godotenv v1.5.1 // indirect + golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect + golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect + golang.org/x/text v0.16.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..cf9eb5d --- /dev/null +++ b/go.sum @@ -0,0 +1,16 @@ +github.com/bwmarrin/discordgo v0.28.1 h1:gXsuo2GBO7NbR6uqmrrBDplPUx2T3nzu775q/Rd1aG4= +github.com/bwmarrin/discordgo v0.28.1/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/libsnake/libsnake.go b/libsnake/libsnake.go new file mode 100644 index 0000000..52fc444 --- /dev/null +++ b/libsnake/libsnake.go @@ -0,0 +1,121 @@ +package libsnake + +import ( + "fmt" + "errors" + "slices" + "math/rand" +) + +type Entity struct { + Id int + Name string + Type string + XDirection int + YDirection int + + ConsumedFood int +} + +type SnakeGame struct { + PlayField [][]int + Entities []Entity +} + +type StepStatus struct { + EliminatedEntities []Entity +} + +func remove_entity(s []Entity, i int) []Entity { + s[i] = s[len(s)-1] + return s[:len(s)-1] +} + +func (sg *SnakeGame) StepGame() StepStatus { + status := StepStatus { + EliminatedEntities: []Entity {}, + } + + for entity_index, entity := range sg.Entities { + if entity.Type == "player" { + for playfield_row_index, playfield_row := range sg.PlayField { + for playfield_col_index, playfield_col := range playfield_row { + if playfield_col == entity.Id { + sg.PlayField[playfield_row_index][playfield_col_index] = 0 + + next_row_direction := playfield_row_index + entity.XDirection + next_col_direction := playfield_col_index + entity.YDirection + + if next_row_direction > len(sg.PlayField) || next_col_direction > len(playfield_row) { + entity = sg.Entities[entity_index] + sg.Entities = remove_entity(sg.Entities, entity_index) + + status.EliminatedEntities = append(status.EliminatedEntities, entity) + continue + } else if next_row_direction < 0 || next_col_direction < 0 { + entity = sg.Entities[entity_index] + sg.Entities = remove_entity(sg.Entities, entity_index) + + status.EliminatedEntities = append(status.EliminatedEntities, entity) + continue + } else if sg.PlayField[next_row_direction][next_col_direction] != 0 { + entity_id := sg.PlayField[next_row_direction][next_col_direction] + entity_index := slices.IndexFunc(sg.Entities, func(e Entity) bool { return e.Id == entity_id }) + + if entity_index == -1 { + fmt.Println("FIXME: entity is in field, but could not be found? wtf?") + continue + } + + found_entity := sg.Entities[entity_index] + + if found_entity.Type == "food" { + entity.ConsumedFood += 1 + sg.PlayField[rand.Intn(len(sg.PlayField))][rand.Intn(len(playfield_row))] = entity_id + } else { + entity = sg.Entities[entity_index] + sg.Entities = remove_entity(sg.Entities, entity_index) + + status.EliminatedEntities = append(status.EliminatedEntities, entity) + continue + } + + sg.PlayField[next_row_direction][next_col_direction] = entity.Id + } + } + } + } + } + } + + return status; +} + +func (sg *SnakeGame) AddEntity(en_id int, en_name string, en_type string) error { + if en_type != "player" && en_type != "food" { + return errors.New("invalid entity type") + } + + if en_id == 0 { + return errors.New("reserved ID (cannot be 0!)") + } + + for _, entity := range sg.Entities { + if entity.Id == en_id { + return errors.New("entity already exists") + } + } + + entity := Entity { + Id: en_id, + Name: en_name, + Type: en_type, + XDirection: 0, + YDirection: 0, + ConsumedFood: 0, + } + + sg.Entities = append(sg.Entities, entity) + + return nil +} \ No newline at end of file diff --git a/snake-go.go b/snake-go.go new file mode 100644 index 0000000..29afadc --- /dev/null +++ b/snake-go.go @@ -0,0 +1,63 @@ +package main + +import ( + "fmt" + "os" + "os/signal" + "strings" + "syscall" + + "github.com/bwmarrin/discordgo" + "github.com/devawaves/snake-go/commands" + "github.com/joho/godotenv" +) + +func main() { + err := godotenv.Load() + errorCheck(err) + token := os.Getenv("DISCORD_TOKEN") + + discord, err := discordgo.New("Bot " + token) + errorCheck(err) + + discord.AddHandler(messageCreate) + + discord.Identify.Intents = discordgo.IntentsGuildMessages + err = discord.Open() + errorCheck(err) + + fmt.Println("Bot is running...") + sc := make(chan os.Signal, 1) + signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt) + <-sc + + discord.Close() +} + +func errorCheck(err error) { + if err != nil { + fmt.Println("er! " + err.Error()) + os.Exit(1) + } +} + +func messageCreate(session *discordgo.Session, msg *discordgo.MessageCreate) { + if msg.Author.ID == session.State.User.ID { + return + } + + for _, command := range commands.Commands { + potential_command := strings.ToLower(msg.Content) + last_command_index := strings.Index(potential_command, " ") + + if last_command_index == -1 { + last_command_index = len(potential_command) + } + + potential_command = potential_command[:last_command_index] + + if potential_command == "$" + command.Name { + command.Handler(session, msg) + } + } +}