Added Force Quit to intcode processor

This commit is contained in:
Brian Buller 2019-12-16 17:31:11 -06:00
parent 11019fa77e
commit 0e315631dd
4 changed files with 238 additions and 21 deletions

View File

@ -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
View 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()
}
}

View File

@ -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

View File

@ -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
}