source: pycodebattler/trunk/pycodebattler/skill.py @ 71

Revision 71, 5.4 KB checked in by atzm, 13 years ago (diff)

add preamble

  • Property svn:keywords set to Id
Line 
1# -*- coding: utf-8 -*-
2#
3#  Copyright (C) 2010 by Atzm WATANABE <atzm@atzm.org>
4#
5#  This program is free software; you can redistribute it and/or modify it
6#  under the terms of the GNU General Public License (version 2) as
7#  published by the Free Software Foundation.  It is distributed in the
8#  hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
9#  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10#  PURPOSE.  See the GNU General Public License for more details.
11#
12# $Id$
13#
14
15import sys
16import random
17
18try:
19    import cStringIO as _StringIO
20except ImportError:
21    import StringIO as _StringIO
22
23try:
24    set, frozenset
25except NameError:
26    from sets import Set as set, ImmutableSet as frozenset
27
28
29def pformat(skills):
30    order = ['NAME', 'TYPE', 'SP', 'LV']
31    mmap = {
32        'NAME': 'name',
33        'TYPE': 'skilltype',
34        'SP':   'point',
35        'LV':   'level',
36    }
37
38    horiz = [[getattr(s, mmap[n])() for n in order] for s in skills]
39
40    for i, t in enumerate(horiz):
41        horiz[i][1] = str(t[1]).split('.')[-1]
42
43    virt = zip(*horiz)
44
45    sepnum = (len(order) * 3) - 1
46    fmt = ['|']
47    for i, t in enumerate(virt):
48        num = max(len(str(n)) for n in list(t) + [order[i]])
49        sepnum += num
50        if i < 2:
51            fmt.append(' %%-%ds |' % num)
52        else:
53            fmt.append(' %%%ds |' % num)
54
55    fmt = ''.join(fmt + ['\n'])
56    sep = ''.join(['+', '-' * sepnum, '+', '\n'])
57
58    io = _StringIO.StringIO()
59    io.write(sep)
60    io.write(fmt % tuple(order))
61    io.write(sep)
62    for d in horiz:
63        io.write(fmt % tuple(d))
64    io.write(sep)
65    io.flush()
66
67    return io.getvalue()
68
69
70class SkillType:
71    def __init__(self, attacker):
72        self.attacker = attacker
73
74    def range(self):
75        return 0
76
77    def selectable(self, warriors):
78        return []
79
80    def efficiency(self):
81        return 0
82
83
84class HealType(SkillType):
85    def range(self):
86        return 1
87
88    def selectable(self, warriors):
89        return [self.attacker]
90
91    def efficiency(self):
92        base = self.attacker.concentration() * 2 + 10
93        gosa = base / 2
94        return 0 - random.randint(base - gosa, base + gosa)
95
96
97class ResurrectionType(SkillType):
98    def range(self):
99        return 1
100
101    def selectable(self, warriors):
102        loosers = [w for w in warriors if w.is_dead()]
103        try:
104            return [random.choice(loosers)]
105        except IndexError:
106            return []
107
108    def efficiency(self):
109        base = self.attacker.concentration() + 10
110        gosa = base / 2
111        return 0 - random.randint(base - gosa, base + gosa)
112
113
114class SingleAttackType(SkillType):
115    def range(self):
116        return 1
117
118    def selectable(self, warriors):
119        living = [w for w in warriors if not w.is_dead()]
120        living.remove(self.attacker)
121        return living
122
123    def efficiency(self):
124        base = int(self.attacker.concentration() * 2.5)
125        gosa = base / 2
126        return random.randint(base - gosa, base + gosa)
127
128
129class RangeAttackType(SkillType):
130    def range(self):
131        return self.attacker.concentration() // 25 + 1
132
133    def selectable(self, warriors):
134        living = [w for w in warriors if not w.is_dead()]
135        living.remove(self.attacker)
136        return living
137
138    def efficiency(self):
139        base = int(self.attacker.concentration() * 2.3)
140        gosa = base / 2
141        return random.randint(base - gosa, base + gosa)
142
143
144class MultiAttackType(SkillType):
145    def range(self):
146        return sys.maxint
147
148    def selectable(self, warriors):
149        living = [w for w in warriors if not w.is_dead()]
150        living.remove(self.attacker)
151        return living
152
153    def efficiency(self):
154        base = int(self.attacker.concentration() * 1.7)
155        gosa = base / 2
156        return random.randint(base - gosa, base + gosa)
157
158
159class SuicideAttackType(SkillType):
160    def range(self):
161        return sys.maxint
162
163    def selectable(self, warriors):
164        living = [w for w in warriors if not w.is_dead()]
165        living.remove(self.attacker)
166        return living + [self.attacker]
167
168    def efficiency(self):
169        return self.attacker.hitpoint()
170
171
172class Skill:
173    def __init__(self, name, point, skilltype, level=1):
174        self._name = name
175        self._point = point
176        self._skilltype = skilltype
177        self._level = level
178
179    def name(self):
180        return self._name
181
182    def point(self):
183        return self._point
184
185    def skilltype(self):
186        return self._skilltype
187
188    def level(self):
189        return self._level
190
191    def range(self, attacker):
192        return self._skilltype(attacker).range()
193
194    def selectable(self, attacker, warriors):
195        return self._skilltype(attacker).selectable(warriors)
196
197    def invoke(self, attacker, targets, warriors):
198        type_ = self._skilltype(attacker)
199
200        if not targets:
201            return []
202        if not warriors:
203            return []
204        if attacker.skillpoint() < self.point():
205            return []
206        if type_.range() * (self._level // 2 + 1) < len(targets):
207            return []
208        if not set(targets).issubset(set(self.selectable(attacker, warriors))):
209            return []
210
211        attacker.spend(self.point())
212
213        return [(t, self._invoke_one(type_, t, targets), False, False)
214                for t in targets]
215
216    def _invoke_one(self, type_, t, targets):
217        return t.damage(int(type_.efficiency() * self.level() / len(targets)))
Note: See TracBrowser for help on using the repository browser.