2016-12-18 15:32:37 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/md5"
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
|
|
|
|
termbox "github.com/nsf/termbox-go"
|
|
|
|
|
2023-12-17 16:52:08 +00:00
|
|
|
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
2016-12-18 15:32:37 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var gridWidth, gridHeight int
|
|
|
|
var path string
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
// TODO: Random seed
|
|
|
|
passcode := "pvhmgsws"
|
|
|
|
gridWidth, gridHeight = 4, 4
|
|
|
|
if len(os.Args) >= 3 {
|
2023-12-17 16:52:08 +00:00
|
|
|
gridWidth = h.Atoi(os.Args[1])
|
|
|
|
gridHeight = h.Atoi(os.Args[2])
|
2016-12-18 15:32:37 +00:00
|
|
|
}
|
|
|
|
run := true
|
|
|
|
err := termbox.Init()
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
defer termbox.Close()
|
|
|
|
var e termbox.Event
|
|
|
|
for run {
|
|
|
|
PrintState("", passcode)
|
|
|
|
e = termbox.PollEvent()
|
|
|
|
if e.Type == termbox.EventKey {
|
|
|
|
if e.Key == termbox.KeyCtrlC {
|
|
|
|
run = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// We cache the last hash calculated
|
|
|
|
// It should speed things up a little
|
|
|
|
var lastHashInput string
|
|
|
|
var lastHash string
|
|
|
|
|
|
|
|
func doorIsOpen(path, passcode string, dir rune) bool {
|
|
|
|
if lastHashInput != passcode+path {
|
|
|
|
lastHashInput = passcode + path
|
|
|
|
lastHash = fmt.Sprintf("%x", md5.Sum([]byte(lastHashInput)))
|
|
|
|
}
|
|
|
|
switch dir {
|
|
|
|
case 'N':
|
|
|
|
return lastHash[0] >= 'b' && lastHash[0] <= 'f'
|
|
|
|
case 'E':
|
|
|
|
return lastHash[3] >= 'b' && lastHash[3] <= 'f'
|
|
|
|
case 'S':
|
|
|
|
return lastHash[1] >= 'b' && lastHash[1] <= 'f'
|
|
|
|
case 'W':
|
|
|
|
return lastHash[2] >= 'b' && lastHash[2] <= 'f'
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func currPos(path string) (int, int) {
|
|
|
|
var cX, cY int
|
|
|
|
for i := range path {
|
|
|
|
switch path[i] {
|
|
|
|
case 'U':
|
|
|
|
cY--
|
|
|
|
case 'D':
|
|
|
|
cY++
|
|
|
|
case 'L':
|
|
|
|
cX--
|
|
|
|
case 'R':
|
|
|
|
cX++
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return cX, cY
|
|
|
|
}
|
|
|
|
|
|
|
|
func PrintState(path, passcode string) {
|
|
|
|
posX, posY := currPos(path)
|
|
|
|
for y := 0; y < gridHeight; y++ {
|
|
|
|
for x := 0; x < gridWidth; x++ {
|
2023-12-17 16:52:08 +00:00
|
|
|
fmt.Print(h.BorderNW)
|
2016-12-18 15:32:37 +00:00
|
|
|
if posX == x && posY == y && doorIsOpen(path, passcode, 'N') {
|
|
|
|
// Current Pos w/ open door
|
2023-12-17 16:52:08 +00:00
|
|
|
fmt.Print(h.BorderSE)
|
|
|
|
fmt.Print(h.BorderSW)
|
2016-12-18 15:32:37 +00:00
|
|
|
} else if y == posY+1 && x == posX && doorIsOpen(path, passcode, 'S') {
|
|
|
|
// Room below, w/ open door
|
2023-12-17 16:52:08 +00:00
|
|
|
fmt.Print(h.BorderNE)
|
|
|
|
fmt.Print(h.BorderNW)
|
2016-12-18 15:32:37 +00:00
|
|
|
} else {
|
|
|
|
// All other cases
|
2023-12-17 16:52:08 +00:00
|
|
|
fmt.Print(h.BorderWE)
|
|
|
|
fmt.Print(h.BorderWE)
|
2016-12-18 15:32:37 +00:00
|
|
|
}
|
2023-12-17 16:52:08 +00:00
|
|
|
fmt.Print(h.BorderNE)
|
2016-12-18 15:32:37 +00:00
|
|
|
}
|
|
|
|
fmt.Println()
|
|
|
|
for x := 0; x < gridWidth; x++ {
|
|
|
|
if posX == x && posY == y && doorIsOpen(path, passcode, 'W') {
|
2023-12-17 16:52:08 +00:00
|
|
|
fmt.Print(h.BorderSE)
|
2016-12-18 15:32:37 +00:00
|
|
|
} else {
|
2023-12-17 16:52:08 +00:00
|
|
|
fmt.Print(h.BorderNS)
|
2016-12-18 15:32:37 +00:00
|
|
|
}
|
|
|
|
if posX == x && posY == y {
|
2023-12-17 16:52:08 +00:00
|
|
|
fmt.Print(h.BorderNW)
|
|
|
|
fmt.Print(h.BorderNE)
|
2016-12-18 15:32:37 +00:00
|
|
|
} else {
|
|
|
|
fmt.Print(" ")
|
|
|
|
fmt.Print(" ")
|
|
|
|
}
|
|
|
|
if posX == x && posY == y && doorIsOpen(path, passcode, 'E') {
|
2023-12-17 16:52:08 +00:00
|
|
|
fmt.Print(h.BorderSW)
|
2016-12-18 15:32:37 +00:00
|
|
|
} else {
|
2023-12-17 16:52:08 +00:00
|
|
|
fmt.Print(h.BorderNS)
|
2016-12-18 15:32:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
fmt.Println()
|
|
|
|
for x := 0; x < gridWidth; x++ {
|
|
|
|
if posX == x && posY == y && doorIsOpen(path, passcode, 'W') {
|
2023-12-17 16:52:08 +00:00
|
|
|
fmt.Print(h.BorderNE)
|
2016-12-18 15:32:37 +00:00
|
|
|
} else {
|
2023-12-17 16:52:08 +00:00
|
|
|
fmt.Print(h.BorderNS)
|
2016-12-18 15:32:37 +00:00
|
|
|
}
|
|
|
|
if posX == x && posY == y {
|
2023-12-17 16:52:08 +00:00
|
|
|
fmt.Print(h.BorderSW)
|
|
|
|
fmt.Print(h.BorderSE)
|
2016-12-18 15:32:37 +00:00
|
|
|
} else {
|
|
|
|
fmt.Print(" ")
|
|
|
|
fmt.Print(" ")
|
|
|
|
}
|
|
|
|
if posX == x && posY == y && doorIsOpen(path, passcode, 'E') {
|
2023-12-17 16:52:08 +00:00
|
|
|
fmt.Print(h.BorderNW)
|
2016-12-18 15:32:37 +00:00
|
|
|
} else {
|
2023-12-17 16:52:08 +00:00
|
|
|
fmt.Print(h.BorderNS)
|
2016-12-18 15:32:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
fmt.Println()
|
|
|
|
for x := 0; x < gridWidth; x++ {
|
2023-12-17 16:52:08 +00:00
|
|
|
fmt.Print(h.BorderSW)
|
2016-12-18 15:32:37 +00:00
|
|
|
if posX == x && posY == y && doorIsOpen(path, passcode, 'S') {
|
2023-12-17 16:52:08 +00:00
|
|
|
fmt.Print(h.BorderNE)
|
|
|
|
fmt.Print(h.BorderNW)
|
2016-12-18 15:32:37 +00:00
|
|
|
} else {
|
2023-12-17 16:52:08 +00:00
|
|
|
fmt.Print(h.BorderWE)
|
|
|
|
fmt.Print(h.BorderWE)
|
2016-12-18 15:32:37 +00:00
|
|
|
}
|
2023-12-17 16:52:08 +00:00
|
|
|
fmt.Print(h.BorderSE)
|
2016-12-18 15:32:37 +00:00
|
|
|
}
|
|
|
|
fmt.Println()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func ClearScreen() {
|
2023-12-17 16:52:08 +00:00
|
|
|
fmt.Print(h.ClearScreen)
|
2016-12-18 15:32:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func printUsageAndExit() {
|
|
|
|
fmt.Println("Usage: ./day17 <passcode> <gridWidth> <gridHeight>")
|
|
|
|
os.Exit(0)
|
|
|
|
}
|