5 Replies - 621 Views - Last Post: 26 February 2016 - 12:16 PM Rate Topic: -----

#1 sublimeaces   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 93
  • Joined: 13-April 14

linked lists runtime error

Posted 25 February 2016 - 01:40 PM

hello, i had this homework assignment that i could not figure out my error in the debugger. It does compile in visual studio but gets a runtime error that says it breaks with First-chance exception at 0x001F6556 in Project1.exe: 0xC0000005: Access violation reading location 0xCDCDCDCD. and unable to read memory in the debugger on ID,LEVEL,NextPlayer... this is very strange to me because i got it to run for quite sometime using linux g++ untill it eventually gets a segment error. It will sort ascending , decending, delete, add but eventually it gets a segment error. I also should point out that i am relatively new to C++ and got some help with this project

my question is if you can help me debug this and figure out where my error is. I can't find it!

I do not know how to go about posting all this code so i will post it one at a time.
GAME.H
#pragma once
// #include <conio.h>
#include <iostream>
using namespace std;
#include <time.h>
#include "Room.h"

class Game
{
private:	
	// Static Constants
	static const int MIN_PLAYER_LEVEL = 1;
	static const int MAX_PLAYER_LEVEL = 80;
	static const int NUMBER_OF_ROOMS = 5;

	// Action Type enum
	enum ActionType
	{
		Add,
		Insert,
		Remove,
		Replace,
		Sort,
		Count
	};

	// Member Variables
	Room* Rooms[NUMBER_OF_ROOMS];

public:
	// Constructor & Destructor
	Game();
	~Game();

	// Public Functions
	void Run();

	// Private Functions
private:
	Player* GetRandomPlayer(Room* room);
	int GetRandomPlayerLevel();
	int GetRandomRoomPosition(Room* room, bool includingLastPostion);
	void PrintRoom(Room* room);
};

Game.CPP
#include "Game.h"

Game::Game()
{
	for (int i = 0; i < NUMBER_OF_ROOMS; i++)
		Rooms[i] = new Room(i+1);
}

Game::~Game()
{
	// Delete Rooms & Players
	for (int i = 0; i < NUMBER_OF_ROOMS; i++)
	{
		Rooms[i]->ClearPlayers();
		delete Rooms[i];
	}
}

void Game::Run()
{
	cout << "Welcome to the Game Server Simulator\n";
	cout << "Press any key to begin.\n\n";
	char input;
	input = cin.get();
	input = 'e'; // Set to something besides 'q' to enter main loop

	// Seed Random Number Generator
	srand((unsigned int)time(NULL));

	// // Create Rooms
	// Room* rooms[NUMBER_OF_ROOMS];
	// for (int i = 0; i < NUMBER_OF_ROOMS; i++)
	// 	rooms[i] = new Room(i + 1);

	ActionType action;
	bool forceAddAPlayer = true;
	int id = -1;

	// Main Game Loop
	while (input != 'q')
	{
		// Get random room number
		int roomNumber = rand() % NUMBER_OF_ROOMS;

		// Get random action
		if (forceAddAPlayer)
		{// Force the program to add players when it first starts to populate rooms with some data
			if (id >= 15)
				forceAddAPlayer = false;
			int r = rand() % 2;
			if (r == 0)
				action = Add;
			else
				action = Insert;
		}
		else
			action = static_cast<ActionType>(rand() % Count);

		// Do something based on that action
		Player* newPlayer;
		Player* oldPlayer;		
		int position;
		switch (action)
		{
		case Add:
			newPlayer = new Player(Rooms[roomNumber]->GetNextPlayerID(), GetRandomPlayerLevel()); // Creates a new player
			id = Rooms[roomNumber]->GetNextPlayerID();
			cout << "Adding Player " << newPlayer->GetID() << " to room " << Rooms[roomNumber]->GetNumber() << endl;
			Rooms[roomNumber]->AddPlayer(newPlayer); // Add player to room
			break;
		case Insert:
			newPlayer = new Player(Rooms[roomNumber]->GetNextPlayerID(), GetRandomPlayerLevel()); // Creates a new player
			id = Rooms[roomNumber]->GetNextPlayerID();
			position = GetRandomRoomPosition(Rooms[roomNumber], true);
			cout << "Inserting Player " << newPlayer->GetID() << " at position " << position << " in room " << Rooms[roomNumber]->GetNumber() << endl;
			Rooms[roomNumber]->InsertPlayer(newPlayer, position); // Insert player in room
			break;
		case Remove:
			oldPlayer = GetRandomPlayer(Rooms[roomNumber]); // Retrieves existing player in this room
			if (oldPlayer != NULL)
			{
				cout << "Removing Player " << oldPlayer->GetID() << " from room " << Rooms[roomNumber]->GetNumber() << endl;
				Rooms[roomNumber]->RemovePlayer(oldPlayer); // Remove player
			}
			break;
		case Replace:
			oldPlayer = GetRandomPlayer(Rooms[roomNumber]); // Retrieves existing player in this room
			if (oldPlayer != NULL)
			{
				newPlayer = new Player(Rooms[roomNumber]->GetNextPlayerID(), GetRandomPlayerLevel()); // Creates a new player
				id = Rooms[roomNumber]->GetNextPlayerID();
				cout << "Replacing Player " << oldPlayer->GetID() << " with Player " << newPlayer->GetID() << " in room " << Rooms[roomNumber]->GetNumber() << endl;
				Rooms[roomNumber]->ReplacePlayer(oldPlayer, newPlayer); // Replace a player with a new player
			}
			break;
		case Sort:
			int order = rand() % 2;
			if (order == 0)
			{
				cout << "Sorting room " << Rooms[roomNumber]->GetNumber() << " in ascending order.\n";
				Rooms[roomNumber]->SortAscending(); // Sort Ascending
			}
			else
			{
				cout << "Sorting room " << Rooms[roomNumber]->GetNumber() << " in descending order.\n";
				Rooms[roomNumber]->SortDescending(); // Sort Descending
			}
			break;
		}

		// Update Rooms with latest ID
		if (id != -1)
		{
			for (int i = 0; i < NUMBER_OF_ROOMS; i++)
				Rooms[i]->SetNextPlayerID(id + 1); // Add 1 to id to make sure every player has a unique ID
		}

		// Print Room Data
		bool printedSomething = false;
		for (int i = 0; i < NUMBER_OF_ROOMS; i++)
		{
			PrintRoom(Rooms[i]);
			printedSomething = true;
		}
		if (!printedSomething)
		{
			cout << "There are currently no players in any rooms.\n";
			forceAddAPlayer = true;
		}

		// Receive User Input
		cout << "\t\tPress any key to continue or 'q' to quit.\n" << endl;
		input = cin.get();
	}

	cout << "Thank you for playing!\n";
	system("pause");	
}

