bugfix sous windows.
[minwii.git] / src / pgu / high.py
1 """Classes for handling high score tables.
2 """
3
4 import os
5
6 def High(fname,limit=10):
7 """Create a Highs object and returns the default high score table.
8
9 <pre>High(fname,limit=10)</pre>
10
11 <dl>
12 <dt>fname <dd>filename to store high scores in
13 <dt>limit <dd>limit of scores to be recorded, defaults to 10
14 </dl>
15 """
16 return Highs(fname,limit)['default']
17
18 class _Score:
19 def __init__(self,score,name,data=None):
20 self.score,self.name,self.data=score,name,data
21
22 class _High:
23 """A high score table. These objects are passed to the user, but should not be created directly.
24
25 <p>You can iterate them:</p>
26 <code>
27 for e in myhigh:
28 print e.score,e.name,e.data
29 </code>
30
31 <p>You can modify them:</p>
32 <code>
33 myhigh[0].name = 'Cuzco'
34 </code>
35
36 <p>You can find out their length:</p>
37 <code>
38 print len(myhigh)
39 </code>
40 """
41
42 def __init__(self,highs,limit=10):
43 self.highs = highs
44 self._list = []
45 self.limit = limit
46
47 def save(self):
48 """Save the high scores.
49
50 <pre>_High.save()</pre>
51 """
52 self.highs.save()
53
54 def submit(self,score,name,data=None):
55 """Submit a high score to this table.
56
57 <pre>_High.submit(score,name,data=None)</pre>
58
59 <p>return -- the position in the table that the score attained. None if the score did not attain a position in the table.</p>
60 """
61 n = 0
62 for e in self._list:
63 if score > e.score:
64 self._list.insert(n,_Score(score,name,data))
65 self._list = self._list[0:self.limit]
66 return n
67 n += 1
68 if len(self._list) < self.limit:
69 self._list.append(_Score(score,name,data))
70 return len(self._list)-1
71
72 def check(self,score):
73 """Check if a score will attain a position in the table.
74
75 <pre>_High.check(score)</pre>
76
77 <p>return -- the position the score will attain, else None</p>
78 """
79 n = 0
80 for e in self._list:
81 if score > e.score:
82 return n
83 n += 1
84 if len(self._list) < self.limit:
85 return len(self._list)
86
87
88 def __iter__(self):
89 return self._list.__iter__()
90
91 def __getitem__(self,key):
92 return self._list[key]
93
94 def __len__(self):
95 return self._list.__len__()
96
97
98 class Highs:
99 """The high score object.
100
101 <pre>Highs(fname,limit=10)</pre>
102 <ul>
103 <dt>fname <dd>filename to store high scores in
104 <dt>limit <dd>limit of scores to be recorded, defaults to 10
105 </ul>
106
107 <p>You may access _High objects through this object:</p>
108
109 <code>
110 my_easy_hs = highs['easy']
111 my_hard_hs = highs['hard']
112 </code>
113
114 """
115 def __init__(self,fname,limit=10):
116 self.fname = fname
117 self.limit = limit
118 self.load()
119
120 def load(self):
121 """Re-load the high scores.
122
123 <pre>Highs.load()</pre>
124 """
125
126 self._dict = {}
127 try:
128 f = open(self.fname)
129 for line in f.readlines():
130 key,score,name,data = line.strip().split("\t")
131 if key not in self._dict:
132 self._dict[key] = _High(self,self.limit)
133 high = self._dict[key]
134 high.submit(int(score),name,data)
135 f.close()
136 except:
137 pass
138
139 def save(self):
140 """Save the high scores.
141
142 <pre>Highs.save()</pre>
143 """
144
145 f = open(self.fname,"w")
146 for key,high in self._dict.items():
147 for e in high:
148 f.write("%s\t%d\t%s\t%s\n"%(key,e.score,e.name,str(e.data)))
149 f.close()
150
151 def __getitem__(self,key):
152 if key not in self._dict:
153 self._dict[key] = _High(self,self.limit)
154 return self._dict[key]