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  import net.sourceforge.jhunters.pool.PoolStatus;
29  
30  /**
31   * Competition Fixture.
32   */
33  public class FixtureList {
34      /**
35       * FixtureList Name.
36       */
37      protected static final String OBJECT_NAME = DataResource.FIXTURELIST_NAME.getValue();
38  
39      /**
40       * List of FixtureSets.
41       */
42      private final List<FixtureSet> theFixtures;
43  
44      /**
45       * The status of the list.
46       */
47      private PoolStatus theStatus;
48  
49      /**
50       * Constructor.
51       */
52      public FixtureList() {
53          theFixtures = new ArrayList<FixtureSet>();
54      }
55  
56      /**
57       * Obtain the status.
58       * @return the status.
59       */
60      public PoolStatus getStatus() {
61          return theStatus;
62      }
63  
64      /**
65       * Obtain the number of FixtureSets.
66       * @return the # fixture sets.
67       */
68      public Integer size() {
69          return theFixtures.size();
70      }
71  
72      /**
73       * Obtain the numbered fixtureSet.
74       * @param pWeek the week #
75       * @return the fixture set.
76       */
77      public FixtureSet getFixtureSet(final Integer pWeek) {
78          return ((pWeek > 0) && (pWeek <= theFixtures.size()))
79                                                                ? theFixtures.get(pWeek - 1)
80                                                                : null;
81      }
82  
83      /**
84       * Reset fixtures.
85       */
86      protected void reset() {
87          theFixtures.clear();
88      }
89  
90      /**
91       * Add fixtureSet.
92       * @param pSet the fixture set.
93       */
94      protected void addFixtureSet(final FixtureSet pSet) {
95          /* Add to the fixture set list */
96          theFixtures.add(pSet);
97      }
98  
99      /**
100      * Set fixtures.
101      * @param pSource the source fixtures.
102      */
103     protected void setFixtures(final Iterator<FixtureSet> pSource) {
104         /* Reset the fixtures */
105         reset();
106 
107         /* Loop through the source list */
108         while (pSource.hasNext()) {
109             FixtureSet mySet = pSource.next();
110 
111             /* Add the set */
112             theFixtures.add(mySet);
113         }
114     }
115 
116     /**
117      * Obtain fixture list.
118      * @return the fixtures
119      */
120     private List<FixtureSet> getFixtures() {
121         return theFixtures;
122     }
123 
124     /**
125      * Obtain fixtureIterator.
126      * @return the iterator
127      */
128     public Iterator<FixtureSet> fixtureIterator() {
129         return theFixtures.iterator();
130     }
131 
132     /**
133      * Set Bye player.
134      * @param pPlayer the final player
135      */
136     protected void setByePlayer(final Player pPlayer) {
137         /* Loop through the fixtureSets */
138         Iterator<FixtureSet> myIterator = fixtureIterator();
139         while (myIterator.hasNext()) {
140             FixtureSet myCurr = myIterator.next();
141 
142             /* Set the bye player */
143             myCurr.setByePlayer(pPlayer);
144         }
145     }
146 
147     /**
148      * Randomise the fixtures.
149      * @param pRandom the random generator
150      */
151     protected void randomise(final SecureRandom pRandom) {
152         /* Randomise the fixture sets */
153         Collections.shuffle(theFixtures, pRandom);
154 
155         /* Loop through the fixtureSets */
156         Iterator<FixtureSet> myIterator = fixtureIterator();
157         while (myIterator.hasNext()) {
158             FixtureSet myCurr = myIterator.next();
159 
160             /* Randomise the fixtureSet */
161             myCurr.randomise(pRandom);
162         }
163     }
164 
165     /**
166      * Set dates.
167      * @param pDate the base date.
168      */
169     protected void setDates(final LocalDate pDate) {
170         /* Loop through the fixtureSets */
171         int myWeekNo = 1;
172         LocalDate myDate = pDate;
173         Iterator<FixtureSet> myIterator = fixtureIterator();
174         while (myIterator.hasNext()) {
175             FixtureSet myCurr = myIterator.next();
176 
177             /* Set the dates */
178             myCurr.setDates(myWeekNo, myDate);
179 
180             /* Shift values */
181             myWeekNo++;
182             myDate = myDate.plusWeeks(1);
183         }
184     }
185 
186     @Override
187     public boolean equals(final Object pThat) {
188         /* Handle trivial cases */
189         if (this == pThat) {
190             return true;
191         }
192         if (pThat == null) {
193             return false;
194         }
195 
196         /* Handle wrong class */
197         if (!(pThat instanceof FixtureList)) {
198             return false;
199         }
200 
201         /* Access as fixtureList */
202         FixtureList myThat = (FixtureList) pThat;
203 
204         /* Test only on fixtures */
205         return theFixtures.equals(myThat.getFixtures());
206     }
207 
208     @Override
209     public int hashCode() {
210         return theFixtures.hashCode();
211     }
212 
213     /**
214      * validate the fixture list.
215      * @param pParticipants the participants
216      * @return the status
217      */
218     protected PoolStatus validate(final PlayerList pParticipants) {
219         /* Create the fixture map */
220         Map<String, List<String>> myMap = new HashMap<String, List<String>>();
221         theStatus = PoolStatus.VALID;
222 
223         /* Loop through the fixture sets */
224         Iterator<FixtureSet> myIterator = fixtureIterator();
225         while (myIterator.hasNext()) {
226             FixtureSet myCurr = myIterator.next();
227 
228             /* Validate the fixture */
229             PoolStatus myStatus = myCurr.validate(pParticipants);
230             if (!myStatus.isValid()) {
231                 theStatus = PoolStatus.INVALID;
232             }
233 
234             /* Loop through the fixtures */
235             Iterator<Fixture> myFixIterator = myCurr.fixtureIterator();
236             while (myFixIterator.hasNext()) {
237                 Fixture myFixture = myFixIterator.next();
238 
239                 /* Ignore byes */
240                 if (myFixture.isBye()) {
241                     continue;
242                 }
243 
244                 /* Access players */
245                 Player myHome = myFixture.getHomePlayer();
246                 Player myAway = myFixture.getAwayPlayer();
247 
248                 /* Register match-up */
249                 registerMatch(myMap, myHome, myAway);
250                 registerMatch(myMap, myAway, myHome);
251             }
252         }
253 
254         /* If we are valid */
255         if (theStatus.isValid()) {
256             /* Determine the number of fixtures */
257             int myNumFixtures = pParticipants.size() - 1;
258 
259             /* Loop through the fixture map */
260             Iterator<List<String>> myMapIterator = myMap.values().iterator();
261             while (myMapIterator.hasNext()) {
262                 List<String> myList = myMapIterator.next();
263 
264                 /* Note If the list is the wrong size */
265                 if (myList.size() != myNumFixtures) {
266                     theStatus = PoolStatus.INVALID;
267                 }
268             }
269         }
270 
271         /* Return the status */
272         return theStatus;
273     }
274 
275     /**
276      * register a match up.
277      * @param pMap the fixture map
278      * @param pFirst the first player
279      * @param pSecond the second player
280      */
281     protected void registerMatch(final Map<String, List<String>> pMap,
282                                  final Player pFirst,
283                                  final Player pSecond) {
284         /* Obtain the list */
285         String myFirst = pFirst.getName();
286         List<String> myList = pMap.get(myFirst);
287         if (myList == null) {
288             myList = new ArrayList<String>();
289             pMap.put(myFirst, myList);
290         }
291 
292         /* Add second player if not already in list */
293         String mySecond = pSecond.getName();
294         if (!myList.contains(mySecond)) {
295             myList.add(mySecond);
296         }
297     }
298 }