예제 #1
0
void scum(unsigned long startingSeed, short numberOfSeedsToScan, short scanThroughDepth) {
    unsigned long theSeed;
    char path[BROGUE_FILENAME_MAX];
    item *theItem;
    creature *monst;
    char buf[500];
    FILE *logFile;
    
    logFile = fopen("Brogue seed catalog.txt", "w");
    rogue.nextGame = NG_NOTHING;
    
    getAvailableFilePath(path, LAST_GAME_NAME, GAME_SUFFIX);
    strcat(path, GAME_SUFFIX);
    
    fprintf(logFile, "Brogue seed catalog, seeds %li to %li, through depth %i.\n\n\
To play one of these seeds, press control-N from the title screen \
and enter the seed number. Knowing which items will appear on \
the first %i depths will, of course, make the game significantly easier.",
            startingSeed, startingSeed + numberOfSeedsToScan - 1, scanThroughDepth, scanThroughDepth);
    
    for (theSeed = startingSeed; theSeed < startingSeed + numberOfSeedsToScan; theSeed++) {
        fprintf(logFile, "\n\nSeed %li:", theSeed);
        printf("\nScanned seed %li.", theSeed);
        rogue.nextGamePath[0] = '\0';
        randomNumbersGenerated = 0;
        
        rogue.playbackMode = false;
        rogue.playbackFastForward = false;
        rogue.playbackBetweenTurns = false;
        
        strcpy(currentFilePath, path);
        initializeRogue(theSeed);
        rogue.playbackOmniscience = true;
        for (rogue.depthLevel = 1; rogue.depthLevel <= scanThroughDepth; rogue.depthLevel++) {
            startLevel(rogue.depthLevel == 1 ? 1 : rogue.depthLevel - 1, 1); // descending into level n
            fprintf(logFile, "\n    Depth %i:", rogue.depthLevel);
            for (theItem = floorItems->nextItem; theItem != NULL; theItem = theItem->nextItem) {
                itemName(theItem, buf, true, true, NULL);
                upperCase(buf);
                fprintf(logFile, "\n        %s", buf);
                if (pmap[theItem->xLoc][theItem->yLoc].machineNumber > 0) {
                    fprintf(logFile, " (vault %i)", pmap[theItem->xLoc][theItem->yLoc].machineNumber);
                }
            }
            for (monst = monsters->nextCreature; monst != NULL; monst = monst->nextCreature) {
                scumMonster(monst, logFile);
            }
            for (monst = dormantMonsters->nextCreature; monst != NULL; monst = monst->nextCreature) {
                scumMonster(monst, logFile);
            }
        }
        freeEverything();
        remove(currentFilePath); // Don't add a spurious LastGame file to the brogue folder.
    }
    fclose(logFile);
}
예제 #2
0
// This is the basic program loop.
// When the program launches, or when a game ends, you end up here.
// If the player has already said what he wants to do next
// (by storing it in rogue.nextGame -- possibilities listed in enum NGCommands),
// we'll do it. The path (rogue.nextGamePath) is essentially a parameter for this command, and
// tells NG_VIEW_RECORDING and NG_OPEN_GAME which file to open. If there is a command but no
// accompanying path, and it's a command that should take a path, then pop up a dialog to have
// the player specify a path. If there is no command (i.e. if rogue.nextGame contains NG_NOTHING),
// then we'll display the title screen so the player can choose.
void mainBrogueJunction() {
	rogueEvent theEvent;
	char path[BROGUE_FILENAME_MAX], buf[100], seedDefault[100];
	char maxSeed[20];
	short i, j, k;
	boolean seedTooBig;
	
	// clear screen and display buffer
	for (i=0; i<COLS; i++) {
		for (j=0; j<ROWS; j++) {
			displayBuffer[i][j].character = 0;
			displayBuffer[i][j].needsUpdate = false;
			displayBuffer[i][j].opacity = 100;
			for (k=0; k<3; k++) {
				displayBuffer[i][j].foreColorComponents[k] = 0;
				displayBuffer[i][j].backColorComponents[k] = 0;
			}
			plotCharWithColor(' ', i, j, &black, &black);
		}
	}
	
	initializeLaunchArguments(&rogue.nextGame, rogue.nextGamePath, &rogue.nextGameSeed);
	
	do {
        rogue.gameHasEnded = false;
        rogue.playbackFastForward = false;
        rogue.playbackMode = false;
		switch (rogue.nextGame) {
			case NG_NOTHING:
				// Run the main menu to get a decision out of the player.
                // Seth: Added
                setBrogueGameEvent(BrogueGameEventShowTitle);
				titleMenu();
				break;
			case NG_NEW_GAME:
			case NG_NEW_GAME_WITH_SEED:
				rogue.nextGamePath[0] = '\0';
				randomNumbersGenerated = 0;
				
				rogue.playbackMode = false;
				rogue.playbackFastForward = false;
				rogue.playbackBetweenTurns = false;
                
                getAvailableFilePath(path, LAST_GAME_NAME, GAME_SUFFIX);
                strcat(path, GAME_SUFFIX);
				strcpy(currentFilePath, path);
				
				if (rogue.nextGame == NG_NEW_GAME_WITH_SEED) {
					if (rogue.nextGameSeed == 0) { // Prompt for seed; default is the previous game's seed.
						sprintf(maxSeed, "%lu", ULONG_MAX);
						if (previousGameSeed == 0) {
							seedDefault[0] = '\0';
						} else {
							sprintf(seedDefault, "%lu", previousGameSeed);
						}
						if (getInputTextString(buf, "Generate dungeon with seed number:",
											   log10(ULONG_MAX) + 1,
											   seedDefault,
											   "",
											   TEXT_INPUT_NUMBERS,
											   true)
							&& buf[0] != '\0') {
							seedTooBig = false;
							if (strlen(buf) > strlen(maxSeed)) {
								seedTooBig = true;
							} else if (strlen(buf) == strlen(maxSeed)) {
								for (i=0; maxSeed[i]; i++) {
									if (maxSeed[i] > buf[i]) {
										break; // we're good
									} else if (maxSeed[i] < buf[i]) {
										seedTooBig = true;
										break;
									}
								}
							}
							if (seedTooBig) {
								rogue.nextGameSeed = ULONG_MAX;
							} else {
								sscanf(buf, "%lu", &rogue.nextGameSeed);
							}
						} else {
							rogue.nextGame = NG_NOTHING;
							break; // Don't start a new game after all.
						}
					}
				} else {
					rogue.nextGameSeed = 0; // Seed based on clock.
				}
				// Seth: Added
                setBrogueGameEvent(BrogueGameEventStartNewGame);
				rogue.nextGame = NG_NOTHING;
				initializeRogue(rogue.nextGameSeed);
				startLevel(rogue.depthLevel, 1); // descending into level 1
				
				mainInputLoop();
				freeEverything();
				break;
			case NG_OPEN_GAME:
				rogue.nextGame = NG_NOTHING;
                // Seth: Added
                setBrogueGameEvent(BrogueGameEventBeginOpenGame);
				path[0] = '\0';
				if (rogue.nextGamePath[0]) {
					strcpy(path, rogue.nextGamePath);
					rogue.nextGamePath[0] = '\0';
				} else {
					dialogChooseFile(path, GAME_SUFFIX, "Open saved game:");
					//chooseFile(path, "Open saved game: ", "Saved game", GAME_SUFFIX);
				}
                
				if (openFile(path)) {
					loadSavedGame();
                    // Seth: Added
                    setBrogueGameEvent(BrogueGameEventOpenGame);
					mainInputLoop();
					freeEverything();
				} else {
					//dialogAlert("File not found.");
				}
				rogue.playbackMode = false;
				rogue.playbackOOS = false;
				// Seth: Added
                setBrogueGameEvent(BrogueGameEventOpenGameFinished);
				break;
			case NG_VIEW_RECORDING:
				rogue.nextGame = NG_NOTHING;
				// Seth: Added
                setBrogueGameEvent(BrogueGameEventBeginOpenGame);
				path[0] = '\0';
				if (rogue.nextGamePath[0]) {
					strcpy(path, rogue.nextGamePath);
					rogue.nextGamePath[0] = '\0';
				} else {
					dialogChooseFile(path, RECORDING_SUFFIX, "View recording:");
					//chooseFile(path, "View recording: ", "Recording", RECORDING_SUFFIX);
				}
				
				if (openFile(path)) {
                    // Seth: Added
                    setBrogueGameEvent(BrogueGameEventPlayRecording);
					randomNumbersGenerated = 0;
					rogue.playbackMode = true;
					initializeRogue(0); // Seed argument is ignored because we're in playback.
					if (!rogue.gameHasEnded) {
						startLevel(rogue.depthLevel, 1);
						pausePlayback();
						displayAnnotation(); // in case there's an annotation for turn 0
					}
					
					while(!rogue.gameHasEnded && rogue.playbackMode) {
						rogue.RNG = RNG_COSMETIC; // dancing terrain colors can't influence recordings
						rogue.playbackBetweenTurns = true;
						nextBrogueEvent(&theEvent, false, true, false);
						rogue.RNG = RNG_SUBSTANTIVE;
						
						executeEvent(&theEvent);
					}
					
					freeEverything();
				} else {
					// announce file not found
				}
				rogue.playbackMode = false;
				rogue.playbackOOS = false;
				
				break;
			case NG_HIGH_SCORES:
				rogue.nextGame = NG_NOTHING;
                // Seth: Added
                setBrogueGameEvent(BrogueGameEventShowHighScores);
				printHighScores(false);
				break;
            case NG_SCUM:
                rogue.nextGame = NG_NOTHING;
                scum(1, 1000, 5);
                break;
			case NG_QUIT:
				// No need to do anything.
				break;
			default:
				break;
		}
	} while (rogue.nextGame != NG_QUIT);
}
예제 #3
0
// This is the basic program loop.
// When the program launches, or when a game ends, you end up here.
// If the player has already said what he wants to do next
// (by storing it in rogue.nextGame -- possibilities listed in enum NGCommands),
// we'll do it. The path (rogue.nextGamePath) is essentially a parameter for this command, and
// tells NG_VIEW_RECORDING and NG_OPEN_GAME which file to open. If there is a command but no
// accompanying path, and it's a command that should take a path, then pop up a dialog to have
// the player specify a path. If there is no command (i.e. if rogue.nextGame contains NG_NOTHING),
// then we'll display the title screen so the player can choose.
void mainBrogueJunction() {
	rogueEvent theEvent;
	char path[BROGUE_FILENAME_MAX], buf[100], seedDefault[100];
	char maxSeed[64];
	short i;
	boolean seedTooBig;

	if (ioInitialize() != 0) {
		printf("Failure to initialize display\n");
		exit(1);
	}
	
	initializeLaunchArguments(&rogue.nextGame, rogue.nextGamePath, &rogue.nextGameSeed);
	
	do {
        rogue.gameHasEnded = false;
        rogue.playbackFastForward = false;
        rogue.playbackMode = false;
		switch (rogue.nextGame) {
			case NG_NOTHING:
				// Run the main menu to get a decision out of the player.
				titleMenu();
				break;
			case NG_NEW_GAME:
			case NG_NEW_GAME_WITH_SEED:
				rogue.nextGamePath[0] = '\0';
				randomNumbersGenerated = 0;
				
				rogue.playbackMode = false;
				rogue.playbackFastForward = false;
				rogue.playbackBetweenTurns = false;
                
                getAvailableFilePath(path, LAST_GAME_NAME, GAME_SUFFIX);
                strcat(path, GAME_SUFFIX);
				strcpy(currentFilePath, path);
				
				if (rogue.nextGame == NG_NEW_GAME_WITH_SEED) {
					if (rogue.nextGameSeed == 0) { // Prompt for seed; default is the previous game's seed.
						sprintf(maxSeed, "%lu", ULONG_MAX);
						if (previousGameSeed == 0) {
							seedDefault[0] = '\0';
						} else {
							sprintf(seedDefault, "%lu", previousGameSeed);
						}
						if (getInputTextString(buf, "输入随机数种子生成地下城:",
											   log10(ULONG_MAX) + 1 + 6, // pad for header text
											   seedDefault,
											   "",
											   TEXT_INPUT_NUMBERS,
											   true)
							&& buf[0] != '\0') {
							seedTooBig = false;
							if (strlen(buf) > strlen(maxSeed)) {
								seedTooBig = true;
							} else if (strlen(buf) == strlen(maxSeed)) {
								for (i=0; maxSeed[i]; i++) {
									if (maxSeed[i] > buf[i]) {
										break; // we're good
									} else if (maxSeed[i] < buf[i]) {
										seedTooBig = true;
										break;
									}
								}
							}
							if (seedTooBig) {
								rogue.nextGameSeed = ULONG_MAX;
							} else {
								sscanf(buf, "%lu", &rogue.nextGameSeed);
							}
						} else {
							rogue.nextGame = NG_NOTHING;
							break; // Don't start a new game after all.
						}
					}
				} else {
					rogue.nextGameSeed = 0; // Seed based on clock.
				}
				
				rogue.nextGame = NG_NOTHING;
				initializeRogue(rogue.nextGameSeed);
				startLevel(rogue.depthLevel, 1); // descending into level 1
				
				mainInputLoop();
				freeEverything();
				break;
			case NG_OPEN_GAME:
				rogue.nextGame = NG_NOTHING;
				path[0] = '\0';
				if (rogue.nextGamePath[0]) {
					strcpy(path, rogue.nextGamePath);
					rogue.nextGamePath[0] = '\0';
				} else {
					dialogChooseFile(path, GAME_SUFFIX, "选择中断存档进行读取:");
					//chooseFile(path, "Open saved game: ", "Saved game", GAME_SUFFIX);
				}
					
				if (openFile(path)) {
					loadSavedGame();
					mainInputLoop();
					freeEverything();
				} else {
					//dialogAlert("File not found.");
				}
				rogue.playbackMode = false;
				rogue.playbackOOS = false;
				
				break;
			case NG_VIEW_RECORDING:
				rogue.nextGame = NG_NOTHING;
				
				path[0] = '\0';
				if (rogue.nextGamePath[0]) {
					strcpy(path, rogue.nextGamePath);
					rogue.nextGamePath[0] = '\0';
				} else {
					dialogChooseFile(path, RECORDING_SUFFIX, "选择录像文件进行回放:");
					//chooseFile(path, "View recording: ", "Recording", RECORDING_SUFFIX);
				}
				
				if (openFile(path)) {
					randomNumbersGenerated = 0;
					rogue.playbackMode = true;
					initializeRogue(0); // Seed argument is ignored because we're in playback.
					if (!rogue.gameHasEnded) {
						startLevel(rogue.depthLevel, 1);
						pausePlayback();
						displayAnnotation(); // in case there's an annotation for turn 0
					}
					
					while(!rogue.gameHasEnded && rogue.playbackMode) {
						rogue.RNG = RNG_COSMETIC; // dancing terrain colors can't influence recordings
						rogue.playbackBetweenTurns = true;
						nextBrogueEvent(&theEvent, false, true, false);
						rogue.RNG = RNG_SUBSTANTIVE;
						
						executeEvent(&theEvent);
					}
					
					freeEverything();
				} else {
					// announce file not found
				}
				rogue.playbackMode = false;
				rogue.playbackOOS = false;
				
				break;
			case NG_HIGH_SCORES:
				rogue.nextGame = NG_NOTHING;
				printHighScores(false);
				break;
            case NG_SCUM:
                rogue.nextGame = NG_NOTHING;
                scum(1, 1000, 5);
                break;
			case NG_QUIT:
				// No need to do anything.
				break;
			default:
				break;
		}
	} while (rogue.nextGame != NG_QUIT);
}