Jump to content

Looping In C - Text Based Game Help

- - - - -

  • Please log in to reply
6 replies to this topic

#1
chewdonkey

chewdonkey

    Newbie

  • Members
  • Pip
  • 6 posts
hi all,

This is my first C project, a simple text based game (moving from room to room using n,s,e,w until you get outside of the house, and a save file).

I am almost done but am having a problem with my main 'describe room, scan input, and call related room from the array of structures' loop. When I compile it all comes up right and waits for me to input my direction. Once this is done it gets stuck in a loop describing 'you cannot move here' and never waits for user input again. My best guess is that I need to clear my i variable? but Im not sure i cant find the answer by reading up on looping. I must be misunderstanding something fundamental.

Iv put the full code here, its well commented with what Im doing and where the problems, maby some one could tell me how much of a noob i am being!
(there are 2 other small problems in the bottom in the comments, feel free to give those a shot but I was going to come onto those later, I will try using my books and searching the forum for those first, should be able to crack them).

Thanks very much for all your help

btw incase anyone is doing a similar project - the other major features are working, the only problems are commented (i think), feel free to use the code! :)

/*

 program title:

 program description: text based game in C

 author details:

 copyright:

*/


//standard libary files

#include <stdio.h>

#include <stdlib.h>


//global external definitions

#define n =0

#define e =1

#define s =2

#define w =3


//global external structure definitions

typedef struct {

	char room_name[51];

	char room_description[201];

	char room_exits_desc[51];

	int north;

	int east;

	int south;

	int west;

} room_detail;


typedef struct {

	char usrname[21];

	int room;

} save_detail;


save_detail usrsave;


//global external array set up details for each room structure

room_detail rooms[12] = {

	{"\nPourch\n\n","Description of room here\n","You can move North\n",1,11,10,10},//room array number 0

	{"\nHall\n\n","Description of room here\n","You can move North or South\n",6,2,0,3},//1

	{"\nToilet\n\n","Description of room here\n","You can move North or South\n",7,10,10,1},//2

	{"\nLounge\n\n","Description of room here\n","You can move North or South\n",5,1,10,10},//3

	{"\nDining Room\n\n","Description of room here\n","You can move North or South\n",10,5,10,10},//4

	{"\nPlay Room\n\n","Description of room here\n","You can move North or South\n",10,6,3,4},//5

	{"\nKitchen\n\n","Description of room here\n","You can move North or South\n",8,10,1,5},//6

	{"\nStairs\n\n","Description of room here\n","You can move North or South\n",10,10,2,10},//7

	{"\nBack Pourch\n\n","Description of room here\n","You can move North or South\n",10,9,6,10},//8

	{"\nGarage\n\n","Description of room here\n","You can move North or South\n",11,10,10,8},//9

	{"\nYou Cannot Move here","\n","\n",10,10,10,10},//10

	{"\nExit\n\n","You mannage to escape the building\n","You have finished the game\n",10,10,10,10},//11

}; 


//function prototypes


//main function

