From 90ad8c0c33b519d5830c69d4128bdc984b5e9de8 Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Mon, 5 Oct 2026 14:22:14 -0400 Subject: feat: cryptocurrency exchange added to casino --- internal/game/render_crypto.go | 63 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 internal/game/render_crypto.go (limited to 'internal/game/render_crypto.go') diff --git a/internal/game/render_crypto.go b/internal/game/render_crypto.go new file mode 100644 index 0000000..899f83b --- /dev/null +++ b/internal/game/render_crypto.go @@ -0,0 +1,63 @@ +package game + +import ( + "thehouseoficarus/internal/casino" + "thehouseoficarus/internal/net" +) + +// Use the same contextual command columns and casino_hints policy as the +// prediction counter and casino tables. Rules are opt-in, never an entry screen. +func (g *Game) cryptoCommands(s *net.Session) []casino.MenuCommand { + if s.CryptoBusy { + return []casino.MenuCommand{{Command: "stop", Desc: "Leave and cancel the update"}} + } + commands := []casino.MenuCommand{} + if !s.CryptoUnavailable { + symbol := s.CryptoSelected + if symbol == "" { + symbol = "SYMBOL" + } + switch s.CryptoScreen { + case "view": + commands = append(commands, + casino.MenuCommand{Command: "buy " + symbol + " AMOUNT", Desc: "Buy coins"}, + casino.MenuCommand{Command: "short " + symbol + " AMOUNT", Desc: "Back a falling price"}, + casino.MenuCommand{Command: "contracts", Desc: "Trade calls and puts"}, + casino.MenuCommand{Command: "back", Desc: "Return to the currencies"}) + case "contracts": + commands = append(commands, + casino.MenuCommand{Command: "quote TYPE " + symbol + " AMOUNT PRICE DAYS", Desc: "Preview a call, put, write-call or write-put"}, + casino.MenuCommand{Command: "option TYPE " + symbol + " AMOUNT PRICE DAYS", Desc: "Buy a call or put"}, + casino.MenuCommand{Command: "write TYPE " + symbol + " AMOUNT PRICE DAYS", Desc: "Write a call or put; risk of debt"}, + casino.MenuCommand{Command: "back", Desc: "Return to the currencies"}) + case "active": + commands = append(commands, casino.MenuCommand{Command: "close ID", Desc: "Close a whole position"}, casino.MenuCommand{Command: "view SYMBOL", Desc: "View a currency's chart"}) + default: + commands = append(commands, casino.MenuCommand{Command: "view SYMBOL", Desc: "Choose a currency"}) + } + commands = append(commands, casino.MenuCommand{Command: "active", Desc: "Your open positions"}, casino.MenuCommand{Command: "closed", Desc: "Your completed trades"}) + } + if s.Player.Crypto.Balance < 0 { + commands = append(commands, casino.MenuCommand{Command: "repay CREDITS", Desc: "Pay your exchange debt"}) + } else { + commands = append(commands, casino.MenuCommand{Command: "fund CREDITS", Desc: "Add trading funds"}, casino.MenuCommand{Command: "withdraw CREDITS", Desc: "Take out available credits"}) + } + return append(commands, casino.MenuCommand{Command: "rules", Desc: "How to trade"}, casino.MenuCommand{Command: "refresh", Desc: "Update this screen"}, casino.MenuCommand{Command: "stop", Desc: "Leave the counter"}) +} +func (g *Game) cryptoHints(s *net.Session, force ...bool) { + forced := len(force) > 0 && force[0] + show := g.casinoHintsVisible(s, &casino.MenuView{ShowHints: s.CryptoShowHints}) + s.CryptoShowHints = false + if !forced && !show { + return + } + s.WriteLine("") + s.WriteLine(g.renderCasinoCommands(s, "", "", g.cryptoCommands(s))) +} +func (g *Game) cryptoOptions(s *net.Session) { + s.CryptoScreen = "contracts" + g.predictionFrame(s, "OPTIONS", []string{ + "Choose a call for a rising price, or a put for a falling price. Preview with quote before buying or writing.", + "AMOUNT is coins, PRICE is your target, and DAYS is 1, 7 or 30. Writing options can leave you owing credits.", + }) +} -- cgit v1.2.3