- Added support for finding and marking players who have lost the game.

- The turn is now both stored and displayed.
This commit is contained in:
Stian Grenborgen 2004-06-07 13:13:37 +00:00
parent 0754f80994
commit 71ab7ab6c1
11 changed files with 232 additions and 28 deletions

View File

@ -360,6 +360,13 @@ public final class FreeColClient {
public Client getClient() {
return client;
}
public void playSound(int sound) {
if (sfxPlayer != null) {
sfxPlayer.play(sfxLibrary.get(sound));
}
}
}

View File

@ -14,6 +14,7 @@ import net.sf.freecol.client.FreeColClient;
import net.sf.freecol.client.networking.Client;
import net.sf.freecol.client.gui.Canvas;
import net.sf.freecol.client.gui.GUI;
import net.sf.freecol.client.gui.sound.*;
import net.sf.freecol.common.FreeColException;
import net.sf.freecol.common.model.*;
@ -130,11 +131,11 @@ public final class InGameController {
case Unit.DISEMBARK: disembark(unit, direction); break;
case Unit.EMBARK: embark(unit, direction); break;
case Unit.MOVE_HIGH_SEAS: moveHighSeas(unit, direction); break;
case Unit.ILLEGAL_MOVE: /*if (sfxPlayer != null) {
case Unit.ILLEGAL_MOVE: freeColClient.playSound(SfxLibrary.ILLEGAL_MOVE); break;
/*if (sfxPlayer != null) {
sfxPlayer.play(sfxLibrary.get(sfxLibrary.ILLEGAL_MOVE));
break;
}*/
break;
default: throw new RuntimeException("unrecognised move: " + move);
}
}
@ -305,6 +306,8 @@ public final class InGameController {
return;
}
freeColClient.playSound(SfxLibrary.LOAD_CARGO);
unit.boardShip(carrier);
Element boardShipElement = Message.createNewRootElement("boardShip");
@ -343,6 +346,8 @@ public final class InGameController {
throw new NullPointerException();
}
freeColClient.playSound(SfxLibrary.LOAD_CARGO);
Client client = freeColClient.getClient();
Element loadCargoElement = Message.createNewRootElement("loadCargo");
@ -376,7 +381,8 @@ public final class InGameController {
/**
* Buys goods in Europe.
*
* @param unit The unit who is going to board the carrier.
* @param type The type of goods to buy.
* @param amount The amount of goods to buy.
* @param carrier The carrier.
*/
public void buyGoods(int type, int amount, Unit carrier) {
@ -396,6 +402,8 @@ public final class InGameController {
if (game.getMarket().getBidPrice(type, amount) > myPlayer.getGold()) {
canvas.errorMessage("notEnoughGold");
}
freeColClient.playSound(SfxLibrary.LOAD_CARGO);
Element buyGoodsElement = Message.createNewRootElement("buyGoods");
buyGoodsElement.setAttribute("carrier", carrier.getID());
@ -424,7 +432,7 @@ public final class InGameController {
client.send(sellGoodsElement);
}
/**
* Equips or unequips a <code>Unit</code> with a certain type of <code>Goods</code>.
*
@ -439,7 +447,7 @@ public final class InGameController {
equipUnitElement.setAttribute("unit", unit.getID());
equipUnitElement.setAttribute("type", Integer.toString(type));
equipUnitElement.setAttribute("amount", Integer.toString(amount));
switch(type) {
case Goods.CROSSES:
@ -480,13 +488,13 @@ public final class InGameController {
Element workElement = Message.createNewRootElement("work");
workElement.setAttribute("unit", unit.getID());
workElement.setAttribute("workLocation", workLocation.getID());
unit.work(workLocation);
client.send(workElement);
}
/**
* Puts the specified unit outside the colony.
* @param unit The <code>Unit</code>

View File

@ -80,6 +80,8 @@ public final class InGameInputHandler implements MessageHandler {
reply = emigrateUnitInEuropeConfirmed(element);
} else if (type.equals("newTurn")) {
reply = newTurn(element);
} else if (type.equals("setDead")) {
reply = setDead(element);
} else if (type.equals("error")) {
reply = error(element);
} else {
@ -267,6 +269,20 @@ public final class InGameInputHandler implements MessageHandler {
}
/**
* Handles a "setDead"-message.
*
* @param element The element (root element in a DOM-parsed XML tree) that
* holds all the information.
*/
private Element setDead(Element element) {
Game game = freeColClient.getGame();
Player player = (Player) game.getFreeColGameObject(element.getAttribute("player"));
player.setDead(true);
return null;
}
/**
* Handles an "error"-message.
*

View File

@ -6,7 +6,6 @@ import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
/**
* The menu bar that is displayed on the top left corner of the <code>Canvas</code>.
* @see Canvas#setJMenuBar
@ -122,5 +121,4 @@ public class FreeColMenuBar extends JMenuBar {
}
});
}
}

View File

@ -7,6 +7,7 @@ import java.util.logging.Logger;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.BevelBorder;
import javax.swing.SwingConstants;
import net.sf.freecol.client.FreeColClient;
import net.sf.freecol.common.model.Game;
@ -28,7 +29,8 @@ public final class InfoPanel extends JPanel {
private final JLabel unitLabel,
unitNameLabel,
unitMovesLabel,
goldLabel;
goldLabel,
turnLabel;
private FreeColClient freeColClient;
private final Game game;
@ -51,35 +53,40 @@ public final class InfoPanel extends JPanel {
unitNameLabel = new JLabel();
unitMovesLabel = new JLabel();
goldLabel = new JLabel();
turnLabel = new JLabel();
turnLabel.setHorizontalAlignment(SwingConstants.RIGHT);
unitLabel.setSize(118, 96);
unitNameLabel.setSize(116, 20);
unitMovesLabel.setSize(116, 20);
goldLabel.setSize(100, 20);
turnLabel.setSize(146, 20);
unitLabel.setLocation(10, 4);
unitNameLabel.setLocation(130, 15);
unitMovesLabel.setLocation(130, 40);
goldLabel.setLocation(10, 102);
turnLabel.setLocation(100, 102);
setLayout(null);
add(unitLabel);
add(unitNameLabel);
add(unitMovesLabel);
add(goldLabel);
add(turnLabel);
unitLabel.setFocusable(false);
unitNameLabel.setFocusable(false);
unitMovesLabel.setFocusable(false);
goldLabel.setFocusable(false);
turnLabel.setFocusable(false);
try {
BevelBorder border = new BevelBorder(BevelBorder.RAISED);
setBorder(border);
}
catch(Exception e) {
}
} catch(Exception e) {}
setSize(256, 128);
}
@ -107,6 +114,7 @@ public final class InfoPanel extends JPanel {
}
goldLabel.setText("Gold: " + freeColClient.getMyPlayer().getGold());
turnLabel.setText("Year: " + freeColClient.getGame().getTurn().toString());
super.paintComponent(graphics);
}

View File

@ -47,6 +47,8 @@ public class Game extends FreeColGameObject {
/* The market for Europe. */
private Market market;
private Turn turn = new Turn(1);
/**
@ -80,6 +82,12 @@ public class Game extends FreeColGameObject {
return market;
}
public Turn getTurn() {
return turn;
}
/**
* Resets this game's Market.
*/
@ -250,11 +258,32 @@ public class Game extends FreeColGameObject {
public Player getNextPlayer() {
int index = players.indexOf(currentPlayer) + 1;
if (index < players.size()) {
return (Player) players.get(index);
} else {
return (Player) players.get(0);
if (index >= players.size()) {
index = 0;
}
// Find first non-dead player:
while (true) {
Player player = (Player) players.get(index);
if (!player.isDead()) {
return player;
}
index++;
if (index >= players.size()) {
index = 0;
}
}
}
/**
* Checks if the next player is in a new turn.
*/
public boolean isNextPlayerInNewTurn() {
int index = players.indexOf(currentPlayer) + 1;
return index >= players.size();
}
@ -414,6 +443,8 @@ public class Game extends FreeColGameObject {
*/
public void newTurn() {
//Iterator iterator = getFreeColGameObjectIterator();
turn.increase();
Iterator iterator = ((HashMap) freeColGameObjects.clone()).values().iterator();
while (iterator.hasNext()) {

View File

@ -325,6 +325,8 @@ public final class Market extends FreeColGameObject {
dataForGoodType[i] = new Data(getGame(), dataElement);
}
priceGoods();
}

View File

@ -88,6 +88,7 @@ public class Player extends FreeColGameObject {
private int crosses;
private int bells;
private boolean dead = false;
private Location entryLocation;
@ -310,6 +311,23 @@ public class Player extends FreeColGameObject {
return admin;
}
/**
* Checks if this player is dead.
* A <code>Player</code> dies when it looses the game.
*/
public boolean isDead() {
return dead;
}
/**
* Sets this player to be dead or not.
*/
public void setDead(boolean dead) {
this.dead = dead;
}
/**
* Returns the name of this player.
@ -490,7 +508,7 @@ public class Player extends FreeColGameObject {
// wherein they count as 4.
// This does that, I think. -sjm
int count = 8;
ArrayList units = new ArrayList();
Map map = getGame().getMap();
@ -542,7 +560,6 @@ public class Player extends FreeColGameObject {
// Nothing to do.
}
/**
* Makes an XML-representation of this object.
*
@ -561,6 +578,7 @@ public class Player extends FreeColGameObject {
playerElement.setAttribute("crosses", Integer.toString(crosses));
playerElement.setAttribute("bells", Integer.toString(bells));
playerElement.setAttribute("ready", Boolean.toString(ready));
playerElement.setAttribute("dead", Boolean.toString(dead));
playerElement.setAttribute("ai", Boolean.toString(ai));
@ -592,6 +610,7 @@ public class Player extends FreeColGameObject {
bells = Integer.parseInt(playerElement.getAttribute("bells"));
ready = (new Boolean(playerElement.getAttribute("ready"))).booleanValue();
ai = (new Boolean(playerElement.getAttribute("ai"))).booleanValue();
dead = (new Boolean(playerElement.getAttribute("dead"))).booleanValue();
if (playerElement.hasAttribute("entryLocation")) {
entryLocation = (Location) getGame().getFreeColGameObject(playerElement.getAttribute("entryLocation"));

View File

@ -0,0 +1,72 @@
package net.sf.freecol.common.model;
import java.util.logging.Logger;
/**
* Represents a given turn in the game.
*/
public class Turn {
public static final String COPYRIGHT = "Copyright (C) 2003 The FreeCol Team";
public static final String LICENSE = "http://www.gnu.org/licenses/gpl.html";
public static final String REVISION = "$Revision$";
private static final Logger logger = Logger.getLogger(Turn.class.getName());
public static final int STARTING_YEAR = 1492;
public static final int SEASON_YEAR = 1600;
private int turn;
public Turn(int turn) {
this.turn = turn;
}
/**
* Increases the turn number by one.
*/
public void increase() {
turn++;
}
/**
* Gets the turn number.
*/
public int getNumber() {
return turn;
}
/**
* Checks if this turn is equal to another turn.
*/
public boolean equals(Object o) {
if (!(o instanceof Turn)) {
return false;
} else {
return (getNumber() == ((Turn) o).getNumber());
}
}
/**
* Returns a string representation of this turn.
* @return A string with the format: "<i>[season] year</i>".
* Examples: "Spring 1602", "1503"...
*/
public String toString() {
if (STARTING_YEAR + turn - 1 < SEASON_YEAR) {
return Integer.toString(STARTING_YEAR + turn - 1);
} else {
int c = turn - (SEASON_YEAR - STARTING_YEAR - 1);
return ((c%2==0) ? " Spring" : " Autumn") + Integer.toString(SEASON_YEAR + c/2 - 1);
}
}
}

View File

@ -80,6 +80,7 @@ public final class AIInGameInputHandler implements MessageHandler {
reply = setCurrentPlayer(connection, element);
} else if (type.equals("emigrateUnitInEuropeConfirmed")) {
} else if (type.equals("newTurn")) {
} else if (type.equals("setDead")) {
} else if (type.equals("error")) {
} else {
logger.warning("Message is of unsupported type \"" + type + "\".");

View File

@ -338,7 +338,7 @@ public final class InGameInputHandler implements MessageHandler {
Tile oldTile = unit.getTile();
boolean tellEnemyPlayers = true;
if (oldTile.getSettlement() != null || oldTile == null) {
if (oldTile == null || oldTile.getSettlement() != null) {
tellEnemyPlayers = false;
}
@ -795,24 +795,66 @@ public final class InGameInputHandler implements MessageHandler {
Player nextPlayer = game.getNextPlayer();
if (nextPlayer.equals(game.getFirstPlayer())) {
while (checkForDeath(nextPlayer)) {
nextPlayer.setDead(true);
Element setDeadElement = Message.createNewRootElement("setDead");
setDeadElement.setAttribute("player", nextPlayer.getID());
freeColServer.getServer().sendToAll(setDeadElement, null);
nextPlayer = game.getNextPlayer();
}
if (game.isNextPlayerInNewTurn()) {
game.newTurn();
Element newTurnElement = Message.createNewRootElement("newTurn");
freeColServer.getServer().sendToAll(newTurnElement, null);
}
game.setCurrentPlayer(nextPlayer);
Element setCurrentPlayerElement = Message.createNewRootElement("setCurrentPlayer");
setCurrentPlayerElement.setAttribute("player", nextPlayer.getID());
freeColServer.getServer().sendToAll(setCurrentPlayerElement, null);
return null;
}
/**
* Checks if this player has died.
* @return <i>true</i> if this player should die.
*/
private boolean checkForDeath(Player player) {
// Die if: (No colonies or units on map) && ((After 20 turns) || (Cannot get a unit from Europe))
Game game = freeColServer.getGame();
Map map = game.getMap();
Iterator tileIterator = map.getWholeMapIterator();
while (tileIterator.hasNext()) {
Tile t = map.getTile((Map.Position) tileIterator.next());
if (t != null && ((t.getFirstUnit() != null && t.getFirstUnit().getOwner().equals(player))
|| t.getSettlement() != null && t.getSettlement().getOwner().equals(player))) {
return false;
}
}
// At this point we know the player does not have any units or settlements on the map.
if (player.getNation() >= 0 && player.getNation() <= 3) {
if (game.getTurn().getNumber() > 20 || player.getEurope().getFirstUnit() == null
&& player.getGold() < 600 && player.getGold() < player.getEurope().getRecruitPrice()) {
return true;
} else {
return false;
}
} else {
return true;
}
}
private void sendUpdatedTileToAll(Tile newTile, Player player) {
Game game = freeColServer.getGame();