2013-06-03 22:57:55 +03:00
|
|
|
import random
|
|
|
|
import sys
|
|
|
|
|
|
|
|
class Section:
|
|
|
|
def __init__(self, name, text):
|
|
|
|
self.name = name
|
|
|
|
self.text = text
|
2013-06-04 23:36:09 +03:00
|
|
|
self.tags = set()
|
|
|
|
|
2013-06-04 23:44:50 +03:00
|
|
|
def add_tags(self, tags):
|
|
|
|
self.tags.update(set(tags))
|
|
|
|
|
|
|
|
def hastag(self, tag):
|
|
|
|
return tag in self.tags
|
2013-06-03 22:57:55 +03:00
|
|
|
|
|
|
|
def __repr__(self):
|
2013-06-04 23:36:09 +03:00
|
|
|
return "Section(%s, %s, %s)" % (repr(self.name), repr(self.text),
|
|
|
|
repr(self.tags))
|
2013-06-03 22:57:55 +03:00
|
|
|
|
2013-06-11 22:59:39 +03:00
|
|
|
class ShuffledSection (Section):
|
|
|
|
def __init__(self, nr, section):
|
|
|
|
self.nr = nr
|
|
|
|
self.name = section.name
|
|
|
|
self.text = section.text
|
|
|
|
self.tags = section.tags.copy()
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
return "ShuffledSection(%d, %s, %s, %s)" % (self.nr,
|
|
|
|
repr(self.name), repr(self.text),
|
|
|
|
repr(self.tags))
|
|
|
|
|
|
|
|
class IntroSection (Section):
|
|
|
|
def __init__(self, section):
|
|
|
|
self.nr = -1
|
|
|
|
self.name = section.name
|
|
|
|
self.text = section.text
|
|
|
|
self.tags = section.tags.copy()
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
return "IntroSection(%d, %s, %s, %s)" % (repr(self.name), repr(self.text),
|
|
|
|
repr(self.tags))
|
|
|
|
|
2013-06-03 22:57:55 +03:00
|
|
|
class ShuffledSections:
|
2013-06-11 22:59:39 +03:00
|
|
|
def __init__(self, as_list, from_nr, from_name, nr_sections):
|
2013-06-03 22:57:55 +03:00
|
|
|
self.as_list = as_list
|
|
|
|
self.from_nr = from_nr
|
|
|
|
self.from_name = from_name
|
|
|
|
self.name_to_nr = {}
|
|
|
|
for n in from_name:
|
2013-06-11 22:59:39 +03:00
|
|
|
self.name_to_nr[n] = from_name[n].nr
|
2013-06-08 21:50:08 +03:00
|
|
|
for nr in nr_sections:
|
|
|
|
self.name_to_nr[nr_sections[nr]] = nr
|
2013-06-03 22:57:55 +03:00
|
|
|
|
2013-06-11 22:59:39 +03:00
|
|
|
STR_BOOK_CONFIG = set(['title', 'author', 'starttext', 'hideintrotext',
|
|
|
|
'showintrotext'])
|
2013-06-11 00:06:37 +03:00
|
|
|
INT_BOOK_CONFIG = set(['max'])
|
|
|
|
|
2013-06-03 22:57:55 +03:00
|
|
|
class Book:
|
|
|
|
def __init__(self):
|
|
|
|
self.sections = []
|
2013-06-11 22:59:39 +03:00
|
|
|
self.introsections = []
|
2013-06-04 00:46:11 +03:00
|
|
|
self.from_name = {}
|
2013-06-03 22:57:55 +03:00
|
|
|
self.nr_sections = {}
|
2013-06-05 01:19:57 +03:00
|
|
|
self.codewords = set()
|
2013-06-10 23:50:06 +03:00
|
|
|
self.config = {'max' : 0,
|
|
|
|
'title' : 'Gamebook',
|
2013-06-11 22:59:39 +03:00
|
|
|
'author' : '',
|
|
|
|
'starttext' : 'Turn to 1 to begin.',
|
|
|
|
'hideintrotext' : '(hide instructions)',
|
|
|
|
'showintrotext' : '(show instructions)'}
|
2013-06-10 23:50:06 +03:00
|
|
|
|
|
|
|
def configure(self, name, value):
|
2013-06-11 00:06:37 +03:00
|
|
|
if name in INT_BOOK_CONFIG:
|
|
|
|
self.config[name] = int(value)
|
|
|
|
elif name in STR_BOOK_CONFIG:
|
|
|
|
self.config[name] = value
|
|
|
|
else:
|
|
|
|
raise Exception("Unknown book option '%s'." % name)
|
2013-06-03 22:57:55 +03:00
|
|
|
|
2013-06-04 00:46:11 +03:00
|
|
|
def add(self, section):
|
2013-06-04 23:32:51 +03:00
|
|
|
if section.name in self.from_name:
|
|
|
|
raise Exception('Duplicate section names (%s) not allowed.' %
|
|
|
|
section.name)
|
2013-06-03 22:57:55 +03:00
|
|
|
self.sections.append(section)
|
2013-06-04 00:46:11 +03:00
|
|
|
self.from_name[section.name] = section
|
2013-06-10 23:50:06 +03:00
|
|
|
if len(self.sections) > self.config['max']:
|
|
|
|
self.config['max'] = len(self.sections)
|
2013-06-04 00:46:11 +03:00
|
|
|
|
2013-06-11 22:59:39 +03:00
|
|
|
def addintro(self, section):
|
|
|
|
self.introsections.append(IntroSection(section))
|
|
|
|
|
2013-06-05 01:19:57 +03:00
|
|
|
def add_codeword(self, word):
|
|
|
|
self.codewords.add(word)
|
|
|
|
|
2013-06-04 00:46:11 +03:00
|
|
|
def force_section_nr(self, name, nr):
|
|
|
|
self.nr_sections[nr] = name
|
2013-06-10 23:50:06 +03:00
|
|
|
if nr > self.config['max']:
|
|
|
|
self.config['max'] = nr
|
2013-06-03 22:57:55 +03:00
|
|
|
|
2013-06-14 00:07:36 +03:00
|
|
|
def shuffle(self, seed=None):
|
2013-06-03 22:57:55 +03:00
|
|
|
as_list = [None]
|
|
|
|
from_nr = {}
|
|
|
|
shuffled = self.sections[:]
|
2013-06-11 22:59:39 +03:00
|
|
|
shuffled_from_name = {}
|
2013-06-11 00:06:37 +03:00
|
|
|
while len(shuffled) < self.config['max']:
|
|
|
|
dummy = Section('Dummy', '')
|
|
|
|
dummy.add_tags(['dummy'])
|
|
|
|
shuffled.append(dummy)
|
2013-06-03 22:57:55 +03:00
|
|
|
for p in self.nr_sections.values():
|
2013-06-08 21:50:08 +03:00
|
|
|
if p in self.from_name:
|
|
|
|
shuffled.remove(self.from_name[p])
|
2013-06-14 00:07:36 +03:00
|
|
|
rnd = random.Random(seed)
|
|
|
|
rnd.shuffle(shuffled)
|
2013-06-10 23:50:06 +03:00
|
|
|
for nr in range(1, self.config['max'] + 1):
|
2013-06-08 21:50:08 +03:00
|
|
|
if (self.nr_sections.has_key(nr)
|
|
|
|
and self.nr_sections[nr] in self.from_name):
|
2013-06-14 00:07:36 +03:00
|
|
|
section = ShuffledSection(nr, self.from_name[
|
|
|
|
self.nr_sections[nr]])
|
2013-06-03 22:57:55 +03:00
|
|
|
elif len(shuffled):
|
2013-06-11 22:59:39 +03:00
|
|
|
section = ShuffledSection(nr, shuffled.pop())
|
2013-06-03 22:57:55 +03:00
|
|
|
else:
|
|
|
|
section = None
|
|
|
|
as_list.append(section)
|
|
|
|
from_nr[nr] = section
|
|
|
|
if section:
|
2013-06-11 22:59:39 +03:00
|
|
|
shuffled_from_name[section.name] = section
|
|
|
|
return ShuffledSections(as_list, from_nr, shuffled_from_name,
|
2013-06-08 21:50:08 +03:00
|
|
|
self.nr_sections)
|