// Command rogue is the Go port of Rogue 5.4.4: Exploring the Dungeons of // Doom. It is a faithful function-by-function port of the classic C game; // see ARCHITECTURE.md at the repository root. package main import ( "flag" "fmt" "os" "os/signal" "os/user" "strconv" "syscall" "time" "git.eeqj.de/sneak/rgoue/game" "git.eeqj.de/sneak/rgoue/term" ) func main() { scores := flag.Bool("s", false, "print the scoreboard and exit") deathDemo := flag.Bool("d", false, "die a random death (demo)") flag.Parse() home, _ := os.UserHomeDir() // get options from environment (main.c) rogueOpts := os.Getenv("ROGUEOPTS") name := "" if u, err := user.Current(); err == nil { name = u.Username } wizard := os.Getenv("ROGUE_WIZARD") != "" // dungeon number: SEED for reproducible dungeons (wizard mode in C), // else time+pid var seed int32 if env := os.Getenv("SEED"); env != "" && wizard { n, _ := strconv.Atoi(env) seed = int32(n) } else { seed = int32(time.Now().Unix()) + int32(os.Getpid()) } cfg := game.Config{ Seed: seed, Name: name, RogueOpts: rogueOpts, Home: home, ScorePath: home + "/.rogue.scores", Wizard: wizard, } if *scores { g := game.NewGame(cfg) g.ShowScores() return } t, err := term.New() if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } defer t.Fini() cfg.Term = t var g *game.RogueGame if args := flag.Args(); len(args) == 1 && !*deathDemo { // restore a saved game g, err = game.Restore(args[0], cfg) if err != nil { t.Fini() fmt.Fprintln(os.Stderr, err) os.Exit(1) } } else { g = game.NewGame(cfg) } if *deathDemo { g.DeathDemo() return } // SIGHUP/SIGTERM autosave (save.c auto_save) sig := make(chan os.Signal, 1) signal.Notify(sig, syscall.SIGHUP, syscall.SIGTERM) go func() { <-sig g.AutoSave() t.Fini() os.Exit(0) }() if err := g.Run(); err != nil { t.Fini() fmt.Fprintln(os.Stderr, err) os.Exit(1) } }