Search in sources :

Example 16 with SOCGameOption

use of soc.game.SOCGameOption in project JSettlers2 by jdmonin.

the class TestBoardLayouts method testSingleLayout.

/**
 * Test one scenario's layout for a given number of players.
 * @param sc  Scenario to test, or {@code null} for classic games
 * @param pl  Number of players (3, 4, 6, etc)
 * @return  True if OK, false if construction failed
 */
public final boolean testSingleLayout(final SOCScenario sc, final int pl) {
    final Map<String, SOCGameOption> gaOpts = SOCGameOption.parseOptionsToMap("PL=" + pl + ((sc != null) ? ",SC=" + sc.key : ""));
    if (gaOpts != null)
        assertNull("Unexpected problems with scenario options", SOCGameOption.adjustOptionsToKnown(gaOpts, null, true));
    // this same pre-check is done by TestScenarioOpts.testAllScenarios()
    final String gaName = ((sc != null) ? sc.key : "classic") + ":" + pl;
    gl.createGame(gaName, "test", "en_US", gaOpts, sgh);
    final SOCGame ga = gl.getGameData(gaName);
    assertNotNull("Game not created", ga);
    // which has a reminder comment to keep sync'd with this test method
    try {
        ga.addPlayer("player", 1);
        // SOCBoard/SOCBoardAtServer.makeNewBoard is called here
        ga.startGame();
        gl.deleteGame(gaName);
    } catch (Exception e) {
        System.err.println("Error at board setup: " + gaName + ", " + pl + " players:");
        e.printStackTrace();
        return false;
    }
    return true;
}
Also used : SOCGameOption(soc.game.SOCGameOption) SOCGame(soc.game.SOCGame)

Example 17 with SOCGameOption

use of soc.game.SOCGameOption in project JSettlers2 by jdmonin.

the class TestScenarioOpts method testAllScenarios.

/**
 * Test all {@link SOCScenario}s' game option consistency,
 * as described in {@link TestScenarioOpts class javadoc}.
 */
@Test
public void testAllScenarios() {
    // use TreeSet for sorted results
    final TreeSet<String> badScens = new TreeSet<String>();
    for (final SOCScenario sc : SOCScenario.getAllKnownScenarios().values()) {
        if (sc.scOpts.equals("-"))
            continue;
        try {
            final Map<String, SOCGameOption> parsedOpts = SOCGameOption.parseOptionsToMap(sc.scOpts);
            // will be null if any opts failed parsing
            StringBuilder sb = null;
            // This same pre-check is done by TestBoardLayouts.testSingleLayout(..)
            if (parsedOpts != null) {
                sb = SOCGameOption.adjustOptionsToKnown(parsedOpts, null, true);
                if (null != sb) {
                    badScens.add(sc.key + ": Bad game options found by SGO.adjustOptionsToKnown: " + sb);
                    continue;
                }
            }
            sb = new StringBuilder();
            // Check for bad or changed values from sc.scOpts name-value pairs (nvpairs)
            for (String nvpair : sc.scOpts.split(SOCMessage.sep2)) {
                if (nvpair.length() == 0) {
                    if (sb.length() > 0)
                        sb.append(", ");
                    sb.append("Adjacent commas in sc.scOpts");
                    continue;
                }
                int i = nvpair.indexOf("=");
                if ((i <= 0) || (i == nvpair.length() - 1)) {
                    if (sb.length() > 0)
                        sb.append(", ");
                    sb.append("Malformed name=value in sc.scOpts: \"" + nvpair + '"');
                    continue;
                }
                if (parsedOpts == null) {
                    if (null == SOCGameOption.parseOptionNameValue(nvpair, false)) {
                        if (sb.length() > 0)
                            sb.append(", ");
                        sb.append("Cannot parse option: check type and syntax: \"" + nvpair + '"');
                    }
                } else {
                    final String origKey = nvpair.substring(0, i);
                    if (!parsedOpts.containsKey(origKey)) {
                        if (sb.length() > 0)
                            sb.append(", ");
                        sb.append("sc.scOpts key not found in parsed opts: \"" + nvpair + '"');
                        continue;
                    }
                    final String repacked = parsedOpts.get(origKey).toString();
                    if (!repacked.equals(nvpair)) {
                        if (sb.length() > 0)
                            sb.append(", ");
                        sb.append("sc.scOpts value changed by SGO.adjustOptionsToKnown: \"" + nvpair + "\" -> \"" + repacked + '"');
                    }
                }
            }
            if (sb.length() > 0) {
                badScens.add(sc.key + ": " + sb);
                sb.delete(0, sb.length());
            }
            // Check opt versions
            if (parsedOpts != null) {
                int optsVers = -1;
                for (SOCGameOption opt : parsedOpts.values()) {
                    final int vers = opt.minVersion;
                    if (vers > optsVers)
                        optsVers = vers;
                    if (vers > sc.minVersion) {
                        if (sb.length() > 0)
                            sb.append(", ");
                        sb.append(opt.key);
                    }
                }
                if (sb.length() > 0)
                    badScens.add(sc.key + ": Game options minVersion (" + optsVers + ") too new for scenario minVersion (" + sc.minVersion + "): " + sb);
            }
        } catch (IllegalArgumentException e) {
            badScens.add(sc.key + ": bad option name: " + e.getMessage());
        }
    }
    if (!badScens.isEmpty())
        System.out.println("SOCScenarios with inconsistent game options: " + badScens);
    assertTrue("SOCScenario game option consistency", badScens.isEmpty());
}
Also used : TreeSet(java.util.TreeSet) SOCGameOption(soc.game.SOCGameOption) SOCScenario(soc.game.SOCScenario) Test(org.junit.Test)

