annotate gamelib/lab.py @ 151:372d886f9e70

New suggest_research() method on Lab.
author Jeremy Thurgood <firxen@gmail.com>
date Fri, 11 May 2012 20:06:36 +0200
parents 14917385a0fd
children a644f6b64a6d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
14
9d61abb3cfaf Better subclass handling.
Jeremy Thurgood <firxen@gmail.com>
parents: 9
diff changeset
1 # -*- test-case-name: gamelib.tests.test_lab -*-
6
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
2
151
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
3 from random import random, choice, sample
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
4
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
5 import networkx
17
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
6
49
373c57ab4140 Product -> Schematic.
Jeremy Thurgood <firxen@gmail.com>
parents: 47
diff changeset
7 from gamelib import research, schematics
45
1e8f7e694f0c Refactor missions and sciences a bit to reduce duplication.
Jeremy Thurgood <firxen@gmail.com>
parents: 36
diff changeset
8 from gamelib.game_base import get_subclasses
6
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
9
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
10
151
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
11 class ScienceGraph(object):
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
12 def __init__(self, all_science, known_science):
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
13 self.graph = networkx.DiGraph()
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
14 self.all_science = all_science
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
15 self.known_science = known_science
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
16 self.add_all_science()
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
17 self.tag_known_science()
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
18 assert networkx.is_directed_acyclic_graph(self.graph)
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
19
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
20 def add_all_science(self):
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
21 # Add level 0 of everything to the graph.
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
22 for science in self.all_science:
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
23 self.graph.add_node((science, 0), known=False)
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
24
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
25 # Walk dependencies and fill in intermediate nodes.
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
26 for science in self.all_science:
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
27 for dep in science.PREREQUISITES:
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
28 self.add_node_string(*dep)
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
29 self.graph.add_edge(dep, (science, 0))
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
30
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
31 def add_node_string(self, science, level):
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
32 node = (science, level)
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
33 if node in self.graph:
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
34 return node
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
35
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
36 # We prepopulate with level 0 of eveything.
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
37 assert level >= 0
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
38
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
39 self.graph.add_node(node, known=False)
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
40 parent = self.add_node_string(science, level - 1)
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
41 self.graph.add_edge(parent, node)
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
42 return node
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
43
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
44 def tag_known_science(self):
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
45 for science in self.known_science:
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
46 # We may know more of this than the graph has.
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
47 self.add_node_string(type(science), science.points + 1)
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
48 for i in range(science.points + 1):
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
49 self.graph.node[(type(science), i)]['known'] = True
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
50
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
51 def is_known(self, node):
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
52 return self.graph.node[node]['known']
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
53
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
54 def distances_to_known(self, science):
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
55 nodes = set()
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
56 nodes_to_check = [(science, 0)]
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
57
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
58 while nodes_to_check:
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
59 node = nodes_to_check.pop()
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
60 if self.is_known(node) or node in nodes:
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
61 continue
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
62 nodes.add(node)
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
63 nodes_to_check.extend(self.graph.predecessors(node))
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
64
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
65 distances = {}
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
66 for node in nodes:
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
67 distances.setdefault(node[0], 0)
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
68 distances[node[0]] += 1
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
69
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
70 return distances
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
71
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
72 def count_unknown(self, sciences):
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
73 return len([s for s in sciences if not self.is_known((s, 0))])
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
74
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
75 def find_prospects(self):
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
76 prospects = {'research': [], 'schematic': []}
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
77 for science in self.all_science:
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
78 distances = self.distances_to_known(science)
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
79 if not distances:
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
80 # We already know this thing.
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
81 continue
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
82 # Remove the thing we're trying to get from the distance.
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
83 distances.pop(science)
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
84 if self.count_unknown(distances.keys()) > 0:
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
85 # We only want direct breakthroughs.
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
86 continue
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
87 prospects[science.SCIENCE_TYPE].append(
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
88 (sum(distances.values()), science, distances))
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
89 return dict((k, sorted(v)) for k, v in prospects.items())
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
90
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
91 def find_promising_areas(self, size=3):
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
92 basic_science = False
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
93 areas_for_research = set()
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
94 areas_for_schematics = set()
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
95 prospects = self.find_prospects()
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
96
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
97 for points, target, distances in prospects['schematic']:
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
98 if points > 0:
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
99 # We need nonzero points in these things.
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
100 areas_for_schematics.update(distances.keys())
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
101 else:
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
102 # Any of these things qualify us.
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
103 areas_for_schematics.update(p for p, _ in target.PREREQUISITES)
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
104
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
105 for points, target, distances in prospects['research']:
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
106 if points == 0:
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
107 basic_science = True
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
108 else:
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
109 areas_for_research.update(distances.keys())
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
110
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
111 suggestions = []
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
112 k = min(size, len(areas_for_schematics))
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
113 suggestions.extend(sample(areas_for_schematics, k))
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
114 if len(suggestions) < size:
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
115 k = min(size - len(suggestions), len(areas_for_research))
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
116 suggestions.extend(sample(areas_for_research, k))
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
117
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
118 return basic_science, suggestions
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
119
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
120
6
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
121 class Lab(object):
17
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
122 BASIC_RESEARCH_SUCCESS_RATE = 0.05
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
123 BASIC_RESEARCH_SUCCESS_MULTIPLIER = 2
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
124
20
718d1ec382f7 Deserialise lab data.
Jeremy Thurgood <firxen@gmail.com>
parents: 17
diff changeset
125 def __init__(self, init_data=None):
6
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
126 self.science = []
45
1e8f7e694f0c Refactor missions and sciences a bit to reduce duplication.
Jeremy Thurgood <firxen@gmail.com>
parents: 36
diff changeset
127 self.new_research = get_subclasses(research.ResearchArea)
49
373c57ab4140 Product -> Schematic.
Jeremy Thurgood <firxen@gmail.com>
parents: 47
diff changeset
128 self.new_schematics = get_subclasses(schematics.Schematic)
151
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
129 self.all_science = [s for s in self.new_research + self.new_schematics]
20
718d1ec382f7 Deserialise lab data.
Jeremy Thurgood <firxen@gmail.com>
parents: 17
diff changeset
130
718d1ec382f7 Deserialise lab data.
Jeremy Thurgood <firxen@gmail.com>
parents: 17
diff changeset
131 if init_data is not None:
718d1ec382f7 Deserialise lab data.
Jeremy Thurgood <firxen@gmail.com>
parents: 17
diff changeset
132 # Load stored state.
718d1ec382f7 Deserialise lab data.
Jeremy Thurgood <firxen@gmail.com>
parents: 17
diff changeset
133 self._load_data(init_data)
718d1ec382f7 Deserialise lab data.
Jeremy Thurgood <firxen@gmail.com>
parents: 17
diff changeset
134 else:
718d1ec382f7 Deserialise lab data.
Jeremy Thurgood <firxen@gmail.com>
parents: 17
diff changeset
135 # New game.
718d1ec382f7 Deserialise lab data.
Jeremy Thurgood <firxen@gmail.com>
parents: 17
diff changeset
136 self._choose_initial_science()
718d1ec382f7 Deserialise lab data.
Jeremy Thurgood <firxen@gmail.com>
parents: 17
diff changeset
137
718d1ec382f7 Deserialise lab data.
Jeremy Thurgood <firxen@gmail.com>
parents: 17
diff changeset
138 def _load_data(self, init_data):
46
d3d277a42ac6 Less getattr/isinstance silliness.
Jeremy Thurgood <firxen@gmail.com>
parents: 45
diff changeset
139 sciences = init_data['science'].copy()
49
373c57ab4140 Product -> Schematic.
Jeremy Thurgood <firxen@gmail.com>
parents: 47
diff changeset
140 for science in self.new_schematics + self.new_research:
46
d3d277a42ac6 Less getattr/isinstance silliness.
Jeremy Thurgood <firxen@gmail.com>
parents: 45
diff changeset
141 # Check if this science is one we should know.
d3d277a42ac6 Less getattr/isinstance silliness.
Jeremy Thurgood <firxen@gmail.com>
parents: 45
diff changeset
142 points = sciences.pop(science.save_name(), None)
d3d277a42ac6 Less getattr/isinstance silliness.
Jeremy Thurgood <firxen@gmail.com>
parents: 45
diff changeset
143 if points is not None:
d3d277a42ac6 Less getattr/isinstance silliness.
Jeremy Thurgood <firxen@gmail.com>
parents: 45
diff changeset
144 # It is! Learn it.
d3d277a42ac6 Less getattr/isinstance silliness.
Jeremy Thurgood <firxen@gmail.com>
parents: 45
diff changeset
145 self._gain_science(science(points))
d3d277a42ac6 Less getattr/isinstance silliness.
Jeremy Thurgood <firxen@gmail.com>
parents: 45
diff changeset
146 if sciences:
d3d277a42ac6 Less getattr/isinstance silliness.
Jeremy Thurgood <firxen@gmail.com>
parents: 45
diff changeset
147 # We're supposed to know an unknowable thing. :-(
d3d277a42ac6 Less getattr/isinstance silliness.
Jeremy Thurgood <firxen@gmail.com>
parents: 45
diff changeset
148 raise ValueError("Unknown science: %s" % (sciences.keys(),))
17
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
149
21
bdc6bfc34ef2 Serialise lab data.
Jeremy Thurgood <firxen@gmail.com>
parents: 20
diff changeset
150 def save_data(self):
47
3e3bed2ce248 Better science saving.
Jeremy Thurgood <firxen@gmail.com>
parents: 46
diff changeset
151 return {'science': dict(s.save_data() for s in self.science)}
21
bdc6bfc34ef2 Serialise lab data.
Jeremy Thurgood <firxen@gmail.com>
parents: 20
diff changeset
152
17
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
153 def _choose_initial_science(self):
49
373c57ab4140 Product -> Schematic.
Jeremy Thurgood <firxen@gmail.com>
parents: 47
diff changeset
154 # We always get all starting schematics.
373c57ab4140 Product -> Schematic.
Jeremy Thurgood <firxen@gmail.com>
parents: 47
diff changeset
155 for schematic in self.new_schematics[:]:
373c57ab4140 Product -> Schematic.
Jeremy Thurgood <firxen@gmail.com>
parents: 47
diff changeset
156 if schematic.STARTING_PRODUCT:
373c57ab4140 Product -> Schematic.
Jeremy Thurgood <firxen@gmail.com>
parents: 47
diff changeset
157 self._gain_science(schematic())
17
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
158
115
ef63532cac13 Rearrange SCIENCE a bit.
Jeremy Thurgood <firxen@gmail.com>
parents: 85
diff changeset
159 # We start with Physics, because it's not Philately.
ef63532cac13 Rearrange SCIENCE a bit.
Jeremy Thurgood <firxen@gmail.com>
parents: 85
diff changeset
160 physics = research.Physics()
ef63532cac13 Rearrange SCIENCE a bit.
Jeremy Thurgood <firxen@gmail.com>
parents: 85
diff changeset
161 self._gain_science(physics)
ef63532cac13 Rearrange SCIENCE a bit.
Jeremy Thurgood <firxen@gmail.com>
parents: 85
diff changeset
162 new_science = [physics]
ef63532cac13 Rearrange SCIENCE a bit.
Jeremy Thurgood <firxen@gmail.com>
parents: 85
diff changeset
163
ef63532cac13 Rearrange SCIENCE a bit.
Jeremy Thurgood <firxen@gmail.com>
parents: 85
diff changeset
164 # We get two other random sciences with no prerequisites.
151
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
165 for science in sample(self.find_new_research(), 2):
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
166 science = science()
17
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
167 self._gain_science(science)
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
168 new_science.append(science)
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
169
49
373c57ab4140 Product -> Schematic.
Jeremy Thurgood <firxen@gmail.com>
parents: 47
diff changeset
170 # Add a point to each of our sciences, and see if we get schematics.
17
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
171 self.spend_points(new_science, 0)
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
172
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
173 def _gain_science(self, science):
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
174 self.science.append(science)
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
175 if isinstance(science, research.ResearchArea):
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
176 self.new_research.remove(type(science))
49
373c57ab4140 Product -> Schematic.
Jeremy Thurgood <firxen@gmail.com>
parents: 47
diff changeset
177 elif isinstance(science, schematics.Schematic):
373c57ab4140 Product -> Schematic.
Jeremy Thurgood <firxen@gmail.com>
parents: 47
diff changeset
178 self.new_schematics.remove(type(science))
6
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
179
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
180 def spend_points(self, things, basic_research):
17
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
181 breakthroughs = []
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
182
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
183 # First, allocate the points.
6
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
184 for thing in things:
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
185 assert thing in self.science
58
52913ba12988 Check for multiple points in can_spend
Neil Muller <drnlmuller@gmail.com>
parents: 49
diff changeset
186 assert thing.can_spend(self, 1)
17
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
187 thing.spend_point()
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
188
49
373c57ab4140 Product -> Schematic.
Jeremy Thurgood <firxen@gmail.com>
parents: 47
diff changeset
189 # Next, check for schematic breakthroughs and upgrades
85
182fce9f70b6 Propaganda! Also, a fix to blueprint breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 73
diff changeset
190 breakthroughs.extend(self.apply_area_research([
182fce9f70b6 Propaganda! Also, a fix to blueprint breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 73
diff changeset
191 thing for thing in things
182fce9f70b6 Propaganda! Also, a fix to blueprint breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 73
diff changeset
192 if isinstance(thing, research.ResearchArea)]))
17
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
193
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
194 # Finally, check for research breakthroughs.
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
195 breakthroughs.extend(self.apply_basic_research(basic_research))
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
196
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
197 return breakthroughs
6
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
198
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
199 def _get_science(self, science_class):
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
200 for science in self.science:
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
201 if isinstance(science, science_class):
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
202 return science
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
203 return None
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
204
17
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
205 def meet_requirements(self, science_class, extra=0):
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
206 total_points = 0
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
207 base_points = 0
6
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
208 for science, level in science_class.PREREQUISITES:
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
209 my_science = self._get_science(science)
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
210 if my_science is None:
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
211 return False
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
212 if my_science.points < level:
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
213 return False
17
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
214 base_points += level
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
215 total_points += my_science.points
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
216 return total_points - base_points >= extra
6
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
217
49
373c57ab4140 Product -> Schematic.
Jeremy Thurgood <firxen@gmail.com>
parents: 47
diff changeset
218 def find_new_schematics(self):
373c57ab4140 Product -> Schematic.
Jeremy Thurgood <firxen@gmail.com>
parents: 47
diff changeset
219 available_schematics = []
373c57ab4140 Product -> Schematic.
Jeremy Thurgood <firxen@gmail.com>
parents: 47
diff changeset
220 for schematic_class in self.new_schematics:
373c57ab4140 Product -> Schematic.
Jeremy Thurgood <firxen@gmail.com>
parents: 47
diff changeset
221 if self.meet_requirements(schematic_class):
373c57ab4140 Product -> Schematic.
Jeremy Thurgood <firxen@gmail.com>
parents: 47
diff changeset
222 available_schematics.append(schematic_class)
373c57ab4140 Product -> Schematic.
Jeremy Thurgood <firxen@gmail.com>
parents: 47
diff changeset
223 return available_schematics
6
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
224
17
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
225 def find_new_research(self):
6
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
226 available_research = []
14
9d61abb3cfaf Better subclass handling.
Jeremy Thurgood <firxen@gmail.com>
parents: 9
diff changeset
227 for research_class in self.new_research:
17
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
228 if self.meet_requirements(research_class):
6
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
229 available_research.append(research_class)
826b44731323 Start of basic lab implementation.
Jeremy Thurgood <firxen@gmail.com>
parents:
diff changeset
230 return available_research
17
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
231
73
b503ccb0a86e Only one schematic per turn, please.
Jeremy Thurgood <firxen@gmail.com>
parents: 58
diff changeset
232 def apply_area_research(self, researches):
49
373c57ab4140 Product -> Schematic.
Jeremy Thurgood <firxen@gmail.com>
parents: 47
diff changeset
233 options = [schema for schema in self.find_new_schematics()
73
b503ccb0a86e Only one schematic per turn, please.
Jeremy Thurgood <firxen@gmail.com>
parents: 58
diff changeset
234 if schema.depends_on(researches)]
49
373c57ab4140 Product -> Schematic.
Jeremy Thurgood <firxen@gmail.com>
parents: 47
diff changeset
235 breakthroughs = [schematic for schematic in options
373c57ab4140 Product -> Schematic.
Jeremy Thurgood <firxen@gmail.com>
parents: 47
diff changeset
236 if random() < schematic.ACQUISITION_CHANCE]
17
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
237 if breakthroughs:
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
238 breakthrough = choice(breakthroughs)()
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
239 self._gain_science(breakthrough)
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
240 breakthroughs = [breakthrough]
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
241 return breakthroughs
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
242
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
243 def apply_basic_research(self, basic_research):
138
14917385a0fd Better handling of mission results and turn-end messages.
Jeremy Thurgood <firxen@gmail.com>
parents: 115
diff changeset
244 if basic_research <= 0:
17
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
245 return []
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
246
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
247 options = self.find_new_research()
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
248 success_chance = self.BASIC_RESEARCH_SUCCESS_RATE * (
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
249 self.BASIC_RESEARCH_SUCCESS_MULTIPLIER ** basic_research)
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
250 breakthroughs = [research for research in options
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
251 if random() < success_chance]
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
252 if breakthroughs:
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
253 breakthrough = choice(breakthroughs)(1)
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
254 self._gain_science(breakthrough)
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
255 breakthroughs = [breakthrough]
10d3db1f1e08 Set up initial research and rework breakthroughs.
Jeremy Thurgood <firxen@gmail.com>
parents: 14
diff changeset
256 return breakthroughs
151
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
257
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
258 def suggest_research(self):
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
259 """Suggest research areas to pursue.
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
260
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
261 Return value is a tuple of (bool, list), where the first element
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
262 indicates whether basic research might pay off and the second contains
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
263 Science classes that can be profitably pursued.
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
264 """
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
265 graph = ScienceGraph(self.all_science, self.science)
372d886f9e70 New suggest_research() method on Lab.
Jeremy Thurgood <firxen@gmail.com>
parents: 138
diff changeset
266 return graph.find_promising_areas()