Player* Game::GetRandomPlayer(Room* room)
{
	int position = GetRandomRoomPosition(room, false);
	PlayerList* players = room->GetPlayerList();
	return players->ElementAt(position);
}

int Game::GetRandomPlayerLevel()
{
	int level = rand() % MAX_PLAYER_LEVEL;
	level += MIN_PLAYER_LEVEL;
	return level;
}

int Game::GetRandomRoomPosition(Room* room, bool includingLastPosition)
{
	PlayerList* players = room->GetPlayerList();
	int count = players->GetCount();
	if (count <= 0)
		return 0;
	else if (includingLastPosition && count == 1)
		return rand() % 2;
	else if (!includingLastPosition && count == 1)
		return 0;
	else if (!includingLastPosition && count > 1)
		return rand() % (count + 1);
	else
		return rand() % count;
}

void Game::PrintRoom(Room* room)
{
	PlayerList* players = room->GetPlayerList();
	if (players->GetCount() > 0)
	{
		cout << "Room: " << room->GetNumber() << endl;
		Player* player = players->GetHead();
		while (player != NULL)
		{
			cout << "\tPlayer: " << player->GetID() << ", Level " << player->GetLevel() << endl;
			player = players->Next(player);
		}
	}
}

PLAYER.H
#pragma once
#include <stdlib.h>

class Player
{
private:
	// Member Variables
	int ID;
	int Level;
	Player* NextPlayer;

public:
	// Constructors
	Player();
	Player(int id, int level);

	// Getters
	int GetID();
	int GetLevel();
	Player* GetNextPlayer();

	// Setters
	void SetID(int id);
	void SetLevel(int level);
	void SetNextPlayer(Player* next);
};


Player.cpp
#include "Player.h"

    Player::Player()
        {
            int ID = 0;
            int Level = 0;
        } // end Defualt const
    
    Player::Player(int ID, int Level) : ID(ID), Level(Level)
        {
        } // end non default const
    
    
    //       GETS     // 
    int Player::GetID() 
        {
            return ID;
        }//end get id
        
    int Player::GetLevel() 
        {
            return Level;
        }//end get level
        
    Player* Player::GetNextPlayer()
        {
            return NextPlayer; 
        }
    
    //      SETS        // 
    
    
    void Player::SetID(int ID)
        {
            this->ID = ID;
        }
    
    void Player::SetLevel(int Level)
        {
            this->Level = Level;
        }
    
    void Player::SetNextPlayer(Player* NextPlayer)
        {
            this->NextPlayer = NextPlayer;
        }


PlayerList.h
#pragma once
#include "Player.h"


class PlayerList
{
public:
	// Public Static Constants
	static const int ASCENDING = 0;
	static const int DESCENDING = 1;
	

private:
	// Member Variables
	int Count;
	Player* HeadPtr;
	Player* TailPtr;
	
	void SwapPlayers(Player* previous, Player* player1, Player* player2);
	void PrintList();

public:
	// Constructor
	PlayerList();

	// Public Functions
	void Add(Player* player);
	void Clear();
	Player* ElementAt(int position);
	int GetCount();
	Player* GetHead();
	int IndexOf(Player* player);
	void Insert(Player* player, int position);
	Player* Next(Player* player);
	void Remove(Player* player);
	void RemoveAt(int position);
	void Sort(int order);
	
};

