package main import ( "red-green/door" ) type SpinRite struct { Width uint8 // Width of the animation (must be odd) Length uint8 // Width of the worm (must be odd) Color string // Color (default CYAN ON BLUE) OutputB []byte // Output CP437/bytes (Width) OutputR []rune // Output Unicode (Width) Buffer []uint8 // Output calculate buffer (Width) Runes []rune // blank, center, top, bottom, both Bytes []byte // blank, center, top, bottom, both CenterPos uint8 // Center Position (Width - 1) / 2 StartPos uint8 // Starting Position (Length -1) / 2 Index uint8 // Index of current iteration } func SpinRiteInit(width uint8, length uint8, color string) SpinRite { if color == "" { color = door.ColorText("CYAN ON BLUE") } var center uint8 = ((width - 1) / 2) var start uint8 = ((length - 1) / 2) var result SpinRite = SpinRite{Width: width, Length: length, Color: color, CenterPos: center, StartPos: start, Buffer: make([]uint8, width), Index: 0} if door.Unicode { result.OutputR = make([]rune, width) result.Runes = []rune{' ', '\u221e', '\u2580', '\u2584', '\u2588'} } else { result.OutputB = make([]byte, width) result.Bytes = []byte{' ', 0xec, 0xdf, 0xdc, 0xdb} } return result } func (sr *SpinRite) PosToIndex(pos int8, top bool) (index uint8, level bool) { if top { if pos >= int8(sr.Width) { // wrap around level = !top idx := int8(sr.Width) + (int8(sr.Width) - (pos + 1)) index = uint8(idx) } else { level = top index = uint8(pos) } } else { // bottom if pos < 0 { level = !top pos++ index = uint8(-pos) } else { level = top index = uint8(pos) } } return } func (sr *SpinRite) Calculate() { for i := range sr.Buffer { sr.Buffer[i] = 0 } sr.Buffer[sr.CenterPos] = 1 // [ S C s ] var top int8 = int8(sr.CenterPos) - int8(sr.StartPos) + int8(sr.Index) var bottom int8 = int8(sr.CenterPos) + int8(sr.StartPos) - int8(sr.Index) var l int8 for l = 0; l < int8(sr.Length); l++ { var index uint8 var level bool index, level = sr.PosToIndex(top+l, true) // log.Println("TOP", l, top+l, index, level) if level { sr.Buffer[index] |= 0x02 } else { sr.Buffer[index] |= 0x04 } index, level = sr.PosToIndex(bottom-l, false) // log.Println("BOT", l, bottom-l, index, level) if level { sr.Buffer[index] |= 0x02 } else { sr.Buffer[index] |= 0x04 } } // log.Println("Index", sr.Index, "Buffer", sr.Buffer) var reset bool = true // Convert from buffer to output if door.Unicode { for l = 0; l < int8(sr.Width); l++ { switch sr.Buffer[l] { case 0: sr.OutputR[l] = sr.Runes[0] case 1: sr.OutputR[l] = sr.Runes[1] reset = false case 2, 3: sr.OutputR[l] = sr.Runes[2] reset = false case 4, 5: sr.OutputR[l] = sr.Runes[3] reset = false case 6, 7: sr.OutputR[l] = sr.Runes[4] } } } else { for l = 0; l < int8(sr.Width); l++ { switch sr.Buffer[l] { case 0: sr.OutputB[l] = sr.Bytes[0] case 1: sr.OutputB[l] = sr.Bytes[1] reset = false case 2, 3: sr.OutputB[l] = sr.Bytes[2] reset = false case 4, 5: sr.OutputB[l] = sr.Bytes[3] reset = false case 6, 7: sr.OutputB[l] = sr.Bytes[4] } } } if reset { // log.Println("RESET") sr.Index = 0 } } func (sr *SpinRite) Output() string { var result string sr.Calculate() if door.Unicode { result = string(sr.OutputR) } else { result = string(sr.OutputB) } sr.Index++ return sr.Color + result } /* Or possibly: · ∞ [ █████ ] [ ▄▄███▀▀ ] [ ▄▄▄▄█▀▀▀▀ ] [ ▄▄▄▄▄•▀▀▀▀▀ ] [▄▄▄▄▄ • ▀▀▀▀▀] [█▄▄▄ • ▀▀▀█] [██▄ • ▀██] [██▀ • ▄██] [█▀▀▀ • ▄▄▄█] [█▀▀▀▀ • ▄▄▄▄█] [ ▀▀▀▀▀•▄▄▄▄▄ ] [ ▀▀▀▀█▄▄▄▄ ] [ ▀▀███▄▄ ] */