View Javadoc
1   /*******************************************************************************
2    * jhunters: Pool League
3    * Copyright 2015 Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   ********************************************************************************/
17  package net.sourceforge.jhunters.pool.data;
18  
19  import java.security.SecureRandom;
20  import java.time.LocalDate;
21  import java.util.ArrayList;
22  import java.util.Collections;
23  import java.util.HashMap;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.util.Map;
27  
28  /**
29   * Fixture Generator.
30   */
31  public class FixtureGenerator {
32      /**
33       * Map of players.
34       */
35      private final Map<Integer, Player> theMap;
36  
37      /**
38       * List of players.
39       */
40      private final List<Player> thePlayers;
41  
42      /**
43       * SecureRandom instance.
44       */
45      private final SecureRandom theRandom;
46  
47      /**
48       * The number of players.
49       */
50      private Integer theNumPlayers;
51  
52      /**
53       * Do we have a bye each week?
54       */
55      private boolean hasBye;
56  
57      /**
58       * The maximum player.
59       */
60      private Integer theMaxPlayer;
61  
62      /**
63       * Constructor.
64       */
65      public FixtureGenerator() {
66          /* Create the map and list */
67          theMap = new HashMap<Integer, Player>();
68          thePlayers = new ArrayList<Player>();
69  
70          /* Create the secureRandom instance */
71          theRandom = new SecureRandom();
72          theRandom.setSeed(System.nanoTime());
73      }
74  
75      /**
76       * Set the player list.
77       * @param pPlayers the players
78       */
79      public void setPlayers(final PlayerList pPlayers) {
80          /* Reset the list */
81          thePlayers.clear();
82  
83          /* Build the map */
84          Iterator<Player> myIterator = pPlayers.playerIterator();
85          while (myIterator.hasNext()) {
86              Player myPlayer = myIterator.next();
87  
88              /* Only copy selected players */
89              if (myPlayer.isSelected()) {
90                  /* Store player in the list */
91                  thePlayers.add(myPlayer);
92              }
93          }
94  
95          /* Store various details */
96          theNumPlayers = thePlayers.size();
97          hasBye = (theNumPlayers % 2) != 0;
98          theMaxPlayer = hasBye
99                               ? theNumPlayers
100                              : theNumPlayers - 1;
101     }
102 
103     /**
104      * randomise the players.
105      */
106     private void randomisePlayers() {
107         /* Reset the map */
108         theMap.clear();
109 
110         /* Shuffle the players */
111         Collections.shuffle(thePlayers, theRandom);
112 
113         /* Build the map */
114         int i = 1;
115         Iterator<Player> myIterator = thePlayers.iterator();
116         while (myIterator.hasNext()) {
117             Player myPlayer = myIterator.next();
118 
119             /* Store player in the map */
120             theMap.put(i++, myPlayer);
121         }
122     }
123 
124     /**
125      * Create CompetitionFixtures.
126      * @param pDate the starting date
127      * @return the fixtures
128      */
129     public FixtureList createFixtures(final LocalDate pDate) {
130         /* create the fixture set */
131         FixtureList myFixtures = new FixtureList();
132 
133         /* Randomise the players */
134         randomisePlayers();
135 
136         /* Loop through the players */
137         for (int i = 1; i <= theMaxPlayer; i++) {
138             /* Create fixture set */
139             FixtureSet mySet = createFixtureSet(i);
140 
141             /* Add it to the competition */
142             myFixtures.addFixtureSet(mySet);
143         }
144 
145         /* If we do not actually have a bye fixture */
146         if (!hasBye) {
147             /* record the final player in place of the bye */
148             myFixtures.setByePlayer(theMap.get(theNumPlayers));
149         }
150 
151         /* randomise the fixtures */
152         myFixtures.randomise(theRandom);
153 
154         /* Set dates for fixtures */
155         myFixtures.setDates(pDate);
156 
157         /* return the fixture list */
158         return myFixtures;
159     }
160 
161     /**
162      * Create FixtureSet.
163      * @param pBye the player top receive a bye
164      * @return the fixture set
165      */
166     private FixtureSet createFixtureSet(final Integer pBye) {
167         /* create the fixture set */
168         FixtureSet mySet = new FixtureSet();
169 
170         /* Determine number of fixtures */
171         int myNumFixtures = theMaxPlayer / 2;
172 
173         /* Determine number of players */
174         int myHome = pBye + 1;
175         int myAway = pBye - 1;
176 
177         /* Loop through the fixtures */
178         for (int i = 0; i < myNumFixtures; i++) {
179             /* Adjust for boundaries */
180             if (myHome > theMaxPlayer) {
181                 myHome = 1;
182             }
183             if (myAway == 0) {
184                 myAway = theMaxPlayer;
185             }
186 
187             /* generate the fixture */
188             mySet.addFixture(theMap.get(myHome), theMap.get(myAway));
189 
190             /* Adjust players */
191             myHome++;
192             myAway--;
193         }
194 
195         /* generate the bye fixture */
196         if ((pBye % 2) == 0) {
197             mySet.addFixture(theMap.get(pBye), null);
198         } else {
199             mySet.addFixture(null, theMap.get(pBye));
200         }
201 
202         /* return the fixture list */
203         return mySet;
204     }
205 }