PlayerList.cpp
#include "PlayerList.h"
#include <stdio.h>
#include <sstream>
#include <string.h>
#include <iostream>


    PlayerList::PlayerList()
    {
        int Count = 0;
	    Player* HeadPtr = NULL;
	    Player* TailPtr = NULL;
	
    }//end default constructor
    
    
    void PlayerList::Add(Player* player)
        {
			
			PrintList();
            if (player == NULL)
            {
               return; 
            }
            if (HeadPtr == NULL)
            {
                HeadPtr = player; 
            }
            else
            {
                TailPtr->SetNextPlayer(player);
            }
            TailPtr = player;
            TailPtr->SetNextPlayer(NULL);    
            Count++;
            PrintList();
        }
    
    void PlayerList::Clear()
        {
            Player * current = HeadPtr;
      
            while(current != NULL)
            {
                Player * next = current->GetNextPlayer();
                delete current;
                current = next;
            }
            
            Count = 0;
            HeadPtr = NULL;
            TailPtr = NULL;
            PrintList();
        }
    
    Player* PlayerList::ElementAt(int position)
        {
            if (position >= Count)
            {
               return NULL;
            }
         
            Player * current = HeadPtr;
            for(int i = 0; i < position; i++)
            {
                current = current->GetNextPlayer();
            }

            return current;
        }
    
    int PlayerList::GetCount()
        {
            return Count;
        }
    
    Player* PlayerList::GetHead()
        {
            return HeadPtr;
        }
    
    int PlayerList::IndexOf(Player* player)
        {
            if(player == NULL)
                {
                    return -1;    
                }

            int index = 0;
            for(Player * current = HeadPtr; current != NULL; current = current->GetNextPlayer())
            {
                    if (current->GetID() == player->GetID())
                    {
                        return index;
                    }
                    index++;
            }
            return -1;
        }
    
    void PlayerList::Insert(Player* player, int position)
        {
            PrintList();
            if (player == NULL)
                {
                    return; 
                }
            if (position == 0)
            {
                if(Count == 0)
                {
                    TailPtr = player;
                }
                player->SetNextPlayer(HeadPtr);
                HeadPtr = player;
            }
            else
            {
                Player * found = ElementAt(position-1);
                if (found == NULL)
                    {
                        return;
                    }
                Player * next = found->GetNextPlayer();
                player->SetNextPlayer(next);
                found->SetNextPlayer(player);
                if (TailPtr == found)
                    {
                        TailPtr = player;
                    }
            }
            Count++;
            PrintList();
        }
    
    Player* PlayerList::Next(Player* player)
        {

            if(player == NULL)
                {
                    return NULL;    
                }

            for(Player * current = HeadPtr; current != NULL; current = current->GetNextPlayer())
                {
                    if (current->GetID() == player->GetID())
                        {
                            return current->GetNextPlayer();
                        }
                }
            return NULL;
    
        }
        
    void PlayerList::Remove(Player* player)
        {
            Player * previous = NULL;
            for(Player * current = HeadPtr; current != NULL; current = current->GetNextPlayer())
            {
               if (current->GetID() == player->GetID())
               {
                  if (previous != NULL)
                  {
					previous->SetNextPlayer(current->GetNextPlayer());
                  }
                  if (current == HeadPtr)
                  {
                     HeadPtr = current->GetNextPlayer();
                  }
                      delete current;
               }
                    previous = current;
             }
            Count--;
            PrintList();
        }
        
    void PlayerList::RemoveAt(int position)
        {
            Player * toDelete = NULL;
            if (position == 0 && HeadPtr != NULL)
            {
                toDelete = HeadPtr;
                HeadPtr = HeadPtr->GetNextPlayer();
            }
            else
            {
                Player * found = ElementAt(position-1);
                if (found == NULL)
                {
                    return;
                }
                toDelete = found->GetNextPlayer();
                found->SetNextPlayer(toDelete->GetNextPlayer());
                if (TailPtr == toDelete)
                {
                   TailPtr = found;
                }
            }
            if (toDelete)
            {
               delete toDelete;
            } 
            Count--;
            PrintList();
        }
        
    void PlayerList::Sort(int order)
    {
        Player* previous = NULL;
		Player* current = HeadPtr;
		Player* next = NULL;
		Player* sorted = NULL;

		if(current == NULL)
		{
			return;
		}
		
		next = current->GetNextPlayer();
		
		if(next == NULL)
		{
            return;
		}

	    while(sorted != HeadPtr->GetNextPlayer())
		{
		    PrintList();
		    printf("Comparing %d with %d\n", current->GetID(), next->GetID());
		    std::cin.get();
		    if(order == 0 && current->GetID() > next->GetID()) 	// ascending
			{
                SwapPlayers(previous, current, next);
                Player * tmp = next;
                next = current;
                current = tmp;
		    }
			else if(order == 1 && current->GetID() < next->GetID())  //descending
			{
                SwapPlayers(previous, current, next);
                Player * tmp = next;
                next = current;
                current = tmp;
		    }

            previous = current;
		    current = current->GetNextPlayer();
		    next = next->GetNextPlayer();
		    
		    if(next == sorted)
		    {
		        sorted = current;
		        current = HeadPtr;
		        next = current->GetNextPlayer();
		        previous = NULL;
		    }

        }
    }
    
    void PlayerList::SwapPlayers(Player* previous, Player* player1, Player* player2)
    {
        if(player1 == NULL || player2 == NULL)
        {
            return;
        }
        printf("Swapping %d with %d\n", player1->GetID(), player2->GetID());
        std::cin.get();
        player1->SetNextPlayer(player2->GetNextPlayer());
        player2->SetNextPlayer(player1);
        if(previous)
        {
            previous->SetNextPlayer(player2);
        }
        if(player1 == HeadPtr)
        {
            HeadPtr = player2;
        }
        if(player2 == TailPtr)
        {
            TailPtr = player1;
        }
        previous = player2;
    }
    
    void PlayerList::PrintList()
    {
        printf("HEAD->");
        for(Player* current = HeadPtr; current != NULL; current=current->GetNextPlayer())
        {
            printf("%d", current->GetID());
            if(TailPtr == current)
			{
                printf("(T)");
            }
            printf("->");
		}
        printf("NULL\n");
    }

