Browse Source

Config save sorted. DB creates on init. ConfigMenu

Config displays SysOp settings.
Setup main menu, ConfigMenu.
Steve Thielemann 3 years ago
parent
commit
8d8d7567be
3 changed files with 230 additions and 130 deletions
  1. 11 2
      config.go
  2. 2 0
      db.go
  3. 217 128
      space-ace.go

+ 11 - 2
config.go

@@ -6,6 +6,7 @@ import (
 	"fmt"
 	"log"
 	"os"
+	"sort"
 	"strings"
 )
 
@@ -62,8 +63,16 @@ func SaveConfig(filename string, config map[string]string) {
 
 	defer file.Close()
 
-	for key, value := range config {
-		fmt.Fprintf(file, "%s: %s\n", key, value)
+	// Sort the Keys
+	var keys []string
+
+	for key := range config {
+		keys = append(keys, key)
+	}
+	sort.Strings(keys)
+
+	for _, key := range keys {
+		fmt.Fprintf(file, "%s: %s\n", key, config[key])
 	}
 }
 

+ 2 - 0
db.go

@@ -17,6 +17,8 @@ func (db *DBData) Open(filename string) {
 	if err != nil {
 		log.Panicln("Error Opening Sqlite3:", err)
 	}
+
+	// Create the tables (if needed)
 	db.Create()
 }
 

+ 217 - 128
space-ace.go

@@ -16,11 +16,7 @@ import (
 	"github.com/seehuhn/mt19937"
 )
 
-func pctUpdate(pct *int64) func() int64 {
-	return func() int64 {
-		return *pct
-	}
-}
+var Config map[string]string
 
 func find_words(text string) [][]int {
 	word, _ := regexp.Compile("([A-Za-z]+)")
@@ -143,7 +139,7 @@ func press_a_key(d *door.Door) int {
 
 func MainMenu() door.Menu {
 	// Make the main menu
-	m := door.Menu{Panel: door.Panel{Width: 45,
+	m := door.Menu{Panel: door.Panel{Width: 25,
 		X:           5,
 		Y:           5,
 		Style:       door.DOUBLE,
@@ -159,12 +155,34 @@ func MainMenu() door.Menu {
 		door.ColorText("BOLD YEL ON BLUE"),
 		door.ColorText("BOLD CYAN ON BLUE"))
 
-	m.AddSelection("A", "ANSI Display")
-	m.AddSelection("D", "Display Information (dropfile, screen)")
-	m.AddSelection("I", "Input Prompt Demo")
-	m.AddSelection("P", "Progress Bars Demo")
-	m.AddSelection("S", "Show Panel")
+	m.AddSelection("P", "Play Cards")
+	m.AddSelection("S", "View Scores")
+	m.AddSelection("C", "Configure")
+	m.AddSelection("H", "Help")
+	m.AddSelection("A", "About this game")
+	m.AddSelection("Q", "Quit")
+	return m
+}
 
+func ConfigMenu() door.Menu {
+	m := door.Menu{Panel: door.Panel{Width: 31,
+		X:           5,
+		Y:           5,
+		Style:       door.DOUBLE,
+		Title:       "[ Configuration Menu ]",
+		TitleColor:  door.ColorText("BRI CYAN ON BLUE"),
+		BorderColor: door.ColorText("CYAN ON BLUE")}}
+	m.SelectedR = door.MakeMenuRender(door.ColorText("BOLD CYAN"),
+		door.ColorText("BOLD BLUE"),
+		door.ColorText("BOLD CYAN"),
+		door.ColorText("BOLD BLUE"))
+	m.UnselectedR = door.MakeMenuRender(door.ColorText("BOLD YEL ON BLUE"),
+		door.ColorText("BOLD WHI ON BLUE"),
+		door.ColorText("BOLD YEL ON BLUE"),
+		door.ColorText("BOLD CYAN ON BLUE"))
+
+	m.AddSelection("D", "Deck Colors")
+	m.AddSelection("V", "View Settings")
 	m.AddSelection("Q", "Quit")
 	return m
 }
@@ -190,104 +208,191 @@ func display_information(d *door.Door) {
 	d.Write(nice_format("Screen Size", fmt.Sprintf("%d X %d", door.Width, door.Height)))
 }
 
-func display_ansi(d *door.Door) {
-	space := SPACE()
-	d.Write(door.Clrscr)
-	for _, line := range space {
+func panel_demo(d *door.Door) {
+	width := 55
+	fmtStr := "%-55s"
+	p := door.Panel{X: 5, Y: 5, Width: width, Style: door.DOUBLE, BorderColor: door.ColorText("CYAN ON BLUE"), Title: "[ Panel Demo ]"}
+
+	lineColor := door.ColorText("BRIGHT WHI ON BLUE")
+	// Add lines to the panel
+	for _, line := range []string{"The BBS Door Panel Demo", "(C) 2021 Red Green Software, https://red-green.com"} {
 		if door.Unicode {
-			d.Write(door.CP437_to_Unicode(line) + door.CRNL)
-		} else {
-			d.Write(line + door.CRNL)
+			line = strings.Replace(line, "(C)", "\u00a9", -1)
 		}
+		l := door.Line{Text: fmt.Sprintf(fmtStr, line), DefaultColor: lineColor}
+		p.Lines = append(p.Lines, l)
 	}
-}
+	p.Lines = append(p.Lines, p.Spacer())
+	p.Lines = append(p.Lines, door.Line{Text: fmt.Sprintf(fmtStr, "Welcome to golang!"), DefaultColor: lineColor})
 
-func input_demo(d *door.Door) {
-	inputColor := door.ColorText("BRI WHI ON BLUE")
-	inputColor2 := door.ColorText("BRI WHI ON GREEN")
-	prompt := door.Line{Text: "What is YOUR Name: "}
-	prompt.RenderF = door.RenderBlueYellow
-	d.Write(prompt.Output() + inputColor)
-	name := d.Input(25)
-	d.Write(door.Reset + door.CRNL)
-	prompt.Text = "What is Your Quest: "
-	d.Write(prompt.Output() + inputColor2)
-	quest := d.Input(35)
-	d.Write(door.Reset + door.CRNL)
-	prompt.Text = "What is your Favorite CoLoR: "
-	d.Write(prompt.Output() + inputColor2)
-	color := d.Input(15)
-	d.Write(door.Reset + door.CRNL)
-	d.Write(fmt.Sprintf("You're %s on the %s quest, and fond of %s."+door.CRNL, name, quest, color))
+	d.Write(door.Clrscr)
+	d.Write(p.Output() + door.CRNL)
 }
 
-func progress_bars(d *door.Door) {
-	d.Write(door.Clrscr)
+func MakeColorsRender(brackets string, text_color string, colors map[string]string) func(string) string {
+	renderF := func(text string) string {
+		words := find_words(text)
+		var option bool = true
+		var color_word bool = false
+		var tpos int = 0
+		var result string
+		var last_color string
+		var word_color string
+		var words_id = 0
+		word_pair := words[words_id]
+		normal := colors["ALL"]
+
+		for _, c := range text {
+			if option {
+				if c == '[' || c == ']' {
+					if last_color != brackets {
+						result += brackets
+						last_color = brackets
+					}
+					if c == ']' {
+						option = false
+					}
+				} else {
+					if last_color != text_color {
+						result += text_color
+						last_color = text_color
+					}
+				}
+				result += string(c)
+			} else {
+				// Out of the options
+				if color_word {
+					if tpos < word_pair[1] {
+						if last_color != word_color {
+							result += word_color
+							last_color = word_color
+						} else {
+							color_word = false
+							if last_color != normal {
+								result += normal
+								last_color = normal
+							}
+						}
+						result += string(c)
+					}
+				} else {
+					// look for COLOR word
+					if tpos >= word_pair[1] {
+						words_id++
+						if words_id > len(words) {
+							word_pair = []int{999, 999}
+						} else {
+							word_pair = words[words_id]
+						}
+					}
 
-	bar := door.BarLine{Line: door.Line{DefaultColor: door.ColorText("BOLD YELLOW")}, Width: 20, Style: door.HALF_STEP}
-	bar2 := door.BarLine{Width: 30, Style: door.SOLID, PercentStyle: door.PERCENT_SPACE}
+					if word_pair[0] == tpos {
+						// start of word
+						possible := text[word_pair[0]:word_pair[1]]
+						color_code, has := colors[possible]
+						if has {
+							word_color = color_code
+						} else {
+							word_color = colors["ALL"]
+						}
+						if last_color != word_color {
+							result += word_color
+							last_color = word_color
+						}
+					}
 
-	bar2.ColorRange = []door.BarRange{
-		{2500, door.ColorText("RED")},
-		{5000, door.ColorText("BROWN")},
-		{7500, door.ColorText("BOLD YEL")},
-		{9500, door.ColorText("GREEN")},
-		{10100, door.ColorText("BRI GRE")}}
+					result += string(c)
+				}
+			}
+		}
+		return result
+	}
+	return renderF
+}
 
-	bar3 := door.BarLine{Width: 15, Style: door.GRADIENT, Line: door.Line{DefaultColor: door.ColorText("CYAN")}}
+func DeckColorMenu() door.Menu {
+	m := door.Menu{Panel: door.Panel{Width: 31,
+		X:           5,
+		Y:           5,
+		Style:       door.DOUBLE,
+		Title:       "[ Deck Menu ]",
+		TitleColor:  door.ColorText("BRI CYAN ON BLUE"),
+		BorderColor: door.ColorText("CYAN ON BLUE")}}
+	m.SelectedR = door.MakeMenuRender(door.ColorText("BOLD CYAN"),
+		door.ColorText("BOLD BLUE"),
+		door.ColorText("BOLD CYAN"),
+		door.ColorText("BOLD BLUE"))
+	m.UnselectedR = door.MakeMenuRender(door.ColorText("BOLD YEL ON BLUE"),
+		door.ColorText("BOLD WHI ON BLUE"),
+		door.ColorText("BOLD YEL ON BLUE"),
+		door.ColorText("BOLD CYAN ON BLUE"))
 
-	var percentage int64
-	bar.UpdateP = pctUpdate(&percentage)
-	bar2.UpdateP = pctUpdate(&percentage)
-	bar3.UpdateP = pctUpdate(&percentage)
+	m.AddSelection("D", "Deck Colors")
+	m.AddSelection("V", "View Settings")
+	m.AddSelection("Q", "Quit")
+	return m
+}
 
-	update_bars := func() {
-		bar.Update()
-		bar2.Update()
-		bar3.Update()
+func RenderStatusValue(status string, value string) func(string) string {
+	renderF := func(text string) string {
+		var result string
+		pos := strings.Index(text, ":")
+		result = status + text[:pos] + value + text[pos:]
+		return result
 	}
+	return renderF
+}
 
-	d.Write(door.Goto(3, 12) + "Half-Step")
-	d.Write(door.Goto(25, 12) + "% with space and Color Range")
-	d.Write(door.Goto(57, 12) + "Gradient")
-
-	bar_start := door.Goto(3, 15)
+// Display the SysOp settings in the Config/yaml file
+func DisplaySettings(d *door.Door) {
+	d.Write(door.Clrscr + door.Reset)
+	W := 35
+	panel := door.Panel{Width: W,
+		X:           5,
+		Y:           5,
+		Style:       door.DOUBLE,
+		BorderColor: door.ColorText("BOLD CYAN ON BLUE"),
+	}
+	l := door.Line{Text: fmt.Sprintf("%*s", W, "Game Settings - SysOp Configurable"),
+		DefaultColor: door.ColorText("BOLD GREEN ON BLUE")}
+	panel.Lines = append(panel.Lines, l)
+	renderF := RenderStatusValue(door.ColorText("BOLD YELLOW ON BLUE"), door.ColorText("BOLD GREEN ON BLUE"))
+	for key, value := range Config {
+		if key[0] == '_' {
+			continue
+		}
+		l = door.Line{Text: fmt.Sprintf("%20s : %*s", key, -(W - 23), value), RenderF: renderF}
+		panel.Lines = append(panel.Lines, l)
+	}
+	d.Write(panel.Output() + door.Reset + door.CRNL)
+	press_a_key(d)
+}
 
-	for f := 0; f <= 100; f++ {
-		percentage = int64(f * 100)
+func Configure(d *door.Door, db *DBData) {
+	menu := ConfigMenu()
+	// deckcolor := "DeckColor"
+	// save_deckcolor := false
+	var choice int
 
-		update_bars()
-		d.Write(bar_start + bar.Output() + "  " + door.Reset + bar2.Output() + door.Reset + "  " + bar3.Output())
+	for choice >= 0 {
+		d.Write(door.Clrscr)
+		choice = menu.Choose(d)
 
-		if d.Disconnected {
-			// don't continue to sleep if we're disconnected
+		if choice < 0 {
 			break
 		}
+		option := menu.GetOption(choice)
 
-		time.Sleep(time.Millisecond * 100)
-	}
-
-}
-
-func panel_demo(d *door.Door) {
-	width := 55
-	fmtStr := "%-55s"
-	p := door.Panel{X: 5, Y: 5, Width: width, Style: door.DOUBLE, BorderColor: door.ColorText("CYAN ON BLUE"), Title: "[ Panel Demo ]"}
-
-	lineColor := door.ColorText("BRIGHT WHI ON BLUE")
-	// Add lines to the panel
-	for _, line := range []string{"The BBS Door Panel Demo", "(C) 2021 Red Green Software, https://red-green.com"} {
-		if door.Unicode {
-			line = strings.Replace(line, "(C)", "\u00a9", -1)
+		switch option {
+		case 'D':
+			// Deck color
+		case 'V':
+			// View settings
+			DisplaySettings(d)
+		case 'Q':
+			choice = -1
 		}
-		l := door.Line{Text: fmt.Sprintf(fmtStr, line), DefaultColor: lineColor}
-		p.Lines = append(p.Lines, l)
 	}
-	p.Lines = append(p.Lines, p.Spacer())
-	p.Lines = append(p.Lines, door.Line{Text: fmt.Sprintf(fmtStr, "Welcome to golang!"), DefaultColor: lineColor})
-
-	d.Write(door.Clrscr)
-	d.Write(p.Output() + door.CRNL)
 }
 
 func main() {
@@ -303,35 +408,26 @@ func main() {
 	rng := rand.New(mt19937.New())
 	rng.Seed(time.Now().UnixNano())
 
-	/*
-		sqliteDatabase, err := sql.Open("sqlite3", "./space-database.db")
-		if err != nil {
-			fmt.Printf("%#v\n", err)
-		}
-		defer sqliteDatabase.Close()
-		createTable(sqliteDatabase)
-	*/
 	d := door.Door{}
-
 	d.Init("space-ace")
 
 	db := DBData{}
 	db.Open("space-database.db")
 	defer db.Close()
-	db.User = d.Config.Real_name // or d.Config.Handle
+	// Use Real_name or Handle?  Or read config?
+	db.User = d.Config.Real_name
 
-	var Config map[string]string
 	const config_filename = "space-ace.yaml"
 
 	if FileExists(config_filename) {
 		Config = LoadConfig(config_filename)
 	} else {
 		Config = make(map[string]string)
-
 	}
 
 	var update_config bool = false
 
+	// Guessing at this point as to what settings I actually want.
 	config_defaults := map[string]string{"hands_per_day": "3",
 		"date_format":     "%B %d",
 		"date_score":      "%m/%d/%Y",
@@ -340,6 +436,12 @@ func main() {
 		"date_monthly":    "%B %Y"}
 
 	// _seed
+	_, ok := Config["_seed"]
+	if !ok {
+		// Initialize the seed
+		Config["_seed"] = fmt.Sprintf("%d,%d,%d", rng.Int31(), rng.Int31(), rng.Int31())
+		update_config = true
+	}
 
 	for key, value := range config_defaults {
 		if SetConfigDefault(&Config, key, value) {
@@ -357,10 +459,14 @@ func main() {
 	s.Display(&d)
 	d.Write(door.Goto(1, 1) + door.Reset)
 
+	// Get the last call value (if they have called before)
 	last_call, _ := strconv.ParseInt(db.GetSetting("LastCall", "0"), 10, 64)
 	now := time.Now()
 	db.SetSetting("LastCall", fmt.Sprintf("%d", now.Unix()))
 
+	// Check for maint run -- get FirstOfMonthDate, and see if
+	// records are older then it is.  (If so, yes -- run maint)!
+
 	if last_call != 0 {
 		d.Write("Welcome Back!" + door.CRNL)
 		delta := now.Sub(time.Unix(last_call, 0))
@@ -377,19 +483,6 @@ func main() {
 		}
 	}
 
-	bold := door.Color(1, 37, 40)
-	bolder := door.ColorText("BLI BOLD YEL ON BLUE")
-	d.Write("Welcome to " + bolder + "door32.sys" + door.Reset + door.CRNL + "..." + door.CRNL)
-	key := press_a_key(&d)
-	d.Write(fmt.Sprintf("Key %s%d / %x%s", bold, key, key, door.Reset) + door.CRNL)
-
-	b := door.AlertBox("Warning: golang is in use!", 1)
-	d.Write(door.ColorText("BRI WHI ON GREEN"))
-	for _, line := range b {
-		d.Write(line + door.CRNL)
-	}
-	d.Write(door.Reset + door.CRNL)
-
 	left := d.TimeLeft()
 
 	message = fmt.Sprintf("You have %0.2f minutes / %0.2f seconds remaining..."+door.CRNL, left.Minutes(), left.Seconds())
@@ -413,25 +506,21 @@ func main() {
 		// fmt.Printf("Choice: %d, Option: %c\n", choice, option)
 
 		switch option {
-		case 'A':
-			display_ansi(&d)
-			press_a_key(&d)
-		case 'D':
-			display_information(&d)
-			press_a_key(&d)
-		case 'I':
-			d.Write(door.Reset + door.CRNL + door.CRNL)
-			input_demo(&d)
-			press_a_key(&d)
 		case 'P':
-			progress_bars(&d)
-			press_a_key(&d)
+			// Play cards
 		case 'S':
-			panel_demo(&d)
+			// View Scores
+		case 'C':
+			// Configure
+			Configure(&d, &db)
+		case 'H':
+			// Help
+			press_a_key(&d)
+		case 'A':
+			// About
 			press_a_key(&d)
 		case 'Q':
 			choice = -1
-			// break
 		}
 
 	}
@@ -441,7 +530,7 @@ func main() {
 	message = fmt.Sprintf("Returning to %s ..."+door.CRNL, d.Config.BBSID)
 	d.Write(message)
 
-	d.WaitKey(1, 0)
+	// d.WaitKey(1, 0)
 	left = d.TimeLeft()
 
 	message = fmt.Sprintf("You had %0.2f minutes / %0.2f seconds remaining!"+door.CRNL, left.Minutes(), left.Seconds())