144 lines
2.8 KiB
Go
144 lines
2.8 KiB
Go
package common
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
|
|
type Tile int
|
|
|
|
const (
|
|
Air Tile = iota
|
|
Rock
|
|
Sand
|
|
)
|
|
|
|
|
|
type Map [][]Tile
|
|
|
|
func NewMap() *Map {
|
|
newMap := Map(make([][]Tile, 1000))
|
|
for i := 0; i < 1000; i++ {
|
|
newMap[i] = make([]Tile, 1000)
|
|
for j := 0; j < 1000; j++ {
|
|
newMap[i][j] = Air
|
|
}
|
|
}
|
|
return &newMap
|
|
}
|
|
|
|
func (tileMap *Map) AddRockStructure(structure RockStructure) {
|
|
var yStart int
|
|
var yEnd int
|
|
var xStart int
|
|
var xEnd int
|
|
|
|
if structure.yEnd > structure.yStart {
|
|
yStart = structure.yStart
|
|
yEnd = structure.yEnd
|
|
} else {
|
|
yStart = structure.yEnd
|
|
yEnd = structure.yStart
|
|
}
|
|
if structure.xEnd > structure.xStart {
|
|
xStart = structure.xStart
|
|
xEnd = structure.xEnd
|
|
} else {
|
|
xStart = structure.xEnd
|
|
xEnd = structure.xStart
|
|
}
|
|
|
|
for i := yStart; i <= yEnd; i++ {
|
|
for j := xStart; j <= xEnd; j++ {
|
|
(*tileMap)[i][j] = Rock
|
|
}
|
|
}
|
|
}
|
|
|
|
func (tileMap *Map) DropSand() bool {
|
|
rest := false
|
|
j := 500
|
|
for i := 0; i < len(*tileMap)-1 && !rest; i++ {
|
|
if (*tileMap)[i+1][j] != Air {
|
|
if (*tileMap)[i+1][j-1] == Air {
|
|
j--
|
|
} else if (*tileMap)[i+1][j+1] == Air {
|
|
j++
|
|
} else {
|
|
(*tileMap)[i][j] = Sand
|
|
rest = true
|
|
}
|
|
}
|
|
}
|
|
return rest
|
|
}
|
|
|
|
func (tileMap *Map) AddFloor() {
|
|
currFloor := 0
|
|
for i := 0; i < len(*tileMap); i++ {
|
|
for j := 0; j < len((*tileMap)[i]); j++ {
|
|
if (*tileMap)[i][j] == Rock && i > currFloor {
|
|
currFloor = i
|
|
}
|
|
}
|
|
}
|
|
currFloor += 2
|
|
|
|
for j := 0; j < len((*tileMap)[currFloor]); j++ {
|
|
(*tileMap)[currFloor][j] = Rock
|
|
}
|
|
}
|
|
|
|
func (tileMap *Map) IsSourceBlocked() bool {
|
|
return (*tileMap)[0][500] != Air
|
|
}
|
|
|
|
func (tileMap *Map) Print(xMin, xMax, yMin, yMax int) {
|
|
for i := yMin; i <= yMax; i++ {
|
|
for j := xMin; j <= xMax; j++ {
|
|
switch (*tileMap)[i][j] {
|
|
case Air:
|
|
fmt.Print(".")
|
|
case Rock:
|
|
fmt.Print("#")
|
|
case Sand:
|
|
fmt.Print("o")
|
|
}
|
|
}
|
|
fmt.Println()
|
|
}
|
|
}
|
|
|
|
type RockStructure struct {
|
|
xStart int
|
|
xEnd int
|
|
yStart int
|
|
yEnd int
|
|
}
|
|
|
|
|
|
func Parse(scanner bufio.Scanner) []RockStructure {
|
|
rockStructures := []RockStructure{}
|
|
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
splittedLine := strings.Split(line, " -> ")
|
|
for i := 0; i < len(splittedLine) - 1; i++ {
|
|
splittedStructureStart := strings.Split(splittedLine[i], ",")
|
|
splittedStructureEnd := strings.Split(splittedLine[i+1], ",")
|
|
|
|
xStart, _ := strconv.Atoi(splittedStructureStart[0])
|
|
yStart, _ := strconv.Atoi(splittedStructureStart[1])
|
|
xEnd, _ := strconv.Atoi(splittedStructureEnd[0])
|
|
yEnd, _ := strconv.Atoi(splittedStructureEnd[1])
|
|
|
|
rockStructures = append(rockStructures, RockStructure{xStart, xEnd, yStart, yEnd})
|
|
}
|
|
}
|
|
|
|
return rockStructures
|
|
}
|