001    /**
002     * Jetrix TetriNET Server
003     * Copyright (C) 2001-2004  Emmanuel Bourg
004     *
005     * This program is free software; you can redistribute it and/or
006     * modify it under the terms of the GNU General Public License
007     * as published by the Free Software Foundation; either version 2
008     * of the License, or (at your option) any later version.
009     *
010     * This program is distributed in the hope that it will be useful,
011     * but WITHOUT ANY WARRANTY; without even the implied warranty of
012     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013     * GNU General Public License for more details.
014     *
015     * You should have received a copy of the GNU General Public License
016     * along with this program; if not, write to the Free Software
017     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
018     */
019    
020    package net.jetrix.config;
021    
022    import java.util.*;
023    
024    /**
025     * Game settings.
026     *
027     * @author Emmanuel Bourg
028     * @version $Revision: 833 $, $Date: 2010-03-08 10:04:45 +0100 (lun., 08 mars 2010) $
029     */
030    public class Settings
031    {
032        /** Default settings used by new Settings objets */
033        private static Settings defaultSettings;
034    
035        /** indicates if this setting objets use the default block occurancy settings */
036        private boolean defaultBlockOccurancy;
037    
038        /** indicates if this setting objets use the default block occurancy settings */
039        private boolean defaultSpecialOccurancy;
040    
041        private boolean defaultStartingLevel;
042        private boolean defaultStackHeight;
043        private boolean defaultLinesPerLevel;
044        private boolean defaultLinesPerSpecial;
045        private boolean defaultLevelIncrease;
046        private boolean defaultSpecialAdded;
047        private boolean defaultSpecialCapacity;
048        private boolean defaultAverageLevels;
049        private boolean defaultClassicRules;
050        private boolean defaultSameBlocks;
051    
052        private boolean defaultSuddenDeathTime;
053        private boolean defaultSuddenDeathMessage;
054        private boolean defaultSuddenDeathLinesAdded;
055        private boolean defaultSuddenDeathDelay;
056    
057        private int startingLevel;
058        private int stackHeight;
059        private int linesPerLevel;
060        private int linesPerSpecial;
061        private int levelIncrease;
062        private int specialAdded;
063        private int specialCapacity;
064        private int blockOccurancy[];
065        private int specialOccurancy[];
066        private boolean averageLevels;
067        private boolean classicRules;
068        private boolean sameBlocks;
069    
070        /** The time in seconds before the sudden death mode starts. */
071        private int suddenDeathTime;
072    
073        /** The message displayed when the sudden death mode starts. */
074        private String suddenDeathMessage;
075    
076        /** The delay in seconds between lines additions in sudden death mode. */
077        private int suddenDeathDelay;
078    
079        /** The number of lines added in sudden death mode. */
080        private int suddenDeathLinesAdded;
081    
082    
083        /**
084         * Creates a new Settings objects using default settings.
085         */
086        public Settings()
087        {
088            this(true);
089        }
090    
091        /**
092         * Creates a new Settings object. If <tt>useDefaultSettings</tt> is <tt>true</tt>,
093         * calls to getBlockOccurancy() will be forwarded to the default settings
094         * objets until the method setBlockOccurancy() is used to overwrite the
095         * default configuration (same thing with specials).
096         */
097        public Settings(boolean useDefaultSettings)
098        {
099            blockOccurancy = new int[Block.values().length];
100            specialOccurancy = new int [Special.values().length];
101    
102            if (useDefaultSettings)
103            {
104                defaultBlockOccurancy = true;
105                defaultSpecialOccurancy = true;
106                defaultStartingLevel = true;
107                defaultStackHeight = true;
108                defaultLinesPerLevel = true;
109                defaultLinesPerSpecial = true;
110                defaultLevelIncrease = true;
111                defaultSpecialAdded = true;
112                defaultSpecialCapacity = true;
113                defaultAverageLevels = true;
114                defaultClassicRules = true;
115                defaultSameBlocks = true;
116                defaultSuddenDeathTime = true;
117                defaultSuddenDeathMessage = true;
118                defaultSuddenDeathDelay = true;
119                defaultSuddenDeathLinesAdded = true;
120            }
121        }
122    
123        /**
124         * Returns the default Settings object.
125         */
126        public static Settings getDefaultSettings()
127        {
128            return defaultSettings;
129        }
130    
131        /**
132         * Sets the default Settings object.
133         */
134        public static void setDefaultSettings(Settings defaultSettings)
135        {
136            Settings.defaultSettings = defaultSettings;
137        }
138    
139        /**
140         * Tell if the current Settings use the default Settings for all its values.
141         */
142        public boolean useDefaultSettings()
143        {
144            return defaultBlockOccurancy
145                    && defaultSpecialOccurancy
146                    && defaultStartingLevel
147                    && defaultStackHeight
148                    && defaultLinesPerLevel
149                    && defaultLinesPerSpecial
150                    && defaultLevelIncrease
151                    && defaultSpecialAdded
152                    && defaultSpecialCapacity
153                    && defaultAverageLevels
154                    && defaultClassicRules
155                    && defaultSameBlocks
156                    && defaultSuddenDeathTime
157                    && defaultSuddenDeathMessage
158                    && defaultSuddenDeathDelay
159                    && defaultSuddenDeathLinesAdded;
160        }
161    
162        public int getStartingLevel()
163        {
164            return isDefaultStartingLevel() ? defaultSettings.getStartingLevel() : startingLevel;
165        }
166    
167        public int getStackHeight()
168        {
169            return isDefaultStackHeight() ? defaultSettings.getStackHeight() : stackHeight;
170        }
171    
172        public int getLinesPerLevel()
173        {
174            return isDefaultLinesPerLevel() ? defaultSettings.getLinesPerLevel() : linesPerLevel;
175        }
176    
177        public int getLinesPerSpecial()
178        {
179            return isDefaultLinesPerSpecial() ? defaultSettings.getLinesPerSpecial() : linesPerSpecial;
180        }
181    
182        public int getLevelIncrease()
183        {
184            return isDefaultLevelIncrease() ? defaultSettings.getLevelIncrease() : levelIncrease;
185        }
186    
187        public int getSpecialAdded()
188        {
189            return isDefaultSpecialAdded() ? defaultSettings.getSpecialAdded() : specialAdded;
190        }
191    
192        public int getSpecialCapacity()
193        {
194            return isDefaultSpecialCapacity() ? defaultSettings.getSpecialCapacity() : specialCapacity;
195        }
196    
197        public boolean getAverageLevels()
198        {
199            return isDefaultAverageLevels() ? defaultSettings.getAverageLevels() : averageLevels;
200        }
201    
202        public boolean getClassicRules()
203        {
204            return isDefaultClassicRules() ? defaultSettings.getClassicRules() : classicRules;
205        }
206    
207        public boolean getSameBlocks()
208        {
209            return isDefaultSameBlocks() ? defaultSettings.getSameBlocks() : sameBlocks;
210        }
211    
212        public int getOccurancy(Block piece)
213        {
214            return isDefaultBlockOccurancy() ? defaultSettings.getOccurancy(piece) : blockOccurancy[piece.ordinal()];
215        }
216    
217        public int getOccurancy(Special special)
218        {
219            return isDefaultSpecialOccurancy() ? defaultSettings.getOccurancy(special) : specialOccurancy[special.ordinal()];
220        }
221    
222        public void setStartingLevel(int startingLevel)
223        {
224            this.startingLevel = startingLevel;
225            defaultStartingLevel = false;
226        }
227    
228        public void setStackHeight(int stackHeight)
229        {
230            this.stackHeight = stackHeight;
231            defaultStackHeight = false;
232        }
233    
234        public void setLinesPerLevel(int linesPerLevel)
235        {
236            this.linesPerLevel = linesPerLevel;
237            defaultLinesPerLevel = false;
238        }
239    
240        public void setLinesPerSpecial(int linesPerSpecial)
241        {
242            this.linesPerSpecial = linesPerSpecial;
243            defaultLinesPerSpecial = false;
244        }
245    
246        public void setLevelIncrease(int levelIncrease)
247        {
248            this.levelIncrease = levelIncrease;
249            defaultLevelIncrease = false;
250        }
251    
252        public void setSpecialAdded(int specialAdded)
253        {
254            this.specialAdded = specialAdded;
255            defaultSpecialAdded = false;
256        }
257    
258        public void setSpecialCapacity(int specialCapacity)
259        {
260            this.specialCapacity = specialCapacity;
261            defaultSpecialCapacity = false;
262        }
263    
264        public void setAverageLevels(boolean averageLevels)
265        {
266            this.averageLevels = averageLevels;
267            defaultAverageLevels = false;
268        }
269    
270        public void setClassicRules(boolean classicRules)
271        {
272            this.classicRules = classicRules;
273            defaultClassicRules = false;
274        }
275    
276        public void setSameBlocks(boolean sameBlocks)
277        {
278            this.sameBlocks = sameBlocks;
279            defaultSameBlocks = false;
280        }
281    
282    
283        public int getSuddenDeathTime()
284        {
285            return isDefaultSuddenDeathTime() ? defaultSettings.getSuddenDeathTime() : suddenDeathTime;
286        }
287    
288        public void setSuddenDeathTime(int suddenDeathTime)
289        {
290            this.suddenDeathTime = suddenDeathTime;
291            defaultSuddenDeathTime = false;
292        }
293    
294        public String getSuddenDeathMessage()
295        {
296            return isDefaultSuddenDeathMessage() ? defaultSettings.getSuddenDeathMessage() : suddenDeathMessage;
297        }
298    
299        public void setSuddenDeathMessage(String suddenDeathMessage)
300        {
301            this.suddenDeathMessage = suddenDeathMessage;
302            defaultSuddenDeathMessage = false;
303        }
304    
305        public int getSuddenDeathLinesAdded()
306        {
307            return isDefaultSuddenDeathLinesAdded() ? defaultSettings.getSuddenDeathLinesAdded() : suddenDeathLinesAdded;
308        }
309    
310        public void setSuddenDeathLinesAdded(int suddenDeathLinesAdded)
311        {
312            this.suddenDeathLinesAdded = suddenDeathLinesAdded;
313            defaultSuddenDeathLinesAdded = false;
314        }
315    
316        public int getSuddenDeathDelay()
317        {
318            return isDefaultSuddenDeathDelay() ? defaultSettings.getSuddenDeathDelay() : suddenDeathDelay;
319        }
320    
321        public void setSuddenDeathDelay(int suddenDeathDelay)
322        {
323            this.suddenDeathDelay = suddenDeathDelay;
324            defaultSuddenDeathDelay = false;
325        }
326    
327    
328        /**
329         * Set the occurancy of a block.
330         *
331         * @since 0.2
332         *
333         * @param block
334         * @param occurancy
335         */
336        public void setOccurancy(Block block, int occurancy)
337        {
338            if (defaultBlockOccurancy)
339            {
340                defaultBlockOccurancy = false;
341                Arrays.fill(blockOccurancy, 0);
342            }
343    
344            blockOccurancy[block.ordinal()] = occurancy;
345        }
346    
347        /**
348         * Set the occurancy of a special block
349         *
350         * @since 0.2
351         *
352         * @param special
353         * @param occurancy
354         */
355        public void setOccurancy(Special special, int occurancy)
356        {
357            if (defaultSpecialOccurancy)
358            {
359                defaultSpecialOccurancy = false;
360                Arrays.fill(specialOccurancy, 0);
361            }
362    
363            specialOccurancy[special.ordinal()] = occurancy;
364        }
365    
366        /**
367         * Normalize array values to get a sum equals to 100.
368         * Any negative value is nullified.
369         */
370        protected void normalize(int[] tab)
371        {
372            int sum = 0;
373    
374            // computing sum
375            for (int i = 0; i < tab.length; i++)
376            {
377                if (tab[i] < 0)
378                {
379                    tab[i] = 0;
380                }
381                sum = sum + tab[i];
382            }
383    
384            if (sum != 100)
385            {
386                // equalization
387                if (sum == 0)
388                {
389                    int v = 100 / tab.length;
390                    for (int i = 0; i < tab.length; i++)
391                    {
392                        tab[i] = v;
393                    }
394                }
395                else
396                {
397                    float f = 100f / sum;
398                    for (int i = 0; i < tab.length; i++)
399                    {
400                        tab[i] = (int) (tab[i] * f);
401                    }
402                }
403    
404                // distributing points left
405                sum = 0;
406                for (int i = 0; i < tab.length; i++)
407                {
408                    sum = sum + tab[i];
409                }
410                int r = 100 - sum;
411                int i = 0;
412                while (i < tab.length && r > 0)
413                {
414                    tab[i] = tab[i] + 1;
415                    r = r - 1;
416                    i = i + 1;
417                }
418            }
419        }
420    
421    
422        public void normalizeBlockOccurancy()
423        {
424            normalize(blockOccurancy);
425        }
426    
427        public void normalizeSpecialOccurancy()
428        {
429            normalize(specialOccurancy);
430        }
431    
432        private boolean isDefault()
433        {
434            return defaultSettings == null || this == defaultSettings;
435        }
436    
437        /**
438         * Tells if the block occurancies of the default settings are used.
439         */
440        public boolean isDefaultBlockOccurancy()
441        {
442            return defaultBlockOccurancy && !isDefault();
443        }
444    
445        public void setDefaultBlockOccurancy(boolean defaultBlockOccurancy)
446        {
447            this.defaultBlockOccurancy = defaultBlockOccurancy;
448        }
449    
450        /**
451         * Tells if the special occurancies of the default settings are used.
452         */
453        public boolean isDefaultSpecialOccurancy()
454        {
455            return defaultSpecialOccurancy && !isDefault();
456        }
457    
458        public void setDefaultSpecialOccurancy(boolean defaultSpecialOccurancy)
459        {
460            this.defaultSpecialOccurancy = defaultSpecialOccurancy;
461        }
462    
463        public boolean isDefaultStartingLevel()
464        {
465            return defaultStartingLevel && !isDefault();
466        }
467    
468        public void setDefaultStartingLevel(boolean defaultStartingLevel)
469        {
470            this.defaultStartingLevel = defaultStartingLevel;
471        }
472    
473        public boolean isDefaultStackHeight()
474        {
475            return defaultStackHeight && !isDefault();
476        }
477    
478        public void setDefaultStackHeight(boolean defaultStackHeight)
479        {
480            this.defaultStackHeight = defaultStackHeight;
481        }
482    
483        public boolean isDefaultLinesPerLevel()
484        {
485            return defaultLinesPerLevel && !isDefault();
486        }
487    
488        public void setDefaultLinesPerLevel(boolean defaultLinesPerLevel)
489        {
490            this.defaultLinesPerLevel = defaultLinesPerLevel;
491        }
492    
493        public boolean isDefaultLinesPerSpecial()
494        {
495            return defaultLinesPerSpecial && !isDefault();
496        }
497    
498        public void setDefaultLinesPerSpecial(boolean defaultLinesPerSpecial)
499        {
500            this.defaultLinesPerSpecial = defaultLinesPerSpecial;
501        }
502    
503        public boolean isDefaultLevelIncrease()
504        {
505            return defaultLevelIncrease && !isDefault();
506        }
507    
508        public void setDefaultLevelIncrease(boolean defaultLevelIncrease)
509        {
510            this.defaultLevelIncrease = defaultLevelIncrease;
511        }
512    
513        public boolean isDefaultSpecialAdded()
514        {
515            return defaultSpecialAdded && !isDefault();
516        }
517    
518        public void setDefaultSpecialAdded(boolean defaultSpecialAdded)
519        {
520            this.defaultSpecialAdded = defaultSpecialAdded;
521        }
522    
523        public boolean isDefaultSpecialCapacity()
524        {
525            return defaultSpecialCapacity && !isDefault();
526        }
527    
528        public void setDefaultSpecialCapacity(boolean defaultSpecialCapacity)
529        {
530            this.defaultSpecialCapacity = defaultSpecialCapacity;
531        }
532    
533        public boolean isDefaultAverageLevels()
534        {
535            return defaultAverageLevels && !isDefault();
536        }
537    
538        public void setDefaultAverageLevels(boolean defaultAverageLevels)
539        {
540            this.defaultAverageLevels = defaultAverageLevels;
541        }
542    
543        public boolean isDefaultClassicRules()
544        {
545            return defaultClassicRules && !isDefault();
546        }
547    
548        public void setDefaultClassicRules(boolean defaultClassicRules)
549        {
550            this.defaultClassicRules = defaultClassicRules;
551        }
552    
553        public boolean isDefaultSameBlocks()
554        {
555            return defaultSameBlocks && !isDefault();
556        }
557    
558        public void setDefaultSameBlocks(boolean defaultSameBlocks)
559        {
560            this.defaultSameBlocks = defaultSameBlocks;
561        }
562    
563        public boolean isDefaultSuddenDeathTime()
564        {
565            return defaultSuddenDeathTime && !isDefault();
566        }
567    
568        public void setDefaultSuddenDeathTime(boolean defaultSuddenDeathTime)
569        {
570            this.defaultSuddenDeathTime = defaultSuddenDeathTime;
571        }
572    
573        public boolean isDefaultSuddenDeathMessage()
574        {
575            return defaultSuddenDeathMessage && !isDefault();
576        }
577    
578        public void setDefaultSuddenDeathMessage(boolean defaultSuddenDeathMessage)
579        {
580            this.defaultSuddenDeathMessage = defaultSuddenDeathMessage;
581        }
582    
583        public boolean isDefaultSuddenDeathLinesAdded()
584        {
585            return defaultSuddenDeathLinesAdded && !isDefault();
586        }
587    
588        public void setDefaultSuddenDeathLinesAdded(boolean defaultSuddenDeathLinesAdded)
589        {
590            this.defaultSuddenDeathLinesAdded = defaultSuddenDeathLinesAdded;
591        }
592    
593        public boolean isDefaultSuddenDeathDelay()
594        {
595            return defaultSuddenDeathDelay && !isDefault();
596        }
597    
598        public void setDefaultSuddenDeathDelay(boolean defaultSuddenDeathDelay)
599        {
600            this.defaultSuddenDeathDelay = defaultSuddenDeathDelay;
601        }
602    
603        public boolean isDefaultSuddenDeath()
604        {
605            return isDefaultSuddenDeathDelay()
606                    && isDefaultSuddenDeathLinesAdded()
607                    && isDefaultSuddenDeathMessage()
608                    && isDefaultSuddenDeathTime();
609        }
610    }