forked from External/mage
308 lines
9.1 KiB
Java
308 lines
9.1 KiB
Java
/*
|
|
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without modification, are
|
|
* permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
* conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
|
* provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
* The views and conclusions contained in the software and documentation are those of the
|
|
* authors and should not be interpreted as representing official policies, either expressed
|
|
* or implied, of BetaSteward_at_googlemail.com.
|
|
*/
|
|
|
|
package mage.game.match;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.Date;
|
|
import java.util.List;
|
|
import java.util.Random;
|
|
import java.util.UUID;
|
|
import mage.cards.decks.Deck;
|
|
import mage.game.Game;
|
|
import mage.game.GameException;
|
|
import mage.game.events.Listener;
|
|
import mage.game.events.TableEvent;
|
|
import mage.game.events.TableEvent.EventType;
|
|
import mage.game.events.TableEventSource;
|
|
import mage.players.Player;
|
|
|
|
|
|
/**
|
|
*
|
|
* @author BetaSteward_at_googlemail.com
|
|
*/
|
|
public abstract class MatchImpl implements Match {
|
|
|
|
protected UUID id = UUID.randomUUID();
|
|
protected List<MatchPlayer> players = new ArrayList<MatchPlayer>();
|
|
protected List<Game> games = new ArrayList<Game>();
|
|
protected MatchOptions options;
|
|
|
|
protected TableEventSource tableEventSource = new TableEventSource();
|
|
|
|
protected Date startTime;
|
|
protected Date endTime;
|
|
|
|
public MatchImpl(MatchOptions options) {
|
|
this.options = options;
|
|
startTime = new Date();
|
|
}
|
|
|
|
@Override
|
|
public List<MatchPlayer> getPlayers() {
|
|
return players;
|
|
}
|
|
|
|
@Override
|
|
public MatchPlayer getPlayer(UUID playerId) {
|
|
for (MatchPlayer player: players) {
|
|
if (player.getPlayer().getId().equals(playerId)) {
|
|
return player;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public void addPlayer(Player player, Deck deck) {
|
|
MatchPlayer mPlayer = new MatchPlayer(player, deck);
|
|
players.add(mPlayer);
|
|
}
|
|
|
|
@Override
|
|
public boolean leave(UUID playerId) {
|
|
MatchPlayer mPlayer = getPlayer(playerId);
|
|
if (mPlayer != null) {
|
|
return players.remove(mPlayer);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void startMatch() throws GameException {
|
|
|
|
}
|
|
|
|
@Override
|
|
public UUID getId() {
|
|
return id;
|
|
}
|
|
|
|
@Override
|
|
public String getName() {
|
|
return options.getName();
|
|
}
|
|
|
|
@Override
|
|
public MatchOptions getOptions() {
|
|
return options;
|
|
}
|
|
|
|
@Override
|
|
public boolean isMatchOver() {
|
|
int activePlayers = 0;
|
|
for (MatchPlayer player: players) {
|
|
if (!player.hasQuit()) {
|
|
activePlayers++;
|
|
}
|
|
if (player.getWins() >= options.getWinsNeeded()) {
|
|
endTime = new Date();
|
|
return true;
|
|
}
|
|
}
|
|
if (activePlayers < 2) {
|
|
endTime = new Date();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public Game getGame() {
|
|
if (games.isEmpty()) {
|
|
return null;
|
|
}
|
|
return games.get(games.size() -1);
|
|
}
|
|
|
|
@Override
|
|
public List<Game> getGames() {
|
|
return games;
|
|
}
|
|
|
|
@Override
|
|
public int getNumGames() {
|
|
return games.size();
|
|
}
|
|
|
|
@Override
|
|
public int getWinsNeeded() {
|
|
return options.getWinsNeeded();
|
|
}
|
|
|
|
@Override
|
|
public int getFreeMulligans() {
|
|
return options.getFreeMulligans();
|
|
}
|
|
|
|
protected void initGame(Game game) throws GameException {
|
|
shufflePlayers();
|
|
for (MatchPlayer matchPlayer: this.players) {
|
|
if (!matchPlayer.hasQuit()) {
|
|
matchPlayer.getPlayer().init(game);
|
|
game.loadCards(matchPlayer.getDeck().getCards(), matchPlayer.getPlayer().getId());
|
|
game.loadCards(matchPlayer.getDeck().getSideboard(), matchPlayer.getPlayer().getId());
|
|
game.addPlayer(matchPlayer.getPlayer(), matchPlayer.getDeck());
|
|
// set the priority time left for the match
|
|
if (matchPlayer.getPriorityTimeLeft() > 0) {
|
|
matchPlayer.getPlayer().setPriorityTimeLeft(matchPlayer.getPriorityTimeLeft());
|
|
}
|
|
}
|
|
}
|
|
game.setPriorityTime(options.getPriorityTime());
|
|
}
|
|
|
|
protected void shufflePlayers() {
|
|
Collections.shuffle(this.players, new Random());
|
|
}
|
|
|
|
@Override
|
|
public void endGame() {
|
|
Game game = getGame();
|
|
for (MatchPlayer player: this.players) {
|
|
Player p = game.getPlayer(player.getPlayer().getId());
|
|
if (p != null) {
|
|
// get the left time from player priority timer
|
|
if (game.getPriorityTime() > 0) {
|
|
player.setPriorityTimeLeft(p.getPriorityTimeLeft());
|
|
}
|
|
if (p.hasQuit()) {
|
|
player.setQuit(true);
|
|
}
|
|
if (p.hasWon()) {
|
|
player.addWin();
|
|
}
|
|
if (p.hasLost()) {
|
|
player.addLose();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public UUID getChooser() {
|
|
UUID loserId = null;
|
|
Game game = getGame();
|
|
for (MatchPlayer player: this.players) {
|
|
Player p = game.getPlayer(player.getPlayer().getId());
|
|
if (p != null && p.hasLost() && !p.hasQuit()) {
|
|
loserId = p.getId();
|
|
}
|
|
}
|
|
return loserId;
|
|
}
|
|
|
|
@Override
|
|
public void addTableEventListener(Listener<TableEvent> listener) {
|
|
tableEventSource.addListener(listener);
|
|
}
|
|
|
|
@Override
|
|
public void sideboard() {
|
|
for (MatchPlayer player: this.players) {
|
|
if (!player.hasQuit()) {
|
|
player.setSideboarding();
|
|
player.getPlayer().sideboard(this, player.getDeck());
|
|
}
|
|
}
|
|
synchronized(this) {
|
|
while (!isDoneSideboarding()) {
|
|
try {
|
|
this.wait();
|
|
} catch (InterruptedException ex) { }
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean isDoneSideboarding() {
|
|
for (MatchPlayer player: this.players) {
|
|
if (!player.hasQuit() && !player.isDoneSideboarding()) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void fireSideboardEvent(UUID playerId, Deck deck) {
|
|
MatchPlayer player = getPlayer(playerId);
|
|
if (player != null) {
|
|
tableEventSource.fireTableEvent(EventType.SIDEBOARD, playerId, deck, SIDEBOARD_TIME);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void submitDeck(UUID playerId, Deck deck) {
|
|
MatchPlayer player = getPlayer(playerId);
|
|
if (player != null) {
|
|
player.submitDeck(deck);
|
|
}
|
|
synchronized (this) {
|
|
this.notifyAll();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void updateDeck(UUID playerId, Deck deck) {
|
|
MatchPlayer player = getPlayer(playerId);
|
|
if (player != null) {
|
|
player.updateDeck(deck);
|
|
}
|
|
}
|
|
|
|
protected String createGameStartMessage() {
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.append("\nMatch score:\n");
|
|
for (MatchPlayer mp :this.getPlayers()) {
|
|
sb.append("- ").append(mp.getPlayer().getName());
|
|
sb.append(" (").append(mp.getWins()).append(mp.getWins()==1?" win / ":" wins / ");
|
|
sb.append(mp.getLoses()).append(mp.getLoses()==1?" loss)":" losses)");
|
|
if (mp.hasQuit()) {
|
|
sb.append(" QUITTED");
|
|
}
|
|
sb.append("\n");
|
|
}
|
|
sb.append("\n").append(this.getWinsNeeded()).append(this.getWinsNeeded() == 1 ? " win":" wins").append(" needed to win the match\n");
|
|
sb.append("\nGame has started\n");
|
|
return sb.toString();
|
|
}
|
|
|
|
@Override
|
|
public Date getStartTime() {
|
|
return startTime;
|
|
}
|
|
|
|
@Override
|
|
public Date getEndTime() {
|
|
return endTime;
|
|
}
|
|
|
|
}
|