package hacking import ( "fmt" "math/rand" "strings" ) type MastermindGame struct { code [4]int guesses []MastermindGuess maxGuess int gameOver bool won bool } type MastermindGuess struct { Digits [4]int Exact int Partial int } func NewMastermindGame() *MastermindGame { return &MastermindGame{ maxGuess: 10, } } func (m *MastermindGame) Name() string { return "Code Breaker" } func (m *MastermindGame) Init(level int) string { pool := []int{1, 2, 3, 4, 5, 6} rand.Shuffle(len(pool), func(i, j int) { pool[i], pool[j] = pool[j], pool[i] }) copy(m.code[:], pool[:4]) m.guesses = nil m.gameOver = false m.won = false var sb strings.Builder sb.WriteString("=== CODE BREAKER ===\n") sb.WriteString("\n") sb.WriteString("The encryption module is running a 4-digit cipher using symbols 1-6.\n") sb.WriteString("No symbol repeats. You have 10 attempts to crack the code.\n") sb.WriteString("\n") sb.WriteString("After each guess, you'll see:\n") sb.WriteString(" {40}[X]{/} = correct symbol in correct position\n") sb.WriteString(" {226}[O]{/} = correct symbol in wrong position\n") sb.WriteString(" [ ] = symbol not in code\n") sb.WriteString("\n") sb.WriteString("Commands:\n") sb.WriteString(" <4 digits> - Guess the code (e.g., 1234)\n") sb.WriteString(" status - Show previous guesses\n") sb.WriteString(" jack out - Disconnect (forfeit)\n") return sb.String() } func (m *MastermindGame) HandleInput(input string) (string, bool, bool) { input = strings.TrimSpace(input) lower := strings.ToLower(strings.TrimSpace(input)) if lower == "status" { return m.doStatus(), false, false } if len(input) != 4 { return "Enter exactly 4 digits (1-6, no repeats).", false, false } var guess [4]int seen := make(map[int]bool) for i, ch := range input { if ch < '1' || ch > '6' { return "Each digit must be 1-6.", false, false } d := int(ch - '0') if seen[d] { return "No repeating digits allowed.", false, false } seen[d] = true guess[i] = d } exact := 0 partial := 0 for i := 0; i < 4; i++ { if guess[i] == m.code[i] { exact++ } else { for j := 0; j < 4; j++ { if guess[i] == m.code[j] { partial++ break } } } } m.guesses = append(m.guesses, MastermindGuess{ Digits: guess, Exact: exact, Partial: partial, }) var sb strings.Builder sb.WriteString(fmt.Sprintf("Attempt %d/%d: ", len(m.guesses), m.maxGuess)) for i, d := range guess { match := "[ ]" if guess[i] == m.code[i] { match = "{40}[X]{/}" } else { for j := 0; j < 4; j++ { if guess[i] == m.code[j] { match = "{226}[O]{/}" break } } } sb.WriteString(fmt.Sprintf("%d%s ", d, match)) } sb.WriteString(fmt.Sprintf(" (%d locked, %d found)", exact, partial)) if exact == 4 { m.gameOver = true m.won = true sb.WriteString("\n\nCode cracked! The encryption module yields.\nConnection terminated.") return sb.String(), true, true } if len(m.guesses) >= m.maxGuess { m.gameOver = true m.won = false sb.WriteString(fmt.Sprintf("\n\nOut of attempts. The code was: %d %d %d %d.\nConnection terminated.", m.code[0], m.code[1], m.code[2], m.code[3])) return sb.String(), true, false } return sb.String(), false, false } func (m *MastermindGame) doStatus() string { if len(m.guesses) == 0 { return fmt.Sprintf("No guesses yet. Remaining: %d/%d", m.maxGuess, m.maxGuess) } var sb strings.Builder sb.WriteString("=== Attempts ===\n") for i, g := range m.guesses { sb.WriteString(fmt.Sprintf(" %2d: %d %d %d %d -> ", i+1, g.Digits[0], g.Digits[1], g.Digits[2], g.Digits[3])) for j, d := range g.Digits { match := "[ ]" if g.Digits[j] == m.code[j] { match = "{40}[X]{/}" } else { found := false for k := 0; k < 4; k++ { if g.Digits[j] == m.code[k] { found = true break } } if found { match = "{226}[O]{/}" } } _ = d sb.WriteString(match) } sb.WriteString(fmt.Sprintf(" (%d locked, %d found)\n", g.Exact, g.Partial)) } sb.WriteString(fmt.Sprintf("Remaining: %d/%d\n", m.maxGuess-len(m.guesses), m.maxGuess)) return sb.String() } func (m *MastermindGame) BonusXP() int { return (m.maxGuess - len(m.guesses)) * 15 }