int main () {

	FILE *savfile; //define pointer is an external file

	int r;

	int i;

	

	savfile = fopen("save.txt", "r+"); //open existing txt file for read and write

		if ((savfile = fopen("save.txt", "r+")) == NULL) {

			savfile = fopen("save.txt", "w+"); //if not possible create new file for read and write

			printf("\nPrint Credits and Instructions\n\n");

			printf("Input name to start:\n");

			fscanf(stdin, "%s", usrsave.usrname); //input username to usrsave structure

			usrsave.room = 0; //set up starting room as 0

			fwrite(&usrsave, sizeof(save_detail), 1, savfile); //write all to save file

		}

		else {

			printf("\nPrint Credits and Instructions\n\n");

			printf("Loading save.txt data...\n\n");

		}

	printf("Starting description goes here - you enter %s's house ect\n", usrsave.usrname);

	r = usrsave.room; //read savfile and put sav_detail.room into r variable (current room)

	

	while (r != 11) { //main rooms loop. Brakes when user enters room 11, game winning room

		printf("%s", rooms[r].room_name); //describe current room (r) (start = 0, or read from save)

		printf("%s", rooms[r].room_description);

		printf("%s", rooms[r].room_exits_desc);

		printf("Which way do you want to move?\n");

	usrinput: { //goto tag

		fscanf(stdin, "%d", &i); //userinput direction, n 0,s 1,e 2,w 3 into direction i variable 

		if (i = 0) { //if north entered

			if (rooms[r].north = 10) { //if current rooms (r) north number is 10 wait again for another user input, keeping current room

				printf("You cannot move here\n");

				goto usrinput;

			}

			else {

				r = rooms[r].north; //change current room (r) to number stored in current rooms (r) north

			}

		}

		else if (i = 1){

			if (rooms[r].east = 10) {

				printf("You cannot move here\n");

				goto usrinput;

			}

			else {

				r = rooms[r].east;

			}

		}

		else if (i = 2){

			if (rooms[r].south = 10) {

				printf("You cannot move here\n");

				goto usrinput;

			}

			else {

				r = rooms[r].south;

			}

		}

		else if (i = 3){

			if (rooms[r].west = 10) {

				printf("You cannot move here\n");

				goto usrinput;

			}

			else {

				r = rooms[r].west;

			}

		}

		else {

			printf("Not a valid movement\n"); //if any other character entered wait again for user input

			goto usrinput;

		}

		i = NULL; //clear the i variable help this dosnt work

		//help needed - the above loop function does not work

	}

	}

	

	//help needed - how to set up the loops correctly for these 2 functions

	//help needed - how to compare fscanf string input to "exit" if wrong, print"Instruction not known

	

	//if exit entered save file and exit program

	//if (fscanf(stdin, "%s", &i)=="exit") {fwrite(&usrsave, sizeof(save_detail), 1, savfile); fclose(savfile); return 0;} 

	//if save entered save file and continue

	//if (fscanf(stdin, "%s", &i)=="save") {fwrite(&usrsave, sizeof(save_detail), 1, savfile);} 

	

	printf("%s", rooms[11].room_name); //describe ending sequence

	printf("%s", rooms[11].room_description);

	printf("%s", rooms[11].room_exits_desc);

	fclose(savfile);

	return 0;

}


#2
Zer033

Zer033

    Learning Programmer

  • Members
  • PipPipPip
  • 79 posts
I don't have time to really analyze the code right now, but all you should have to do is create a while loop with some escape condition. Your escape condition seems kind of convoluted (I'm c++ programmer not c btw) just at a glance. Make it something simple like if player reaches finishing position then set finished variable to true. I know that is what you're essentially trying to do, but maybe make a separate function just to separate things a bit for your saving function and loading function. I actually did a similar program to this one a long time ago that you're welcome to look at. It's in C++, but maybe can help with some things still.

I notice the area you seem to lock up is with that usrinput goto tag. I don't use goto tags and I'm not sure if that is common for c programs to do, but I don't think it is. Maybe take that out and allow your while loop to just flow.

Here is my program if you want to look at it:


/*
I modified my maze game to use a finite state machine where the rooms are states and
when a new state is entered information will be displayed on the screen.  Transition is the way to get back
to another state by leaving the room and the state name is the room that you are currently in. Most of the new 
finite state machine code is near the top.
*/

#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <string>
#include <stdio.h>
#include <time.h>
#include <fstream>

#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

//states
#define initialRoom 0
#define northRoom	1
#define southRoom	2
#define westRoom	3
#define eastRoom	4
#define EXIT		5

void gotoxy(short x, short y) 
{
	HANDLE hConsoleOutput;
	COORD Cursor_Pos = {x, y};

	hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(hConsoleOutput, Cursor_Pos);
}

void setcolor(unsigned short color)                
{                                                   
    HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hcon,color);
}

using namespace std;

