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 }