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

Revision 85, 5.2 KB checked in by atzm, 13 years ago (diff)

support to make warrior by parameters

  • 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        self._name = name
69        self._skill_list = {}
70        self._max_hitpoint = self._hitpoint = hitpoint
71        self._max_skillpoint = self._skillpoint = skillpoint
72        self._strength = strength
73        self._concentration = concentration
74        self._defense = defense
75        self._agility = agility
76        self._luck = luck
77        self._luck_range = luck_range
78
79        for sk in skill_list:
80            self._skill_list[sk.name()] = sk
81
82    @classmethod
83    def make(klass, name, fp, skill_list=[], luck_range=5000):
84        scorer = pycodebattler.score.Scorer(fp.readlines())
85
86        hitpoint = scorer.style_score()
87        skillpoint = scorer.name_score()
88        strength = scorer.complex_score()
89        concentration = scorer.colon_score()
90        defense = scorer.lines_score()
91        agility = scorer.const_score()
92        luck = luck_range // (hitpoint + skillpoint + strength +
93                              concentration + defense + agility) or 1
94
95        return klass(name, hitpoint, skillpoint, strength, concentration,
96                     defense, agility, luck, skill_list, luck_range)
97
98    def __str__(self):
99        return self.name()
100
101    def name(self):
102        return self._name
103
104    def max_hitpoint(self):
105        return self._max_hitpoint
106
107    def hitpoint(self):
108        return self._hitpoint
109
110    def max_skillpoint(self):
111        return self._max_skillpoint
112
113    def skillpoint(self):
114        return self._skillpoint
115
116    def strength(self):
117        return self._strength
118
119    def concentration(self):
120        return self._concentration
121
122    def defense(self):
123        return self._defense
124
125    def agility(self):
126        return self._agility
127
128    def luck(self):
129        return self._luck
130
131    def skill_list(self):
132        return self._skill_list.keys()
133
134    def skill(self, name):
135        return self._skill_list[name]
136
137    def lucky(self):
138        r = random.randint(-256, self._luck_range)
139        return r <= (self.luck() + self.agility() / 8)
140
141    def is_injured(self):
142        return self.hitpoint() <= (self.max_hitpoint() / 10)
143
144    def is_dead(self):
145        return self.hitpoint() <= 0
146
147    def can_invoke(self, name):
148        try:
149            return self.skill(name).point() < self.skillpoint()
150        except KeyError:
151            return False
152
153    def invoke(self, name, enemy, warriors):
154        try:
155            return self.skill(name).invoke(self, enemy, warriors)
156        except KeyError:
157            return []
158
159    def spend(self, point):
160        self._skillpoint -= point
161        if self._skillpoint < 0:
162            self._skillpoint = 0
163        return point
164
165    def damage_from(self, enemy):
166        miss = False
167        critical = False
168
169        rgosa = enemy.strength() / 2
170        gosa = random.randint(0 - rgosa, rgosa)
171
172        if enemy.lucky():
173            critical = True
174            damage = (enemy.strength() + gosa) * random.randint(3, 8)
175        else:
176            damage = enemy.strength() + gosa - self.defense()
177
178        if damage <= 0:
179            damage = 1
180
181        if self.lucky() and not critical:
182            miss = True
183            damage = 0
184
185        return self.damage(damage), miss, critical
186
187    def damage(self, damage):
188        self._hitpoint -= damage
189        if self.hitpoint() < 0:
190            self._hitpoint = 0
191        if self.hitpoint() > self.max_hitpoint():
192            self._hitpoint = self.max_hitpoint()
193        return damage
194
195    def attack_to(self, enemy):
196        return enemy.damage_from(self)
Note: See TracBrowser for help on using the repository browser.