jarrhead13
jarrhead13

Reputation: 11

Creating Multiple Instances of a class and distinguishing between them

I'm working on a project that creates a class with a few pieces of information. For example

public Player(string Playername, int PlayerRating)
        {
            name = Playername;
            rating = PlayerRating;
        }

My question is how can I create a way to distinguish between multiple Instances of the Player class to updating Rating. I tried some kind of ID number to select the correct class. I thought maybe I could make an array of ID pointers and have each point to a different player.

edit: changed from Copies to Instances. edit: For clarification on what the programs function is. The idea is to have a large group a "Players" and have them play a matches outside of this project. Then after the match is over I come back to this and update the ratings of the players.

Upvotes: 0

Views: 9775

Answers (4)

DSander
DSander

Reputation: 1124

What you are probably looking for is a Dictionary. A dictionary can have a key and a value. No two keys can be the same. The key and value can be an integer, string, or any object (class) you want. Is your PlayerName unique? If so, you can use the PlayerName as the key when adding to the dictionary. Otherwise, you can generate a Guid and use that. Something like this:

// Keep a dictionary of all players
Dictionary<string, Player> PlayerDict = new Dictionary<string, Player>();

public void addNewPlayer(string newPlayerName)
{
    // create new player with rating of 0
    Player newPlayer = new Player(newPlayerName, 0);
    // check if the player already exists in dictionary
    if (!PlayerDict.ContainsKey(newPlayer.name))
    {
        // player doesn't exist / add player
        PlayerDict.Add(newPlayer.name, newPlayer);
    }
}

public void changePlayerRating(String name, int newRating)
{
    // check if player exists in dictionary
    if (PlayerDict.ContainsKey(name))
    {
        // player exists - change player rating
        PlayerDict[name].rating = newRating;
    }
    else
    {
        // player doesnt exist - add the player
        addNewPlayer(name);
    }
}

public class Player
{
    public string name { get; }
    public int rating { get; set; }

    public Player(string Playername, int PlayerRating)
    {
        name = Playername;
        rating = PlayerRating;
    }
}

Then you can just do this:

addNewPlayer("John");
changePlayerRating("John", 1000);

Or increment the rating like this:

PlayerDict["John"].rating += 10

Upvotes: 6

Bradley Uffner
Bradley Uffner

Reputation: 16991

Based on discussion in comments you probably want something more like this than my other answer. LoadPlayersFromDisk and SavePlayersToDisk would have to be added on your own. Showing you how to do that here is really beyond the scope of this question. Feel free to create a new question (after doing some research) about it though, once you get to that point.

This doesn't cover how to handle what happens when you use the name of a Player that isn't in the Dictionary, or how to add new Players either, but it should give you a good start. Donald Sander's answer shows some good ways to handle both those situations.

Player.cs:

public class Player
{
    public string Name { get; set;}
    public int Rank{get;set;
}

Main.cs:

var players = new Dictionary<string, Player>();

LoadPlayersFromDisk();

var winnerName = Console.ReadLine("Enter the name of the winner:");
var winner = players[winnerName];
winner.Rank++;
Console.WriteLine($"{winner.Name}'s rank has increased to {winner.Rank}")

SavePlayersToDisk();

Upvotes: 1

Bradley Uffner
Bradley Uffner

Reputation: 16991

It looks like your Player class already has a way to distinguish between players, namely, the Name property. There are many ways you could do this, but here is just one example.

If you have a List<Player> called Players, you can find the Player names "John" like this:

var player = Players.Where(p => p.Name == "John").First();

After that line, player will contain the first Player instance with the Name of "John".

Another options is to use a Dictionary<string, Player>, which would work like var player = Players["John"].

Both of these methods rely on Name being unique, no 2 players could have the same name.


After thinking on your question more, you might just be confused about how to track the players within a single game. This is usually covered pretty early in computer classes, so forgive me if you already know this.

This is the concept of "references". We deal with 3 things in the area as programmers, variables, instances, and references. var player defines a variable. new Player() creates a new instance of Player, and return a reference to it. You can place that reference in to a variable by combining those 2 statements with var player = new Player(). The player variable now holds a reference to an instance of Player.

If we were talking about houses, the class would be the blueprint. Only one of them would ever exist at a time, and it defines how to build a house. An instance is what is created whenever someone uses the blueprint to build a house. You could have 10 separate houses, all built from the same blueprint. Each of these houses would be distinct houses, but have the exact same physical features.

In a game, you could have multiple players, they could be stored in a List<Player>, and your game could keep a currentPlayer variable around that contains an int with the index of who's turn it is.

As a quick example, this is an easy game loop (without the actual logic for a turn). Most likely you would also want to persist the Player instances to something more permanent, like a database. The same basic loop could be used for any number of players, and it will move through each one, turn by turn.

bool gameOver = false;
var players = new List<Player>();
players.Add(new Player("John"));
players.Add(new Player("Bob"));
int currentPlayerIndex = 0;
Player winner = null;

while(!gameOver)
{
    var currentPlayer = players[currentPlayerIndex];

    //Do a player's turn here, "currentPlayer" will be whoever's turn it is.
    //set won to true if the current player won the game.

    if(won)
    {
       currentPlayer.Rating++;
       gameOver = true;
    }

    currentPlayerIndex++;
    if(currentPlayerIndex >= players.Count)
    {
        currentPlayerIndex = 0;
    }
}

Upvotes: 0

svick
svick

Reputation: 244757

the best way I can describe it is if I make a Player (Bob, 1000) play a chess match vs Player (Joe,1200). i have two copies of the Player class and after the match i would want to change the values of the players rating. My problem is I'm not sure how I can Select Bobs Player Class and set his rating to a new value and then do the same for Joe.

I'm not sure I understand the question correctly, but since each player is in a separate variable, you should be able to just update the rating using those variables.

In code, it could look something like:

class Player
{
    public string Name { get; }
    public int Rating { get; set; }

    public Player(string name, int rating)
    {
        Name = name;
        Rating = rating;
    }
}

static class Game
{
    static void Play(Player player1, Player player2)
    {
        // code to play the game here, also sets player1NewRating and player2NewRating

        player1.Rating = player1NewRating;
        player2.Rating = player2NewRating;
    }

    static void Main()
    {
        var bob = new Player("Bob", 1000);
        var joe = new Player("Joe", 1200);

        Play(bob, joe);
    }
}

Upvotes: 0

Related Questions