Example 18 with SOCGameOption

use of soc.game.SOCGameOption in project JSettlers2 by jdmonin.

the class NewGameOptionsFrame method readOptsValuesFromControls.

/**
 * Read option values from controls, as prep to request the new game.
 * If there is a problem (out of range, bad character in integer field, etc),
 * set {@link #msgText} and set focus on the field.
 * @param checkOptionsMinVers Warn the user if the options will require a
 *           minimum client version?  Won't do so if {@link #forPractice} is set,
 *           because this isn't a problem for local practice games.
 *           The warning is skipped if that minimum is an old version
 *           &lt;= {@link Version#versionNumberMaximumNoWarn()}.
 * @return true if all were read OK, false if a problem (such as NumberFormatException)
 */
private boolean readOptsValuesFromControls(final boolean checkOptionsMinVers) {
    if (readOnly)
        // shouldn't be called in that case
        return false;
    boolean allOK = true;
    for (Component ctrl : controlsOpts.keySet()) {
        if (ctrl instanceof Label)
            continue;
        SOCGameOption op = controlsOpts.get(ctrl);
        if (op.key.equals("SC")) {
            // Special case: AWT event listeners have already set its value from controls
            if (!op.getBoolValue())
                op.setStringValue("");
            continue;
        }
        if (ctrl instanceof Checkbox) {
            op.setBoolValue(((Checkbox) ctrl).getState());
        } else if (ctrl instanceof TextField) {
            String txt = ((TextField) ctrl).getText().trim();
            if ((op.optType == SOCGameOption.OTYPE_STR) || (op.optType == SOCGameOption.OTYPE_STRHIDE)) {
                try {
                    op.setStringValue(txt);
                } catch (IllegalArgumentException ex) {
                    allOK = false;
                    // only a single line of text allowed
                    msgText.setText(strings.get("game.options.singleline"));
                    ctrl.requestFocusInWindow();
                }
            } else {
            // OTYPE_INT, OTYPE_INTBOOL; defer setting until after all checkboxes have been read
            }
        } else if (ctrl instanceof Choice) {
            // this works with OTYPE_INT, OTYPE_INTBOOL, OTYPE_ENUM, OTYPE_ENUMBOOL
            // 0 to n-1
            int chIdx = ((Choice) ctrl).getSelectedIndex();
            if (chIdx != -1)
                op.setIntValue(chIdx + op.minIntValue);
            else
                allOK = false;
        }
    }
    // Use 0 if blank (still checks if in range).
    for (Component ctrl : controlsOpts.keySet()) {
        if (!(ctrl instanceof TextField))
            continue;
        SOCGameOption op = controlsOpts.get(ctrl);
        if (op.optType == SOCGameOption.OTYPE_INTBOOL) {
            if (!op.getBoolValue())
                continue;
        } else if (op.optType != SOCGameOption.OTYPE_INT) {
            continue;
        }
        String txt = ((TextField) ctrl).getText().trim();
        try {
            int iv;
            if (txt.length() > 0)
                iv = Integer.parseInt(txt);
            else
                iv = 0;
            op.setIntValue(iv);
            if (iv != op.getIntValue()) {
                allOK = false;
                msgText.setText(// "out of range"
                strings.get("game.options.outofrange", op.minIntValue, op.maxIntValue));
                ctrl.requestFocusInWindow();
            }
        } catch (NumberFormatException ex) {
            allOK = false;
            // "please use only digits here"
            msgText.setText(strings.get("game.options.onlydigits"));
            ctrl.requestFocusInWindow();
        }
    }
    if (allOK && checkOptionsMinVers && !forPractice) {
        int optsVers = SOCVersionedItem.itemsMinimumVersion(controlsOpts);
        if ((optsVers > -1) && (optsVers > Version.versionNumberMaximumNoWarn())) {
            allOK = false;
            new VersionConfirmDialog(this, optsVers).setVisible(true);
        }
    }
    return allOK;
}
Also used : Choice(java.awt.Choice) Checkbox(java.awt.Checkbox) SOCGameOption(soc.game.SOCGameOption) Label(java.awt.Label) TextField(java.awt.TextField) Component(java.awt.Component)

