001 /////////////////////////////////////////////////////////////////////////////// 002 // Copyright (c) 2006, Frank S. Nestel, All Rights Reserved. 003 // 004 // This library is free software; you can redistribute it and/or 005 // modify it under the terms of the GNU Lesser General Public 006 // License as published by the Free Software Foundation; either 007 // version 2.1 of the License, or (at your option) any later version. 008 // 009 // This library is distributed in the hope that it will be useful, 010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 // GNU General Public License for more details. 013 // 014 // You should have received a copy of the GNU Lesser General Public 015 // License along with this program; if not, write to the Free Software 016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 017 /////////////////////////////////////////////////////////////////////////////// 018 019 package de.spieleck.app.turn.pairing; 020 021 import java.util.Arrays; 022 import java.util.Random; 023 024 import org.apache.log4j.Logger; 025 026 import de.spieleck.app.turn.Game; 027 import de.spieleck.app.turn.Player; 028 import de.spieleck.app.turn.SplittingMode; 029 import de.spieleck.app.turn.PlayerRegistry; 030 031 /** 032 * This is a first strategy which heuristically solves basic problems. 033 * The basic problems are: 034 * <ul> 035 * <li>Give every player as many different opponents as possible.</li> 036 * <li>Give every player as many big tables as possible.</li> 037 * </ul> 038 * Note: This class kind of fails to give every player the optimal 039 * number of players as often as possible, when the optimal number is 040 * smaller than the non optimal ones. That is the case for Skat, where 041 * optimal tables are 3 player and 4 players are a compromise, but the 042 * programm would try to maximise the number of 4 player tables players 043 * get. 044 * 045 * <p><a href="$URL: https://svn.sourceforge.net/svnroot/jtourney/src/de/spieleck/app/turn/pairing/MixingPairing1.java $">$URL: https://svn.sourceforge.net/svnroot/jtourney/src/de/spieleck/app/turn/pairing/MixingPairing1.java $</a></p> 046 * 047 * @author Frank S. Nestel 048 * @author $Author: nestefan $ 049 * @version $Revision: 2 $ $Date: 2006-03-20 14:33:27 +0100 (Mo, 20 Mrz 2006) $ $Author: nestefan $ 050 */ 051 public class MixingPairing1 052 extends BasePairing 053 { 054 private final static Logger L = Logger.getLogger(MixingPairing1.class); 055 056 public Game[] pairing(int round, PlayerRegistry pRegistry, SplittingMode sm) 057 { 058 Player[] standing = pRegistry.getActivePlayers(); 059 int n = standing.length; 060 WrappedPlayer[] wps = new WrappedPlayer[n]; 061 for(int i = 0; i < n; i++) 062 wps[i] = new WrappedPlayer(standing[i]); 063 Arrays.sort(wps); 064 if (L.isDebugEnabled()) for(int i = 0; i < wps.length; i++) L.debug(" "+i+". "+wps[i].p+" "+wps[i].differentOpponents+" "+wps[i].opponents+" "+wps[i].offset); 065 int[] splitting = sm.split(n); 066 int gameSize = splitting.length - 1; 067 int gameCount = sum(splitting); 068 int k = 0; 069 GameImpl[] res = new GameImpl[gameCount]; 070 while ( k < gameCount ) 071 { 072 while ( splitting[gameSize] == 0 ) 073 gameSize--; 074 GameImpl g = new GameImpl(k+1); 075 while ( g.size() < gameSize ) 076 { 077 Arrays.sort(wps, 0, n); 078 WrappedPlayer wp = (WrappedPlayer) wps[0]; 079 g.add(wp.p); 080 wps[0] = wps[--n]; 081 for(int i = 1; i < n; i++) 082 { 083 int c = wp.p.getPlayedAgainst(wps[i].p); 084 wps[i].offset += c * c; 085 } 086 } 087 for(int i = 0; i < n; i++) 088 wps[i].offset = 0; 089 splitting[gameSize]--; 090 res[k++] = g; 091 } 092 return res; 093 } 094 095 public String toString() 096 { 097 return "MixingPairing1"; 098 } 099 100 private static class WrappedPlayer 101 implements Comparable 102 { 103 Player p; 104 int offset = 0; 105 int differentOpponents = 0; 106 int opponents = 0; 107 108 public WrappedPlayer(Player p) 109 { 110 this.p = p; 111 Player[] opps = p.getRegistry().getPlayers(); 112 for(int i = 0; i < opps.length; i++) 113 { 114 int c = p.getPlayedAgainst(opps[i]); 115 if ( c > 0 ) 116 { 117 differentOpponents++; 118 opponents += c; 119 } 120 } 121 } 122 123 public int compareTo(Object o) 124 { 125 if ( !(o instanceof WrappedPlayer) ) 126 { 127 return -1; 128 } 129 int h; 130 WrappedPlayer p2 = (WrappedPlayer) o; 131 h = offset - p2.offset; 132 if ( h != 0 ) 133 return h; 134 h = differentOpponents - p2.differentOpponents; 135 if ( h != 0 ) 136 return h; 137 h = opponents - p2.opponents; 138 if ( h != 0 ) 139 return h; 140 return p.compareTo(p2); 141 } 142 } 143 }