diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..da22126 --- /dev/null +++ b/build.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/project.properties b/project.properties new file mode 100644 index 0000000..0ce6f35 --- /dev/null +++ b/project.properties @@ -0,0 +1,6 @@ +#Sun Jul 04 00:39:50 CDT 2010 +app.version=0.3.0 +src.dir=src +build.number=4 +build.dir=build +app.name=team-maker diff --git a/src/com/jdbernard/teammaker/Player.groovy b/src/com/jdbernard/teammaker/Player.groovy new file mode 100644 index 0000000..ee82f8d --- /dev/null +++ b/src/com/jdbernard/teammaker/Player.groovy @@ -0,0 +1,14 @@ +package com.jdbernard.teammaker + +public class Player implements Comparable { + String name + int gamesSat + + public int compareTo(Player that) { + int r = this.gamesSat - that.gamesSat + if (r == 0) r = this.name.compareTo(that.name) + return r + } + + public String toString() { return name } +} diff --git a/src/com/jdbernard/teammaker/PlayerChooser.groovy b/src/com/jdbernard/teammaker/PlayerChooser.groovy new file mode 100644 index 0000000..1875b2b --- /dev/null +++ b/src/com/jdbernard/teammaker/PlayerChooser.groovy @@ -0,0 +1,14 @@ +package com.jdbernard.teammaker + +public abstract class PlayerChooser { + public abstract Player choose (def players) + public abstract float calculateOdds(def players, def player) + + public final static Random = new Random(System.currentTimeMillis()) + + public static final Player chooseRandomly(def choices) { + choices.sort { rand.nextInt() } + return choices[0] + } + +} diff --git a/src/com/jdbernard/teammaker/PlayerListCellRenderer.groovy b/src/com/jdbernard/teammaker/PlayerListCellRenderer.groovy new file mode 100644 index 0000000..c1914d6 --- /dev/null +++ b/src/com/jdbernard/teammaker/PlayerListCellRenderer.groovy @@ -0,0 +1,68 @@ +package com.jdbernard.teammaker + +import java.awt.Color +import java.awt.Component +import javax.swing.EmptyBorder +import javax.swing.JLabel +import javax.swing.JList +import javax.swing.JPanel +import javax.swing.LineBorder +import javax.swing.ListCellRenderer + +public class PlayerListCellRenderer extends JPanel implements ListCellRenderer { + + boolean showStats + boolean colored + + private PlayerChooser chooser + private JLabel nameLabel + private JLabel statsLabel + private static def linedBorder = new LineBorder(Color.BLACK) + private static def emptyBorder = new EmptyBorder(1) + + private def colors = [Color.getHSBColor(0.32f, 1f, 1f), + Color.getHSBColor(0.24f,1f,1f), Color.getHSBColor(0.16f, 1f, 1f), + Color.getHSBColor(0.08f, 1f, 1f), Color.getHSBColor(0.0f, 1f, 1f)] + + public PlayerListCellRenderer(Map params) { + showStats = params.showStats ?: false + colored = params.colored ?: false + chooser = params.chooser ?: WeightedChooser.getInstance() + + setLayout(new BorderLayout()) + setOpaque(colored) + + nameLabel = new JLabel() + nameLabel.opaque = false + nameLabel.horizontalAlignment = JLabel.LEADING + add(nameLabel, BorderLayout.WEST) + + if (showStats) { + statsLabel = new JLabel() + statsLabel.horizontalAlignment = JLabel.TRAILING, + statsLabel.opaque = false + add(statsLabel, BorderLayout.EAST) + } + } + + public Component getListCellRendererComponent(JList list, Object value, + int index, boolean isSelected, boolean cellHasFocus) { + + assert value instanceof Player + + nameLabel.setText(value.name) + + if (isSelected) setBorder(linedBorder) + else setBorder(emptyBorder) + + if (showStats) + statsLabel.text = value.gamesSat + + if (colored) { + def c = colors[Math.min(4, value.gamesSat)] + setBackground(c) + } + + return this + } +} diff --git a/src/com/jdbernard/teammaker/RandomChooser.groovy b/src/com/jdbernard/teammaker/RandomChooser.groovy new file mode 100644 index 0000000..0b5e8ad --- /dev/null +++ b/src/com/jdbernard/teammaker/RandomChooser.groovy @@ -0,0 +1,14 @@ +package com.jdbernard.teammaker + +public class RandomChooser extends PlayerChooser { + + public Player choose(def players) { + def choices = [] + players.each { choices << it } + chooseRandomly(choices) + } + + public float calculateOdds(def players, def player) { + return 1f / (float) players + } +} diff --git a/src/com/jdbernard/teammaker/SortedPlayerModel.groovy b/src/com/jdbernard/teammaker/SortedPlayerModel.groovy new file mode 100644 index 0000000..65e16f6 --- /dev/null +++ b/src/com/jdbernard/teammaker/SortedPlayerModel.groovy @@ -0,0 +1,28 @@ +package com.jdbernard.teammaker + +import javax.swing.AbstractListModel + +public class SortedPlayerModel extends AbstractListModel { + private TreeSet set = new TreeSet() + + public int getSize() { return set.size() } + public Object getElementAt(int index) { + int i = 0 + for (player in set) { + if (i == index) return player + i++ + } + throw new ArrayIndexOutOfBoundsException() + } + + public void addElement(Player p) { + set.add(p) + fireIntervalAdded(this, 0, set.size()) + } + + + public void removeElement(Player p) { + set.remove(p) + fireIntervalRemoved(this, 0, set.size()) + } +} diff --git a/TeamMaker.groovy b/src/com/jdbernard/teammaker/TeamMaker.groovy similarity index 72% rename from TeamMaker.groovy rename to src/com/jdbernard/teammaker/TeamMaker.groovy index 8cd7f17..0290a05 100644 --- a/TeamMaker.groovy +++ b/src/com/jdbernard/teammaker/TeamMaker.groovy @@ -1,18 +1,13 @@ +package com.jdbernard.teammaker + import groovy.beans.Bindable import groovy.swing.SwingBuilder -import java.awt.Color -import java.awt.Component import java.awt.GridBagConstraints as GBC import java.awt.GridBagLayout import java.awt.BorderLayout -import javax.swing.AbstractListModel import javax.swing.DefaultListModel import javax.swing.JFrame -import javax.swing.JLabel -import javax.swing.JList import javax.swing.JOptionPane -import javax.swing.JPanel -import javax.swing.ListCellRenderer public class TeamMaker { @@ -20,7 +15,6 @@ public class TeamMaker { public static def swing = new SwingBuilder() public static final String version = "0.2" - public static final Random rand = new Random(System.currentTimeMillis()) def frame def team1List @@ -30,23 +24,11 @@ public class TeamMaker { def newGameButton def sittingList + PlayerChooser chooser = new RandomChooser() + @Bindable boolean inGame = false @Bindable int teamSize = 4 - class Player implements Comparable { - String name - int gamesSat - - public int compareTo(Player that) { - int r = this.gamesSat - that.gamesSat - if (r == 0) r = this.name.compareTo(that.name) - return r - } - } - - class SortedPlayerModel extends AbstractListModel { - - } /* ======== VIEW ======== */ @@ -95,7 +77,7 @@ public class TeamMaker { label('Team B', constraints: gbc(gridx: 1, gridy: 0, fill: GBC.BOTH, insets: [5, 5, 0, 5])) - def teamListRenderer = new PlayerRenderer(showStats: false, + def teamListRenderer = new PlayerListCellRenderer(showStats: false, colored: false) team1List = list(cellRenderer: teamListRenderer, @@ -150,9 +132,9 @@ public class TeamMaker { fill: GBC.BOTH, insets: [5, 5, 0, 5], weighty: 1), border: titledBorder(title: 'Sitting Players')) { - sittingList = list(cellRenderer: new PlayerRenderer( + sittingList = list(cellRenderer: new PlayerListCellRenderer( showStats: true, colored: true), - model: new DefaultListModel()) + model: new SortedPlayerModel()) } button('Next Game', constraints: gbc(gridx: 0, gridy: 1, @@ -180,72 +162,9 @@ public class TeamMaker { } } - - swing.bind(source: this, sourceProperty: 'inGame', - target: team1WinsButton, targetProperty: 'enabled') - - swing.bind(source: this, sourceProperty: 'inGame', - target: team2WinsButton, targetProperty: 'enabled') - } - class PlayerRenderer extends JPanel implements ListCellRenderer { - boolean showStats - boolean colored - - private JLabel nameLabel - private JLabel statsLabel - private static def linedBorder - private static def emptyBorder - - private def colors = [Color.getHSBColor(0.32f, 1f, 1f), - Color.getHSBColor(0.24f,1f,1f), Color.getHSBColor(0.16f, 1f, 1f), - Color.getHSBColor(0.08f, 1f, 1f), Color.getHSBColor(0.0f, 1f, 1f)] - - public PlayerRenderer(Map params) { - showStats = params.showStats ?: false - colored = params.colored ?: false - - setLayout(new BorderLayout()) - setOpaque(colored) - - linedBorder = TeamMaker.swing.lineBorder(color: Color.BLACK) - emptyBorder = TeamMaker.swing.emptyBorder(1) - - nameLabel = TeamMaker.swing.label(opaque: false, - horizontalAlignment: JLabel.LEADING) - add(nameLabel, BorderLayout.WEST) - - if (showStats) { - statsLabel = TeamMaker.swing.label( - horizontalAlignment: JLabel.TRAILING, - opaque: false) - add(statsLabel, BorderLayout.EAST) - } - } - - public Component getListCellRendererComponent(JList list, Object value, - int index, boolean isSelected, boolean cellHasFocus) { - - assert value instanceof Player - - nameLabel.setText(value.name) - - if (isSelected) setBorder(linedBorder) - else setBorder(emptyBorder) - - if (showStats) - statsLabel.text = value.gamesSat - - if (colored) { - def c = colors[Math.min(4, value.gamesSat)] - setBackground(c) - } - - return this - } - } /* ======== CONTROLLER ======== */ @@ -281,8 +200,15 @@ public class TeamMaker { private static Player choosePlayer(def list) { def choices = [] - list.model.each { choices << it } + list.model.each { player -> + player.gamesSat.times { choices << player } + } + + // if no players have sat at least one game, add all once + if (choices.size() == 0) list.model.each { player -> choices << player } + choices.sort { rand.nextInt() } + println choices return choices[0] }