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('/')
 
        '/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('/')
 standingvals = ('Able/Distinguished/Respected/Master'+
                '/Renowned/Grand-Master/Legendary/Ultimate').split('/')
+standing_limit = len(standingvals)
 
 pirate_ref_re = regexp.compile('^/yoweb/pirate\\.wm')
 
 
 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]
                                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:
                                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:
        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
                        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)
                #  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 []
                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'
 
                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():
 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 = '/-\\'
 
 
        rotate_nya = '/-\\'
 
+       sort = NameSorter()
+
        while True:
                track.catchup()
                now = time.time()
        while True:
                track.catchup()
                now = time.time()
@@ -1040,6 +1082,8 @@ def ship_aid_core(myself, track, displayer, kreader):
 
                aboard = track.aboard(vn)
 
 
                aboard = track.aboard(vn)
 
+               sort.lsort_pa(aboard)
+
                for pa in aboard:
                        pi = pa.pirate_info()
 
                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
 
                        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 ----------
 
 
 #---------- 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.
 
    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:
 
 
 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.
 
    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,
 Other things to mention:
 
  * There are some things which don't reliably appear in the chat log,