Room.h
#pragma once
#include "PlayerList.h"

class Room
{
private:
	// Member Variables
	int NextPlayerID;
	int Number;
	PlayerList* Players;

public:
	// Constructors & Destructor
	Room();
	Room(int num);
	~Room();

	// Public Functions
	void AddPlayer(Player* player);	
	void ClearPlayers();
	int GetNextPlayerID();
	int GetNumber();
	PlayerList* GetPlayerList();
	void InsertPlayer(Player* player, int position);
	void RemovePlayer(Player* player);
	void ReplacePlayer(Player* oldPlayer, Player* newPlayer);
	void SetNextPlayerID(int id);
	void SetNumber(int num);
	void SortAscending();
	void SortDescending();
};

ROOM.cpp
#include "Room.h"

Room::Room()
{
	Number = -1;
	NextPlayerID = 1;

	Players = new PlayerList();
}

Room::Room(int num)
{
	Number = num;
	NextPlayerID = 1;

	Players = new PlayerList();
}

Room::~Room()
{
	delete Players;
}

void Room::AddPlayer(Player* player)
{
	Players->Add(player);
	NextPlayerID++;
}

void Room::ClearPlayers()
{
	Players->Clear();
}

int Room::GetNextPlayerID()
{
	return NextPlayerID;
}

int Room::GetNumber()
{
	return Number;
}

PlayerList* Room::GetPlayerList()
{
	return Players;
}

void Room::InsertPlayer(Player* player, int position)
{
	Players->Insert(player, position);
	NextPlayerID++;
}

void Room::RemovePlayer(Player* player)
{
	Players->Remove(player);
}

void Room::ReplacePlayer(Player* oldPlayer, Player* newPlayer)
{
	int index = Players->IndexOf(oldPlayer);
	if (index >= 0)
	{
		Players->RemoveAt(index);
		Players->Insert(newPlayer, index);
	}
	NextPlayerID++;
}

void Room::SetNextPlayerID(int id)
{
	NextPlayerID = id;
}

void Room::SetNumber(int num)
{
	Number = num;
}

void Room::SortAscending()
{
	Players->Sort(0);
}

void Room::SortDescending()
{
	Players->Sort(1);
}

project1.cpp
#include "Game.h"

int main()
{
	Game* game = new Game();
	game->Run();
	//delete game;
	return 0;
}


Thanks for all the help and am here to answer questions

This post has been edited by sublimeaces: 25 February 2016 - 04:21 PM


Is This A Good Question/Topic? 0
  • +

Replies To: linked lists runtime error

#2 baavgai   User is offline

  • Dreaming Coder
  • member icon


Reputation: 7181
  • View blog
  • Posts: 14,969
  • Joined: 16-October 07

Re: linked lists runtime error

Posted 25 February 2016 - 06:29 PM

Just a quick glance shows this:
PlayerList::PlayerList() {
    int Count = 0;
    Player* HeadPtr = NULL;
    Player* TailPtr = NULL;
}



Your constructor isn't really doing anything. You're creating variables that are never used. I suspect you want something more like:
PlayerList::PlayerList() : Count(0), HeadPtr(NULL), TailPtr(NULL) { }



Curiously, you do this correctly in one of your Player constructors, but in the empty one you repeat the same error.

I'm dubious of your design in general. You seem to be passing about a lot of pointers. Additionally, you allow a player object to exist in multiple room objects, which just doesn't seem like a good idea. Rather, it would seem a player would want to belong to a single room; so player references room, not the other way around.

In PlayerList you seem to want to manage your own linked list. Why not an std::vector? Indeed, while it's good to understand how to implement abstract data types, reinventing the wheel isn't generally a good idea.

The proper case names for member vars is confusing to anyone familiar with C++ conventions.

Hope this helps.
Was This Post Helpful? 1
  • +
  • -

#3 sublimeaces   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 93
  • Joined: 13-April 14

Re: linked lists runtime error

Posted 26 February 2016 - 04:08 AM

I fixed the other constructors, thanks for pointing that out. and i'm not to sure what you mean about the player and room because i was just following directions on that one.

View Postbaavgai, on 25 February 2016 - 06:29 PM, said:

You seem to be passing about a lot of pointers.



In PlayerList you seem to want to manage your own linked list. Why not an std::vector?

The purpose of this program was to use pointers in linked lists. its for a data structures class

Quote

The proper case names for member vars is confusing to anyone familiar with C++ conventions.

Yeah, i really only know java and the instructor wrote game and the .h files and we were supposed to work off of that i didn't name these variables. But i feel like after struggling with this i'm at least a little fluent in c++ kinda a crash course i guess.

