It now uses tcell colors to show build status and when you die.

master
Zed A. Shaw 3 weeks ago
parent 4453076c6c
commit 16aa91742c
  1. 1
      .ttarpit.json
  2. 2
      Makefile
  3. 22
      builder/build.go
  4. 1
      config/settings.go
  5. 12
      game/engine.go
  6. 4
      go.mod
  7. 8
      go.sum
  8. 12
      main.go
  9. 72
      ui.go

@ -1,5 +1,6 @@
{ {
"StartingHP": 10, "StartingHP": 10,
"Deadline": "1h30m0s",
"Includes": [ "Includes": [
"^.*.go$" "^.*.go$"
], ],

@ -18,7 +18,7 @@ build_tester:
go build -o tester$(GO_IS_STUPID_EXE) ./tools/cmd/tester/main.go go build -o tester$(GO_IS_STUPID_EXE) ./tools/cmd/tester/main.go
docs: docs:
go tool pkgsite --open pkgsite --open
coverage: coverage:
go build -cover -o webapp go build -cover -o webapp

@ -19,11 +19,19 @@ import (
type ErrorHandler func (data.ErrInfo) type ErrorHandler func (data.ErrInfo)
const (
START=0
RUNNING=1
FAILED=2
PASSED=3
)
type Builder struct { type Builder struct {
settings config.Config settings config.Config
OnError ErrorHandler OnError ErrorHandler
BuildRunning bool BuildState int
HadErrors bool
} }
func New(settings config.Config, handler ErrorHandler) (*Builder) { func New(settings config.Config, handler ErrorHandler) (*Builder) {
@ -75,6 +83,7 @@ func (build *Builder) LaunchLogger(in io.Reader, out io.Writer, err error) {
if ok { if ok {
build.OnError(errinfo) build.OnError(errinfo)
build.HadErrors = true
} }
} }
} }
@ -122,8 +131,9 @@ func (build *Builder) MatchesPath(fp string) bool {
} }
func (build *Builder) BeginBuild() bool { func (build *Builder) BeginBuild() bool {
if !build.BuildRunning { if build.BuildState != RUNNING {
build.BuildRunning = true build.BuildState = RUNNING
build.HadErrors = false
return true return true
} else { } else {
return false return false
@ -131,7 +141,11 @@ func (build *Builder) BeginBuild() bool {
} }
func (build *Builder) EndBuild() { func (build *Builder) EndBuild() {
build.BuildRunning = false if build.HadErrors {
build.BuildState = FAILED
} else {
build.BuildState = PASSED
}
} }
func (build *Builder) RunBuild() { func (build *Builder) RunBuild() {

@ -20,6 +20,7 @@ type Config struct {
Includes []string Includes []string
Processes map[string]Process Processes map[string]Process
StartingHP int StartingHP int
Deadline string
ConfigPath string ConfigPath string

@ -4,6 +4,7 @@ import (
"lcthw.dev/go/ttarpit/config" "lcthw.dev/go/ttarpit/config"
"lcthw.dev/go/ttarpit/data" "lcthw.dev/go/ttarpit/data"
. "lcthw.dev/go/ttarpit/debug" . "lcthw.dev/go/ttarpit/debug"
"time"
) )
type Game struct { type Game struct {
@ -11,6 +12,8 @@ type Game struct {
HP int HP int
Errors int Errors int
StartTime time.Time
EndTime time.Time
} }
func New(settings config.Config) *Game { func New(settings config.Config) *Game {
@ -18,6 +21,14 @@ func New(settings config.Config) *Game {
game.settings = settings game.settings = settings
game.HP = settings.StartingHP game.HP = settings.StartingHP
game.StartTime = time.Now()
time_out, err := time.ParseDuration(settings.Deadline)
if err != nil {
panic(err)
}
game.EndTime = time.Now().Add(time_out)
return game return game
} }
@ -33,7 +44,6 @@ func (game *Game) TakeHit(errinfo data.ErrInfo) {
if game.HP <= 0 { if game.HP <= 0 {
Log.Println("!!!!!! YOU DIED !!!!!!!") Log.Println("!!!!!! YOU DIED !!!!!!!")
game.HP = game.settings.StartingHP
} }
Log.Println("===========================") Log.Println("===========================")

@ -11,7 +11,7 @@ require (
github.com/gdamore/encoding v1.0.1 // indirect github.com/gdamore/encoding v1.0.1 // indirect
github.com/lucasb-eyer/go-colorful v1.3.0 // indirect github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect github.com/rivo/uniseg v0.4.7 // indirect
golang.org/x/sys v0.38.0 // indirect golang.org/x/sys v0.39.0 // indirect
golang.org/x/term v0.37.0 // indirect golang.org/x/term v0.37.0 // indirect
golang.org/x/text v0.31.0 // indirect golang.org/x/text v0.32.0 // indirect
) )

@ -26,8 +26,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@ -38,8 +38,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=

@ -1,7 +1,6 @@
package main package main
import ( import (
"time"
"lcthw.dev/go/ttarpit/builder" "lcthw.dev/go/ttarpit/builder"
"lcthw.dev/go/ttarpit/config" "lcthw.dev/go/ttarpit/config"
"lcthw.dev/go/ttarpit/game" "lcthw.dev/go/ttarpit/game"
@ -24,16 +23,7 @@ func main() {
ui := MakeUI() ui := MakeUI()
go func () { ui.RenderLoop(g, build)
for {
ui.Render(g)
time.Sleep(100 * time.Millisecond)
}
}()
for ui.HandleEvents() {
ui.Render(g)
}
ui.Exit() ui.Exit()
} }

72
ui.go

@ -2,14 +2,19 @@ package main
import ( import (
. "lcthw.dev/go/ttarpit/debug" . "lcthw.dev/go/ttarpit/debug"
"time"
"fmt" "fmt"
"github.com/gdamore/tcell/v2" "github.com/gdamore/tcell/v2"
"github.com/gdamore/tcell/v2/encoding" "github.com/gdamore/tcell/v2/encoding"
"lcthw.dev/go/ttarpit/game" "lcthw.dev/go/ttarpit/game"
"lcthw.dev/go/ttarpit/builder"
) )
type UI struct { type UI struct {
Screen tcell.Screen Screen tcell.Screen
DefaultStyle tcell.Style
DeadStyle tcell.Style
} }
func (ui *UI) DrawText(x int, y int, text string) { func (ui *UI) DrawText(x int, y int, text string) {
@ -18,12 +23,48 @@ func (ui *UI) DrawText(x int, y int, text string) {
} }
} }
func (ui *UI) Render(data *game.Game) { func (ui *UI) StyleText(x int, y int, text string, style tcell.Style) {
for i, cell := range text {
ui.Screen.SetContent(x+i, y, cell, nil, style)
}
}
func (ui *UI) Render(data *game.Game, build *builder.Builder) {
if data.HP <= 0 {
ui.Screen.SetStyle(ui.DeadStyle)
ui.Screen.Sync()
ui.Screen.Clear()
ui.DrawText(0, 10, fmt.Sprintf("YOU DIED!"))
} else {
ui.Screen.SetStyle(ui.DefaultStyle)
ui.Screen.Clear() ui.Screen.Clear()
}
time_since := time.Until(data.EndTime)
ui.DrawText(0, 0, "Welcome to Turing's Tarpit") ui.DrawText(0, 0, "Welcome to Turing's Tarpit")
ui.DrawText(0, 1, fmt.Sprintf("HP: %d", data.HP)) ui.DrawText(0, 2, fmt.Sprintf("HP: %d", data.HP))
ui.DrawText(0, 2, fmt.Sprintf("Errors: %d", data.Errors)) ui.DrawText(0, 3, fmt.Sprintf("Errors: %d", data.Errors))
ui.DrawText(0, 4, fmt.Sprintf("Deadline: %s", time_since.Round(time.Second)))
green := tcell.StyleDefault.Background(tcell.ColorGreen).Foreground(tcell.ColorBlack)
red := tcell.StyleDefault.Background(tcell.ColorRed).Foreground(tcell.ColorBlack)
yellow := tcell.StyleDefault.Background(tcell.ColorYellow).Foreground(tcell.ColorBlack)
switch build.BuildState {
case builder.START:
ui.StyleText(0, 5, "Build: READY", green)
case builder.RUNNING:
ui.StyleText(0, 5, "Build: RUNNING", yellow)
case builder.PASSED:
ui.StyleText(0, 5, "Build: PASSED", green)
case builder.FAILED:
ui.StyleText(0, 5, "Build: FAILED", red)
}
// show the errors
ui.Screen.Show() ui.Screen.Show()
} }
@ -57,6 +98,19 @@ func (ui *UI) Exit() {
ui.Screen.Fini() ui.Screen.Fini()
} }
func (ui *UI) RenderLoop(g *game.Game, build *builder.Builder) {
go func () {
for {
ui.Render(g, build)
time.Sleep(100 * time.Millisecond)
}
}()
for ui.HandleEvents() {
ui.Render(g, build)
}
}
func MakeUI() *UI { func MakeUI() *UI {
var err error var err error
@ -70,6 +124,16 @@ func MakeUI() *UI {
err = ui.Screen.Init() err = ui.Screen.Init()
if err != nil { Log.Fatal(err) } if err != nil { Log.Fatal(err) }
ui.DefaultStyle = tcell.StyleDefault.
Background(tcell.ColorBlack).
Foreground(tcell.ColorWhite)
ui.DeadStyle = tcell.StyleDefault.
Background(tcell.ColorDarkRed).
Foreground(tcell.ColorWhite)
ui.Screen.SetStyle(ui.DefaultStyle)
ui.Screen.Clear()
return ui return ui
} }

Loading…
Cancel
Save