Added Force Quit to intcode processor
This commit is contained in:
parent
11019fa77e
commit
0e315631dd
@ -8,10 +8,13 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
intcode "git.bullercodeworks.com/brian/adventofcode/2019/intcode-processor"
|
intcode "git.bullercodeworks.com/brian/adventofcode/2019/intcode-processor"
|
||||||
|
helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||||
)
|
)
|
||||||
|
|
||||||
var auto bool
|
var auto bool
|
||||||
|
|
||||||
|
var maze *Maze
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
progFileName := "input"
|
progFileName := "input"
|
||||||
|
|
||||||
@ -19,20 +22,49 @@ func main() {
|
|||||||
auto = true
|
auto = true
|
||||||
}
|
}
|
||||||
prog := intcode.ReadIntCodeFile(progFileName)
|
prog := intcode.ReadIntCodeFile(progFileName)
|
||||||
|
maze = NewMaze()
|
||||||
|
|
||||||
play(prog)
|
play(prog)
|
||||||
}
|
}
|
||||||
|
|
||||||
func play(prog []int) {
|
func play(prog []int) {
|
||||||
p := intcode.NewProgram(prog)
|
p := intcode.NewProgram(prog)
|
||||||
go func() {
|
go func() {
|
||||||
|
var roadTaken []helpers.Coordinate
|
||||||
for {
|
for {
|
||||||
|
time.Sleep(500)
|
||||||
|
fmt.Println(helpers.CLEAR_SCREEN)
|
||||||
|
maze.Print()
|
||||||
for !p.NeedsInput() {
|
for !p.NeedsInput() {
|
||||||
time.Sleep(1)
|
time.Sleep(1)
|
||||||
}
|
}
|
||||||
|
var movingDir int
|
||||||
|
var moveToCoord *helpers.Coordinate
|
||||||
if auto {
|
if auto {
|
||||||
|
var picked bool
|
||||||
|
directions := []int{DIR_N, DIR_E, DIR_S, DIR_W}
|
||||||
|
// If we have an unexplored location, try it
|
||||||
|
for _, tryDir := range directions {
|
||||||
|
v := maze.GetCoord(maze.GetDirFromBot(tryDir))
|
||||||
|
if v == MAZE_UNKNOWN {
|
||||||
|
movingDir = tryDir
|
||||||
|
picked = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !picked {
|
||||||
|
movingDir = maze.GetDirectionToLast()
|
||||||
|
if movingDir == -1 {
|
||||||
|
fmt.Println("Maze Created")
|
||||||
|
p.ForceQuit()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
picked = true
|
||||||
|
}
|
||||||
|
moveToCoord = maze.GetDirFromBot(movingDir)
|
||||||
} else {
|
} else {
|
||||||
var gotInput bool
|
for movingDir == 0 {
|
||||||
for !gotInput {
|
|
||||||
fmt.Print("Input (vimlike): ")
|
fmt.Print("Input (vimlike): ")
|
||||||
reader := bufio.NewReader(os.Stdin)
|
reader := bufio.NewReader(os.Stdin)
|
||||||
inp, err := reader.ReadString('\n')
|
inp, err := reader.ReadString('\n')
|
||||||
@ -41,38 +73,40 @@ func play(prog []int) {
|
|||||||
}
|
}
|
||||||
inp = strings.TrimSpace(inp)
|
inp = strings.TrimSpace(inp)
|
||||||
switch inp {
|
switch inp {
|
||||||
case "h":
|
case "h": // West
|
||||||
p.Input(3)
|
movingDir = DIR_W
|
||||||
gotInput = true
|
moveToCoord = maze.bot.GetWestCoord()
|
||||||
case "j":
|
case "j": // South
|
||||||
p.Input(2)
|
movingDir = DIR_S
|
||||||
gotInput = true
|
moveToCoord = maze.bot.GetSouthCoord()
|
||||||
case "k":
|
case "k": // North
|
||||||
p.Input(1)
|
movingDir = DIR_N
|
||||||
gotInput = true
|
moveToCoord = maze.bot.GetNorthCoord()
|
||||||
case "l":
|
case "l": // East
|
||||||
p.Input(4)
|
movingDir = DIR_E
|
||||||
gotInput = true
|
moveToCoord = maze.bot.GetEastCoord()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
p.Input(movingDir)
|
||||||
for !p.NeedsOutput() {
|
for !p.NeedsOutput() {
|
||||||
time.Sleep(1)
|
time.Sleep(1)
|
||||||
}
|
}
|
||||||
moveRes := p.Output()
|
moveRes := p.Output()
|
||||||
|
maze.SetCoord(moveToCoord, moveRes)
|
||||||
switch moveRes {
|
switch moveRes {
|
||||||
case 0: // Hit a wall
|
case 1, 2: // Moved
|
||||||
fmt.Println("WALL")
|
roadTaken = append(roadTaken, *maze.bot)
|
||||||
case 1: // Moved
|
maze.MoveBot(movingDir)
|
||||||
fmt.Println("OK")
|
}
|
||||||
case 2: // Moved and done
|
if p.State() == intcode.RET_DONE || p.State() == intcode.RET_ERR {
|
||||||
fmt.Println("DONE")
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
ret := p.Run()
|
ret := p.Run()
|
||||||
if ret == intcode.RET_DONE {
|
if ret == intcode.RET_DONE {
|
||||||
|
maze.Print()
|
||||||
} else if ret == intcode.RET_ERR {
|
} else if ret == intcode.RET_ERR {
|
||||||
fmt.Println("ERROR")
|
fmt.Println("ERROR")
|
||||||
fmt.Println(p.Error())
|
fmt.Println(p.Error())
|
||||||
|
139
2019/day15/maze.go
Normal file
139
2019/day15/maze.go
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
MAZE_UNKNOWN = -1
|
||||||
|
MAZE_WALL = 0
|
||||||
|
MAZE_EMPTY = 1
|
||||||
|
MAZE_O2SYS = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DIR_N = 1
|
||||||
|
DIR_S = 2
|
||||||
|
DIR_W = 3
|
||||||
|
DIR_E = 4
|
||||||
|
)
|
||||||
|
|
||||||
|
type Maze struct {
|
||||||
|
maze map[string]int
|
||||||
|
maxX, minX int
|
||||||
|
maxY, minY int
|
||||||
|
bot *helpers.Coordinate
|
||||||
|
path []*helpers.Coordinate
|
||||||
|
dirHistory []int
|
||||||
|
dnt bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMaze() *Maze {
|
||||||
|
m := &Maze{
|
||||||
|
maze: make(map[string]int),
|
||||||
|
maxX: helpers.MIN_INT,
|
||||||
|
minX: helpers.MAX_INT,
|
||||||
|
maxY: helpers.MIN_INT,
|
||||||
|
minY: helpers.MAX_INT,
|
||||||
|
bot: helpers.NewCoordinate(0, 0),
|
||||||
|
}
|
||||||
|
m.path = append(m.path, helpers.NewCoordinate(0, 0))
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Maze) SetCoord(c *helpers.Coordinate, val int) {
|
||||||
|
m.maze[c.String()] = val
|
||||||
|
if m.maxX < c.X {
|
||||||
|
m.maxX = c.X
|
||||||
|
}
|
||||||
|
if m.minX > c.X {
|
||||||
|
m.minX = c.X
|
||||||
|
}
|
||||||
|
if m.maxY < c.Y {
|
||||||
|
m.maxY = c.Y
|
||||||
|
}
|
||||||
|
if m.minY > c.Y {
|
||||||
|
m.minY = c.Y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Maze) GetCoord(c *helpers.Coordinate) int {
|
||||||
|
v, ok := m.maze[c.String()]
|
||||||
|
if !ok {
|
||||||
|
return MAZE_UNKNOWN
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Maze) GetDirFromBot(dir int) *helpers.Coordinate {
|
||||||
|
switch dir {
|
||||||
|
case DIR_N:
|
||||||
|
return m.bot.GetNorthCoord()
|
||||||
|
case DIR_E:
|
||||||
|
return m.bot.GetEastCoord()
|
||||||
|
case DIR_S:
|
||||||
|
return m.bot.GetSouthCoord()
|
||||||
|
case DIR_W:
|
||||||
|
return m.bot.GetWestCoord()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Maze) MoveBot(dir int) bool {
|
||||||
|
dest := m.GetDirFromBot(dir)
|
||||||
|
if m.GetCoord(dest) == MAZE_UNKNOWN || m.GetCoord(dest) == MAZE_WALL {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
m.bot.X, m.bot.Y = dest.X, dest.Y
|
||||||
|
if !m.dnt {
|
||||||
|
m.path = append(m.path, helpers.NewCoordinate(m.bot.X, m.bot.Y))
|
||||||
|
m.dirHistory = append(m.dirHistory, dir)
|
||||||
|
}
|
||||||
|
m.dnt = false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Maze) GetDirectionToLast() int {
|
||||||
|
if len(m.dirHistory) == 0 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
m.dnt = true
|
||||||
|
var dir int
|
||||||
|
dir, m.dirHistory = m.dirHistory[len(m.dirHistory)-1], m.dirHistory[:len(m.dirHistory)-1]
|
||||||
|
switch dir {
|
||||||
|
case DIR_N:
|
||||||
|
return DIR_S
|
||||||
|
case DIR_S:
|
||||||
|
return DIR_N
|
||||||
|
case DIR_W:
|
||||||
|
return DIR_E
|
||||||
|
case DIR_E:
|
||||||
|
return DIR_W
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Maze) Print() {
|
||||||
|
for y := m.minY; y <= m.maxY; y++ {
|
||||||
|
for x := m.minX; x <= m.maxX; x++ {
|
||||||
|
c := helpers.NewCoordinate(x, y)
|
||||||
|
if m.bot.Equals(*c) {
|
||||||
|
fmt.Print("%")
|
||||||
|
} else {
|
||||||
|
switch m.GetCoord(c) {
|
||||||
|
case MAZE_UNKNOWN:
|
||||||
|
fmt.Print("~")
|
||||||
|
case MAZE_WALL:
|
||||||
|
fmt.Print("#")
|
||||||
|
case MAZE_EMPTY:
|
||||||
|
fmt.Print(" ")
|
||||||
|
case MAZE_O2SYS:
|
||||||
|
fmt.Print("O")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
}
|
@ -44,6 +44,7 @@ type Program struct {
|
|||||||
state int
|
state int
|
||||||
error error
|
error error
|
||||||
|
|
||||||
|
bail bool
|
||||||
waitingForInput bool
|
waitingForInput bool
|
||||||
input chan int
|
input chan int
|
||||||
waitingForOutput bool
|
waitingForOutput bool
|
||||||
@ -113,6 +114,12 @@ func (p *Program) Error() error {
|
|||||||
return p.error
|
return p.error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Program) ForceQuit() {
|
||||||
|
p.bail = true
|
||||||
|
close(p.input)
|
||||||
|
close(p.output)
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Program) Run() int {
|
func (p *Program) Run() int {
|
||||||
for {
|
for {
|
||||||
p.state = p.Step()
|
p.state = p.Step()
|
||||||
@ -123,6 +130,10 @@ func (p *Program) Run() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Program) Step() int {
|
func (p *Program) Step() int {
|
||||||
|
if p.bail {
|
||||||
|
p.error = errors.New("Force Quit")
|
||||||
|
return RET_ERR
|
||||||
|
}
|
||||||
if len(p.code) < p.ptr {
|
if len(p.code) < p.ptr {
|
||||||
p.error = errors.New("Pointer Exception")
|
p.error = errors.New("Pointer Exception")
|
||||||
return RET_ERR
|
return RET_ERR
|
||||||
|
@ -10,6 +10,35 @@ type Coordinate struct {
|
|||||||
X, Y int
|
X, Y int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewCoordinate(x, y int) *Coordinate {
|
||||||
|
return &Coordinate{x, y}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Coordinate) GetNorthCoord() *Coordinate {
|
||||||
|
return &Coordinate{
|
||||||
|
X: c.X,
|
||||||
|
Y: c.Y - 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (c *Coordinate) GetEastCoord() *Coordinate {
|
||||||
|
return &Coordinate{
|
||||||
|
X: c.X + 1,
|
||||||
|
Y: c.Y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (c *Coordinate) GetSouthCoord() *Coordinate {
|
||||||
|
return &Coordinate{
|
||||||
|
X: c.X,
|
||||||
|
Y: c.Y + 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (c *Coordinate) GetWestCoord() *Coordinate {
|
||||||
|
return &Coordinate{
|
||||||
|
X: c.X - 1,
|
||||||
|
Y: c.Y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func CoordinateFromString(str string) *Coordinate {
|
func CoordinateFromString(str string) *Coordinate {
|
||||||
c := Coordinate{}
|
c := Coordinate{}
|
||||||
r := strings.NewReader(str)
|
r := strings.NewReader(str)
|
||||||
@ -35,3 +64,7 @@ func (c Coordinate) String() string {
|
|||||||
func (c Coordinate) Distance(t Coordinate) int {
|
func (c Coordinate) Distance(t Coordinate) int {
|
||||||
return AbsInt(c.X-t.X) + AbsInt(c.Y-t.Y)
|
return AbsInt(c.X-t.X) + AbsInt(c.Y-t.Y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c Coordinate) Equals(c2 Coordinate) bool {
|
||||||
|
return c.X == c2.X && c.Y == c2.Y
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user