string playerName;
int selection;
int score = 0;
int row;
int col;
int x = 15;
int y = 10;
int exitFlag = 0;
int finished = 0;
const int MAZE_WIDTH = 30;
const int MAZE_HEIGHT = 20;
clock_t counter;
int seconds = 0;
int minutes;
int smPebble;
int lgPebble;
time_t start, end;
int menuTime;

char maze[MAZE_HEIGHT][MAZE_WIDTH] =
{
{'|','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','|'},
{'|','=','=','=','=','=','=','=','=','=','=','|',' ',' ',' ',' ',' ',' ',' ','|','=','=','=','=','=','=','=','=','=','|'},
{'|','=','=','=','=','=','=','=','=','=','=','|',' ',' ',' ','O',' ',' ',' ','|','=','=','=','=','=','=','=','=','=','|'},
{'|','=','=','=','=','=','=','=','=','=','=','|',' ',' ',' ','o',' ',' ',' ','|','=','=','=','=','=','=','=','=','=','|'},
{'|','=','=','=','=','=','=','=','=','=','=','|',' ',' ',' ','o',' ',' ',' ','|','=','=','=','=','=','=','=','=','=','|'},
{'|','=','=','=','=','=','=','=','=','=','=','|','=','=','=','o','=','=','=','|','=','=','=','=','=','=','=','=','=','|'},
{'|','=','=','=','=','=','=','=','=','=','=',' ',' ',' ',' ',' ',' ',' ',' ',' ','=','=','=','=','=','=','=','=','=','|'},
{'|','E','|',' ',' ',' ',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|','X','|',' ',' ',' ',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|',' ','|',' ',' ',' ',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ',' ',' ','O','o','o','o','o',' ',' ',' ',' ',' ',' ',' ',' ',' ','o','o','o','o','O',' ',' ',' ',' ','|'},
{'|','I','|',' ',' ',' ',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|','T','|',' ',' ',' ',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|','=','=','=','=','=','=','=','=','=','=',' ',' ',' ',' ',' ',' ',' ',' ',' ','=','=','=','=','=','=','=','=','=','|'},
{'|','=','=','=','=','=','=','=','=','=','=','|','=','=','=','o','=','=','=','|','=','=','=','=','=','=','=','=','=','|'},
{'|','=','=','=','=','=','=','=','=','=','=','|',' ',' ',' ','o',' ',' ',' ','|','=','=','=','=','=','=','=','=','=','|'},
{'|','=','=','=','=','=','=','=','=','=','=','|',' ',' ',' ','o',' ',' ',' ','|','=','=','=','=','=','=','=','=','=','|'},
{'|','=','=','=','=','=','=','=','=','=','=','|',' ',' ',' ','O',' ',' ',' ','|','=','=','=','=','=','=','=','=','=','|'},
{'|','=','=','=','=','=','=','=','=','=','=','|',' ',' ',' ',' ',' ',' ',' ','|','=','=','=','=','=','=','=','=','=','|'},
{'|','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','=','|'}
};

//New state class
class State
{
public:

State();

int state;
string transition;
string stateName;

void InitialRoom();
void NorthRoom();
void SouthRoom();
void WestRoom();
void EastRoom();
void FinalRoom();

};

State player;

//constructor
State::State()
{
	transition = "North, South, East, West";
	stateName = "Initial Room";
}

//room state change functions
void State::InitialRoom()
{
	transition = "North, South, East, West";
	stateName = "Initial Room";
}

void State::NorthRoom()
{
	transition = "South                         ";
	stateName = "North Room    ";
}

void State::SouthRoom()
{
	transition = "North                        ";
	stateName = "South Room    ";
}

void State::WestRoom()
{
	transition = "East, West                      ";
	stateName = "West Room    ";
}

void State::EastRoom()
{
	transition = "West                          ";
	stateName = "East Room    ";
}

//exit game when final room is reached
void State::FinalRoom()
{
	finished = 1;
}

//check nodes and set state accordingly
void CheckStates()
{
	if ((x == 15 && y == 6) || (x == 15 && y == 13) || (x == 11 && y == 10) || (x == 19 && y == 10))
	{
		player.state = initialRoom;
	}
	if (x == 15 && y == 5)
	{
		player.state = northRoom;
	}
	if (x == 15 && y == 14)
	{
		player.state = southRoom;
	}
	if (x == 10 && y == 10)
	{
		player.state = westRoom;
	}
	if (x == 20 && y == 10)
	{
		player.state = eastRoom;
	}
	if (x == 1 && y == 10)
	{
		player.state = EXIT;
	}
}

//call functions depending on state entered
void ChangeStates()
{
	switch(player.state)
	{
	case initialRoom:
		player.InitialRoom();
		break;
	case northRoom:
		player.NorthRoom();
		break;
	case southRoom:
		player.SouthRoom();
		break;
	case westRoom:
		player.WestRoom();
		break;
	case eastRoom:
		player.EastRoom();
		break;
	case EXIT:
		player.FinalRoom();
		break;
	}
}

void DisplayStateInfo()
{
	gotoxy(44, 3);
	setcolor(8);
	cout << player.transition;

	gotoxy(39, 5);
	setcolor(8);
	cout << player.stateName;
}

//---------------------------------------------------------
// Function: DrawMaze()
// Purpose:  Draws the character array to create the maze and colors it
//---------------------------------------------------------
void DrawMaze()
{
system("cls");

	for (row = 0; row < MAZE_HEIGHT; row++)
	{
		for (col = 0; col < MAZE_WIDTH; col++)
		{
			if (maze[row][col] == '=' || maze[row][col] == '|')
				setcolor(8);
			else if (maze[row][col] == 'o')
				setcolor(13);
			else if (maze[row][col] == 'O')
				setcolor(14);
			else if (maze[row][col] == 'F')
				setcolor(12);

			cout << maze[row][col];
		}
		cout << "\n";
	}//end for
}//end DrawMaze()

//---------------------------------------------------------
// Function: CheckKeys()
// Purpose:  Checks for user keyboard input and handles it
//---------------------------------------------------------
void CheckKeys()
{
		//move up
		if (KEY_DOWN(VK_UP))
			{
				y = y - 1;//move position

				if (maze[y][x] == ' ' || maze[y][x] == 'o' || maze[y][x] == 'O')//check to see if new position is traversable
				{
					Sleep(200);//delay so only one coord is moved

					gotoxy(x, y + 1);//erase character as it is moved
					cout << " ";
				}
				else if (maze[y][x] == '=' || maze[y][x] == '|')//if new position is a wall then reset position
				{
					y = y + 1;
				}
			}
		//move down
		else if (KEY_DOWN(VK_DOWN))
			{			
				y = y + 1;

				if (maze[y][x] == ' ' || maze[y][x] == 'o' || maze[y][x] == 'O')
				{
					Sleep(200);

					gotoxy(x, y - 1);
					cout << " ";
				}
				else if (maze[y][x] == '=' || maze[y][x] == '|')
				{
					y = y - 1;
				}
				
			}
		//move left
		else if (KEY_DOWN(VK_LEFT))
			{
				x = x - 1;

				if (maze[y][x] == ' ' || maze[y][x] == 'o' || maze[y][x] == 'O')
				{
					Sleep(200);

					gotoxy(x + 1, y);
					cout << " ";
				}
				else if (maze[y][x] == '=' || maze[y][x] == '|')
				{
					x = x + 1;
				}

			}
		//move right
		else if (KEY_DOWN(VK_RIGHT))
			{
				x = x + 1;

				if (maze[y][x] == ' ' || maze[y][x] == 'o' || maze[y][x] == 'O')
				{
					Sleep(200);

					gotoxy(x - 1, y);
					cout << " ";
				}
				else if (maze[y][x] == '=' || maze[y][x] == '|')
				{
					x = x - 1;
				}
			}
		//escape = quit
		else if (KEY_DOWN(VK_ESCAPE))
			{
				exitFlag = 1;//exit game
				Sleep(200);
			}
}//end CheckKeys()

//---------------------------------------------------------
// Function: DisplayMenus()
// Purpose:  Displays menu and handles menu branching
//---------------------------------------------------------
void DisplayMenus()
{
system("cls");

cout << "Make Your Selection, " << playerName << ": \n\n";
cout << "1 - Start Game\n";
cout << "2 - Instructions\n";
cout << "3 - About\n";
cout << "4 - Quit\n\n";
cout << "Selection: ";
cin >> selection;

	switch(selection)
	{
		case 1:
			DrawMaze();
			break;
		case 2:
			system("cls");
			cout << "The objective of the game is to traverse the maze while picking up items to \nincrease your score, but hurry up time is ticking.";
			cout << "\n\nGame Items:";
			setcolor(12);
			cout << "\n\nX - YOU, The Player";
			setcolor(13);
			cout << "\no - Adds 100 points to your score";
			setcolor(14);
			cout << "\nO - Adds 1000 points to your score";
			setcolor(8);
			cout << "\n= - Wall type 1 (cannot be passed through)";
			cout << "\n| - Wall type 2 (cannot be passed through)";
			setcolor(12);
			cout << "\nF - Finish Line";
			setcolor(3);
			cout << "\n\nGame Controls:";
			cout << "\n\nArrow Keys - Move left, right, up, down";
			cout << "\nEscape     - Exit Game\n\n";
			cout << "1 - Return to Main Menu\n\n";
			cout << "Selection: ";
			cin >> selection;
			if (selection == 1)
			{
				DisplayMenus();
			}
			break;
		case 3:
			system("cls");
			cout << "Written by:  BN \n\n";
			cout <<	"Objective:   A MAZE GAME MADE FROM C++\n\n";
			cout << "1 - Return to Main Menu\n\n";
			cout << "Selection: ";
			cin >> selection;
			if (selection == 1)
			{
				DisplayMenus();
			}
			break;
		case 4:
			exitFlag = 1;
			break;
		default:
			DisplayMenus();
			break;
	}//end switch
}//end DisplayMenus()

//---------------------------------------------------------
// Function: ScoreKeeper()
// Purpose:  Adds to the score when items are encountered 
//			 in-game and displays the score to the screen
//---------------------------------------------------------
void ScoreKeeper()
{
	if (maze[y][x] == 'o')
	{
		maze[y][x] = ' ';
		score = score + 100;
		smPebble = smPebble + 1;
	}
	if (maze[y][x] == 'O')
	{
		maze[y][x] = ' ';
		score = score + 1000;
		lgPebble = lgPebble + 1;
	}

	gotoxy(39, 7);
	setcolor(8);
	cout << score;
}//end ScoreKeeper()

//---------------------------------------------------------
// Function: SaveScore()
// Purpose:  Allows the player to save their score to a file
//---------------------------------------------------------
void SaveScore()
{
	ofstream scoreFile;
	scoreFile.open ("score.txt", ios::app);
	scoreFile << playerName << "'s score card:";
	scoreFile << "\nNumber of small pebbles recovered: " << smPebble;
	scoreFile << "\nNumber of large pebbles recovered: " << lgPebble;
	scoreFile << "\nBase score: " << score;
	scoreFile << "\nSeconds elapsed: " << seconds;
	scoreFile << "\nFinal score: " << score/seconds;
	scoreFile << "\n\n";
	scoreFile.close();
}//end SaveScore()

//---------------------------------------------------------
// Function: BeatGame()
// Purpose:  This code executes when the player reaches
//           the end of the maze. Gives the player the
//           option to save their score before quitting.
//---------------------------------------------------------
void BeatGame()
{
	system("cls");
	setcolor(3);
	cout << "You've beat the game, CONGRATULATIONS!";
	cout << "\n\n\tScore Summary: ";
	cout << "\n\n\tNumber of small pebbles recovered: " << smPebble;
	cout << "\n\n\tNumber of large pebbles recovered: " << lgPebble;
	cout << "\n\n\tBase score: " << score;
	cout << "\n\n\tSeconds elapsed: " << seconds;
	cout << "\n\n\tFinal score: " << score/seconds;
	cout << "\n\n1 - Save score to a file and quit";
	cout << "\n\n2 - Quit without saving score";
	cout << "\n\nSelection: ";
	cin >> selection;
	switch (selection)
	{
	case 1:
		SaveScore();
		exitFlag = 1;
		break;
	case 2:
		exitFlag = 1;
		break;
	default:
		BeatGame();
	}//end switch
}//end BeatGame()

//---------------------------------------------------------
// Function: DisplayTimer()
// Purpose:  Times and displays the time to the screen.
//           Seconds taken is also used in score calculation.
//---------------------------------------------------------
void DisplayTimer()
{
	seconds = (clock()/1000) - menuTime + 1;

	gotoxy(39, 9);
	setcolor(8);
	cout << seconds;
}//end DisplayTimer()

//---------------------------------------------------------
// Main Module
// The game starts here
//---------------------------------------------------------
int main()
{
time(&start);
system("cls");

setcolor(3);
cout << "Welcome to MAZE GAME!\n\n";
cout << "Please, Introduce yourself\n\n";
cout << "What name would you like to go by? ";
cin >> playerName;

		DisplayMenus();

	gotoxy(32, 1);
	cout << playerName << "'s Maze";
	gotoxy(32, 3);
	cout << "Transition: ";
	gotoxy(32, 5);
	cout << "State: ";
	gotoxy(32, 7);
	cout << "Score:";
	gotoxy(32, 9);
	cout << "Time:";

time(&end);
menuTime = difftime(end, start);/*get menu run time so I can subtract from the game run time so my timer is accurate
								  since it starts when the program starts*/

	//game loop
	while (exitFlag == 0)
	{
		CheckKeys();
		ScoreKeeper();
		DisplayTimer();
		DisplayStateInfo();

		CheckStates();
		ChangeStates();

		gotoxy(x, y);//Draw character as coords change
		setcolor(12);
		cout << "X";
/*
		if (maze[y][x] == 'F')
		{
			finished = 1;//reached finished line so finished is true
		}
*/
		if (finished == 1)//if finish line is reached exit game loop by going to the end of the game screen
		{
			BeatGame();
		}
	}//end while

}//end main

#3
chewdonkey

chewdonkey

    Newbie

  • Members
  • Pip
  • 6 posts
Thanks for your help Zer033, The sample code is useful for understanding the looping and function arrangement. I will try to cut down my loop and give it a proper brake arrangement as well as move my whole main structure to separate functions. Once I have done that I will try it again then repost here!

#4
chewdonkey

chewdonkey

    Newbie

  • Members
  • Pip
  • 6 posts
Ok, an update.

I have created a gameloop function. my loop is structured as follows. While r variable (current room number) is not equal to 11 (my final/winning room) then print room name, wait for int input from user, if 1 read which room is to the north of the current room by looking up in structure. Change this room number to current room. if the room to the north is room 10, print you cannot move here (this is my movement not possible room).

This should loop until my finishing room is found. However there are 2 problems, both of which I am stuck on.

1) when a letter is entered instead of an int the loop has a else print "not valid movement" part. meaning if a valid direction (1 = north, 2 = east, 3 = south, 4 = west) is not entered it should keep current room and loop again, asking for another user inout. HOWEVER instead a letter sends it into melt down, looping infinitely but staying in the same room

