OSDN Git Service

ワークスペース初期構築
[jugglemaster/source.git] / workspace / JuggleMaster / src / com / jm / SiteSwap.java
1 package com.jm;\r
2 \r
3 import java.io.Serializable;\r
4 import java.util.Hashtable;\r
5 \r
6 public class SiteSwap implements Serializable {\r
7         private static final long serialVersionUID = 8397505993446975803L;\r
8         private static final Hashtable<String, SiteSwap> MAP = new Hashtable<String, SiteSwap>();\r
9         private static final int MAX_N_SITESWAP = 255;\r
10         private static final int MAX_N_MULTIPLEX = 11;\r
11         private static final byte CROSS = (byte)'x' - 'a' + 10;\r
12         private static final byte COMMA = -1;  \r
13         private static final byte BRA = -2;\r
14         private static final byte KET = -3;\r
15         private static final byte PAR = -4;\r
16         private static final byte ENTHESIS = -5;\r
17         private static final byte ERROR = Byte.MIN_VALUE;\r
18 \r
19         /*********************************************************************\r
20          \83C\83\93\83X\83^\83\93\83X\82ð\8eæ\93¾\82µ\82Ü\82·\r
21          *********************************************************************/\r
22         protected static SiteSwap getInstance(String siteswap) {\r
23                 if (MAP.containsKey(siteswap)) return (SiteSwap)MAP.get(siteswap);\r
24                 SiteSwap ss = new SiteSwap();\r
25                 if (!ss.setSiteswap(siteswap)) return null;\r
26                 MAP.put(siteswap, ss);\r
27                 return ss;\r
28         }\r
29         public static void clearCashe() {\r
30                 MAP.clear();\r
31         }\r
32 \r
33         /*********************************************************************\r
34          *********************************************************************/\r
35         private static String toSiteswapString(byte b) {\r
36                 String ret = "";\r
37                 if (b < 0) {\r
38                         b = (byte)-b;\r
39                         ret = "x";\r
40                 }\r
41                 if (b < 10) return b + ret;\r
42                 return (char)('a' + b - 10) + ret;\r
43         }\r
44 \r
45         /*********************************************************************\r
46          *********************************************************************/\r
47         private static byte toSiteswapByte(char c) {\r
48                 switch(c) {\r
49                 case '(' : return PAR;\r
50                 case ')' : return ENTHESIS;\r
51                 case ',' : return COMMA;\r
52                 case '[' : return BRA;\r
53                 case ']' : return KET;\r
54                 default:\r
55                         if ('0' <= c && c <= '9')               return (byte)(c - '0');\r
56                         else if ('a' <= c && c <= 'z')  return (byte)(c - 'a' + 10);\r
57                         else if ('A' <= c && c <= 'Z')  return (byte)(c - 'A' + 10);\r
58                 }\r
59                 return ERROR;\r
60         }\r
61 \r
62 \r
63         private byte[][]        siteswap;\r
64         private boolean         isSynchronous;\r
65         private byte            maxValue;\r
66         private int             number;\r
67 \r
68         /*********************************************************************\r
69          \83C\83\93\83X\83^\83\93\83X\82ð\90\90¬\82µ\82Ü\82·\r
70          *********************************************************************/\r
71         private SiteSwap()\r
72         {\r
73                 this.siteswap = null;\r
74                 this.isSynchronous = false;\r
75                 this.number = 0;\r
76                 this.maxValue = 0;\r
77         }\r
78         \r
79         /*********************************************************************\r
80          i\94Ô\96Ú\82Ì\83T\83C\83g\83X\83\8f\83b\83v\92l\82ð\95Ô\82µ\82Ü\82·\r
81          i\94Ô\96Ú\82ª\83}\83\8b\83`\82Ì\8fê\8d\87\82Í\82»\82Ì j\8cÂ\96Ú\82ð\95Ô\82µ\82Ü\82·\81B\r
82          *********************************************************************/\r
83         public byte getValue(int i, int j) {\r
84                 i = i % siteswap.length;\r
85                 return siteswap[i][j % siteswap[i].length];\r
86         }\r
87 \r
88         /*********************************************************************\r
89          \83T\83C\83g\83X\83\8f\83b\83v\92l\82Ì\8dÅ\91å\92l\82ð\95Ô\82µ\82Ü\82·\r
90          *********************************************************************/\r
91         public int getMaxValue() {\r
92                 return maxValue;\r
93         }\r
94 \r
95         /*********************************************************************\r
96          \83{\81[\83\8b\82Ì\8cÂ\90\94\82ð\95Ô\82µ\82Ü\82·\r
97          *********************************************************************/\r
98         public int getNumberOfBalls() {\r
99                 return number;\r
100         }\r
101         \r
102         /*********************************************************************\r
103          \83V\83\93\83N\83\8d\82È\82ç\82Îtrue\82ð\95Ô\82µ\82Ü\82·\r
104          *********************************************************************/\r
105         public boolean isSynchronous() {\r
106                 return isSynchronous;\r
107         }\r
108 \r
109         /*********************************************************************\r
110          \83T\83C\83g\83X\83\8f\83b\83v\82Ì\92·\82³\82ð\95Ô\82µ\82Ü\82·\r
111          *********************************************************************/\r
112         public int size() {\r
113                 return siteswap.length;\r
114         }\r
115         \r
116         /*********************************************************************\r
117          index\94Ô\96Ú\82Ì\83T\83C\83g\83X\83\8f\83b\83v\92l\82Ì\83}\83\8b\83`\90\94\82ð\95Ô\82µ\82Ü\82·\r
118          *********************************************************************/\r
119         public int size(int index) {\r
120                 return siteswap[index % siteswap.length].length;\r
121         }\r
122         \r
123         /*********************************************************************\r
124          *********************************************************************/\r
125         public String[] getStrings() {\r
126                 if (isSynchronous()) return getSynStrings();            \r
127                 String[] ret = new String[siteswap.length];\r
128                 for(int i = 0; i < siteswap.length; i++){\r
129                         ret[i] = getString(i);\r
130                 }\r
131                 return ret;\r
132         }\r
133         \r
134         /*********************************************************************\r
135          *********************************************************************/\r
136         private String[] getSynStrings() {\r
137                 String[] ret = new String[siteswap.length/2];\r
138                 for(int i = 0; i < ret.length; i++) {\r
139                         ret[i] = '(' + getString(i*2) + ',' + getString(i*2+1) + ')';\r
140                 }\r
141                 return ret;\r
142         }\r
143 \r
144         /*********************************************************************\r
145          *********************************************************************/\r
146         private String getString(int i) {\r
147                 if (siteswap[i].length == 0) return "0";\r
148                 if (siteswap[i].length == 1) return toSiteswapString(siteswap[i][0]);\r
149                 StringBuffer p = new StringBuffer("[");\r
150                 for (int j = 0; j < siteswap[i].length; j++){\r
151                         p.append(toSiteswapString(siteswap[i][j]));\r
152                 }\r
153                 p.append(']');\r
154                 return p.toString();\r
155         }\r
156 \r
157         /*********************************************************************\r
158          *********************************************************************/\r
159         public String toString() {\r
160                 StringBuffer str = new StringBuffer("");\r
161                 String[] s = getStrings();\r
162                 for (int i = 0; i < s.length; i++)\r
163                         str.append(s[i]);\r
164                 return str.toString();\r
165         }\r
166         \r
167         /*********************************************************************\r
168          \83T\83C\83g\83X\83\8f\83b\83v\95\\8bL\96@\82Å\8f\91\82©\82ê\82½\95\8e\9a\97ñ\82ð\89ð\90Í\82µ\82Ä\83Z\83b\83g\82µ\82Ü\82·\r
169          \r
170          @return        \95\96@\83G\83\89\81[\82È\82ç\82Îfalse\r
171          *********************************************************************/\r
172         private boolean setSiteswap(String s) {\r
173                 if (number != 0)                                        return false;\r
174                 if (s == null)                                          return false;\r
175                 s = s.trim();\r
176                 if (s.length() < 0)                                     return false;\r
177                 if (s.length() > MAX_N_SITESWAP)        return false;\r
178                 if (s.charAt(0) == '(') isSynchronous = true;\r
179 \r
180                 int parenthesisFlag = 0;\r
181                 boolean braketFlag = false;\r
182                 byte[][] patt = new byte[s.length()][MAX_N_MULTIPLEX];\r
183                 int[] patts = new int[s.length()];\r
184                 int pattw = 0;\r
185                 byte a = 0;\r
186 \r
187                 for (int ch = 0; ch < s.length(); ch++) {\r
188                         byte t = toSiteswapByte(s.charAt(ch));\r
189                         switch (t) {\r
190                         case ERROR : return false;\r
191                         case BRA :                              // [\r
192                                 braketFlag = true;\r
193                                 patts[pattw] = 0;\r
194                                 continue;\r
195                         case KET :                              // ]\r
196                                 if (!braketFlag)                        return false;\r
197                                 braketFlag = false;\r
198                                 pattw++;\r
199                                 continue;\r
200                         case PAR :                              // (\r
201                                 if (!isSynchronous)                     return false;\r
202                                 if (parenthesisFlag != 0)       return false;\r
203                                 parenthesisFlag = 1;\r
204                                 continue;\r
205                         case ENTHESIS :                 // )\r
206                                 if (!isSynchronous)                     return false;\r
207                                 if (parenthesisFlag != 5)       return false;\r
208                                 parenthesisFlag = 0;\r
209                                 continue;\r
210                         case COMMA :                    // ,\r
211                                 if (!isSynchronous)                     return false;\r
212                                 if (parenthesisFlag != 2)       return false;\r
213                                 parenthesisFlag = 4;\r
214                                 continue;\r
215                         case CROSS :                    // x\r
216                                 if (!isSynchronous)                     break;\r
217                                 if (parenthesisFlag != 2 && parenthesisFlag != 5) return false;\r
218                                 if (braketFlag) patt[pattw][patts[pattw] - 1] = (byte)-a;\r
219                                 else patt[pattw - 1][0] = (byte)-a;\r
220                                 continue;\r
221                         }\r
222                         a = t;\r
223                         if (isSynchronous) {\r
224                                 if (a % 2 != 0) return false;\r
225                                 if (!braketFlag && parenthesisFlag != 1 && parenthesisFlag != 4) return false;\r
226                                 if (parenthesisFlag == 1) parenthesisFlag = 2;\r
227                                 else if (parenthesisFlag == 4) parenthesisFlag = 5;\r
228                         }\r
229                         if (braketFlag) {\r
230                                 if (a == 0) return false;\r
231                                 patt[pattw][patts[pattw]++] = a;\r
232                                 if (patts[pattw] > MAX_N_MULTIPLEX) return false;\r
233                         } else {\r
234                                 patt[pattw][0] = a;\r
235                                 if (a == 0)     patts[pattw++] = 0;\r
236                                 else            patts[pattw++] = 1;\r
237                         }\r
238                 }\r
239                 if (parenthesisFlag != 0 || braketFlag || pattw == 0) return false;\r
240 \r
241                 siteswap = new byte[pattw][];\r
242                 for (int i = 0; i < siteswap.length; i++) {\r
243                         siteswap[i] = new byte[patts[i]];\r
244                         for (int j = 0; j < siteswap[i].length; j++) {\r
245                                 siteswap[i][j] = patt[i][j];\r
246                                 int b = Math.abs(siteswap[i][j]);\r
247                                 number += b;\r
248                                 maxValue = (byte)Math.max(maxValue, b);\r
249                         }\r
250                 }\r
251                 if (number % siteswap.length != 0) return false;\r
252                 number /= siteswap.length;\r
253                 if (number == 0) return false;\r
254                 return true;\r
255         }\r
256 }\r