chiark / gitweb /
Ability to sort pirates by ability in specific duty puzzles
authorIan Jackson <ian@liberator.(none)>
Wed, 27 May 2009 21:21:13 +0000 (22:21 +0100)
committerIan Jackson <ian@liberator.relativity.greenend.org.uk>
Wed, 27 May 2009 21:28:55 +0000 (22:28 +0100)
yoweb-scrape
yoweb-scrape.txt

index 3567f0dcd08d154904a67162dce9f87cca983ada..d2d194c213e9039b941a1465c464239654ca14ae 100755 (executable)
@@ -28,8 +28,20 @@ puzzles = ('Swordfighting/Bilging/Sailing/Rigging/Navigating'+
        '/Drinking/Spades/Hearts/Treasure Drop/Poker/Distilling'+
        '/Alchemistry/Shipwrightery/Blacksmithing/Foraging').split('/')
 
+core_duty_puzzles = [
+               'Gunning',
+               ['Sailing','Rigging'],
+               'Bilging',
+               'Carpentry',
+               ]
+
+duty_puzzles = ([ 'Navigating', 'Battle Navigation' ] +
+               core_duty_puzzles +
+               [ 'Treasure Haul' ])
+
 standingvals = ('Able/Distinguished/Respected/Master'+
                '/Renowned/Grand-Master/Legendary/Ultimate').split('/')
+standing_limit = len(standingvals)
 
 pirate_ref_re = regexp.compile('^/yoweb/pirate\\.wm')
 
@@ -252,7 +264,7 @@ u'\\s*\\S*/([-A-Za-z]+)\\s*$|\\s*\\S*/\\S*\\s*\\(ocean\\-wide(?:\\s|\\xa0)+([-A-
                                skl.msg('puzzle "%s" no standing found' % puzzle)
                                continue
                        standing = sl[0]
-                       for i in range(0, len(standingvals)):
+                       for i in range(0, standing_limit):
                                if standing == standingvals[i]:
                                        self.standings[puzzle] = i
                        if not puzzle in self.standings:
@@ -339,14 +351,7 @@ class StandingsTable:
        def __init__(self, use_puzzles=None, col_width=6):
                if use_puzzles is None:
                        if opts.ship_duty:
-                               use_puzzles=[
-                                       'Navigating','Battle Navigation',
-                                       'Gunning',
-                                       ['Sailing','Rigging'],
-                                       'Bilging',
-                                       'Carpentry',
-                                       'Treasure Haul'
-                               ]
+                               use_puzzles=duty_puzzles
                        else:
                                use_puzzles=puzzles
                self._puzzles = use_puzzles
@@ -839,6 +844,8 @@ class ChatLogTracker:
                #  sorted by pirate name
                #  you can pass this None and you'll get []
                #  or True for the current vessel (which is the default)
+               #  the returned value is a fresh list of persistent
+               #  PirateAboard objects
                if vesselname is True: v = self._v
                else: v = self._vl.get(vesselname.title())
                if v is None: return []
@@ -1008,6 +1015,39 @@ def do_ship_aid(args, bu):
                kreader.stop()
                print '\n'
 
+class KeyBasedSorter:
+       def compar_key_pa(self, pa):
+               return self.compar_key(pa.pirate_info())
+       def lsort_pa(self, l):
+               l.sort(key = self.compar_key_pa)
+
+class NameSorter(KeyBasedSorter):
+       def compar_key(self, pi): return pi.name
+
+class SkillSorter(NameSorter):
+       def __init__(self, relevant):
+               self._want = frozenset(relevant.split('/'))
+               self._avoid = set()
+               for p in core_duty_puzzles:
+                       if isinstance(p,basestring): self._avoid.add(p)
+                       else: self._avoid |= set(p)
+               self._avoid -= self._want
+       
+       def compar_key(self, pi):
+               best_want = max([
+                       pi.standings.get(puz,-1)
+                       for puz in self._want
+                       ])
+               best_avoid = [
+                       -pi.standings.get(puz,standing_limit)
+                       for puz in self._avoid
+                       ]
+               best_avoid.sort()
+               def negate(x): return -x
+               debug('compar_key %s bw=%s ba=%s' % (pi.name, `best_want`,
+                       `best_avoid`))
+               return (-best_want, map(negate, best_avoid), pi.name)
+
 def ship_aid_core(myself, track, displayer, kreader):
 
        def find_vessel():
@@ -1025,6 +1065,8 @@ def ship_aid_core(myself, track, displayer, kreader):
 
        rotate_nya = '/-\\'
 
+       sort = NameSorter()
+
        while True:
                track.catchup()
                now = time.time()
@@ -1040,6 +1082,8 @@ def ship_aid_core(myself, track, displayer, kreader):
 
                aboard = track.aboard(vn)
 
+               sort.lsort_pa(aboard)
+
                for pa in aboard:
                        pi = pa.pirate_info()
 
@@ -1062,8 +1106,16 @@ def ship_aid_core(myself, track, displayer, kreader):
                        rotate_nya = rotate_nya[1:3] + rotate_nya[0]
                        continue
 
-               if k == 'q':
-                       break
+               if k == 'q': break
+               elif k == 'g': sort = SkillSorter('Gunning')
+               elif k == 'c': sort = SkillSorter('Carpentry')
+               elif k == 's': sort = SkillSorter('Sailing/Rigging')
+               elif k == 'b': sort = SkillSorter('Bilging')
+               elif k == 'n': sort = SkillSorter('Navigating')
+               elif k == 'd': sort = SkillSorter('Battle Navigation')
+               elif k == 't': sort = SkillSorter('Treasure Haul')
+               elif k == 'a': sort = NameSorter()
+               else: pass # unknown key command
 
 #---------- individual keystroke input ----------
 
index f9b3237ad108d44d64da4076df12455367622221..88244ccf105fcea146c8541f0764adaf9b04ef86 100644 (file)
@@ -32,6 +32,14 @@ Key features:
    display twirling batons while you wait for data, so that crew
    on board info remains correct.
 
+ * Can sort pirates by their skills in the key duty puzzles.  Press
+   a single keystroke to sort by:
+      s: sailing                   b: bilging
+      c: carpentry                 g: gunning
+      n: navigation (duty nav)     t: treasure haul
+      d: driving (battle nav)      a: sort by pirate name
+   It will prefer to list near the top pirates whose other skills
+   are weaker.  This functionality is disabled if stdin is not a tty.
 
 Things you need to know:
 
@@ -91,6 +99,9 @@ Things you need to know:
    so that everyone else's yoweb-scrape knows which ship they're on
    and thus which ship their /a commands refer to.
 
+ * For the ship duty puzzle display, and for sorting pirates by
+   skill, we take the best of Sailing and Rigging.
+
 Other things to mention:
 
  * There are some things which don't reliably appear in the chat log,