Just a simple, and painful to use calculator for the game Factorio written in Python
Revision | 8f46c16204395834810c0e54e421e7fdffe21a75 (tree) |
---|---|
Time | 2017-08-06 03:23:09 |
Author | Eric Hopper <hopper@omni...> |
Commiter | Eric Hopper |
Initial checkin.
@@ -0,0 +1,89 @@ | ||
1 | +#!/usr/bin/python3 | |
2 | + | |
3 | +import pickle | |
4 | +import os | |
5 | +import os.path as _osp | |
6 | +from fractions import Fraction as _F | |
7 | + | |
8 | +class ProductionItem: | |
9 | + __slots__ = ('_name', '_time', '_ingredients', '_produced', '__weakref__') | |
10 | + | |
11 | + def __init__(self, name, time, ingredients, produced=1, **kargs): | |
12 | + super().__init__(**kargs) | |
13 | + self._produced = produced | |
14 | + self._name = name | |
15 | + self._time = time | |
16 | + self._ingredients = ingredients | |
17 | + | |
18 | + def __hash__(self): | |
19 | + return hash(self._name) | |
20 | + | |
21 | + def __eq__(self, other): | |
22 | + if isinstance(other, ProductionItem): | |
23 | + return self._name == other._name | |
24 | + | |
25 | + def __repr__(self): | |
26 | + return f'ProductionItem({self._name!r}, {self._time}, ' \ | |
27 | + f'{self._ingredients!r}, produced={self._produced})' | |
28 | + | |
29 | + @property | |
30 | + def base_rate(self): | |
31 | + base_rate = (self._produced / _F(1,1)) / (self._time / _F(1,1)) | |
32 | + return base_rate | |
33 | + | |
34 | + def factories(self, rate): | |
35 | + return rate / self.base_rate | |
36 | + | |
37 | + def rate_with_factories(self, numfactories): | |
38 | + return numfactories * self.base_rate | |
39 | + | |
40 | +class ItemSet(set): | |
41 | + def __init__(self, *args, **kargs): | |
42 | + super().__init__(*args, **kargs) | |
43 | + self._by_name = dict() | |
44 | + | |
45 | + def __getitem__(self, name): | |
46 | + item = self._by_name.get(name) | |
47 | + if item is not None: | |
48 | + return item | |
49 | + else: | |
50 | + for item in self: | |
51 | + if item._name == name: | |
52 | + self._by_name[item._name] = item | |
53 | + return item | |
54 | + raise KeyError(name) | |
55 | + | |
56 | +_mod_dir = _osp.dirname(__file__) | |
57 | +db_fname = _osp.join(_mod_dir, 'item-db.pickle') | |
58 | + | |
59 | +if _osp.exists(db_fname): | |
60 | + with open(db_fname, 'rb') as _item_f: | |
61 | + item_db = pickle.load(_item_f) | |
62 | +else: | |
63 | + item_db = set() | |
64 | + | |
65 | +def save_items(): | |
66 | + tmp_new = db_fname + '.new' | |
67 | + with open(tmp_new, 'wb') as item_f: | |
68 | + pickle.dump(item_db, item_f, -1) | |
69 | + os.unlink(db_fname) | |
70 | + os.link(tmp_new, db_fname) | |
71 | + os.unlink(tmp_new) | |
72 | + | |
73 | +def production_rate(dest_item, rate, source_item): | |
74 | + if dest_item is source_item: | |
75 | + return rate | |
76 | + if dest_item._produced is None: | |
77 | + return 0 | |
78 | + produced = dest_item._produced / _F(1,1) | |
79 | + scale = rate / produced | |
80 | + print(f"name, scale == {dest_item._name}, {scale}") | |
81 | + total = 0 | |
82 | + for sub_item_ct, sub_item in dest_item._ingredients: | |
83 | + sub_rate = production_rate(sub_item, scale * sub_item_ct, source_item) | |
84 | + total += sub_rate | |
85 | + return total | |
86 | + | |
87 | +def how_many_produced(source_item, rate, dest_item): | |
88 | + forward_rate = production_rate(dest_item, _F(1,1), source_item) | |
89 | + return rate / forward_rate |