Example 19 with SOCGameOption

use of soc.game.SOCGameOption in project JSettlers2 by jdmonin.

the class NewGameOptionsFrame method fireOptionChangeListener.

/**
 * Handle firing a game option's ChangeListener, and refreshing related
 * gameopts' values on-screen if needed.
 * If <tt>oldValue</tt>.equals(<tt>newValue</tt>), nothing happens and
 * the ChangeListener is not called.
 * @param cl  The ChangeListener; must not be null
 * @param opt  The game option
 * @param oldValue  Old value, string or boxed primitive
 * @param newValue  New value, string or boxed primitive
 * @since 1.1.13
 */
private void fireOptionChangeListener(SOCGameOption.ChangeListener cl, SOCGameOption opt, final Object oldValue, final Object newValue) {
    if (oldValue.equals(newValue))
        // <--- Early return: Value didn't change ---
        return;
    try {
        cl.valueChanged(opt, oldValue, newValue, opts);
    } catch (Throwable thr) {
        System.err.println("-- Error caught in ChangeListener: " + thr.toString() + " --");
        thr.printStackTrace();
        while (thr.getCause() != null) {
            thr = thr.getCause();
            System.err.println(" --> Cause: " + thr + " --");
            thr.printStackTrace();
        }
        System.err.println("-- Error stack trace end --");
        System.err.println();
    }
    List<SOCGameOption> refresh = SOCGameOption.getAndClearRefreshList();
    if (refresh == null)
        // <--- Early return: Nothing else changed ---
        return;
    // Refresh each one now, depending on type:
    if (optsControls == null)
        // should only be null if readOnly, and thus no changes to values anyway
        return;
    for (int i = refresh.size() - 1; i >= 0; --i) {
        final SOCGameOption op = refresh.get(i);
        final Component opComp = optsControls.get(op.key);
        switch(// OTYPE_*
        op.optType) {
            case SOCGameOption.OTYPE_BOOL:
                ((Checkbox) opComp).setState(op.getBoolValue());
                break;
            case SOCGameOption.OTYPE_INT:
            case SOCGameOption.OTYPE_INTBOOL:
                {
                    if (opComp instanceof TextField)
                        ((TextField) opComp).setText(Integer.toString(op.getIntValue()));
                    else
                        ((Choice) opComp).select(op.getIntValue() - op.minIntValue);
                    final boolean hasCheckbox = (op.optType == SOCGameOption.OTYPE_INTBOOL);
                    if (hasCheckbox) {
                        Checkbox cb = boolOptCheckboxes.get(op.key);
                        if (cb != null)
                            cb.setState(op.getBoolValue());
                    }
                }
                break;
            case SOCGameOption.OTYPE_ENUM:
            case SOCGameOption.OTYPE_ENUMBOOL:
                {
                    ((Choice) opComp).select(op.getIntValue() - op.minIntValue);
                    final boolean hasCheckbox = (op.optType == SOCGameOption.OTYPE_ENUMBOOL);
                    if (hasCheckbox) {
                        Checkbox cb = boolOptCheckboxes.get(op.key);
                        if (cb != null)
                            cb.setState(op.getBoolValue());
                    }
                }
                break;
            case SOCGameOption.OTYPE_STR:
            case SOCGameOption.OTYPE_STRHIDE:
                ((TextField) opComp).setText(op.getStringValue());
                break;
        }
    }
}
Also used : Choice(java.awt.Choice) Checkbox(java.awt.Checkbox) SOCGameOption(soc.game.SOCGameOption) TextField(java.awt.TextField) Component(java.awt.Component)