WOAH after making those changes i actually get some stuff to print out .. wish i would have caught that earlier! lmao

This post has been edited by sublimeaces: 26 February 2016 - 04:07 AM

Was This Post Helpful? 0
  • +
  • -

#4 baavgai   User is offline

  • Dreaming Coder
  • member icon


Reputation: 7181
  • View blog
  • Posts: 14,969
  • Joined: 16-October 07

Re: linked lists runtime error

Posted 26 February 2016 - 04:46 AM

View Postsublimeaces, on 26 February 2016 - 06:08 AM, said:

The purpose of this program was to use pointers in linked lists. its for a data structures class


Fair enough. But that doesn't mean exposing all the pointers. Encapsulation, one of your OOP principles, is about only revealing instance details that you have to. You should be able to use a linked list without knowing anything about how the list is implemented. It could be singly linked, doubly linked, circular, a tree, whatever. The A of ADT is abstract. That means, you do it properly but don't need to bother me with how you did it exactly.

For what you have, I would have done something like:
class Player {
private:
    // Member Variables
    int id, level;
    // no, this is a data type
    // it shouldn't deal with list details
    // Player* NextPlayer;

public:
    Player();
    Player(int id, int level);

    // Getters
    // not the const, this action doesn't change the object
    int getID() const; 
    int getLevel() const;
    // no
    // Player* GetNextPlayer();

    // Setters
    // should ID ever be changed?  probably not
    // void SetID(int id);
    void setLevel(int level);
};

class PlayerList {
public:
    // Public Static Constants
    // these should really be part of an enum
    static const int ASCENDING = 0;
    static const int DESCENDING = 1;

    // Constructor
    PlayerList();

    // Public Functions
    //void Add(Player* player);
    // remember, data
    void add(const Player &);
    void clear();
    Player &elementAt(int position);
    int getCount() const;
    // no, this is an implementation detail
    // not to be shared
    // Player* GetHead();
    int indexOf(const Player &) const;
    void insert(const Player &, int position);
    // no
    // Player* Next(Player* player);
    void remove(const Player &);
    void removeAt(int position);
    // again, enum would be better
    // though considering it's a boolean choice, bool?
    void sort(int order);
private:
    // the user of your class shouldn't be messing with nodes
    // make one here
    struct Node {
        Player player;
        Node *next;
        Node(const Player &p, Node *n) : player(p), next(n) { }
    };
    // no, this can be worried out from your data
    // int Count;
    Player *head, *tail;
    // wtf
    // void SwapPlayers(Player* previous, Player* player1, Player* player2);
    // why would this be private?
    // void PrintList();

};



Don't know if that helps, but it made me feel better. ;)
Was This Post Helpful? 0
  • +
  • -

#5 sublimeaces   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 93
  • Joined: 13-April 14

Re: linked lists runtime error

Posted 26 February 2016 - 10:23 AM

OK, Now i am seriously confused WHY did it work when i changed it to

Room::Room():Number(-1),NextPlayerID(1)
{
	Players = new PlayerList();
}

Room::Room(int num) :Number(num), NextPlayerID(1)
{
	Players = new PlayerList();
}



    Player::Player():ID(0),Level(0)
        {
        } // end Defualt const
    
    Player::Player(int ID, int Level) : ID(ID), Level(Level)
        {
        } // end non default const



isn't that just change in syntax and not logic?????? or is there something i am missing..also i just want to debug what i have minus a whole restructure of the program although mine does look dirty hah

This post has been edited by sublimeaces: 26 February 2016 - 10:34 AM

Was This Post Helpful? 0
  • +
  • -

#6 baavgai   User is offline

  • Dreaming Coder
  • member icon


Reputation: 7181
  • View blog
  • Posts: 14,969
  • Joined: 16-October 07

Re: linked lists runtime error

Posted 26 February 2016 - 12:16 PM

View Postsublimeaces, on 26 February 2016 - 12:23 PM, said:

i just want to debug what i have minus a whole restructure


Indeed. Well, I don't. Messy programs make for debug hell.

I can tell your that your PlayerList is not building properly and that you don't get to see how bad it is until you go to remove a node:
StuffCpp.exe!Player::GetID() Line 316	C++
>	StuffCpp.exe!PlayerList::Remove(Player * player) Line 465	C++
StuffCpp.exe!Room::RemovePlayer(Player * player) Line 629	C++
StuffCpp.exe!Game::Run() Line 220	C++
StuffCpp.exe!main() Line 141	C++



This is the program of yours I ran. I put it all in one file, as life is too short to screw with all those files for something so messy. Here's what I tested against.
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <cstdio>
#include <sstream>
#include <cstring>


using namespace std;

class Player {
private:
    // Member Variables
    int ID;
    int Level;
    Player* NextPlayer;

public:
    // Constructors
    Player();
    Player(int id, int level);

    // Getters
    int GetID();
    int GetLevel();
    Player *GetNextPlayer();

    // Setters
    void SetID(int id);
    void SetLevel(int level);
    void SetNextPlayer(Player *);
};

class PlayerList {
public:
    // Public Static Constants
    static const int ASCENDING = 0;
    static const int DESCENDING = 1;


private:
    // Member Variables
    int Count;
    Player* HeadPtr;
    Player* TailPtr;