2) if you enter a valid direction, 1,2,3,4 or indeed ANY number including non valid ones the program reads from room 10 and tells you that this movement is not valid


any help would be appreciated. Iv just shown the loop bellow to make it easer to look at, all the rest of the code (the structures inilitising is unchanged and shown in the full code of my first post). im still trying to follow your code Zer033 and updating my format, but its a little hard as i dont know any of the specific C++ parts, i can get the general idea though.

void gameloop(int r) {//gameloop function loops user movements

	int i; //direction key pressed

	

	while (r != 11) { //main rooms loop. Brakes when user enters room 11, game winning room

		printf("%s", rooms[r].room_name); //describe current room (r) (start = 0, or read from save)

		printf("%s", rooms[r].room_description);

		printf("%s", rooms[r].room_exits_desc);

		printf("Which way do you want to move?\n");

		fscanf(stdin, "%d", &i); //userinput direction, n 1,s 2,e 3,w 4 into direction i variable 

		printf("You move %d\n", i);

		if (i = 1) { //if north entered

			if (rooms[r].north = 10) { //if current rooms (r) north number is 10 wait again for another user input, keeping current room

				printf("%s\n", rooms[10].room_description);//You cannot move here room

				r = r; //keep current room and print descriptions again

			}

			else {

				r = rooms[r].north; //change current room (r) to number stored in current rooms (r) north

			}

		}

		else if (i = 2){

			if (rooms[r].east = 10) {

				printf("%s\n", rooms[10].room_description);

				r = r;

			}

			else {

				r = rooms[r].east;

			}

		}

		else if (i = 3){

			if (rooms[r].south = 10) {

				printf("%s\n", rooms[10].room_description);

				r = r;

			}

			else {

				r = rooms[r].south;

			}

		}

		else if (i = 4){

			if (rooms[r].west = 10) {

				printf("%s\n", rooms[10].room_description);

				r = r;

			}

			else {

				r = rooms[r].west;

			}

		}

		else {//i = anything else

			printf("Not a valid movement\n"); //if any other character entered wait again for user input

			r = r;

			}

	}//end loop

	

	//if exit entered save file and exit program

	//if (fscanf(stdin, "%s", &i)=="exit") {fwrite(&usrsave, sizeof(save_detail), 1, savfile); fclose(savfile); return 0;} 

	//if save entered save file and continue

	//if (fscanf(stdin, "%s", &i)=="save") {fwrite(&usrsave, sizeof(save_detail), 1, savfile);} 

	

	//help needed - how to set up the loops correctly for these 2 functions

	//help needed - how to compare fscanf string input to "exit" if wrong, print"Instruction not known

	

	printf("%s", rooms[11].room_name); //Ending sequence once room 11 reached

	printf("%s", rooms[11].room_description);

	printf("%s", rooms[11].room_exits_desc);

	return;

}//end gameloop

 