Example 20 with SOCGameOption

use of soc.game.SOCGameOption in project JSettlers2 by jdmonin.

the class NewGameOptionsFrame method textValueChanged.

/**
 * When gamename contents change, enable/disable buttons as appropriate. (TextListener)
 * Also handles {@link SOCGameOption#OTYPE_INTBOOL} textfield/checkbox combos.
 * Also sets {@link SOCGameOption#userChanged}.
 * @param e textevent from {@link #gameName}, or from a TextField in {@link #controlsOpts}
 */
public void textValueChanged(TextEvent e) {
    if (readOnly)
        return;
    Object srcObj = e.getSource();
    if (!(srcObj instanceof TextField))
        return;
    final String newText = ((TextField) srcObj).getText().trim();
    final boolean notEmpty = (newText.length() > 0);
    if (srcObj == gameName) {
        if (notEmpty != create.isEnabled())
            // enable "create" btn only if game name filled in
            create.setEnabled(notEmpty);
    } else {
        // Check for a ChangeListener for OTYPE_STR and OTYPE_STRHIDE,
        // OTYPE_INT and OTYPE_INTBOOL.
        // if source is OTYPE_INTBOOL, check its checkbox vs notEmpty.
        SOCGameOption opt = controlsOpts.get(srcObj);
        if (opt == null)
            return;
        final String oldText = opt.getStringValue();
        boolean validChange = false;
        boolean otypeIsInt;
        int oldIntValue = 0;
        if ((opt.optType == SOCGameOption.OTYPE_STR) || (opt.optType == SOCGameOption.OTYPE_STRHIDE)) {
            otypeIsInt = false;
            try {
                opt.setStringValue(newText);
                validChange = true;
            } catch (IllegalArgumentException ex) {
            }
        } else {
            otypeIsInt = true;
            try // OTYPE_INT, OTYPE_INTBOOL
            {
                final int iv = Integer.parseInt(newText);
                oldIntValue = opt.getIntValue();
                // ignored if outside min,max range
                opt.setIntValue(iv);
                if (iv == opt.getIntValue())
                    validChange = true;
            } catch (NumberFormatException ex) {
            }
        }
        if (validChange && !opt.userChanged)
            opt.userChanged = true;
        // If this string or int option also has a bool checkbox,
        // set or clear that based on string/int not empty.
        boolean cbSet = false;
        Checkbox cb = boolOptCheckboxes.get(opt.key);
        if ((cb != null) && (notEmpty != cb.getState())) {
            cb.setState(notEmpty);
            opt.setBoolValue(notEmpty);
            cbSet = true;
        }
        SOCGameOption.ChangeListener cl = opt.getChangeListener();
        if (cl == null)
            return;
        // calling fireOptionChangeListener.  Boolean is called before int.
        if (cbSet) {
            // ChangeListener for checkbox
            final Boolean newValue = (notEmpty) ? Boolean.TRUE : Boolean.FALSE;
            final Boolean oldValue = (notEmpty) ? Boolean.FALSE : Boolean.TRUE;
            fireOptionChangeListener(cl, opt, oldValue, newValue);
        }
        // ChangeListener for text field
        if (validChange) {
            if (otypeIsInt)
                fireOptionChangeListener(cl, opt, new Integer(oldIntValue), new Integer(opt.getIntValue()));
            else
                fireOptionChangeListener(cl, opt, oldText, newText);
        }
    }
}
Also used : Checkbox(java.awt.Checkbox) SOCGameOption(soc.game.SOCGameOption) TextField(java.awt.TextField)

Aggregations

SOCGameOption (soc.game.SOCGameOption)20 Checkbox (java.awt.Checkbox)5 TextField (java.awt.TextField)3 MissingResourceException (java.util.MissingResourceException)3 TreeSet (java.util.TreeSet)3 SOCScenario (soc.game.SOCScenario)3 Choice (java.awt.Choice)2 Component (java.awt.Component)2 Label (java.awt.Label)2 ArrayList (java.util.ArrayList)2 Test (org.junit.Test)2 FileInputStream (java.io.FileInputStream)1 IOException (java.io.IOException)1 SQLException (java.sql.SQLException)1 Timestamp (java.sql.Timestamp)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 PropertyResourceBundle (java.util.PropertyResourceBundle)1 StringTokenizer (java.util.StringTokenizer)1 SOCGame (soc.game.SOCGame)1