    void SwapPlayers(Player* previous, Player* player1, Player* player2);
    void PrintList();

public:
    // Constructor
    PlayerList();

    // Public Functions
    void Add(Player* player);
    void Clear();
    Player* ElementAt(int position);
    int GetCount();
    Player* GetHead();
    int IndexOf(Player* player);
    void Insert(Player* player, int position);
    Player* Next(Player* player);
    void Remove(Player* player);
    void RemoveAt(int position);
    void Sort(int order);

};


class Room {
private:
    // Member Variables
    int NextPlayerID;
    int Number;
    PlayerList *Players;

public:
    // Constructors & Destructor
    Room();
    Room(int num);
    ~Room();

    // Public Functions
    void AddPlayer(Player* player);
    void ClearPlayers();
    int GetNextPlayerID();
    int GetNumber();
    PlayerList *GetPlayerList();
    void InsertPlayer(Player* player, int position);
    void RemovePlayer(Player* player);
    void ReplacePlayer(Player* oldPlayer, Player* newPlayer);
    void SetNextPlayerID(int id);
    void SetNumber(int num);
    void SortAscending();
    void SortDescending();
};


class Game {
private:
    // Static Constants
    static const int MIN_PLAYER_LEVEL = 1;
    static const int MAX_PLAYER_LEVEL = 80;
    static const int NUMBER_OF_ROOMS = 5;

    // Action Type enum
    enum ActionType { Add, Insert, Remove, Replace, Sort, Count };

    // Member Variables
    Room *Rooms[NUMBER_OF_ROOMS];

public:
    // Constructor & Destructor
    Game();
    ~Game();

    // Public Functions
    void Run();

    // Private Functions
private:
    Player* GetRandomPlayer(Room* room);
    int GetRandomPlayerLevel();
    int GetRandomRoomPosition(Room* room, bool includingLastPostion);
    void PrintRoom(Room* room);
};







int main() {
    srand((unsigned int)time(NULL));
    // Game* game = new Game();
    // game->Run();
    //delete game;
    Game game;
    game.Run();
    return 0;
}



Game::Game() {
    for (int i = 0; i < NUMBER_OF_ROOMS; i++) {
        Rooms[i] = new Room(i + 1);
    }
}

Game::~Game() {
    // Delete Rooms & Players
    for (int i = 0; i < NUMBER_OF_ROOMS; i++) {
        Rooms[i]->ClearPlayers();
        delete Rooms[i];
    }
}

void Game::Run() {
    cout << "Welcome to the Game Server Simulator\n";
    cout << "Press any key to begin.\n\n";
    char input;
    // input = cin.get();
    input = 'e'; // Set to something besides 'q' to enter main loop

    // Seed Random Number Generator
    //srand((unsigned int)time(NULL));

    // // Create Rooms
    // Room* rooms[NUMBER_OF_ROOMS];
    // for (int i = 0; i < NUMBER_OF_ROOMS; i++)
    // 	rooms[i] = new Room(i + 1);

    ActionType action;
    bool forceAddAPlayer = true;
    int id = -1;

    // Main Game Loop
    while (input != 'q') {
        // Get random room number
        int roomNumber = rand() % NUMBER_OF_ROOMS;

        // Get random action
        if (forceAddAPlayer) {// Force the program to add players when it first starts to populate rooms with some data
            if (id >= 15)
                forceAddAPlayer = false;
            int r = rand() % 2;
            if (r == 0)
                action = Add;
            else
                action = Insert;
        } else
            action = static_cast<ActionType>(rand() % Count);

        // Do something based on that action
        Player* newPlayer;
        Player* oldPlayer;
        int position;
        switch (action) {
        case Add:
            newPlayer = new Player(Rooms[roomNumber]->GetNextPlayerID(), GetRandomPlayerLevel()); // Creates a new player
            id = Rooms[roomNumber]->GetNextPlayerID();
            cout << "Adding Player " << newPlayer->GetID() << " to room " << Rooms[roomNumber]->GetNumber() << endl;
            Rooms[roomNumber]->AddPlayer(newPlayer); // Add player to room
            break;
        case Insert:
            newPlayer = new Player(Rooms[roomNumber]->GetNextPlayerID(), GetRandomPlayerLevel()); // Creates a new player
            id = Rooms[roomNumber]->GetNextPlayerID();
            position = GetRandomRoomPosition(Rooms[roomNumber], true);
            cout << "Inserting Player " << newPlayer->GetID() << " at position " << position << " in room " << Rooms[roomNumber]->GetNumber() << endl;
            Rooms[roomNumber]->InsertPlayer(newPlayer, position); // Insert player in room
            break;
        case Remove:
            oldPlayer = GetRandomPlayer(Rooms[roomNumber]); // Retrieves existing player in this room
            if (oldPlayer != NULL) {
                cout << "Removing Player " << oldPlayer->GetID() << " from room " << Rooms[roomNumber]->GetNumber() << endl;
                Rooms[roomNumber]->RemovePlayer(oldPlayer); // Remove player
            }
            break;
        case Replace:
            oldPlayer = GetRandomPlayer(Rooms[roomNumber]); // Retrieves existing player in this room
            if (oldPlayer != NULL) {
                newPlayer = new Player(Rooms[roomNumber]->GetNextPlayerID(), GetRandomPlayerLevel()); // Creates a new player
                id = Rooms[roomNumber]->GetNextPlayerID();
                cout << "Replacing Player " << oldPlayer->GetID() << " with Player " << newPlayer->GetID() << " in room " << Rooms[roomNumber]->GetNumber() << endl;
                Rooms[roomNumber]->ReplacePlayer(oldPlayer, newPlayer); // Replace a player with a new player
            }
            break;
        case Sort:
            int order = rand() % 2;
            if (order == 0) {
                cout << "Sorting room " << Rooms[roomNumber]->GetNumber() << " in ascending order.\n";
                Rooms[roomNumber]->SortAscending(); // Sort Ascending
            } else {
                cout << "Sorting room " << Rooms[roomNumber]->GetNumber() << " in descending order.\n";
                Rooms[roomNumber]->SortDescending(); // Sort Descending
            }
            break;
        }

        // Update Rooms with latest ID
        if (id != -1) {
            for (int i = 0; i < NUMBER_OF_ROOMS; i++)
                Rooms[i]->SetNextPlayerID(id + 1); // Add 1 to id to make sure every player has a unique ID
        }

        // Print Room Data
        bool printedSomething = false;
        for (int i = 0; i < NUMBER_OF_ROOMS; i++) {
            PrintRoom(Rooms[i]);
            printedSomething = true;
        }
        if (!printedSomething) {
            cout << "There are currently no players in any rooms.\n";
            forceAddAPlayer = true;
        }

        // Receive User Input
        cout << "\t\tPress any key to continue or 'q' to quit.\n" << endl;
        input = cin.get();
    }

    cout << "Thank you for playing!\n";
    system("pause");
}