#5
chewdonkey

chewdonkey

    Newbie

  • Members
  • Pip
  • 6 posts
i have managed to solve one of my issues! I was using = to mean equal to, in C the operator for equal to is ==. now i can move around my house by inputing 1,2,3,4. but if i input a letter i go into a infinite loop instead of saying "you cannot move here"

#6
Megak

Megak

    Newbie

  • Members
  • PipPip
  • 16 posts

chewdonkey said:

i have managed to solve one of my issues! I was using = to mean equal to, in C the operator for equal to is ==. now i can move around my house by inputing 1,2,3,4. but if i input a letter i go into a infinite loop instead of saying "you cannot move here"

interesting, usually the compiler will pick that up. Try turning warnings on and reading through them in your IDE

#7
Alexander

Alexander

    It's Science!

  • Moderators
  • 4,118 posts
  • Location:Vancouver, Eh! Cleverness: 200

chewdonkey said:

but if i input a letter i go into a infinite loop
This is due to the fact scanf family of functions will not consume a character, if they are scanning for an integer. It will simply scan for an integer infinite times as the character will always be within stdin stream.

man page said:

Return Value:
On success, the function returns the number of items succesfully read. This count can match the expected number of readings or be less -even zero- in the case of a matching failure.
In the case of an input failure before any data could be successfully read, EOF is returned.

This means you can check the result of your fscanf function, if the result == 1 then it has scanned an integer successfully. If it returns 0 or EOF then you must clear the standard input completely before continuing, with something such as getchar() and then ask for an input again.
Be sure to read the updated FAQ! || Health is achieved through the same 10,000 steps.
If a suggested code/method fails, informing us is less important than telling us why or what errors occurred.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users