spjspj - Add option of 'Number of Seats'. This is for Tournaments so that you can draft say a 4 way draft and then have a 4 way game at the end of it.

This commit is contained in:
spjspj 2016-09-25 00:46:16 +10:00
parent 101a1db649
commit 16bb17e5bb
14 changed files with 366 additions and 60 deletions

View file

@ -36,6 +36,7 @@ import mage.cards.decks.Deck;
import mage.game.Game;
import mage.game.draft.Draft;
import mage.game.match.MatchOptions;
import mage.game.tournament.MultiplayerRound;
import mage.game.tournament.TournamentPairing;
/**
@ -46,7 +47,7 @@ public class TableEvent extends EventObject implements ExternalEvent, Serializab
public enum EventType {
UPDATE, INFO, STATUS, START_DRAFT, START_MATCH, SIDEBOARD, CONSTRUCT, SUBMIT_DECK, END, END_GAME_INFO, ERROR,
INIT_TIMER, RESUME_TIMER, PAUSE_TIMER, CHECK_STATE_PLAYERS
INIT_TIMER, RESUME_TIMER, PAUSE_TIMER, CHECK_STATE_PLAYERS, START_MULTIPLAYER_MATCH
}
private Game game;
@ -58,6 +59,7 @@ public class TableEvent extends EventObject implements ExternalEvent, Serializab
private UUID playerId;
private Deck deck;
private TournamentPairing pair;
private MultiplayerRound round;
private MatchOptions options;
private int timeout;
private boolean withTime;
@ -115,6 +117,13 @@ public class TableEvent extends EventObject implements ExternalEvent, Serializab
this.options = options;
this.eventType = eventType;
}
public TableEvent(EventType eventType, MultiplayerRound round, MatchOptions options) {
super(options);
this.round = round;
this.options = options;
this.eventType = eventType;
}
public Game getGame() {
return game;
@ -151,6 +160,10 @@ public class TableEvent extends EventObject implements ExternalEvent, Serializab
public TournamentPairing getPair() {
return pair;
}
public MultiplayerRound getMultiplayerRound() {
return round;
}
public MatchOptions getMatchOptions() {
return options;

View file

@ -38,6 +38,7 @@ import mage.game.tournament.TournamentPairing;
import java.io.Serializable;
import java.util.UUID;
import mage.game.tournament.MultiplayerRound;
/**
*
@ -93,4 +94,8 @@ public class TableEventSource implements EventSource<TableEvent>, Serializable {
public void fireTableEvent(EventType eventType, TournamentPairing pair, MatchOptions options) {
dispatcher.fireEvent(new TableEvent(eventType, pair, options));
}
public void fireTableEvent(EventType eventType, MultiplayerRound round, MatchOptions options) {
dispatcher.fireEvent(new TableEvent(eventType, round, options));
}
}

View file

@ -52,21 +52,50 @@ public class MatchOptions implements Serializable {
protected String deckType;
protected boolean limited;
protected List<String> playerTypes = new ArrayList<>();
protected boolean multiPlayer;
protected int numSeats;
protected String password;
protected SkillLevel skillLevel;
protected boolean rollbackTurnsAllowed;
protected int quitRatio;
protected boolean rated;
protected int numSeatsForMatch;
/**
* Time each player has during the game to play using his\her priority.
*/
protected MatchTimeLimit matchTimeLimit; // 0 = no priorityTime handling
public MatchOptions(String name, String gameType) {
/*public MatchOptions(String name, String gameType) {
this.name = name;
this.gameType = gameType;
this.password = "";
this.multiPlayer = false;
this.numSeats = 2;
}*/
public MatchOptions(String name, String gameType, boolean multiPlayer, int numSeats ) {
this.name = name;
this.gameType = gameType;
this.password = "";
this.multiPlayer = multiPlayer;
this.numSeats = numSeats;
}
public void setNumSeats (int numSeats) {
this.numSeats = numSeats;
}
public int getNumSeats () {
return numSeats;
}
public void setMultiPlayer(boolean multiPlayer) {
this.multiPlayer = multiPlayer;
}
public boolean getMultiPlayer() {
return multiPlayer;
}
public String getName() {

View file

@ -0,0 +1,97 @@
/*
* Copyright 2011 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.tournament;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.game.match.Match;
/**
*
* @author spjspj
*/
public class MultiplayerRound {
private final int roundNum;
private final Tournament tournament;
private final int numSeats;
private final List<TournamentPlayer> allPlayers = new ArrayList<>();
private Match match;
private UUID tableId;
public MultiplayerRound(int roundNum, Tournament tournament, int numSeats) {
this.roundNum = roundNum;
this.tournament = tournament;
this.numSeats = numSeats;
}
public List<TournamentPlayer> getAllPlayers () {
return allPlayers;
}
public TournamentPlayer getPlayer (int i) {
if (i >= 0 && i < numSeats && i < allPlayers.size()) {
return allPlayers.get(i);
}
return null;
}
public void addPairing(TournamentPairing match) {
this.allPlayers.add(match.getPlayer1());
this.allPlayers.add(match.getPlayer2());
}
public void addPlayer(TournamentPlayer player) {
this.allPlayers.add(player);
}
public int getRoundNumber() {
return this.roundNum;
}
public void setMatch (Match match) {
this.match = match;
}
public void setTableId (UUID tableId) {
this.tableId = tableId;
}
public boolean isRoundOver() {
boolean roundIsOver = true;
if (this.match != null) {
if (!this.match.hasEnded()) {
roundIsOver = false;
}
}
return roundIsOver;
}
}

View file

@ -261,6 +261,12 @@ public abstract class TournamentImpl implements Tournament {
}
updateResults();
}
protected void playMultiplayerRound(MultiplayerRound round) {
playMultiPlayerMatch(round);
updateResults(); // show points from byes
}
protected List<TournamentPlayer> getActivePlayers() {
List<TournamentPlayer> activePlayers = new ArrayList<>();
@ -456,6 +462,10 @@ public abstract class TournamentImpl implements Tournament {
options.getMatchOptions().getPlayerTypes().add(pair.getPlayer2().getPlayerType());
tableEventSource.fireTableEvent(EventType.START_MATCH, pair, options.getMatchOptions());
}
public void playMultiPlayerMatch(MultiplayerRound round) {
tableEventSource.fireTableEvent(EventType.START_MULTIPLAYER_MATCH, round, options.getMatchOptions());
}
public void end() {
endTime = new Date();

View file

@ -41,15 +41,16 @@ public class TournamentOptions implements Serializable {
protected String name;
protected String tournamentType;
protected List<String> playerTypes = new ArrayList<>();
protected MatchOptions matchOptions = new MatchOptions("", "Two Player Duel");
protected MatchOptions matchOptions;
protected LimitedOptions limitedOptions;
protected boolean watchingAllowed = true;
protected int numberRounds;
protected String password;
protected int quitRatio;
public TournamentOptions(String name) {
public TournamentOptions(String name, String matchType, int numSeats) {
this.name = name;
this.matchOptions = new MatchOptions("", matchType, numSeats > 2, numSeats);
}
public String getName() {

View file

@ -34,8 +34,8 @@ package mage.game.tournament;
*/
public class TournamentSealedOptions extends TournamentOptions {
public TournamentSealedOptions(String name) {
super(name);
public TournamentSealedOptions(String name, String matchType, int numSeats) {
super(name, matchType, numSeats);
}
}

View file

@ -28,6 +28,7 @@
package mage.game.tournament;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import mage.game.events.TableEvent;
@ -50,16 +51,25 @@ public abstract class TournamentSingleElimination extends TournamentImpl {
entry.getValue().setResults("Auto Eliminated");
}
}
while (this.getActivePlayers().size() > 1) {
// check if some player got killed / disconnected meanwhile and update their state
tableEventSource.fireTableEvent(TableEvent.EventType.CHECK_STATE_PLAYERS);
Round round = createRoundRandom();
playRound(round);
eliminatePlayers(round);
if (options.matchOptions.getNumSeats() == 2) {
while (this.getActivePlayers().size() > 1) {
// check if some player got killed / disconnected meanwhile and update their state
tableEventSource.fireTableEvent(TableEvent.EventType.CHECK_STATE_PLAYERS);
Round round = createRoundRandom();
playRound(round);
eliminatePlayers(round);
}
} else {
MultiplayerRound round = new MultiplayerRound(0, this, options.matchOptions.getNumSeats());
for (TournamentPlayer player : getActivePlayers()) {
round.addPlayer(player);
}
playMultiplayerRound(round);
}
nextStep();
}
private void eliminatePlayers(Round round) {
for (TournamentPairing pair: round.getPairs()) {
pair.eliminatePlayers();

View file

@ -56,13 +56,19 @@ public abstract class TournamentSwiss extends TournamentImpl {
}
}
while (this.getActivePlayers().size() > 1 && this.getNumberRounds() > this.getRounds().size()) {
// check if some player got killed / disconnected meanwhile and update their state
tableEventSource.fireTableEvent(TableEvent.EventType.CHECK_STATE_PLAYERS);
// Swiss pairing
Round round = createRoundSwiss();
playRound(round);
if (options.matchOptions.getNumSeats() == 2) {
while (this.getActivePlayers().size() > 1 && this.getNumberRounds() > this.getRounds().size()) {
// check if some player got killed / disconnected meanwhile and update their state
tableEventSource.fireTableEvent(TableEvent.EventType.CHECK_STATE_PLAYERS);
// Swiss pairing
Round round = createRoundSwiss();
playRound(round);
}
} else {
MultiplayerRound round = createMultiplayerRound();
playMultiplayerRound(round);
}
nextStep();
}
@ -70,33 +76,60 @@ public abstract class TournamentSwiss extends TournamentImpl {
List<TournamentPlayer> roundPlayers = getActivePlayers();
boolean isLastRound = (rounds.size() + 1 == getNumberRounds());
RoundPairings roundPairings;
if (roundPlayers.size() <= 16) {
SwissPairingMinimalWeightMatching swissPairing = new SwissPairingMinimalWeightMatching(roundPlayers, rounds, isLastRound);
roundPairings = swissPairing.getRoundPairings();
} else {
SwissPairingSimple swissPairing = new SwissPairingSimple(roundPlayers, rounds);
roundPairings = swissPairing.getRoundPairings();
}
Round round = new Round(rounds.size() + 1, this);
rounds.add(round);
for (TournamentPairing pairing : roundPairings.getPairings()) {
round.addPairing(pairing);
}
for (TournamentPlayer playerBye : roundPairings.getPlayerByes()) {
// player free round - add to bye players of this round
round.getPlayerByes().add(playerBye);
if (isLastRound) {
playerBye.setState(TournamentPlayerState.FINISHED);
Round round = null;
if (options.matchOptions.getNumSeats() == 2) {
RoundPairings roundPairings;
if (roundPlayers.size() <= 16) {
SwissPairingMinimalWeightMatching swissPairing = new SwissPairingMinimalWeightMatching(roundPlayers, rounds, isLastRound);
roundPairings = swissPairing.getRoundPairings();
} else {
playerBye.setState(TournamentPlayerState.WAITING);
SwissPairingSimple swissPairing = new SwissPairingSimple(roundPlayers, rounds);
roundPairings = swissPairing.getRoundPairings();
}
round = new Round(rounds.size() + 1, this);
rounds.add(round);
for (TournamentPairing pairing : roundPairings.getPairings()) {
round.addPairing(pairing);
}
for (TournamentPlayer playerBye : roundPairings.getPlayerByes()) {
// player free round - add to bye players of this round
round.getPlayerByes().add(playerBye);
if (isLastRound) {
playerBye.setState(TournamentPlayerState.FINISHED);
} else {
playerBye.setState(TournamentPlayerState.WAITING);
}
playerBye.setStateInfo("Round Bye");
updateResults();
}
playerBye.setStateInfo("Round Bye");
updateResults();
}
return round;
}
public MultiplayerRound createMultiplayerRound() {
List<TournamentPlayer> roundPlayers = getActivePlayers();
boolean isLastRound = (rounds.size() + 1 == getNumberRounds());
MultiplayerRound round = null;
if (options.matchOptions.getNumSeats() > 2) {
RoundPairings roundPairings;
if (roundPlayers.size() <= 16) {
SwissPairingMinimalWeightMatching swissPairing = new SwissPairingMinimalWeightMatching(roundPlayers, rounds, isLastRound);
roundPairings = swissPairing.getRoundPairings();
} else {
SwissPairingSimple swissPairing = new SwissPairingSimple(roundPlayers, rounds);
roundPairings = swissPairing.getRoundPairings();
}
round = new MultiplayerRound(rounds.size() + 1, this, options.matchOptions.getNumSeats());
for (TournamentPairing pairing : roundPairings.getPairings()) {
round.addPairing(pairing);
}
}
return round;
}
}