Never depend on the order of items FindGameObjectsWithTag returns as this is not specified in the documentation and can be unpredictable. You have to add a custom function that loops through the array and finds your specified GameObject by comparing with the GameObject.name property.
GameObject[] players;
void test()
{
players = GameObject.FindGameObjectsWithTag("Player");
foreach (GameObject go in players)
{
Debug.Log("Player " + go + " is named " + go.name);
}
}
GameObject getGameObject(string gameObjectName)
{
for (int i = 0; i < players.Length; i++)
{
//Return GameObject if the name Matches
if (players[i].name == gameObjectName)
{
return players[i];
}
}
Debug.Log("No GameObject with the name \"" + gameObjectName + "\" found in the array");
//No Match found, return null
return null;
}
Usage:
GameObject card1 = getGameObject("card1");
GameObject card2 = getGameObject("card2");
GameObject card3 = getGameObject("card3");
GameObject card4 = getGameObject("card4");
EDIT:
If your goal is to sort the items in the array, in order, then this should do it:
players = GameObject.FindGameObjectsWithTag("Player");
players = players.OrderBy(c => c.name).ToArray();