wopr.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. package door
  2. import (
  3. "bytes"
  4. "fmt"
  5. "strings"
  6. "time"
  7. )
  8. /*
  9. WOPR
  10. [ GAME ]
  11. [ TIME ELAPSED ]
  12. [ XX HRS ]
  13. [ XX MIN XX SEC ]
  14. [■ ] ->
  15. [ GAME ]
  16. [ TIME REMAINING ]
  17. [ XX HRS ]
  18. [ XX MIN XX SEC ]
  19. [ ■] <-
  20. Border SINGLE
  21. Ok, Width = 16
  22. 1000 / 16 = 62.5 ms = 62500 us
  23. Width 16 (at pos 1, update time/sec increment)
  24. Black on Cyan
  25. */
  26. type WOPR struct {
  27. ElapsedPanel Panel
  28. Elapsed time.Duration
  29. RemainingPanel Panel
  30. Remaining time.Duration
  31. Color string
  32. Index int
  33. Ticker *time.Ticker
  34. }
  35. // Initialize, Set X, Y on Panels, Animate()
  36. // Initialize, and create panels
  37. func (w *WOPR) Init(elapsed time.Duration, remaining time.Duration, color string) {
  38. if color == "" {
  39. color = ColorText("BLACK ON CYAN")
  40. }
  41. w.Elapsed = elapsed
  42. w.Remaining = remaining
  43. w.Index = 0
  44. w.ElapsedPanel = Panel{Width: 16,
  45. BorderColor: color,
  46. Style: SINGLE}
  47. w.ElapsedPanel.Lines = append(w.ElapsedPanel.Lines, Line{Text: " GAME "})
  48. w.ElapsedPanel.Lines = append(w.ElapsedPanel.Lines, Line{Text: " TIME ELAPSED "})
  49. var ehour Line = Line{}
  50. ehour.UpdateF = func() string {
  51. var hours int = int(w.Elapsed.Hours())
  52. return fmt.Sprintf(" %02d HRS ", hours%100)
  53. }
  54. ehour.Text = ehour.UpdateF()
  55. w.ElapsedPanel.Lines = append(w.ElapsedPanel.Lines, ehour)
  56. var eminsec Line = Line{}
  57. eminsec.UpdateF = func() string {
  58. var mins int = int(w.Elapsed.Minutes()) % 60
  59. var secs int = int(w.Elapsed.Seconds()) % 60
  60. return fmt.Sprintf(" %02d MIN %02d SEC ", mins, secs)
  61. }
  62. eminsec.Text = eminsec.UpdateF()
  63. w.ElapsedPanel.Lines = append(w.ElapsedPanel.Lines, eminsec)
  64. var eanimate Line = Line{}
  65. eanimate.UpdateF = func() string {
  66. // Left to Right
  67. if Unicode {
  68. var buffer []rune = []rune(strings.Repeat(" ", 16))
  69. buffer[w.Index] = '\u25a0'
  70. return string(buffer)
  71. } else {
  72. var buffer []byte = bytes.Repeat([]byte(" "), 16)
  73. buffer[w.Index] = '\xfe'
  74. return string(buffer)
  75. }
  76. }
  77. eanimate.Text = eanimate.UpdateF()
  78. w.ElapsedPanel.Lines = append(w.ElapsedPanel.Lines, eanimate)
  79. w.RemainingPanel = Panel{Width: 16,
  80. BorderColor: color,
  81. Style: SINGLE}
  82. w.RemainingPanel.Lines = append(w.RemainingPanel.Lines, Line{Text: " GAME "})
  83. w.RemainingPanel.Lines = append(w.RemainingPanel.Lines, Line{Text: " TIME REMAINING "})
  84. var rhour Line = Line{}
  85. rhour.UpdateF = func() string {
  86. var hours int = int(w.Remaining.Hours())
  87. return fmt.Sprintf(" %02d HRS ", hours%100)
  88. }
  89. rhour.Text = rhour.UpdateF()
  90. w.RemainingPanel.Lines = append(w.RemainingPanel.Lines, rhour)
  91. var rminsec Line = Line{}
  92. rminsec.UpdateF = func() string {
  93. var mins int = int(w.Remaining.Minutes()) % 60
  94. var secs int = int(w.Remaining.Seconds()) % 60
  95. return fmt.Sprintf(" %02d MIN %02d SEC ", mins, secs)
  96. }
  97. rminsec.Text = rminsec.UpdateF()
  98. w.RemainingPanel.Lines = append(w.RemainingPanel.Lines, rminsec)
  99. var ranimate Line = Line{}
  100. ranimate.UpdateF = func() string {
  101. // Left to Right
  102. if Unicode {
  103. var buffer []rune = []rune(strings.Repeat(" ", 16))
  104. buffer[15-w.Index] = '\u25a0'
  105. return string(buffer)
  106. } else {
  107. var buffer []byte = bytes.Repeat([]byte(" "), 16)
  108. buffer[15-w.Index] = '\xfe'
  109. return string(buffer)
  110. }
  111. }
  112. ranimate.Text = ranimate.UpdateF()
  113. w.RemainingPanel.Lines = append(w.RemainingPanel.Lines, ranimate)
  114. }
  115. func (w *WOPR) Inc() {
  116. w.Index++
  117. if w.Index == 16 {
  118. w.Remaining = time.Duration(w.Remaining.Seconds()-1) * time.Second
  119. w.Elapsed = time.Duration(w.Elapsed.Seconds()+1) * time.Second
  120. w.Index = 0
  121. }
  122. }
  123. func (w *WOPR) Animate(d *Door) {
  124. w.Ticker = time.NewTicker(time.Microsecond * time.Duration(62500))
  125. go func(d *Door) {
  126. var output string
  127. for range w.Ticker.C {
  128. w.ElapsedPanel.Update()
  129. w.RemainingPanel.Update()
  130. output = SavePos + w.ElapsedPanel.Output() + w.RemainingPanel.Output() + RestorePos
  131. if !d.Disconnect() {
  132. d.Write(output)
  133. } else {
  134. w.Ticker.Stop()
  135. return
  136. }
  137. w.Inc()
  138. }
  139. }(d)
  140. }
  141. func (w *WOPR) Stop() {
  142. w.Ticker.Stop()
  143. }