source: pycodebattler/trunk/pycodebattler/warrior.py @ 87

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

add error check

  • 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
15try:
16    import cStringIO as _StringIO
17except ImportError:
18    import StringIO as _StringIO
19
20import random
21import pycodebattler
22
23
24def pformat(warriors):
25    order = ['NAME', 'HP', 'SP', 'STR', 'CON', 'DEF', 'AGI', 'LCK']
26    mmap = {
27        'NAME': 'name',
28        'HP':   'hitpoint',
29        'SP':   'skillpoint',
30        'STR':  'strength',
31        'CON':  'concentration',
32        'DEF':  'defense',
33        'AGI':  'agility',
34        'LCK':  'luck',
35    }
36
37    horiz = [[getattr(w, mmap[n])() for n in order] for w in warriors]
38    virt = zip(*horiz)
39
40    sepnum = (len(order) * 3) - 1
41    fmt = ['|']
42    for i, t in enumerate(virt):
43        num = max(len(str(n)) for n in list(t) + [order[i]])
44        sepnum += num
45        if i == 0:
46            fmt.append(' %%-%ds |' % num)
47        else:
48            fmt.append(' %%%ds |' % num)
49
50    fmt = ''.join(fmt + ['\n'])
51    sep = ''.join(['+', '-' * sepnum, '+', '\n'])
52
53    io = _StringIO.StringIO()
54    io.write(sep)
55    io.write(fmt % tuple(order))
56    io.write(sep)
57    for d in horiz:
58        io.write(fmt % tuple(d))
59    io.write(sep)
60    io.flush()
61
62    return io.getvalue()
63
64
65class Warrior:
66    def __init__(self, name, hitpoint, skillpoint, strength, concentration,
67                 defense, agility, luck, skill_list=[], luck_range=5000):
68        for val in [hitpoint, skillpoint, strength, concentration,
69                    defense, agility, luck, luck_range]:
70            if val <= 0:
71                raise ValueError('parameter includes invalid value')
72
73        self._name = name
74        self._skill_list = {}
75        self._max_hitpoint = self._hitpoint = hitpoint
76        self._max_skillpoint = self._skillpoint = skillpoint
77        self._strength = strength
78        self._concentration = concentration
79        self._defense = defense
80        self._agility = agility
81        self._luck = luck
82        self._luck_range = luck_range
83
84        for sk in skill_list:
85            self._skill_list[sk.name()] = sk
86
87    @classmethod
88    def make(klass, name, fp, skill_list=[], luck_range=5000):
89        scorer = pycodebattler.score.Scorer(fp.readlines())
90
91        hitpoint = scorer.style_score()
92        skillpoint = scorer.name_score()
93        strength = scorer.complex_score()
94        concentration = scorer.colon_score()
95        defense = scorer.lines_score()
96        agility = scorer.const_score()
97        luck = luck_range // (hitpoint + skillpoint + strength +
98                              concentration + defense + agility) or 1
99
100        return klass(name, hitpoint, skillpoint, strength, concentration,
101                     defense, agility, luck, skill_list, luck_range)
102
103    def __str__(self):
104        return self.name()
105
106    def name(self):
107        return self._name
108
109    def max_hitpoint(self):
110        return self._max_hitpoint
111
112    def hitpoint(self):
113        return self._hitpoint
114
115    def max_skillpoint(self):
116        return self._max_skillpoint
117
118    def skillpoint(self):
119        return self._skillpoint
120
121    def strength(self):
122        return self._strength
123
124    def concentration(self):
125        return self._concentration
126
127    def defense(self):
128        return self._defense
129
130    def agility(self):
131        return self._agility
132
133    def luck(self):
134        return self._luck
135
136    def skill_list(self):
137        return self._skill_list.keys()
138
139    def skill(self, name):
140        return self._skill_list[name]
141
142    def lucky(self):
143        r = random.randint(-256, self._luck_range)
144        return r <= (self.luck() + self.agility() / 8)
145
146    def is_injured(self):
147        return self.hitpoint() <= (self.max_hitpoint() / 10)
148
149    def is_dead(self):
150        return self.hitpoint() <= 0
151
152    def can_invoke(self, name):
153        try:
154            return self.skill(name).point() < self.skillpoint()
155        except KeyError:
156            return False
157
158    def invoke(self, name, enemy, warriors):
159        try:
160            return self.skill(name).invoke(self, enemy, warriors)
161        except KeyError:
162            return []
163
164    def spend(self, point):
165        self._skillpoint -= point
166        if self._skillpoint < 0:
167            self._skillpoint = 0
168        return point
169
170    def damage_from(self, enemy):
171        miss = False
172        critical = False
173
174        rgosa = enemy.strength() / 2
175        gosa = random.randint(0 - rgosa, rgosa)
176
177        if enemy.lucky():
178            critical = True
179            damage = (enemy.strength() + gosa) * random.randint(3, 8)
180        else:
181            damage = enemy.strength() + gosa - self.defense()
182
183        if damage <= 0:
184            damage = 1
185
186        if self.lucky() and not critical:
187            miss = True
188            damage = 0
189
190        return self.damage(damage), miss, critical
191
192    def damage(self, damage):
193        self._hitpoint -= damage
194        if self.hitpoint() < 0:
195            self._hitpoint = 0
196        if self.hitpoint() > self.max_hitpoint():
197            self._hitpoint = self.max_hitpoint()
198        return damage
199
200    def attack_to(self, enemy):
201        return enemy.damage_from(self)
Note: See TracBrowser for help on using the repository browser.