⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wump.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1989, 1993 *	The Regents of the University of California.  All rights reserved. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Dave Taylor, of Intuitive Systems. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char copyright[] ="@(#) Copyright (c) 1989, 1993\n\	The Regents of the University of California.  All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)wump.c	8.1 (Berkeley) 5/31/93";#endif /* not lint *//* * A very new version of the age old favorite Hunt-The-Wumpus game that has * been a part of the BSD distribution of Unix for longer than us old folk * would care to remember. */#include <sys/types.h>#include <sys/file.h>#include <stdio.h>#include "pathnames.h"/* some defines to spec out what our wumpus cave should look like */#define	MAX_ARROW_SHOT_DISTANCE	6		/* +1 for '0' stopper */#define	MAX_LINKS_IN_ROOM	25		/* a complex cave */#define	MAX_ROOMS_IN_CAVE	250#define	ROOMS_IN_CAVE		20#define	MIN_ROOMS_IN_CAVE	10#define	LINKS_IN_ROOM		3#define	NUMBER_OF_ARROWS	5#define	PIT_COUNT		3#define	BAT_COUNT		3#define	EASY			1		/* levels of play */#define	HARD			2/* some macro definitions for cleaner output */#define	plural(n)	(n == 1 ? "" : "s")/* simple cave data structure; +1 so we can index from '1' not '0' */struct room_record {	int tunnel[MAX_LINKS_IN_ROOM];	int has_a_pit, has_a_bat;} cave[MAX_ROOMS_IN_CAVE+1];/* * global variables so we can keep track of where the player is, how * many arrows they still have, where el wumpo is, and so on... */int player_loc = -1;			/* player location */int wumpus_loc = -1;			/* The Bad Guy location */int level = EASY;			/* level of play */int arrows_left;			/* arrows unshot */#ifdef DEBUGint debug = 0;#endifint pit_num = PIT_COUNT;		/* # pits in cave */int bat_num = BAT_COUNT;		/* # bats */int room_num = ROOMS_IN_CAVE;		/* # rooms in cave */int link_num = LINKS_IN_ROOM;		/* links per room  */int arrow_num = NUMBER_OF_ARROWS;	/* arrow inventory */char answer[20];			/* user input */main(argc, argv)	int argc;	char **argv;{	extern char *optarg;	int c;#ifdef DEBUG	while ((c = getopt(argc, argv, "a:b:hp:r:t:d")) != EOF)#else	while ((c = getopt(argc, argv, "a:b:hp:r:t:")) != EOF)#endif		switch (c) {		case 'a':			arrow_num = atoi(optarg);			break;		case 'b':			bat_num = atoi(optarg);			break;#ifdef DEBUG		case 'd':			debug = 1;			break;#endif		case 'h':			level = HARD;			break;		case 'p':			pit_num = atoi(optarg);			break;		case 'r':			room_num = atoi(optarg);			if (room_num < MIN_ROOMS_IN_CAVE) {				(void)fprintf(stderr,	"No self-respecting wumpus would live in such a small cave!\n");				exit(1);			}			if (room_num > MAX_ROOMS_IN_CAVE) {				(void)fprintf(stderr,	"Even wumpii can't furnish caves that large!\n");				exit(1);			}			break;		case 't':			link_num = atoi(optarg);			if (link_num < 2) {				(void)fprintf(stderr,	"Wumpii like extra doors in their caves!\n");				exit(1);			}			break;		case '?':		default:			usage();	}	if (link_num > MAX_LINKS_IN_ROOM ||	    link_num > room_num - (room_num / 4)) {		(void)fprintf(stderr,"Too many tunnels!  The cave collapsed!\n(Fortunately, the wumpus escaped!)\n");		exit(1);	}	if (level == HARD) {		bat_num += ((random() % (room_num / 2)) + 1);		pit_num += ((random() % (room_num / 2)) + 1);	}	if (bat_num > room_num / 2) {		(void)fprintf(stderr,"The wumpus refused to enter the cave, claiming it was too crowded!\n");		exit(1);	}	if (pit_num > room_num / 2) {		(void)fprintf(stderr,"The wumpus refused to enter the cave, claiming it was too dangerous!\n");		exit(1);	}	instructions();	cave_init();	/* and we're OFF!  da dum, da dum, da dum, da dum... */	(void)printf("\nYou're in a cave with %d rooms and %d tunnels leading from each room.\n\There are %d bat%s and %d pit%s scattered throughout the cave, and your\n\quiver holds %d custom super anti-evil Wumpus arrows.  Good luck.\n",	    room_num, link_num, bat_num, plural(bat_num), pit_num,	    plural(pit_num), arrow_num);	for (;;) {		initialize_things_in_cave();		arrows_left = arrow_num;		do {			display_room_stats();			(void)printf("Move or shoot? (m-s) ");			(void)fflush(stdout);			if (!fgets(answer, sizeof(answer), stdin))				break;		} while (!take_action());		if (!getans("\nCare to play another game? (y-n) "))			exit(0);		if (getans("In the same cave? (y-n) "))			clear_things_in_cave();		else			cave_init();	}	/* NOTREACHED */}display_room_stats(){	register int i;	/*	 * Routine will explain what's going on with the current room, as well	 * as describe whether there are pits, bats, & wumpii nearby.  It's	 * all pretty mindless, really.	 */	(void)printf("\nYou are in room %d of the cave, and have %d arrow%s left.\n",	    player_loc, arrows_left, plural(arrows_left));	if (bats_nearby())		(void)printf("*rustle* *rustle* (must be bats nearby)\n");	if (pit_nearby())		(void)printf("*whoosh* (I feel a draft from some pits).\n");	if (wump_nearby())		(void)printf("*sniff* (I can smell the evil Wumpus nearby!)\n");	(void)printf("There are tunnels to rooms %d, ",	   cave[player_loc].tunnel[0]);	for (i = 1; i < link_num - 1; i++)		if (cave[player_loc].tunnel[i] <= room_num)			(void)printf("%d, ", cave[player_loc].tunnel[i]);	(void)printf("and %d.\n", cave[player_loc].tunnel[link_num - 1]);}take_action(){	/*	 * Do the action specified by the player, either 'm'ove, 's'hoot	 * or something exceptionally bizarre and strange!  Returns 1	 * iff the player died during this turn, otherwise returns 0.	 */	switch (*answer) {		case 'M':		case 'm':			/* move */			return(move_to(answer + 1));		case 'S':		case 's':			/* shoot */			return(shoot(answer + 1));		case 'Q':		case 'q':		case 'x':			exit(0);		case '\n':			return(0);		}	if (random() % 15 == 1)		(void)printf("Que pasa?\n");	else		(void)printf("I don't understand!\n");	return(0);}move_to(room_number)	char *room_number;{	int i, just_moved_by_bats, next_room, tunnel_available;	/*	 * This is responsible for moving the player into another room in the	 * cave as per their directions.  If room_number is a null string,	 * then we'll prompt the user for the next room to go into.   Once	 * we've moved into the room, we'll check for things like bats, pits,	 * and so on.  This routine returns 1 if something occurs that kills	 * the player and 0 otherwise...	 */	tunnel_available = just_moved_by_bats = 0;	next_room = atoi(room_number);	/* crap for magic tunnels */	if (next_room == room_num + 1 &&	    cave[player_loc].tunnel[link_num-1] != next_room)		++next_room;	while (next_room < 1 || next_room > room_num + 1) {		if (next_room < 0 && next_room != -1)(void)printf("Sorry, but we're constrained to a semi-Euclidean cave!\n");		if (next_room > room_num + 1)(void)printf("What?  The cave surely isn't quite that big!\n");		if (next_room == room_num + 1 &&		    cave[player_loc].tunnel[link_num-1] != next_room) {			(void)printf("What?  The cave isn't that big!\n");			++next_room;		}		(void)printf("To which room do you wish to move? ");		(void)fflush(stdout);		if (!fgets(answer, sizeof(answer), stdin))			return(1);		next_room = atoi(answer);	}	/* now let's see if we can move to that room or not */	tunnel_available = 0;	for (i = 0; i < link_num; i++)		if (cave[player_loc].tunnel[i] == next_room)			tunnel_available = 1;	if (!tunnel_available) {		(void)printf("*Oof!*  (You hit the wall)\n");		if (random() % 6 == 1) {(void)printf("Your colorful comments awaken the wumpus!\n");			move_wump();			if (wumpus_loc == player_loc) {				wump_kill();				return(1);			}		}		return(0);	}	/* now let's move into that room and check it out for dangers */	if (next_room == room_num + 1)		jump(next_room = (random() % room_num) + 1);	player_loc = next_room;	for (;;) {		if (next_room == wumpus_loc) {		/* uh oh... */			wump_kill();			return(1);		}		if (cave[next_room].has_a_pit)			if (random() % 12 < 2) {				pit_survive();				return(0);			} else {				pit_kill();				return(1);			}		if (cave[next_room].has_a_bat) {			(void)printf("*flap*  *flap*  *flap*  (humongous bats pick you up and move you%s!)\n",			    just_moved_by_bats ? " again": "");			next_room = player_loc = (random() % room_num) + 1;			just_moved_by_bats = 1;		}		else			break;	}	return(0);}shoot(room_list)	char *room_list;{	int chance, next, roomcnt;	int j, arrow_location, link, ok;	char *p, *strtok();	/*	 * Implement shooting arrows.  Arrows are shot by the player indicating	 * a space-separated list of rooms that the arrow should pass through;	 * if any of the rooms they specify are not accessible via tunnel from	 * the room the arrow is in, it will instead fly randomly into another	 * room.  If the player hits the wumpus, this routine will indicate	 * such.  If it misses, this routine will *move* the wumpus one room.	 * If it's the last arrow, the player then dies...  Returns 1 if the	 * player has won or died, 0 if nothing has happened.	 */	arrow_location = player_loc;	for (roomcnt = 1;; ++roomcnt, room_list = NULL) {		if (!(p = strtok(room_list, " \t\n")))			if (roomcnt == 1) {				(void)printf(			"The arrow falls to the ground at your feet!\n");				return(0);			} else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -