Mercurial > hg > lib > markup
annotate python/safe.py @ 13:1cd5c7952aaa default tip
fix failure to read first line of Air/Lava,
keep me from swimming in Lava, again!
author | Henry S. Thompson <ht@inf.ed.ac.uk> |
---|---|
date | Sun, 30 Jan 2022 14:49:33 -0500 |
parents | 1e42c0147a49 |
children |
rev | line source |
---|---|
4 | 1 #!/usr/bin/python3 |
2 '''Find a safe landing space (i.e. in air, not above lava) near a cluster''' | |
3 import sys, math | |
4 | |
5 from util import * | |
10 | 6 from bisect import insort |
4 | 7 |
8 def usage(): | |
10 | 9 print("""Usage: safe.py [-d n] [filename] |
4 | 10 n is maximum distance of landing to some point in the cluster, default is 10. |
11 | |
12 Feed stdin with lines from the output of cluster.py, having produced | |
13 air.tsv with the same settings as the cluster input, and lava.tsv | |
14 with a lower-bound on Y of 0""") | |
15 | |
16 class Block: | |
8
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
17 '''Shared by Air and Lava, |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
18 holds points and columns. |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
19 Columns are dictionaries indexed by (x,z) coords, |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
20 value is upward-ordered list of pairs, closed intervals of y''' |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
21 def __init__(self,filename): |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
22 with open(filename,'r') as file: |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
23 self.readHeaders(file) |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
24 self.readPoints(file) |
4 | 25 |
8
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
26 cc=self.columns={} |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
27 tc={} |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
28 for p in self.points: |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
29 k=(p[0],p[2]) |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
30 y=p[1] |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
31 try: |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
32 yy=tc[k] |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
33 insort(yy,y) |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
34 except KeyError: |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
35 tc[k]=[y] |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
36 # convert to lists of intervals |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
37 for k,yy in tc.items(): |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
38 tyy=[yy] |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
39 ii=[] |
13
1cd5c7952aaa
fix failure to read first line of Air/Lava,
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
12
diff
changeset
|
40 # if k==(108.5, -45.5): WTF?? |
1cd5c7952aaa
fix failure to read first line of Air/Lava,
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
12
diff
changeset
|
41 # pass |
8
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
42 while True: |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
43 clean=True |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
44 for j,yy in enumerate(tyy): |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
45 if len(yy)==1+(yy[-1]-yy[0]): |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
46 ii.append((yy[0],yy[-1])) |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
47 else: |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
48 clean=False |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
49 for i in range(len(yy)-1): |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
50 if yy[i]+1!=yy[i+1]: |
11 | 51 ii.append((yy[0],yy[i])) |
8
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
52 tyy=[yy[i+1:]]+tyy[j+1:] |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
53 break |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
54 if clean: |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
55 break |
10 | 56 self.columns[k]=set(ii) # so we can merge later |
8
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
57 |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
58 def readPoints(self,file): |
12
1e42c0147a49
minutor changed file format for minecraft 1.18
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
11
diff
changeset
|
59 self.points=[[float(i) for i in l.split('\t')[2].split('/')] for l in file] |
8
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
60 |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
61 Block.readHeaders=readHeaders # from util |
4 | 62 |
63 class Air(Block): | |
8
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
64 pass |
4 | 65 |
66 | |
67 class Lava(Block): | |
8
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
68 pass |
fcef94b6324c
move all the action to Block
Henry S. Thompson <ht@inf.ed.ac.uk>
parents:
7
diff
changeset
|
69 |
4 | 70 def d(p1,p2): |
71 dx=p1[0]-p2[0] | |
72 dz=p1[1]-p2[1] | |
73 dy=p1[2]-p2[2] | |
74 return math.sqrt((dx*dx)+(dy*dy)+(dz*dz)) | |
75 | |
9 | 76 def safety(p): |
11 | 77 ka=[((a[0],a[2]),d(a,p)) for a in A.points if d(a,p)<=n] |
78 return [(k,A.columns[k[0]],L.columns.get(k[0],None)) for k in ka] | |
79 | |
80 if __name__=='__main__': | |
81 n=10.0 | |
82 if len(sys.argv)>1: | |
83 if sys.argv[1]=='-d': | |
84 sys.argv.pop(1) | |
85 n=float(sys.argv.pop(1)) | |
86 | |
87 if len(sys.argv)>1: | |
88 infile=open(sys.argv.pop(1)) | |
89 else: | |
90 infile=sys.stdin | |
91 | |
92 A=Air('air.tsv') | |
93 | |
94 L=Lava('lava.tsv') | |
95 | |
96 readHeaders(sys.modules['__main__'],infile,False) | |
4 | 97 |
11 | 98 for l in infile: |
99 c=eval(l) | |
100 ss=[] | |
101 hits={} | |
102 misses=[] | |
103 for p in c: | |
104 ss=safety(p) | |
105 if ss: | |
106 for (k,a,l) in ss: | |
107 try: | |
108 (aa,ll)=hits[k] | |
109 aa.update(a) | |
110 if l is not None: | |
111 ll.update(l) | |
112 except KeyError: | |
113 hits[k]=(a,l) | |
114 else: | |
115 misses.append(p) | |
116 print(c) | |
117 if hits: | |
118 print(' %s nearby landing columns'%len(hits)) | |
119 done={} | |
120 for k in sorted(hits.keys(),key=lambda k:k[1]): | |
121 if k[0] not in done: | |
122 done[k[0]]=1 | |
123 aa,ll=hits[k] | |
124 laa=sorted(list(aa)) | |
125 lowAir=laa[0][0] | |
126 j=-1 | |
127 if ll is not None: | |
128 lll=sorted(list(ll)) | |
129 highLava=-1 | |
130 for i,(_,h) in enumerate(lll): | |
131 if h>highLava and h<lowAir: | |
132 highLava=h | |
133 if h+1==lowAir: | |
134 j=i | |
135 break | |
136 if j>-1: | |
137 lava='['+','.join(str(e) if i!=j else \ | |
138 "(%s,%s)"%(e[0],RedFmt%e[1]) for i,e in enumerate(lll))+']' | |
139 lowAir=RedFmt%lowAir | |
140 else: | |
141 lava=None | |
142 else: | |
143 lava=None | |
144 print("%s(%s %s %s)@%0.1f: %s %s"%(' ' if j>-1 else '', | |
145 k[0][0],lowAir,k[0][1],k[1],laa,lava)) | |
9 | 146 else: |
11 | 147 print(' No nearby landing zones') |
10 | 148 |
11 | 149 if infile!=sys.stdin: |
150 infile.close() |