snakething-bot/libsnake/libsnake.go
2024-07-13 19:45:54 -04:00

121 lines
No EOL
3 KiB
Go

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
}