diff --git a/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java b/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java index 7d302cad11d..532ea79bc9d 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java @@ -594,7 +594,7 @@ public class NewTableDialog extends MageDialog { private MatchOptions getMatchOptions() { // current settings GameTypeView gameType = (GameTypeView) cbGameType.getSelectedItem(); - MatchOptions options = new MatchOptions(this.txtName.getText(), gameType.getName(), false, 2); + MatchOptions options = new MatchOptions(this.txtName.getText(), gameType.getName(), false); options.getPlayerTypes().add(PlayerType.HUMAN); for (TablePlayerPanel player : players) { options.getPlayerTypes().add(player.getPlayerType()); diff --git a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.form b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.form index 82a2df067f9..83ba9d4551e 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.form +++ b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.form @@ -99,19 +99,21 @@ + + - - - - + + + + + - - + @@ -119,10 +121,7 @@ - - - - + @@ -200,11 +199,7 @@ - - - - - + @@ -222,8 +217,6 @@ - - @@ -287,7 +280,7 @@ - + @@ -295,15 +288,17 @@ - - + + + + + + + + + - - - - - - + @@ -504,19 +499,18 @@ - - - - - - + + + + + - + @@ -615,7 +609,7 @@ - + @@ -672,8 +666,6 @@ - - diff --git a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java index 188f63d6056..47be24286dc 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java @@ -40,6 +40,8 @@ public class NewTournamentDialog extends MageDialog { private static final Logger logger = Logger.getLogger(NewTournamentDialog.class); + private static final int MAX_PLAYERS_PER_GAME = 6; // it's ok to have 6 players at the screen, 8+ is too big + // temp settings on loading players list private final List prefPlayerTypes = new ArrayList<>(); private final List prefPlayerSkills = new ArrayList<>(); @@ -77,12 +79,15 @@ public class NewTournamentDialog extends MageDialog { private int getCurrentNumPlayers() { int res = (Integer) spnNumPlayers.getValue(); - return res > 0 ? res : 2; + return Math.max(2, res); } private int getCurrentNumSeats() { - int res = (Integer) spnNumSeats.getValue(); - return res > 0 ? res : 2; + if (chkSingleMultiplayerGame.isSelected()) { + return getCurrentNumPlayers(); + } else { + return 2; + } } public void showDialog(UUID roomId) { @@ -159,9 +164,8 @@ public class NewTournamentDialog extends MageDialog { lblPacks = new javax.swing.JLabel(); pnlPacks = new javax.swing.JPanel(); lblNbrPlayers = new javax.swing.JLabel(); - lblNbrSeats = new javax.swing.JLabel(); spnNumPlayers = new javax.swing.JSpinner(); - spnNumSeats = new javax.swing.JSpinner(); + chkSingleMultiplayerGame = new javax.swing.JCheckBox(); pnlDraftOptions = new javax.swing.JPanel(); jLabel6 = new javax.swing.JLabel(); cbDraftTiming = new javax.swing.JComboBox(); @@ -321,17 +325,17 @@ public class NewTournamentDialog extends MageDialog { lblNbrPlayers.setText("Players:"); - lblNbrSeats.setText("Seats:"); - spnNumPlayers.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { spnNumPlayersStateChanged(evt); } }); - spnNumSeats.addChangeListener(new javax.swing.event.ChangeListener() { - public void stateChanged(javax.swing.event.ChangeEvent evt) { - spnNumSeatsStateChanged(evt); + chkSingleMultiplayerGame.setText("play as single game"); + chkSingleMultiplayerGame.setToolTipText("Allow to play single game with all tourney's players -- e.g. play one game after draft with 4 players"); + chkSingleMultiplayerGame.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + chkSingleMultiplayerGameItemStateChanged(evt); } }); @@ -390,7 +394,7 @@ public class NewTournamentDialog extends MageDialog { ); pnlPlayersLayout.setVerticalGroup( pnlPlayersLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(pnlOtherPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, 8, Short.MAX_VALUE) + .addComponent(pnlOtherPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, 15, Short.MAX_VALUE) ); btnOk.setText("Create"); @@ -460,25 +464,26 @@ public class NewTournamentDialog extends MageDialog { .addComponent(pnlPacks, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(lblPacks) + .addComponent(lblPlayer1) .addGroup(layout.createSequentialGroup() .addComponent(lblNbrPlayers) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(spnNumPlayers, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(layout.createSequentialGroup() - .addComponent(lblNbrSeats) + .addComponent(spnNumPlayers, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(spnNumSeats, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(lblPacks) - .addComponent(lblPlayer1)) + .addComponent(lblNumWins) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(chkSingleMultiplayerGame))) + .addGap(21, 21, 21) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(28, 28, 28) .addComponent(pnlDraftOptions, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(lblNumRounds)) - .addGroup(layout.createSequentialGroup() - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(lblConstructionTime))) + .addComponent(lblConstructionTime)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(spnConstructTime, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) @@ -545,11 +550,7 @@ public class NewTournamentDialog extends MageDialog { .addComponent(lbBufferTime) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(cbBufferTime, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblNumWins) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGap(87, 87, 87) .addComponent(chkRollbackTurnsAllowed) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(cbAllowSpectators))))) @@ -561,8 +562,6 @@ public class NewTournamentDialog extends MageDialog { .addGap(2, 2, 2) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(lblNumWins) - .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(chkRollbackTurnsAllowed) .addComponent(cbAllowSpectators, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) @@ -612,20 +611,21 @@ public class NewTournamentDialog extends MageDialog { .addGroup(layout.createSequentialGroup() .addComponent(pnlPacks, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pnlRandomPacks, javax.swing.GroupLayout.DEFAULT_SIZE, 9, Short.MAX_VALUE) + .addComponent(pnlRandomPacks, javax.swing.GroupLayout.DEFAULT_SIZE, 20, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(spnNumRounds, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(lblNumRounds)) .addComponent(lblNbrPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(spnNumPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE) - .addComponent(pnlDraftOptions, javax.swing.GroupLayout.PREFERRED_SIZE, 23, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) - .addComponent(lblNbrSeats, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(spnNumSeats)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(spnNumPlayers) + .addComponent(chkSingleMultiplayerGame) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(lblNumWins) + .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(pnlDraftOptions, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) + .addGap(27, 27, 27) .addComponent(lblPlayer1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(spnConstructTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) @@ -652,7 +652,7 @@ public class NewTournamentDialog extends MageDialog { }// //GEN-END:initComponents private void cbTournamentTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbTournamentTypeActionPerformed - prepareTourneyView(false, prepareVersionStr(-1, false), getCurrentNumPlayers(), getCurrentNumSeats()); + loadTourneyView(false, prepareVersionStr(-1, false), getCurrentNumPlayers(), chkSingleMultiplayerGame.isSelected()); jumpstartPacksFilename = ""; if (cbTournamentType.getSelectedItem().toString().matches(".*Jumpstart.*Custom.*")) { @@ -741,44 +741,29 @@ public class NewTournamentDialog extends MageDialog { doClose(); }//GEN-LAST:event_btnCancelActionPerformed - private void updateNumSeats() { - int numSeats = (Integer) this.spnNumSeats.getValue(); + private void applyNewPlayersCount() { + // make sure players count is compatible + int numPlayers = getCurrentNumPlayers(); + int compatiblePlayers = getCompatiblePlayersCount(numPlayers); + if (numPlayers != compatiblePlayers) { + numPlayers = compatiblePlayers; + spnNumPlayers.setValue(numPlayers); + } + createPlayers(numPlayers - 1); - if (numSeats > 2) { - TournamentTypeView tournamentType = (TournamentTypeView) cbTournamentType.getSelectedItem(); - if (numSeats >= tournamentType.getMinPlayers()) { - createPlayers(numSeats - 1); - spnNumPlayers.setValue(numSeats); - } else { - numSeats = tournamentType.getMinPlayers(); - createPlayers(numSeats - 1); - spnNumPlayers.setValue(numSeats); - spnNumSeats.setValue(numSeats); - } + // make sure wins is compatible + // is's can be a too long match for 2+ wins in 4+ game + if (chkSingleMultiplayerGame.isSelected()) { spnNumWins.setValue(1); } } private void spnNumPlayersStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnNumPlayersStateChanged - int numPlayers = getCurrentNumPlayers(); - createPlayers(numPlayers - 1); - int numSeats = (Integer) this.spnNumSeats.getValue(); - if (numSeats > 2 && numPlayers != numSeats) { - updateNumSeats(); - } + applyNewPlayersCount(); }//GEN-LAST:event_spnNumPlayersStateChanged - private void spnNumSeatsStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnNumSeatsStateChanged - int numSeats = (Integer) this.spnNumSeats.getValue(); - this.spnNumPlayers.setEnabled(numSeats <= 2); - updateNumSeats(); - }//GEN-LAST:event_spnNumSeatsStateChanged - private void spnNumWinsnumPlayersChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnNumWinsnumPlayersChanged - int numSeats = getCurrentNumSeats(); - if (numSeats > 2) { - spnNumWins.setValue(1); - } + applyNewPlayersCount(); }//GEN-LAST:event_spnNumWinsnumPlayersChanged private JFileChooser fcSelectDeck = null; @@ -880,27 +865,51 @@ public class NewTournamentDialog extends MageDialog { customOptions.showDialog(); }//GEN-LAST:event_btnCustomOptionsActionPerformed + private void chkSingleMultiplayerGameItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_chkSingleMultiplayerGameItemStateChanged + // for checkboxes - it's important to use ItemStateChanged instead stateChanged + // (the last one will raise on moving mouse over, not on checkbox state change only) + applyNewPlayersCount(); + }//GEN-LAST:event_chkSingleMultiplayerGameItemStateChanged + private void setGameOptions() { createPlayers(getCurrentNumPlayers() - 1); } - private void prepareTourneyView(boolean loadPlayerSettings, String versionStr, int numPlayers, int numSeats) { + private int getCompatiblePlayersCount(int count) { + TournamentTypeView tournamentType = (TournamentTypeView) cbTournamentType.getSelectedItem(); + if (tournamentType == null) { + return count; + } + int compatibleMin = tournamentType.getMinPlayers(); + int compatibleMax = tournamentType.getMaxPlayers(); + + if (chkSingleMultiplayerGame.isSelected()) { + compatibleMax = Math.min(MAX_PLAYERS_PER_GAME, compatibleMax); + } + + int compatibleCount = count; + compatibleCount = Math.max(compatibleCount, compatibleMin); + compatibleCount = Math.min(compatibleCount, compatibleMax); + return compatibleCount; + } + + private void loadTourneyView(boolean loadPlayerSettings, String versionStr, int numPlayers, boolean isSingleMultiplayerGame) { TournamentTypeView tournamentType = (TournamentTypeView) cbTournamentType.getSelectedItem(); activatePanelElements(tournamentType); - if (numPlayers < tournamentType.getMinPlayers() || numPlayers > tournamentType.getMaxPlayers()) { - numPlayers = tournamentType.getMinPlayers(); - } + numPlayers = getCompatiblePlayersCount(numPlayers); this.spnNumPlayers.setModel(new SpinnerNumberModel(numPlayers, tournamentType.getMinPlayers(), tournamentType.getMaxPlayers(), 1)); this.spnNumPlayers.setEnabled(tournamentType.getMinPlayers() != tournamentType.getMaxPlayers()); - this.spnNumSeats.setModel(new SpinnerNumberModel(2, 2, tournamentType.getMaxPlayers(), 1)); - // manual call change events to apply players/seats restrictions and create miss panels + // manual call change events to apply players restrictions and create miss panels before load player related settings // TODO: refactor to use isLoading and restrictions from a code instead restrictions from a component + this.chkSingleMultiplayerGame.setSelected(isSingleMultiplayerGame); this.spnNumPlayers.setValue(numPlayers); spnNumPlayersStateChanged(null); - this.spnNumSeats.setValue(numSeats); - spnNumSeatsStateChanged(null); + + // wins must be loaded after chkSingleMultiplayerGame change, cause it can be limited by 1 + int numWins = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_WINS + versionStr, "2")); + this.spnNumWins.setValue(numWins); if (loadPlayerSettings) { // load player data @@ -1259,8 +1268,7 @@ public class NewTournamentDialog extends MageDialog { private TournamentOptions getTournamentOptions() { TournamentTypeView tournamentType = (TournamentTypeView) cbTournamentType.getSelectedItem(); - int numSeats = (Integer) this.spnNumSeats.getValue(); - TournamentOptions tOptions = new TournamentOptions(this.txtName.getText(), "", numSeats); + TournamentOptions tOptions = new TournamentOptions(this.txtName.getText(), "", chkSingleMultiplayerGame.isSelected()); tOptions.setTournamentType(tournamentType.getName()); tOptions.setPassword(txtPassword.getText()); tOptions.getPlayerTypes().add(PlayerType.HUMAN); @@ -1423,7 +1431,6 @@ public class NewTournamentDialog extends MageDialog { break; } } - this.spnNumWins.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_WINS + versionStr, "2"))); this.spnQuitRatio.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_QUIT_RATIO + versionStr, "100"))); this.spnMinimumRating.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_MINIMUM_RATING + versionStr, "0"))); @@ -1431,7 +1438,6 @@ public class NewTournamentDialog extends MageDialog { activatePanelElements(tournamentType); int defaultNumberPlayers = 2; - int defaultNumberSeats = 2; if (tournamentType.isLimited()) { if (tournamentType.isDraft()) { defaultNumberPlayers = 4; @@ -1462,8 +1468,8 @@ public class NewTournamentDialog extends MageDialog { } int numPlayers = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_PLAYERS + versionStr, String.valueOf(defaultNumberPlayers))); - int numSeats = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_SEATS + versionStr, String.valueOf(defaultNumberSeats))); - prepareTourneyView(true, versionStr, numPlayers, numSeats); + boolean isSingleMultiplayerGame = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_SINGLE_MULTIPLAYER_GAME + versionStr, "No").equals("Yes"); + loadTourneyView(true, versionStr, numPlayers, isSingleMultiplayerGame); this.customOptions.onLoadSettings(version); } @@ -1511,7 +1517,7 @@ public class NewTournamentDialog extends MageDialog { } PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_PLAYERS + versionStr, Integer.toString(tOptions.getPlayerTypes().size())); - PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_SEATS + versionStr, Integer.toString((Integer) this.spnNumSeats.getValue())); + PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_SINGLE_MULTIPLAYER_GAME + versionStr, (tOptions.getMatchOptions().isSingleGameTourney() ? "Yes" : "No")); // save player data // player type @@ -1552,6 +1558,7 @@ public class NewTournamentDialog extends MageDialog { private javax.swing.JComboBox cbTournamentType; private javax.swing.JCheckBox chkRated; private javax.swing.JCheckBox chkRollbackTurnsAllowed; + private javax.swing.JCheckBox chkSingleMultiplayerGame; private javax.swing.JLabel jLabel6; private javax.swing.JLabel lbBufferTime; private javax.swing.JLabel lbDeckType; @@ -1563,7 +1570,6 @@ public class NewTournamentDialog extends MageDialog { private javax.swing.JLabel lblMinimumRating; private javax.swing.JLabel lblName; private javax.swing.JLabel lblNbrPlayers; - private javax.swing.JLabel lblNbrSeats; private javax.swing.JLabel lblNumRounds; private javax.swing.JLabel lblNumWins; private javax.swing.JLabel lblPacks; @@ -1592,7 +1598,6 @@ public class NewTournamentDialog extends MageDialog { private javax.swing.JSpinner spnMinimumRating; private javax.swing.JSpinner spnNumPlayers; private javax.swing.JSpinner spnNumRounds; - private javax.swing.JSpinner spnNumSeats; private javax.swing.JSpinner spnNumWins; private javax.swing.JSpinner spnQuitRatio; private javax.swing.JTextField txtName; diff --git a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java index aa9b7405784..1afc6ea294b 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java @@ -244,7 +244,7 @@ public class PreferencesDialog extends javax.swing.JDialog { public static final String KEY_NEW_TOURNAMENT_PACKS_DRAFT = "newTournamentPacksDraft"; public static final String KEY_NEW_TOURNAMENT_PACKS_RANDOM_DRAFT = "newTournamentPacksRandomDraft"; public static final String KEY_NEW_TOURNAMENT_NUMBER_PLAYERS = "newTournamentNumberPlayers"; - public static final String KEY_NEW_TOURNAMENT_NUMBER_SEATS = "newTournamentNumberSeats"; + public static final String KEY_NEW_TOURNAMENT_SINGLE_MULTIPLAYER_GAME = "newTournamentSingleMultiplayerGame"; public static final String KEY_NEW_TOURNAMENT_PLAYER_TYPES = "newTournamentPlayerTypes"; public static final String KEY_NEW_TOURNAMENT_PLAYER_SKILLS = "newTournamentPlayerSkills"; public static final String KEY_NEW_TOURNAMENT_DRAFT_TIMING = "newTournamentDraftTiming"; diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java index d94baacf55f..13301a9c6cd 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -1694,13 +1694,13 @@ public class TablesPanel extends javax.swing.JPanel { DeckCardLists testDeck = DeckImporter.importDeckFromFile(testDeckFile, false); PlayerType aiType = useMonteCarloAI ? PlayerType.COMPUTER_MONTE_CARLO : PlayerType.COMPUTER_MAD; - int numSeats = gameName.contains("2") || gameName.contains("Monte Carlo") ? 2 : 4; - boolean multiPlayer = numSeats > 2; + int numPlayers = gameName.contains("2") || gameName.contains("Monte Carlo") ? 2 : 4; + boolean multiPlayer = numPlayers > 2; - MatchOptions options = new MatchOptions(gameName, gameType, multiPlayer, numSeats); + MatchOptions options = new MatchOptions(gameName, gameType, multiPlayer); options.getPlayerTypes().add(PlayerType.HUMAN); options.getPlayerTypes().add(aiType); - for (int i=2 ; i < numSeats ; i++) { + for (int i=2 ; i < numPlayers ; i++) { options.getPlayerTypes().add(aiType); } options.setDeckType("Variant Magic - Freeform Commander"); @@ -1720,7 +1720,7 @@ public class TablesPanel extends javax.swing.JPanel { SessionHandler.joinTable(roomId, table.getTableId(), "Human", PlayerType.HUMAN, 1, testDeck, ""); SessionHandler.joinTable(roomId, table.getTableId(), "Computer", aiType, 1, testDeck, ""); - for (int i=2 ; i < numSeats ; i++) { + for (int i=2 ; i < numPlayers ; i++) { SessionHandler.joinTable(roomId, table.getTableId(), "Computer" + i, aiType, 1, testDeck, ""); } SessionHandler.startMatch(roomId, table.getTableId()); diff --git a/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java b/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java index aba4906af42..d614593caa2 100644 --- a/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java +++ b/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java @@ -234,12 +234,15 @@ public class TournamentPanel extends javax.swing.JPanel { if (tournament.getStepStartTime() != null) { usedTime = Format.getDuration((tournament.getServerTime().getTime() - tournament.getStepStartTime().getTime()) / 1000); } - txtTournamentState.setText(tournament.getTournamentState() + " (" + usedTime + ") " + tournament.getRunningInfo()); + txtTournamentState.setText(tournament.getTournamentState() + " (" + usedTime + ")"); break; default: txtTournamentState.setText(tournament.getTournamentState()); break; } + if (!tournament.getRunningInfo().isEmpty()) { + txtTournamentState.setText(txtTournamentState.getText() + ", " + tournament.getRunningInfo()); + } if (txtEndTime == null) { return; diff --git a/Mage.Common/src/main/java/mage/view/MatchView.java b/Mage.Common/src/main/java/mage/view/MatchView.java index 2aa07d3010a..52a92f98d06 100644 --- a/Mage.Common/src/main/java/mage/view/MatchView.java +++ b/Mage.Common/src/main/java/mage/view/MatchView.java @@ -121,8 +121,10 @@ public class MatchView implements Serializable { for (TournamentPlayer tPlayer : table.getTournament().getPlayers()) { sb2.append(tPlayer.getPlayer().getName()).append(": ").append(tPlayer.getResults()).append(' '); } + } else if (table.getTournament().getOptions().getMatchOptions().isSingleGameTourney()) { + sb2.append("Started single game"); } else { - sb2.append("Canceled"); + sb2.append("Canceled"); } this.result = sb2.toString(); this.startTime = table.getTournament().getStartTime(); diff --git a/Mage.Common/src/main/java/mage/view/TableView.java b/Mage.Common/src/main/java/mage/view/TableView.java index 63abb2e3f5d..8f7e33e435a 100644 --- a/Mage.Common/src/main/java/mage/view/TableView.java +++ b/Mage.Common/src/main/java/mage/view/TableView.java @@ -134,6 +134,8 @@ public class TableView implements Serializable { // TOURNAMENT if (table.getTournament().getOptions().getNumberRounds() > 0) { this.gameType = this.gameType + ' ' + table.getTournament().getOptions().getNumberRounds() + " Rounds"; + } else if (table.getTournament().getOptions().getMatchOptions().isSingleGameTourney()) { + this.gameType = this.gameType + " Single Game"; } StringBuilder sb1 = new StringBuilder(); for (TournamentPlayer tp : table.getTournament().getPlayers()) { @@ -167,6 +169,10 @@ public class TableView implements Serializable { infoTextShort.append(", Pick time: ").append(draftOptions.getTiming().getShortName()); infoTextLong.append("
Pick time: ").append(draftOptions.getTiming().getName()); } + if (table.getTournament().getOptions().getMatchOptions().isSingleGameTourney()) { + infoTextShort.append(", 1 GAME"); + infoTextLong.append("
Single Game with all players (1 GAME)"); + } if (table.getTournament().getOptions().isWatchingAllowed()) { infoTextShort.append(", SP"); infoTextLong.append("
Spectators allowed (SP)"); diff --git a/Mage.Common/src/main/java/mage/view/TournamentView.java b/Mage.Common/src/main/java/mage/view/TournamentView.java index 9da79bd8cad..48a7f9add3c 100644 --- a/Mage.Common/src/main/java/mage/view/TournamentView.java +++ b/Mage.Common/src/main/java/mage/view/TournamentView.java @@ -54,6 +54,8 @@ public class TournamentView implements Serializable { if (tournament.getTournamentState().equals("Drafting") && tournament.getDraft() != null) { runningInfo = "booster/card: " + tournament.getDraft().getBoosterNum() + '/' + (tournament.getDraft().getCardNum()); + } else if (tournament.getOptions().getMatchOptions().isSingleGameTourney()) { + runningInfo = "running single game match"; } else { runningInfo = ""; } diff --git a/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java b/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java index f486de1f0d6..939ee2db5b9 100644 --- a/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java +++ b/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java @@ -208,9 +208,18 @@ public class TournamentController { } private void endTournament() { - for (TournamentPlayer player : tournament.getPlayers()) { - player.setStateAtTournamentEnd(); + boolean setFinishPlayersStatus = true; + if (tournament.getRounds().isEmpty() && tournament.getOptions().getMatchOptions().isSingleGameTourney()) { + // single multiplayer game immediately finish the tourney, so keep dueling info all the time in tourney window + setFinishPlayersStatus = false; } + + if (setFinishPlayersStatus) { + for (TournamentPlayer player : tournament.getPlayers()) { + player.setStateAtTournamentEnd(); + } + } + for (final TournamentSession tournamentSession : tournamentSessions.values()) { tournamentSession.tournamentOver(); } @@ -270,9 +279,14 @@ public class TournamentController { table.setTournamentSubTable(this.tableId); table.setTournament(tournament); table.setState(TableState.WAITING); - if (round.getAllPlayers().stream().allMatch(tournamentPlayer -> getPlayerUserId(tournamentPlayer.getPlayer().getId()).isPresent())) { + if (round.getAllPlayers().stream() + .filter(t -> t.getPlayerType().equals(PlayerType.HUMAN)) + .allMatch(t -> getPlayerUserId(t.getPlayer().getId()).isPresent()) + ) { for (TournamentPlayer player : round.getAllPlayers()) { - tableManager.addPlayer(getPlayerUserId(player.getPlayer().getId()).get(), table.getId(), player); + // userId = null - it's AI opponent + UUID userId = getPlayerUserId(player.getPlayer().getId()).orElse(null); + tableManager.addPlayer(userId, table.getId(), player); } table.setState(TableState.STARTING); tableManager.startTournamentSubMatch(null, table.getId()); @@ -284,9 +298,11 @@ public class TournamentController { player.setState(TournamentPlayerState.DUELING); } }); + } else { + logger.error("tourney - startMultiplayerMatch can't start due disconnected players"); } } catch (GameException ex) { - logger.fatal("TournamentController startMatch error", ex); + logger.fatal("tourney - startMultiplayerMatch error", ex); } } diff --git a/Mage.Tests/src/frozen/org/mage/test/clientside/base/MageBase.java b/Mage.Tests/src/frozen/org/mage/test/clientside/base/MageBase.java index fd148123c09..5bd7fcc6e29 100644 --- a/Mage.Tests/src/frozen/org/mage/test/clientside/base/MageBase.java +++ b/Mage.Tests/src/frozen/org/mage/test/clientside/base/MageBase.java @@ -63,7 +63,7 @@ public class MageBase { connect("player", "localhost", 17171); UUID roomId = server.getMainRoomId(); - MatchOptions options = new MatchOptions("1", "Two Player Duel"); + MatchOptions options = new MatchOptions("1", "Two Player Duel", false); options.getPlayerTypes().add("Human"); options.getPlayerTypes().add("Computer - default"); options.setDeckType("Limited"); diff --git a/Mage.Tests/src/test/java/org/mage/test/game/FreeformUnlimitedCommander/FreeformUnlimitedCommanderMatchTest.java b/Mage.Tests/src/test/java/org/mage/test/game/FreeformUnlimitedCommander/FreeformUnlimitedCommanderMatchTest.java index e40706dfe5d..25897120080 100644 --- a/Mage.Tests/src/test/java/org/mage/test/game/FreeformUnlimitedCommander/FreeformUnlimitedCommanderMatchTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/game/FreeformUnlimitedCommander/FreeformUnlimitedCommanderMatchTest.java @@ -15,8 +15,7 @@ public class FreeformUnlimitedCommanderMatchTest extends MageTestPlayerBase { MatchOptions options = new MatchOptions( "test name", "test match name", - false, - 2 + false ); // Act @@ -32,8 +31,7 @@ public class FreeformUnlimitedCommanderMatchTest extends MageTestPlayerBase { MatchOptions options = new MatchOptions( "test name", "test match name", - false, - 2 + false ); Match match = new FreeformUnlimitedCommanderMatch(options); @@ -50,8 +48,7 @@ public class FreeformUnlimitedCommanderMatchTest extends MageTestPlayerBase { MatchOptions options = new MatchOptions( "test name", "test match name", - false, - 2 + false ); Match match = new FreeformUnlimitedCommanderMatch(options); diff --git a/Mage.Tests/src/test/java/org/mage/test/load/LoadTest.java b/Mage.Tests/src/test/java/org/mage/test/load/LoadTest.java index 8fad6bac7ef..97b27a023ea 100644 --- a/Mage.Tests/src/test/java/org/mage/test/load/LoadTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/load/LoadTest.java @@ -578,7 +578,7 @@ public class LoadTest { } private MatchOptions createSimpleGameOptions(String gameName, GameTypeView gameTypeView, Session session, PlayerType playersType) { - MatchOptions options = new MatchOptions(gameName, gameTypeView.getName(), true, 2); + MatchOptions options = new MatchOptions(gameName, gameTypeView.getName(), true); options.getPlayerTypes().add(playersType); options.getPlayerTypes().add(playersType); diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java index 014e2fb865e..a0c6cf587e1 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java @@ -178,8 +178,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement } // prepare fake match (needs for testing some client-server code) - // always 4 seats - MatchOptions matchOptions = new MatchOptions("test match", "test game type", true, 4); + MatchOptions matchOptions = new MatchOptions("test match", "test game type", true); currentMatch = new FreeForAllMatch(matchOptions); currentGame = createNewGameAndPlayers(); diff --git a/Mage/src/main/java/mage/game/FakeMatch.java b/Mage/src/main/java/mage/game/FakeMatch.java index 44cb401b961..44dbf6a7281 100644 --- a/Mage/src/main/java/mage/game/FakeMatch.java +++ b/Mage/src/main/java/mage/game/FakeMatch.java @@ -11,7 +11,7 @@ import mage.game.match.MatchOptions; public class FakeMatch extends MatchImpl { public FakeMatch() { - super(new MatchOptions("fake match", "fake game type", true, 2)); + super(new MatchOptions("fake match", "fake game type", false)); } @Override diff --git a/Mage/src/main/java/mage/game/match/MatchOptions.java b/Mage/src/main/java/mage/game/match/MatchOptions.java index a878a911f35..55e0eca3063 100644 --- a/Mage/src/main/java/mage/game/match/MatchOptions.java +++ b/Mage/src/main/java/mage/game/match/MatchOptions.java @@ -31,8 +31,7 @@ public class MatchOptions implements Serializable { protected String deckType; protected boolean limited; protected List playerTypes = new ArrayList<>(); - protected boolean multiPlayer; - protected int numSeats; + protected boolean multiPlayer; // allow to play single game with all tourney's players protected String password; protected SkillLevel skillLevel = SkillLevel.CASUAL; protected boolean rollbackTurnsAllowed; @@ -51,27 +50,14 @@ public class MatchOptions implements Serializable { protected Collection perPlayerEmblemCards = Collections.emptySet(); protected Collection globalEmblemCards = Collections.emptySet(); - public MatchOptions(String name, String gameType, boolean multiPlayer, int numSeats) { + public MatchOptions(String name, String gameType, boolean multiPlayer) { 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() { + public boolean isSingleGameTourney() { return multiPlayer; } diff --git a/Mage/src/main/java/mage/game/tournament/MultiplayerRound.java b/Mage/src/main/java/mage/game/tournament/MultiplayerRound.java index 6c9ba9f0b78..2f19c2c2d97 100644 --- a/Mage/src/main/java/mage/game/tournament/MultiplayerRound.java +++ b/Mage/src/main/java/mage/game/tournament/MultiplayerRound.java @@ -15,28 +15,19 @@ public class MultiplayerRound { private final int roundNum; private final Tournament tournament; - private final int numSeats; private final List allPlayers = new ArrayList<>(); private Match match; private UUID tableId; - public MultiplayerRound(int roundNum, Tournament tournament, int numSeats) { + public MultiplayerRound(int roundNum, Tournament tournament) { this.roundNum = roundNum; this.tournament = tournament; - this.numSeats = numSeats; } public List 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()); diff --git a/Mage/src/main/java/mage/game/tournament/TournamentImpl.java b/Mage/src/main/java/mage/game/tournament/TournamentImpl.java index 3872189d581..1af54ac63ce 100644 --- a/Mage/src/main/java/mage/game/tournament/TournamentImpl.java +++ b/Mage/src/main/java/mage/game/tournament/TournamentImpl.java @@ -25,6 +25,8 @@ import java.util.concurrent.CopyOnWriteArrayList; */ public abstract class TournamentImpl implements Tournament { + private static final Logger logger = Logger.getLogger(TournamentImpl.class); + protected UUID id = UUID.randomUUID(); protected UUID tableId = null; // assign on table create protected List rounds = new CopyOnWriteArrayList<>(); @@ -223,9 +225,11 @@ public abstract class TournamentImpl implements Tournament { } protected void playMultiplayerRound(MultiplayerRound round) { + // it's a single game, so tourney will be ends immediately + // and will keep one game active for better performance + // and less max tourney restrictions on the server + updateResults(); playMultiPlayerMatch(round); - - updateResults(); // show points from byes } protected List getActivePlayers() { @@ -248,6 +252,8 @@ public abstract class TournamentImpl implements Tournament { player.setPoints(0); player.setStateInfo(""); } + + // multiple games tourney for (Round round : rounds) { for (TournamentPairing pair : round.getPairs()) { Match match = pair.getMatch(); @@ -256,8 +262,10 @@ public abstract class TournamentImpl implements Tournament { TournamentPlayer tp2 = pair.getPlayer2(); MatchPlayer mp1 = match.getPlayer(pair.getPlayer1().getPlayer().getId()); MatchPlayer mp2 = match.getPlayer(pair.getPlayer2().getPlayer().getId()); + // set player state if they finished the round - if (round.getRoundNumber() == rounds.size()) { // for elimination getRoundNumber = 0 so never true here + // for elimination getRoundNumber = 0 so never true here + if (round.getRoundNumber() == rounds.size()) { match.setTournamentRound(round.getRoundNumber()); if (tp1.getState() == TournamentPlayerState.DUELING) { if (round.getRoundNumber() == getNumberRounds()) { @@ -274,6 +282,7 @@ public abstract class TournamentImpl implements Tournament { } } } + // Add round result tp1.setResults(addRoundResult(round.getRoundNumber(), pair, tp1, tp2)); tp2.setResults(addRoundResult(round.getRoundNumber(), pair, tp2, tp1)); diff --git a/Mage/src/main/java/mage/game/tournament/TournamentOptions.java b/Mage/src/main/java/mage/game/tournament/TournamentOptions.java index c81294ce3ee..4822ba1d583 100644 --- a/Mage/src/main/java/mage/game/tournament/TournamentOptions.java +++ b/Mage/src/main/java/mage/game/tournament/TournamentOptions.java @@ -26,9 +26,9 @@ public class TournamentOptions implements Serializable { protected int quitRatio; protected int minimumRating; - public TournamentOptions(String name, String matchType, int numSeats) { + public TournamentOptions(String name, String matchType, boolean isSingleMultiplayerGame) { this.name = name; - this.matchOptions = new MatchOptions("", matchType, numSeats > 2, numSeats); + this.matchOptions = new MatchOptions("", matchType, isSingleMultiplayerGame); } public String getName() { diff --git a/Mage/src/main/java/mage/game/tournament/TournamentSealedOptions.java b/Mage/src/main/java/mage/game/tournament/TournamentSealedOptions.java index 19d9ab3d6b5..5df7d96cf43 100644 --- a/Mage/src/main/java/mage/game/tournament/TournamentSealedOptions.java +++ b/Mage/src/main/java/mage/game/tournament/TournamentSealedOptions.java @@ -8,8 +8,8 @@ package mage.game.tournament; */ public class TournamentSealedOptions extends TournamentOptions { - public TournamentSealedOptions(String name, String matchType, int numSeats) { - super(name, matchType, numSeats); + public TournamentSealedOptions(String name, String matchType, boolean isSingleMultiplayerGame) { + super(name, matchType, isSingleMultiplayerGame); } } diff --git a/Mage/src/main/java/mage/game/tournament/TournamentSingleElimination.java b/Mage/src/main/java/mage/game/tournament/TournamentSingleElimination.java index 8d366a2136c..e2499db4344 100644 --- a/Mage/src/main/java/mage/game/tournament/TournamentSingleElimination.java +++ b/Mage/src/main/java/mage/game/tournament/TournamentSingleElimination.java @@ -2,13 +2,13 @@ package mage.game.tournament; -import java.util.Map; -import java.util.UUID; import mage.constants.MultiplayerAttackOption; import mage.game.events.TableEvent; +import java.util.Map; +import java.util.UUID; + /** - * * @author BetaSteward_at_googlemail.com */ public abstract class TournamentSingleElimination extends TournamentImpl { @@ -19,38 +19,39 @@ public abstract class TournamentSingleElimination extends TournamentImpl { @Override protected void runTournament() { - for (Map.Entry entry: players.entrySet()) { + for (Map.Entry entry : players.entrySet()) { if (entry.getValue().getPlayer().autoLoseGame()) { entry.getValue().setEliminated(); entry.getValue().setResults("Auto Eliminated"); } - } - if (options.matchOptions.getNumSeats() == 2) { + } + if (options.matchOptions.isSingleGameTourney()) { + // one game with all players + options.matchOptions.setAttackOption(MultiplayerAttackOption.MULTIPLE); + MultiplayerRound round = new MultiplayerRound(0, this); + for (TournamentPlayer player : getActivePlayers()) { + round.addPlayer(player); + } + playMultiplayerRound(round); + } else { + // split to multiple rounds/games 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 { - options.matchOptions.setAttackOption(MultiplayerAttackOption.MULTIPLE); - 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()) { + for (TournamentPairing pair : round.getPairs()) { pair.eliminatePlayers(); } } - } diff --git a/Mage/src/main/java/mage/game/tournament/TournamentSwiss.java b/Mage/src/main/java/mage/game/tournament/TournamentSwiss.java index 714305a73af..1870098ee87 100644 --- a/Mage/src/main/java/mage/game/tournament/TournamentSwiss.java +++ b/Mage/src/main/java/mage/game/tournament/TournamentSwiss.java @@ -1,19 +1,18 @@ package mage.game.tournament; -import java.util.List; -import java.util.Map.Entry; -import java.util.UUID; import mage.constants.MultiplayerAttackOption; - import mage.constants.TournamentPlayerState; import mage.game.events.TableEvent; import mage.game.tournament.pairing.RoundPairings; import mage.game.tournament.pairing.SwissPairingMinimalWeightMatching; import mage.game.tournament.pairing.SwissPairingSimple; +import java.util.List; +import java.util.Map.Entry; +import java.util.UUID; + /** - * * @author BetaSteward_at_googlemail.com */ public abstract class TournamentSwiss extends TournamentImpl { @@ -31,82 +30,65 @@ public abstract class TournamentSwiss extends TournamentImpl { } } - if (options.matchOptions.getNumSeats() == 2) { + if (options.matchOptions.isSingleGameTourney()) { + // one game with all players (it's same as normal tourney's mode) + options.matchOptions.setAttackOption(MultiplayerAttackOption.MULTIPLE); + MultiplayerRound round = new MultiplayerRound(0, this); + for (TournamentPlayer player : getActivePlayers()) { + round.addPlayer(player); + } + playMultiplayerRound(round); + } else { + // split to multiple rounds/games 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 { - options.matchOptions.setAttackOption(MultiplayerAttackOption.MULTIPLE); - MultiplayerRound round = createMultiplayerRound(); - playMultiplayerRound(round); } - + nextStep(); } protected Round createRoundSwiss() { + // multiple rounds, can be called multiple times per tourney + List roundPlayers = getActivePlayers(); boolean isLastRound = (rounds.size() + 1 == getNumberRounds()); + if (options.matchOptions.isSingleGameTourney()) { + throw new IllegalStateException("Wrong code usage: multi rounds for non single game tourneys only (e.g. with two seats)"); + } 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 { - 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(); + 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 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(); } return round; } - - public MultiplayerRound createMultiplayerRound() { - List roundPlayers = getActivePlayers(); - boolean isLastRound = (rounds.size() + 1 == getNumberRounds()); - - MultiplayerRound round = null; - if (options.matchOptions.getNumSeats() > 2) { - options.matchOptions.setAttackOption(MultiplayerAttackOption.MULTIPLE); - 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; - - } }