Player* Game::GetRandomPlayer(Room* room) {
    int position = GetRandomRoomPosition(room, false);
    PlayerList* players = room->GetPlayerList();
    return players->ElementAt(position);
}

int Game::GetRandomPlayerLevel() {
    int level = rand() % MAX_PLAYER_LEVEL;
    level += MIN_PLAYER_LEVEL;
    return level;
}

int Game::GetRandomRoomPosition(Room* room, bool includingLastPosition) {
    PlayerList* players = room->GetPlayerList();
    int count = players->GetCount();
    if (count <= 0)
        return 0;
    else if (includingLastPosition && count == 1)
        return rand() % 2;
    else if (!includingLastPosition && count == 1)
        return 0;
    else if (!includingLastPosition && count > 1)
        return rand() % (count + 1);
    else
        return rand() % count;
}

void Game::PrintRoom(Room* room) {
    PlayerList* players = room->GetPlayerList();
    if (players->GetCount() > 0) {
        cout << "Room: " << room->GetNumber() << endl;
        Player* player = players->GetHead();
        while (player != NULL) {
            cout << "\tPlayer: " << player->GetID() << ", Level " << player->GetLevel() << endl;
            player = players->Next(player);
        }
    }
}


Player::Player() : Player(0, 0) { }

Player::Player(int id, int level) : ID(id), Level(level) {
} // end non default const


  //       GETS     // 
int Player::GetID() {
    return ID;
}//end get id

int Player::GetLevel() {
    return Level;
}//end get level

Player* Player::GetNextPlayer() {
    return NextPlayer;
}

//      SETS        // 


void Player::SetID(int ID) {
    this->ID = ID;
}

void Player::SetLevel(int Level) {
    this->Level = Level;
}

void Player::SetNextPlayer(Player* NextPlayer) {
    this->NextPlayer = NextPlayer;
}


PlayerList::PlayerList() : Count(0), HeadPtr(NULL), TailPtr(NULL) {
    /*
    int Count = 0;
    Player* HeadPtr = NULL;
    Player* TailPtr = NULL;
    */
}//end default constructor


void PlayerList::Add(Player* player) {

    PrintList();
    if (player == NULL) {
        return;
    }
    if (HeadPtr == NULL) {
        HeadPtr = player;
    } else {
        TailPtr->SetNextPlayer(player);
    }
    TailPtr = player;
    TailPtr->SetNextPlayer(NULL);
    Count++;
    PrintList();
}

void PlayerList::Clear() {
    Player * current = HeadPtr;

    while (current != NULL) {
        Player * next = current->GetNextPlayer();
        delete current;
        current = next;
    }

    Count = 0;
    HeadPtr = NULL;
    TailPtr = NULL;
    PrintList();
}

Player* PlayerList::ElementAt(int position) {
    if (position >= Count) {
        return NULL;
    }

    Player * current = HeadPtr;
    for (int i = 0; i < position; i++) {
        current = current->GetNextPlayer();
    }

    return current;
}

int PlayerList::GetCount() {
    return Count;
}

Player* PlayerList::GetHead() {
    return HeadPtr;
}

int PlayerList::IndexOf(Player* player) {
    if (player == NULL) {
        return -1;
    }

    int index = 0;
    for (Player * current = HeadPtr; current != NULL; current = current->GetNextPlayer()) {
        if (current->GetID() == player->GetID()) {
            return index;
        }
        index++;
    }
    return -1;
}

