121 lines
No EOL
3 KiB
Go
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
|
|
} |