简体   繁体   中英

Comparing of the 2 lists of different objects but with a same fields

I have a

class Player 
{
    public Vector3 position;
     public String name;
}

and a

class Field
{
    public Vector3 position;
    public bool isTarget;
}

I have a game with 3 players, 10 fields and 3 target fields. For winning, user should place all players on target fields. Is there a nice way for comparing 2 different objects lists (List< Player> and List< Field>) but with the same fields (positions) ?

Or should i inherit both Player and Field from

class BaseItem
{
    public Vector3 position;
}

class Player : BaseItem 
{
    public String name;
}

and compare List<BaseItem> ?

EDIT: just to add some clarify: i have a List< Player> and List< Field> and i want to check if all of Players has the same position as all isTarget Fields. Order doesn't matter.

var listPlayer = new List<Player>();
listPlayer.Add(new Player { position = new Vector3(1,0,0); name = "a"; }
listPlayer.Add(new Player { position = new Vector3(0,1,0); name = "b"; }
listPlayer.Add(new Player { position = new Vector3(0,0,1); name = "c"; }

var listFields = new List<Field>();
listFields.Add(new Field { position = new Vector3(1,0,0);  isTarget = true;}
listFields.Add(new Field { position = new Vector3(0,1,0);  isTarget = true;}
listFields.Add(new Field { position = new Vector3(0,0,1);  isTarget = true;}
listFields.Add(new Field { position = new Vector3(1,1,0);  }
listFields.Add(new Field { position = new Vector3(1,0,1);  }
****

how can i run through all players and fields and see, if every player has a corresponding field (it should have equal position and isTarget should be true)?


SOLUTION: i'd like to keep Aybe's answer as solution, but i had finished algorytm so i'd like to share it in case it would be useful:

private void CheckIfWin()
{
    foreach (var target in gameboardTargets)        
        if (!IsAnyPlayerOnTarget(target))
            return;

    MessageBox.Show(HandleMessage,"You made it!", "Hooray!", MessageBoxButtons.OK);
}


private bool IsAnyPlayerOnTarget(Field target)
{
    foreach (var player in playersList)         
        if (target.GridPosition.Equals(player.GridPosition)) // can be replaced with BaseItem.ComparePosition()
            return true;

    return false;
}

Not sure whether comparing two different things is the right approach.

You can however make these two things derive from a base class:

internal class BoardEntity {
    public Vector3 Position { get; set; }
}

internal class Player : BoardEntity {
    public string Name { get; set; }
}

internal class Field : BoardEntity {
    public bool IsTarget { get; set; }
}

Now there are other things emerging:

  • you'll have to cast them to base class every time which can get boring with time
  • it is strange to compare two different things even if they do share the same property
  • comparing floats is discouraged since the result can (will) be wrong

Code:

internal class BoardEntity {
    public Vector3 Position { get; set; }

    protected bool Equals(BoardEntity other) {
        return Position.Equals(other.Position);
    }

    public override bool Equals(object obj) {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        var other = obj as BoardEntity;
        return other != null && Equals(other);
    }

    public override int GetHashCode() {
        return Position.GetHashCode();
    }
}

internal class MyClass {
    public MyClass() {
        var player = new Player();
        var field = new Field();

        BoardEntity boardEntity1 = player;
        BoardEntity boardEntity2 = field;
        bool b = boardEntity1.Equals(boardEntity2);
    }
}

Suggestion:

Providing a ComparePosition() method sounds more natural IMO, and since we cast to integers the comparison will be always correct.

internal class BoardEntity {
    public Vector3 Position { get; set; }

    public bool ComparePosition(BoardEntity boardEntity) {
        var v1 = new Vector3(boardEntity.Position.X, boardEntity.Position.Y, boardEntity.Position.Z);
        var v2 = new Vector3(Position.X, Position.Y, Position.Z);
        return v1.Equals(v2);
    }
}

internal class MyClass {
    public MyClass() {
        var player = new Player();
        var field = new Field();

        bool comparePosition = player.ComparePosition(field);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM