package net.sf.colossus.client;
import java.util.List;
import net.sf.colossus.game.Game;
import net.sf.colossus.game.Legion;
import net.sf.colossus.game.Player;
import net.sf.colossus.game.PlayerColor;
import net.sf.colossus.server.CustomRecruitBase;
import net.sf.colossus.util.InstanceTracker;
import net.sf.colossus.util.Split;
import net.sf.colossus.variant.CreatureType;
/**
* This class holds client-side version of a player.
*
* @author David Ripton
*/
public final class PlayerClientSide extends Player
{
private PredictSplits predictSplits;
/**
* Two-stage initialization at the moment, only some data here, the rest comes
* through {@link #update(String)}.
*
* TODO: the object should be properly initialized in the constructor
*/
PlayerClientSide(Game game, String playerName, int number)
{
super(game, playerName, number);
CustomRecruitBase.addPlayerClientSide(this);
InstanceTracker.register(this, playerName);
}
@SuppressWarnings("unchecked")
@Override
public List<LegionClientSide> getLegions()
{
return (List<LegionClientSide>)super.getLegions();
}
/** Takes a colon-separated string of form
* dead:name:tower:color:elim:legions:markers:creatures:value:titan:score
*
* TODO this is part of the network protocol and should be somewhere in there
*/
void update(String infoString)
{
List<String> data = Split.split(":", infoString);
String buf;
buf = data.remove(0);
setDead(Boolean.parseBoolean(buf));
setName(data.remove(0));
// TODO This is a workaround - fix better, init variant at proper
// time somehow proper way?
try
{
String towerHex = data.remove(0);
setStartingTower(getGame().getVariant().getMasterBoard()
.getHexByLabel(towerHex));
}
catch (NullPointerException e)
{
// When loading a game in remote client, in beginning variant is
// not loaded yes, so that may cause NPE which we ignore here.
// After syncOptions variant name is known,
// and in initBoard it is loaded, so all future updates go fine.
}
setColor(PlayerColor.getByName(data.remove(0)));
setType(data.remove(0));
setPlayersElim(data.remove(0));
buf = data.remove(0); // numLegions -- we can calculate that later
buf = data.remove(0); // numCreatures -- we can calculate that later
buf = data.remove(0);
int titanPower = Integer.parseInt(buf);
buf = data.remove(0);
setScore(Integer.parseInt(buf));
assert titanPower == getTitanPower() : "Titan strength inconsistent between client and server";
buf = data.remove(0);
setMulligansLeft(Integer.parseInt(buf));
clearMarkersAvailable();
for (String markerId : data)
{
addMarkerAvailable(markerId);
}
}
public void updateValues(boolean isDead, String eliminatedPlayers,
int score, int mulligansLeft, String freeMarkers)
{
setDead(isDead);
setPlayersElim(eliminatedPlayers);
setScore(score);
setMulligansLeft(mulligansLeft);
clearMarkersAvailable();
List<String> markerIds = Split.split(",", freeMarkers);
if (!freeMarkers.equals(""))
{
for (String markerId : markerIds)
{
addMarkerAvailable(markerId);
}
}
}
public PredictSplits getPredictSplits()
{
return predictSplits;
}
public void initPredictSplits(Legion rootLegion,
List<CreatureType> creatures)
{
this.predictSplits = new PredictSplits(rootLegion.getMarkerId(),
creatures, getGame().getVariant());
}
@Override
public LegionClientSide getLegionByMarkerId(String markerId)
{
return (LegionClientSide)super.getLegionByMarkerId(markerId);
}
}