void PlayerList::Insert(Player* player, int position) {
    PrintList();
    if (player == NULL) {
        return;
    }
    if (position == 0) {
        if (Count == 0) {
            TailPtr = player;
        }
        player->SetNextPlayer(HeadPtr);
        HeadPtr = player;
    } else {
        Player * found = ElementAt(position - 1);
        if (found == NULL) {
            return;
        }
        Player * next = found->GetNextPlayer();
        player->SetNextPlayer(next);
        found->SetNextPlayer(player);
        if (TailPtr == found) {
            TailPtr = player;
        }
    }
    Count++;
    PrintList();
}

Player* PlayerList::Next(Player* player) {

    if (player == NULL) {
        return NULL;
    }

    for (Player * current = HeadPtr; current != NULL; current = current->GetNextPlayer()) {
        if (current->GetID() == player->GetID()) {
            return current->GetNextPlayer();
        }
    }
    return NULL;

}

void PlayerList::Remove(Player* player) {
    Player * previous = NULL;
    for (Player * current = HeadPtr; current != NULL; current = current->GetNextPlayer()) {
        if (current->GetID() == player->GetID()) {
            if (previous != NULL) {
                previous->SetNextPlayer(current->GetNextPlayer());
            }
            if (current == HeadPtr) {
                HeadPtr = current->GetNextPlayer();
            }
            delete current;
        }
        previous = current;
    }
    Count--;
    PrintList();
}

void PlayerList::RemoveAt(int position) {
    Player * toDelete = NULL;
    if (position == 0 && HeadPtr != NULL) {
        toDelete = HeadPtr;
        HeadPtr = HeadPtr->GetNextPlayer();
    } else {
        Player * found = ElementAt(position - 1);
        if (found == NULL) {
            return;
        }
        toDelete = found->GetNextPlayer();
        found->SetNextPlayer(toDelete->GetNextPlayer());
        if (TailPtr == toDelete) {
            TailPtr = found;
        }
    }
    if (toDelete) {
        delete toDelete;
    }
    Count--;
    PrintList();
}

void PlayerList::Sort(int order) {
    Player* previous = NULL;
    Player* current = HeadPtr;
    Player* next = NULL;
    Player* sorted = NULL;

    if (current == NULL) {
        return;
    }

    next = current->GetNextPlayer();

    if (next == NULL) {
        return;
    }

    while (sorted != HeadPtr->GetNextPlayer()) {
        PrintList();
        printf("Comparing %d with %d\n", current->GetID(), next->GetID());
        std::cin.get();
        if (order == 0 && current->GetID() > next->GetID()) 	// ascending
        {
            SwapPlayers(previous, current, next);
            Player * tmp = next;
            next = current;
            current = tmp;
        } else if (order == 1 && current->GetID() < next->GetID())  //descending
        {
            SwapPlayers(previous, current, next);
            Player * tmp = next;
            next = current;
            current = tmp;
        }

        previous = current;
        current = current->GetNextPlayer();
        next = next->GetNextPlayer();

        if (next == sorted) {
            sorted = current;
            current = HeadPtr;
            next = current->GetNextPlayer();
            previous = NULL;
        }

    }
}

void PlayerList::SwapPlayers(Player* previous, Player* player1, Player* player2) {
    if (player1 == NULL || player2 == NULL) {
        return;
    }
    printf("Swapping %d with %d\n", player1->GetID(), player2->GetID());
    std::cin.get();
    player1->SetNextPlayer(player2->GetNextPlayer());
    player2->SetNextPlayer(player1);
    if (previous) {
        previous->SetNextPlayer(player2);
    }
    if (player1 == HeadPtr) {
        HeadPtr = player2;
    }
    if (player2 == TailPtr) {
        TailPtr = player1;
    }
    previous = player2;
}

void PlayerList::PrintList() {
    printf("HEAD->");
    for (Player* current = HeadPtr; current != NULL; current = current->GetNextPlayer()) {
        printf("%d", current->GetID());
        if (TailPtr == current) {
            printf("(T)");
        }
        printf("->");
    }
    printf("NULL\n");
}

Room::Room() {
    Number = -1;
    NextPlayerID = 1;

    Players = new PlayerList();
}

Room::Room(int num) {
    Number = num;
    NextPlayerID = 1;

    Players = new PlayerList();
}

Room::~Room() {
    delete Players;
}

void Room::AddPlayer(Player* player) {
    Players->Add(player);
    NextPlayerID++;
}

void Room::ClearPlayers() {
    Players->Clear();
}

int Room::GetNextPlayerID() {
    return NextPlayerID;
}

int Room::GetNumber() {
    return Number;
}

PlayerList* Room::GetPlayerList() {
    return Players;
}

void Room::InsertPlayer(Player* player, int position) {
    Players->Insert(player, position);
    NextPlayerID++;
}

void Room::RemovePlayer(Player* player) {
    Players->Remove(player);
}

void Room::ReplacePlayer(Player* oldPlayer, Player* newPlayer) {
    int index = Players->IndexOf(oldPlayer);
    if (index >= 0) {
        Players->RemoveAt(index);
        Players->Insert(newPlayer, index);
    }
    NextPlayerID++;
}

void Room::SetNextPlayerID(int id) {
    NextPlayerID = id;
}

void Room::SetNumber(int num) {
    Number = num;
}

void Room::SortAscending() {
    Players->Sort(0);
}

void Room::SortDescending() {
    Players->Sort(1);
}



Good luck.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1