Bunco Simulator

Hex Artifact Content

Artifact a97ef9d75aae89ae6edea42c8bf0303b5cca15cf9918b20f436ceb36c1153971:


0000: 23 20 54 65 73 74 0a 69 6d 70 6f 72 74 20 63 73  # Test.import cs
0010: 76 2c 20 72 61 6e 64 6f 6d 2c 20 73 71 6c 69 74  v, random, sqlit
0020: 65 33 0a 66 72 6f 6d 20 73 74 61 74 69 73 74 69  e3.from statisti
0030: 63 73 20 69 6d 70 6f 72 74 20 6d 65 64 69 61 6e  cs import median
0040: 0a 0a 74 65 61 6d 6d 61 74 65 5f 6c 6f 6f 6b 75  ..teammate_looku
0050: 70 20 3d 20 7b 20 30 3a 20 32 2c 20 31 3a 20 33  p = { 0: 2, 1: 3
0060: 2c 20 32 3a 20 30 2c 20 33 3a 20 31 20 7d 0a 0a  , 2: 0, 3: 1 }..
0070: 66 75 7a 7a 79 64 69 65 5f 68 6f 6c 64 65 72 20  fuzzydie_holder 
0080: 3d 20 27 78 27 0a 0a 74 61 62 6c 65 5f 6d 6f 76  = 'x'..table_mov
0090: 65 5f 63 61 6c 6c 62 61 63 6b 20 3d 20 4e 6f 6e  e_callback = Non
00a0: 65 0a 0a 64 65 66 20 54 75 72 6e 49 6e 50 72 6f  e..def TurnInPro
00b0: 67 72 65 73 73 28 29 3a 0a 20 20 20 20 72 65 74  gress():.    ret
00c0: 75 72 6e 20 2d 31 0a 0a 64 65 66 20 72 6f 6c 6c  urn -1..def roll
00d0: 5f 64 69 63 65 28 29 3a 0a 20 20 20 20 64 69 63  _dice():.    dic
00e0: 65 20 3d 20 5b 5d 0a 20 20 20 20 66 6f 72 20 5f  e = [].    for _
00f0: 20 69 6e 20 72 61 6e 67 65 28 33 29 3a 0a 20 20   in range(3):.  
0100: 20 20 20 20 20 20 64 69 63 65 2e 61 70 70 65 6e        dice.appen
0110: 64 28 72 61 6e 64 6f 6d 2e 72 61 6e 64 69 6e 74  d(random.randint
0120: 28 31 2c 36 29 29 0a 20 20 20 20 72 65 74 75 72  (1,6)).    retur
0130: 6e 20 64 69 63 65 0a 0a 63 6c 61 73 73 20 50 6c  n dice..class Pl
0140: 61 79 65 72 3a 0a 20 20 20 20 64 65 66 20 5f 5f  ayer:.    def __
0150: 69 6e 69 74 5f 5f 28 73 65 6c 66 2c 20 6e 61 6d  init__(self, nam
0160: 65 2c 20 70 68 6f 6e 65 2c 20 64 65 78 2c 20 6d  e, phone, dex, m
0170: 61 74 68 2c 20 73 70 65 65 64 29 3a 0a 20 20 20  ath, speed):.   
0180: 20 20 20 20 20 73 65 6c 66 2e 6e 61 6d 65 20 3d       self.name =
0190: 20 6e 61 6d 65 0a 20 20 20 20 20 20 20 20 73 65   name.        se
01a0: 6c 66 2e 73 6d 73 6e 75 6d 62 65 72 20 3d 20 70  lf.smsnumber = p
01b0: 68 6f 6e 65 0a 20 20 20 20 20 20 20 20 73 65 6c  hone.        sel
01c0: 66 2e 64 65 78 20 3d 20 64 65 78 0a 20 20 20 20  f.dex = dex.    
01d0: 20 20 20 20 73 65 6c 66 2e 6d 61 74 68 5f 63 6f      self.math_co
01e0: 6d 70 72 65 68 65 6e 73 69 6f 6e 20 3d 20 6d 61  mprehension = ma
01f0: 74 68 0a 20 20 20 20 20 20 20 20 73 65 6c 66 2e  th.        self.
0200: 72 6f 6c 6c 5f 73 70 65 65 64 20 3d 20 73 70 65  roll_speed = spe
0210: 65 64 0a 20 20 20 20 20 20 20 20 73 65 6c 66 2e  ed.        self.
0220: 6d 61 78 5f 73 74 72 65 61 6b 20 3d 20 30 0a 20  max_streak = 0. 
0230: 20 20 20 20 20 20 20 73 65 6c 66 2e 72 6f 75 6e         self.roun
0240: 64 5f 62 75 6e 63 6f 5f 63 6f 75 6e 74 73 20 3d  d_bunco_counts =
0250: 20 5b 30 5d 0a 20 20 20 20 20 20 20 20 73 65 6c   [0].        sel
0260: 66 2e 72 6f 75 6e 64 5f 73 63 6f 72 65 73 20 3d  f.round_scores =
0270: 20 5b 30 5d 0a 20 20 20 20 20 20 20 20 73 65 6c   [0].        sel
0280: 66 2e 72 6f 75 6e 64 5f 72 6f 6c 6c 5f 63 6f 75  f.round_roll_cou
0290: 6e 74 73 20 3d 20 5b 30 5d 0a 20 20 20 20 20 20  nts = [0].      
02a0: 20 20 73 65 6c 66 2e 70 65 72 73 6f 6e 61 6c 5f    self.personal_
02b0: 72 6f 6c 6c 5f 73 63 6f 72 65 73 20 3d 20 5b 30  roll_scores = [0
02c0: 5d 0a 20 20 20 20 20 20 20 20 73 65 6c 66 2e 72  ].        self.r
02d0: 6f 75 6e 64 5f 77 69 6e 73 20 3d 20 5b 30 5d 0a  ound_wins = [0].
02e0: 20 20 20 20 20 20 20 20 73 65 6c 66 2e 74 75 72          self.tur
02f0: 6e 5f 70 72 6f 67 72 65 73 73 20 3d 20 30 0a 20  n_progress = 0. 
0300: 20 20 20 20 20 20 20 73 65 6c 66 2e 63 75 72 72         self.curr
0310: 65 6e 74 5f 73 74 72 65 61 6b 20 3d 20 30 0a 20  ent_streak = 0. 
0320: 20 20 20 20 20 20 20 73 65 6c 66 2e 6d 61 78 5f         self.max_
0330: 66 75 7a 7a 79 64 69 65 5f 73 74 72 65 61 6b 20  fuzzydie_streak 
0340: 3d 20 30 0a 20 20 20 20 20 20 20 20 73 65 6c 66  = 0.        self
0350: 2e 63 75 72 72 65 6e 74 5f 66 75 7a 7a 79 64 69  .current_fuzzydi
0360: 65 5f 73 74 72 65 61 6b 20 3d 20 30 0a 20 20 20  e_streak = 0.   
0370: 20 20 20 20 20 73 65 6c 66 2e 72 6f 6c 6c 65 64       self.rolled
0380: 5f 62 75 6e 63 6f 20 3d 20 46 61 6c 73 65 0a 20  _bunco = False. 
0390: 20 20 20 20 20 20 20 73 65 6c 66 2e 63 75 72 72         self.curr
03a0: 65 6e 74 5f 72 6f 6c 6c 20 3d 20 5b 5d 0a 20 20  ent_roll = [].  
03b0: 20 20 0a 20 20 20 20 64 65 66 20 5f 5f 72 65 70    .    def __rep
03c0: 72 5f 5f 28 73 65 6c 66 29 3a 0a 20 20 20 20 20  r__(self):.     
03d0: 20 20 20 72 65 74 75 72 6e 20 66 22 3c 50 6c 61     return f"<Pla
03e0: 79 65 72 20 7b 73 65 6c 66 2e 6e 61 6d 65 7d 3a  yer {self.name}:
03f0: 20 22 20 5c 0a 20 20 20 20 20 20 20 20 20 20 20   " \.           
0400: 20 2b 20 66 22 5c 74 73 63 6f 72 65 73 5c 74 5c   + f"\tscores\t\
0410: 74 7b 73 65 6c 66 2e 72 6f 75 6e 64 5f 73 63 6f  t{self.round_sco
0420: 72 65 73 7d 3e 22 20 5c 0a 20 20 20 20 20 20 20  res}>" \.       
0430: 20 20 20 20 20 2b 20 66 22 5c 74 72 6f 6c 6c 20       + f"\troll 
0440: 63 6f 75 6e 74 73 5c 74 7b 73 65 6c 66 2e 72 6f  counts\t{self.ro
0450: 75 6e 64 5f 72 6f 6c 6c 5f 63 6f 75 6e 74 73 7d  und_roll_counts}
0460: 3e 22 0a 0a 20 20 20 20 64 65 66 20 5f 5f 73 74  >"..    def __st
0470: 72 5f 5f 28 73 65 6c 66 29 3a 0a 20 20 20 20 20  r__(self):.     
0480: 20 20 20 72 65 74 75 72 6e 20 73 65 6c 66 2e 6e     return self.n
0490: 61 6d 65 0a 0a 20 20 20 20 64 65 66 20 70 72 65  ame..    def pre
04a0: 70 5f 6e 65 77 5f 72 6f 75 6e 64 28 73 65 6c 66  p_new_round(self
04b0: 29 3a 0a 20 20 20 20 20 20 20 20 73 65 6c 66 2e  ):.        self.
04c0: 72 6f 75 6e 64 5f 73 63 6f 72 65 73 2e 61 70 70  round_scores.app
04d0: 65 6e 64 28 30 29 0a 20 20 20 20 20 20 20 20 73  end(0).        s
04e0: 65 6c 66 2e 72 6f 75 6e 64 5f 72 6f 6c 6c 5f 63  elf.round_roll_c
04f0: 6f 75 6e 74 73 2e 61 70 70 65 6e 64 28 30 29 0a  ounts.append(0).
0500: 20 20 20 20 20 20 20 20 73 65 6c 66 2e 70 65 72          self.per
0510: 73 6f 6e 61 6c 5f 72 6f 6c 6c 5f 73 63 6f 72 65  sonal_roll_score
0520: 73 2e 61 70 70 65 6e 64 28 30 29 0a 20 20 20 20  s.append(0).    
0530: 20 20 20 20 73 65 6c 66 2e 72 6f 75 6e 64 5f 62      self.round_b
0540: 75 6e 63 6f 5f 63 6f 75 6e 74 73 2e 61 70 70 65  unco_counts.appe
0550: 6e 64 28 30 29 0a 20 20 20 20 20 20 20 20 73 65  nd(0).        se
0560: 6c 66 2e 72 6f 75 6e 64 5f 77 69 6e 73 2e 61 70  lf.round_wins.ap
0570: 70 65 6e 64 28 30 29 0a 20 20 20 20 20 20 20 20  pend(0).        
0580: 73 65 6c 66 2e 74 75 72 6e 5f 70 72 6f 67 72 65  self.turn_progre
0590: 73 73 20 3d 20 30 0a 20 20 20 20 20 20 20 20 73  ss = 0.        s
05a0: 65 6c 66 2e 63 75 72 72 65 6e 74 5f 73 74 72 65  elf.current_stre
05b0: 61 6b 20 3d 20 30 0a 20 20 20 20 0a 20 20 20 20  ak = 0.    .    
05c0: 64 65 66 20 61 76 65 72 61 67 65 5f 63 6f 6e 74  def average_cont
05d0: 72 69 62 5f 70 63 74 28 73 65 6c 66 29 3a 0a 20  rib_pct(self):. 
05e0: 20 20 20 20 20 20 20 70 63 74 73 20 3d 20 5b 5d         pcts = []
05f0: 0a 20 20 20 20 20 20 20 20 66 6f 72 20 6e 20 69  .        for n i
0600: 6e 20 72 61 6e 67 65 28 6c 65 6e 28 73 65 6c 66  n range(len(self
0610: 2e 72 6f 75 6e 64 5f 73 63 6f 72 65 73 29 29 3a  .round_scores)):
0620: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20  .            if 
0630: 73 65 6c 66 2e 72 6f 75 6e 64 5f 73 63 6f 72 65  self.round_score
0640: 73 5b 6e 5d 20 3e 20 30 3a 0a 20 20 20 20 20 20  s[n] > 0:.      
0650: 20 20 20 20 20 20 20 20 20 20 70 63 74 73 2e 61            pcts.a
0660: 70 70 65 6e 64 28 73 65 6c 66 2e 70 65 72 73 6f  ppend(self.perso
0670: 6e 61 6c 5f 72 6f 6c 6c 5f 73 63 6f 72 65 73 5b  nal_roll_scores[
0680: 6e 5d 20 2f 20 73 65 6c 66 2e 72 6f 75 6e 64 5f  n] / self.round_
0690: 73 63 6f 72 65 73 5b 6e 5d 29 0a 20 20 20 20 20  scores[n]).     
06a0: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
06b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 63 74               pct
06c0: 73 2e 61 70 70 65 6e 64 28 30 29 0a 20 20 20 20  s.append(0).    
06d0: 20 20 20 20 72 65 74 75 72 6e 20 73 75 6d 28 70      return sum(p
06e0: 63 74 73 29 20 2f 20 6c 65 6e 28 70 63 74 73 29  cts) / len(pcts)
06f0: 0a 0a 20 20 20 20 64 65 66 20 73 63 6f 72 65 5f  ..    def score_
0700: 6c 61 73 74 5f 72 6f 6c 6c 28 73 65 6c 66 29 3a  last_roll(self):
0710: 0a 20 20 20 20 20 20 20 20 64 65 73 69 72 65 64  .        desired
0720: 5f 6e 75 6d 20 3d 20 47 61 6d 65 2e 63 75 72 72  _num = Game.curr
0730: 65 6e 74 5f 72 6f 75 6e 64 28 29 20 25 20 36 0a  ent_round() % 6.
0740: 20 20 20 20 20 20 20 20 64 65 73 69 72 65 64 5f          desired_
0750: 6e 75 6d 20 3d 20 36 20 69 66 20 64 65 73 69 72  num = 6 if desir
0760: 65 64 5f 6e 75 6d 20 3d 3d 20 30 20 65 6c 73 65  ed_num == 0 else
0770: 20 64 65 73 69 72 65 64 5f 6e 75 6d 0a 20 20 20   desired_num.   
0780: 20 0a 20 20 20 20 20 20 20 20 72 6f 6c 6c 5f 73   .        roll_s
0790: 63 6f 72 65 20 3d 20 30 0a 20 20 20 20 20 20 20  core = 0.       
07a0: 20 0a 20 20 20 20 20 20 20 20 69 66 20 61 6c 6c   .        if all
07b0: 28 64 69 65 20 3d 3d 20 64 65 73 69 72 65 64 5f  (die == desired_
07c0: 6e 75 6d 20 66 6f 72 20 64 69 65 20 69 6e 20 73  num for die in s
07d0: 65 6c 66 2e 63 75 72 72 65 6e 74 5f 72 6f 6c 6c  elf.current_roll
07e0: 29 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 23  ):.            #
07f0: 20 42 75 6e 63 6f 21 0a 20 20 20 20 20 20 20 20   Bunco!.        
0800: 20 20 20 20 72 6f 6c 6c 5f 73 63 6f 72 65 20 3d      roll_score =
0810: 20 32 31 0a 20 20 20 20 20 20 20 20 65 6c 69 66   21.        elif
0820: 20 61 6c 6c 28 64 69 65 20 3d 3d 20 73 65 6c 66   all(die == self
0830: 2e 63 75 72 72 65 6e 74 5f 72 6f 6c 6c 5b 30 5d  .current_roll[0]
0840: 20 66 6f 72 20 64 69 65 20 69 6e 20 73 65 6c 66   for die in self
0850: 2e 63 75 72 72 65 6e 74 5f 72 6f 6c 6c 29 3a 0a  .current_roll):.
0860: 20 20 20 20 20 20 20 20 20 20 20 20 23 20 41 6c              # Al
0870: 6c 20 74 68 72 65 65 20 64 69 63 65 20 6d 61 74  l three dice mat
0880: 63 68 2c 20 62 75 74 20 6e 6f 74 20 42 75 6e 63  ch, but not Bunc
0890: 6f 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 6f  o.            ro
08a0: 6c 6c 5f 73 63 6f 72 65 20 3d 20 35 0a 20 20 20  ll_score = 5.   
08b0: 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20       else:.     
08c0: 20 20 20 20 20 20 20 66 6f 72 20 64 69 65 20 69         for die i
08d0: 6e 20 73 65 6c 66 2e 63 75 72 72 65 6e 74 5f 72  n self.current_r
08e0: 6f 6c 6c 3a 0a 20 20 20 20 20 20 20 20 20 20 20  oll:.           
08f0: 20 20 20 20 20 72 6f 6c 6c 5f 73 63 6f 72 65 20       roll_score 
0900: 2b 3d 20 31 20 69 66 20 64 69 65 20 3d 3d 20 64  += 1 if die == d
0910: 65 73 69 72 65 64 5f 6e 75 6d 20 65 6c 73 65 20  esired_num else 
0920: 30 0a 0a 20 20 20 20 20 20 20 20 69 66 20 72 6f  0..        if ro
0930: 6c 6c 5f 73 63 6f 72 65 20 3e 20 30 3a 0a 20 20  ll_score > 0:.  
0940: 20 20 20 20 20 20 20 20 20 20 73 65 6c 66 2e 63            self.c
0950: 75 72 72 65 6e 74 5f 73 74 72 65 61 6b 20 2b 3d  urrent_streak +=
0960: 20 31 0a 20 20 20 20 20 20 20 20 20 20 20 20 73   1.            s
0970: 65 6c 66 2e 6d 61 78 5f 73 74 72 65 61 6b 20 3d  elf.max_streak =
0980: 20 6d 61 78 28 73 65 6c 66 2e 63 75 72 72 65 6e   max(self.curren
0990: 74 5f 73 74 72 65 61 6b 2c 20 73 65 6c 66 2e 6d  t_streak, self.m
09a0: 61 78 5f 73 74 72 65 61 6b 29 0a 20 20 20 20 20  ax_streak).     
09b0: 20 20 20 20 20 20 20 73 65 6c 66 2e 72 6f 75 6e         self.roun
09c0: 64 5f 73 63 6f 72 65 73 5b 47 61 6d 65 2e 63 75  d_scores[Game.cu
09d0: 72 72 65 6e 74 5f 72 6f 75 6e 64 28 29 20 2d 20  rrent_round() - 
09e0: 31 5d 20 2b 3d 20 72 6f 6c 6c 5f 73 63 6f 72 65  1] += roll_score
09f0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 65 6c  .            sel
0a00: 66 2e 70 65 72 73 6f 6e 61 6c 5f 72 6f 6c 6c 5f  f.personal_roll_
0a10: 73 63 6f 72 65 73 5b 47 61 6d 65 2e 63 75 72 72  scores[Game.curr
0a20: 65 6e 74 5f 72 6f 75 6e 64 28 29 20 2d 20 31 5d  ent_round() - 1]
0a30: 20 2b 3d 20 72 6f 6c 6c 5f 73 63 6f 72 65 0a 20   += roll_score. 
0a40: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 72 6f             if ro
0a50: 6c 6c 5f 73 63 6f 72 65 20 3d 3d 20 32 31 3a 0a  ll_score == 21:.
0a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a70: 73 65 6c 66 2e 72 6f 75 6e 64 5f 62 75 6e 63 6f  self.round_bunco
0a80: 5f 63 6f 75 6e 74 73 5b 47 61 6d 65 2e 63 75 72  _counts[Game.cur
0a90: 72 65 6e 74 5f 72 6f 75 6e 64 28 29 20 2d 20 31  rent_round() - 1
0aa0: 5d 20 2b 3d 20 31 0a 20 20 20 20 20 20 20 20 20  ] += 1.         
0ab0: 20 20 20 20 20 20 20 73 65 6c 66 2e 72 6f 6c 6c         self.roll
0ac0: 65 64 5f 62 75 6e 63 6f 20 3d 20 54 72 75 65 0a  ed_bunco = True.
0ad0: 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20          else:.  
0ae0: 20 20 20 20 20 20 20 20 20 20 73 65 6c 66 2e 63            self.c
0af0: 75 72 72 65 6e 74 5f 73 74 72 65 61 6b 20 3d 20  urrent_streak = 
0b00: 30 0a 20 20 20 20 20 20 20 20 0a 20 20 20 20 20  0.        .     
0b10: 20 20 20 6c 6f 67 5f 72 6f 6c 6c 28 73 65 6c 66     log_roll(self
0b20: 2c 20 73 65 6c 66 2e 63 75 72 72 65 6e 74 5f 72  , self.current_r
0b30: 6f 6c 6c 2c 20 72 6f 6c 6c 5f 73 63 6f 72 65 29  oll, roll_score)
0b40: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
0b50: 72 6f 6c 6c 5f 73 63 6f 72 65 0a 20 20 20 20 20  roll_score.     
0b60: 20 20 20 0a 20 20 20 20 64 65 66 20 74 69 63 6b     .    def tick
0b70: 28 73 65 6c 66 29 3a 0a 20 20 20 20 20 20 20 20  (self):.        
0b80: 67 6c 6f 62 61 6c 20 66 75 7a 7a 79 64 69 65 5f  global fuzzydie_
0b90: 68 6f 6c 64 65 72 0a 20 20 20 20 20 20 20 20 72  holder.        r
0ba0: 65 73 75 6c 74 20 3d 20 54 75 72 6e 49 6e 50 72  esult = TurnInPr
0bb0: 6f 67 72 65 73 73 28 29 0a 0a 20 20 20 20 20 20  ogress()..      
0bc0: 20 20 69 66 20 66 75 7a 7a 79 64 69 65 5f 68 6f    if fuzzydie_ho
0bd0: 6c 64 65 72 20 69 73 20 73 65 6c 66 3a 0a 20 20  lder is self:.  
0be0: 20 20 20 20 20 20 20 20 20 20 73 65 6c 66 2e 63            self.c
0bf0: 75 72 72 65 6e 74 5f 66 75 7a 7a 79 64 69 65 5f  urrent_fuzzydie_
0c00: 73 74 72 65 61 6b 20 2b 3d 20 31 0a 20 20 20 20  streak += 1.    
0c10: 20 20 20 20 20 20 20 20 73 65 6c 66 2e 6d 61 78          self.max
0c20: 5f 66 75 7a 7a 79 64 69 65 5f 73 74 72 65 61 6b  _fuzzydie_streak
0c30: 20 3d 20 6d 61 78 28 73 65 6c 66 2e 6d 61 78 5f   = max(self.max_
0c40: 66 75 7a 7a 79 64 69 65 5f 73 74 72 65 61 6b 2c  fuzzydie_streak,
0c50: 20 73 65 6c 66 2e 63 75 72 72 65 6e 74 5f 66 75   self.current_fu
0c60: 7a 7a 79 64 69 65 5f 73 74 72 65 61 6b 29 0a 20  zzydie_streak). 
0c70: 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20         else:.   
0c80: 20 20 20 20 20 20 20 20 20 73 65 6c 66 2e 63 75           self.cu
0c90: 72 72 65 6e 74 5f 66 75 7a 7a 79 64 69 65 5f 73  rrent_fuzzydie_s
0ca0: 74 72 65 61 6b 20 3d 20 30 0a 0a 20 20 20 20 20  treak = 0..     
0cb0: 20 20 20 69 66 20 73 65 6c 66 2e 74 75 72 6e 5f     if self.turn_
0cc0: 70 72 6f 67 72 65 73 73 20 3c 20 32 35 3a 0a 20  progress < 25:. 
0cd0: 20 20 20 20 20 20 20 20 20 20 20 23 20 47 72 61             # Gra
0ce0: 62 62 69 6e 67 20 74 68 65 20 64 69 63 65 0a 20  bbing the dice. 
0cf0: 20 20 20 20 20 20 20 20 20 20 20 23 20 54 4f 44             # TOD
0d00: 4f 3a 20 49 6e 63 6f 72 70 6f 72 61 74 65 20 44  O: Incorporate D
0d10: 45 58 54 45 52 49 54 59 20 73 74 61 74 0a 20 20  EXTERITY stat.  
0d20: 20 20 20 20 20 20 20 20 20 20 73 65 6c 66 2e 74            self.t
0d30: 75 72 6e 5f 70 72 6f 67 72 65 73 73 20 2b 3d 20  urn_progress += 
0d40: 72 61 6e 64 6f 6d 2e 72 61 6e 64 69 6e 74 28 31  random.randint(1
0d50: 32 2c 32 35 29 0a 20 20 20 20 20 20 20 20 65 6c  2,25).        el
0d60: 69 66 20 73 65 6c 66 2e 74 75 72 6e 5f 70 72 6f  if self.turn_pro
0d70: 67 72 65 73 73 20 3c 20 35 30 3a 0a 20 20 20 20  gress < 50:.    
0d80: 20 20 20 20 20 20 20 20 23 20 52 6f 6c 6c 69 6e          # Rollin
0d90: 67 20 74 68 65 20 64 69 63 65 0a 20 20 20 20 20  g the dice.     
0da0: 20 20 20 20 20 20 20 23 20 54 4f 44 4f 3a 20 49         # TODO: I
0db0: 6e 63 6f 72 70 6f 72 61 74 65 20 52 4f 4c 4c 20  ncorporate ROLL 
0dc0: 53 50 45 45 44 20 73 74 61 74 0a 20 20 20 20 20  SPEED stat.     
0dd0: 20 20 20 20 20 20 20 73 65 6c 66 2e 74 75 72 6e         self.turn
0de0: 5f 70 72 6f 67 72 65 73 73 20 2b 3d 20 72 61 6e  _progress += ran
0df0: 64 6f 6d 2e 72 61 6e 64 69 6e 74 28 31 32 2c 32  dom.randint(12,2
0e00: 35 29 0a 20 20 20 20 20 20 20 20 65 6c 69 66 20  5).        elif 
0e10: 73 65 6c 66 2e 74 75 72 6e 5f 70 72 6f 67 72 65  self.turn_progre
0e20: 73 73 20 3c 20 37 35 3a 0a 20 20 20 20 20 20 20  ss < 75:.       
0e30: 20 20 20 20 20 23 20 52 65 61 64 69 6e 67 20 74       # Reading t
0e40: 68 65 20 6e 75 6d 62 65 72 73 0a 20 20 20 20 20  he numbers.     
0e50: 20 20 20 20 20 20 20 23 20 54 4f 44 4f 3a 20 49         # TODO: I
0e60: 6e 63 6f 72 70 6f 72 61 74 65 20 4d 41 54 48 20  ncorporate MATH 
0e70: 43 4f 4d 50 52 45 48 45 4e 53 49 4f 4e 20 73 74  COMPREHENSION st
0e80: 61 74 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  at.            i
0e90: 66 20 6e 6f 74 20 73 65 6c 66 2e 63 75 72 72 65  f not self.curre
0ea0: 6e 74 5f 72 6f 6c 6c 3a 0a 20 20 20 20 20 20 20  nt_roll:.       
0eb0: 20 20 20 20 20 20 20 20 20 73 65 6c 66 2e 63 75           self.cu
0ec0: 72 72 65 6e 74 5f 72 6f 6c 6c 20 3d 20 72 6f 6c  rrent_roll = rol
0ed0: 6c 5f 64 69 63 65 28 29 0a 20 20 20 20 20 20 20  l_dice().       
0ee0: 20 20 20 20 20 20 20 20 20 73 65 6c 66 2e 72 6f           self.ro
0ef0: 75 6e 64 5f 72 6f 6c 6c 5f 63 6f 75 6e 74 73 5b  und_roll_counts[
0f00: 47 61 6d 65 2e 63 75 72 72 65 6e 74 5f 72 6f 75  Game.current_rou
0f10: 6e 64 28 29 20 2d 20 31 5d 20 2b 3d 20 31 0a 20  nd() - 1] += 1. 
0f20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c                 l
0f30: 6f 67 28 73 65 6c 66 2c 20 66 22 7b 73 65 6c 66  og(self, f"{self
0f40: 2e 6e 61 6d 65 7d 20 72 6f 6c 6c 65 64 20 74 68  .name} rolled th
0f50: 65 20 64 69 63 65 22 29 0a 20 20 20 20 20 20 20  e dice").       
0f60: 20 20 20 20 20 73 65 6c 66 2e 74 75 72 6e 5f 70       self.turn_p
0f70: 72 6f 67 72 65 73 73 20 2b 3d 20 72 61 6e 64 6f  rogress += rando
0f80: 6d 2e 72 61 6e 64 69 6e 74 28 31 32 2c 32 35 29  m.randint(12,25)
0f90: 0a 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20  .        else:. 
0fa0: 20 20 20 20 20 20 20 20 20 20 20 23 20 46 69 6e             # Fin
0fb0: 69 73 68 65 64 20 72 65 61 64 69 6e 67 20 74 68  ished reading th
0fc0: 65 20 6e 75 6d 62 65 72 73 20 2d 2d 20 67 6f 6f  e numbers -- goo
0fd0: 64 20 6a 6f 62 2c 20 65 79 65 62 61 6c 6c 73 20  d job, eyeballs 
0fe0: 61 6e 64 20 62 72 61 69 6e 21 0a 20 20 20 20 20  and brain!.     
0ff0: 20 20 20 20 20 20 20 72 65 73 75 6c 74 20 3d 20         result = 
1000: 73 65 6c 66 2e 73 63 6f 72 65 5f 6c 61 73 74 5f  self.score_last_
1010: 72 6f 6c 6c 28 29 0a 20 20 20 20 20 20 20 20 20  roll().         
1020: 20 20 20 73 65 6c 66 2e 63 75 72 72 65 6e 74 5f     self.current_
1030: 72 6f 6c 6c 20 3d 20 5b 5d 0a 20 20 20 20 20 20  roll = [].      
1040: 20 20 20 20 20 20 73 65 6c 66 2e 74 75 72 6e 5f        self.turn_
1050: 70 72 6f 67 72 65 73 73 20 3d 20 30 0a 20 20 20  progress = 0.   
1060: 20 20 20 20 20 72 65 74 75 72 6e 20 72 65 73 75       return resu
1070: 6c 74 0a 0a 63 6c 61 73 73 20 54 61 62 6c 65 3a  lt..class Table:
1080: 0a 20 20 20 20 64 65 66 20 5f 5f 69 6e 69 74 5f  .    def __init_
1090: 5f 28 73 65 6c 66 29 3a 0a 20 20 20 20 20 20 20  _(self):.       
10a0: 20 73 65 6c 66 2e 74 61 62 6c 65 5f 6e 75 6d 62   self.table_numb
10b0: 65 72 20 3d 20 30 0a 20 20 20 20 20 20 20 20 73  er = 0.        s
10c0: 65 6c 66 2e 74 65 61 6d 31 5f 73 63 6f 72 65 20  elf.team1_score 
10d0: 3d 20 30 0a 20 20 20 20 20 20 20 20 73 65 6c 66  = 0.        self
10e0: 2e 74 65 61 6d 32 5f 73 63 6f 72 65 20 3d 20 30  .team2_score = 0
10f0: 0a 20 20 20 20 20 20 20 20 73 65 6c 66 2e 70 6c  .        self.pl
1100: 61 79 65 72 73 20 3d 20 5b 5d 0a 20 20 20 20 20  ayers = [].     
1110: 20 20 20 73 65 6c 66 2e 61 63 74 69 76 65 5f 70     self.active_p
1120: 6c 61 79 65 72 20 3d 20 2d 31 0a 0a 20 20 20 20  layer = -1..    
1130: 64 65 66 20 5f 5f 72 65 70 72 5f 5f 28 73 65 6c  def __repr__(sel
1140: 66 29 3a 0a 20 20 20 20 20 20 20 20 6e 61 6d 65  f):.        name
1150: 73 20 3d 20 22 2c 20 22 2e 6a 6f 69 6e 28 5b 70  s = ", ".join([p
1160: 2e 6e 61 6d 65 20 66 6f 72 20 70 20 69 6e 20 73  .name for p in s
1170: 65 6c 66 2e 70 6c 61 79 65 72 73 5d 29 0a 20 20  elf.players]).  
1180: 20 20 20 20 20 20 72 65 74 75 72 6e 20 66 22 3c        return f"<
1190: 54 61 62 6c 65 20 7b 73 65 6c 66 2e 74 61 62 6c  Table {self.tabl
11a0: 65 5f 6e 75 6d 62 65 72 7d 3a 20 7b 6e 61 6d 65  e_number}: {name
11b0: 73 7d 3e 22 0a 0a 20 20 20 20 64 65 66 20 5f 5f  s}>"..    def __
11c0: 73 74 72 5f 5f 28 73 65 6c 66 29 3a 0a 20 20 20  str__(self):.   
11d0: 20 20 20 20 20 69 66 20 73 65 6c 66 2e 74 61 62       if self.tab
11e0: 6c 65 5f 6e 75 6d 62 65 72 20 3d 3d 20 31 3a 0a  le_number == 1:.
11f0: 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75              retu
1200: 72 6e 20 22 48 65 61 64 20 54 61 62 6c 65 22 0a  rn "Head Table".
1210: 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20          else:.  
1220: 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e            return
1230: 20 66 22 54 61 62 6c 65 20 7b 73 65 6c 66 2e 74   f"Table {self.t
1240: 61 62 6c 65 5f 6e 75 6d 62 65 72 7d 22 0a 0a 20  able_number}".. 
1250: 20 20 20 64 65 66 20 75 70 64 61 74 65 5f 74 65     def update_te
1260: 61 6d 6d 61 74 65 5f 73 63 6f 72 65 28 73 65 6c  ammate_score(sel
1270: 66 2c 20 73 63 6f 72 65 29 3a 0a 20 20 20 20 20  f, score):.     
1280: 20 20 20 74 65 61 6d 6d 61 74 65 20 3d 20 73 65     teammate = se
1290: 6c 66 2e 70 6c 61 79 65 72 73 5b 74 65 61 6d 6d  lf.players[teamm
12a0: 61 74 65 5f 6c 6f 6f 6b 75 70 5b 73 65 6c 66 2e  ate_lookup[self.
12b0: 61 63 74 69 76 65 5f 70 6c 61 79 65 72 5d 5d 0a  active_player]].
12c0: 20 20 20 20 20 20 20 20 74 65 61 6d 6d 61 74 65          teammate
12d0: 2e 72 6f 75 6e 64 5f 73 63 6f 72 65 73 5b 47 61  .round_scores[Ga
12e0: 6d 65 2e 63 75 72 72 65 6e 74 5f 72 6f 75 6e 64  me.current_round
12f0: 28 29 20 2d 20 31 5d 20 2b 3d 20 73 63 6f 72 65  () - 1] += score
1300: 0a 0a 20 20 20 20 64 65 66 20 74 69 63 6b 28 73  ..    def tick(s
1310: 65 6c 66 29 3a 0a 20 20 20 20 20 20 20 20 69 66  elf):.        if
1320: 20 73 65 6c 66 2e 61 63 74 69 76 65 5f 70 6c 61   self.active_pla
1330: 79 65 72 20 3d 3d 20 2d 31 3a 0a 20 20 20 20 20  yer == -1:.     
1340: 20 20 20 20 20 20 20 23 20 46 69 72 73 74 20 74         # First t
1350: 69 63 6b 20 66 6f 72 20 74 68 65 20 74 61 62 6c  ick for the tabl
1360: 65 20 74 68 69 73 20 72 6f 75 6e 64 0a 20 20 20  e this round.   
1370: 20 20 20 20 20 20 20 20 20 73 65 6c 66 2e 61 63           self.ac
1380: 74 69 76 65 5f 70 6c 61 79 65 72 20 3d 20 72 61  tive_player = ra
1390: 6e 64 6f 6d 2e 72 61 6e 64 69 6e 74 28 31 2c 20  ndom.randint(1, 
13a0: 6c 65 6e 28 73 65 6c 66 2e 70 6c 61 79 65 72 73  len(self.players
13b0: 29 29 20 2d 20 31 0a 0a 20 20 20 20 20 20 20 20  )) - 1..        
13c0: 72 65 73 75 6c 74 20 3d 20 73 65 6c 66 2e 70 6c  result = self.pl
13d0: 61 79 65 72 73 5b 73 65 6c 66 2e 61 63 74 69 76  ayers[self.activ
13e0: 65 5f 70 6c 61 79 65 72 5d 2e 74 69 63 6b 28 29  e_player].tick()
13f0: 0a 0a 20 20 20 20 20 20 20 20 69 66 20 72 65 73  ..        if res
1400: 75 6c 74 20 21 3d 20 54 75 72 6e 49 6e 50 72 6f  ult != TurnInPro
1410: 67 72 65 73 73 28 29 3a 0a 20 20 20 20 20 20 20  gress():.       
1420: 20 20 20 20 20 23 20 50 6c 61 79 65 72 20 72 6f       # Player ro
1430: 6c 6c 65 64 0a 20 20 20 20 20 20 20 20 20 20 20  lled.           
1440: 20 69 66 20 72 65 73 75 6c 74 20 3e 20 30 3a 0a   if result > 0:.
1450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1460: 69 66 20 28 73 65 6c 66 2e 61 63 74 69 76 65 5f  if (self.active_
1470: 70 6c 61 79 65 72 20 25 20 32 29 20 3d 3d 20 30  player % 2) == 0
1480: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
1490: 20 20 20 20 20 20 73 65 6c 66 2e 74 65 61 6d 31        self.team1
14a0: 5f 73 63 6f 72 65 20 2b 3d 20 72 65 73 75 6c 74  _score += result
14b0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
14c0: 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20 20   else:.         
14d0: 20 20 20 20 20 20 20 20 20 20 20 73 65 6c 66 2e             self.
14e0: 74 65 61 6d 32 5f 73 63 6f 72 65 20 2b 3d 20 72  team2_score += r
14f0: 65 73 75 6c 74 0a 0a 20 20 20 20 20 20 20 20 20  esult..         
1500: 20 20 20 20 20 20 20 73 65 6c 66 2e 75 70 64 61         self.upda
1510: 74 65 5f 74 65 61 6d 6d 61 74 65 5f 73 63 6f 72  te_teammate_scor
1520: 65 28 72 65 73 75 6c 74 29 0a 20 20 20 20 20 20  e(result).      
1530: 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20        else:.    
1540: 20 20 20 20 20 20 20 20 20 20 20 20 73 65 6c 66              self
1550: 2e 61 63 74 69 76 65 5f 70 6c 61 79 65 72 20 2b  .active_player +
1560: 3d 20 31 0a 20 20 20 20 20 20 20 20 20 20 20 20  = 1.            
1570: 20 20 20 20 69 66 20 73 65 6c 66 2e 61 63 74 69      if self.acti
1580: 76 65 5f 70 6c 61 79 65 72 20 3e 20 28 6c 65 6e  ve_player > (len
1590: 28 73 65 6c 66 2e 70 6c 61 79 65 72 73 29 20 2d  (self.players) -
15a0: 20 31 29 3a 20 73 65 6c 66 2e 61 63 74 69 76 65   1): self.active
15b0: 5f 70 6c 61 79 65 72 20 3d 20 30 0a 20 20 20 20  _player = 0.    
15c0: 0a 20 20 20 20 64 65 66 20 72 6f 6c 6c 5f 6f 66  .    def roll_of
15d0: 66 28 73 65 6c 66 29 3a 0a 20 20 20 20 20 20 20  f(self):.       
15e0: 20 22 22 22 41 74 74 65 6d 70 74 20 74 6f 20 73   """Attempt to s
15f0: 65 74 74 6c 65 20 61 20 74 69 65 20 62 79 20 67  ettle a tie by g
1600: 6f 69 6e 67 20 72 6f 75 6e 64 20 74 68 65 20 74  oing round the t
1610: 61 62 6c 65 20 6f 6e 63 65 22 22 22 0a 20 20 20  able once""".   
1620: 20 20 20 20 20 73 65 6c 66 2e 61 63 74 69 76 65       self.active
1630: 5f 70 6c 61 79 65 72 20 3d 20 30 0a 20 20 20 20  _player = 0.    
1640: 20 20 20 20 0a 20 20 20 20 20 20 20 20 23 20 4c      .        # L
1650: 65 74 20 74 68 65 20 66 69 72 73 74 20 70 6c 61  et the first pla
1660: 79 65 72 20 67 6f 20 75 6e 74 69 6c 20 74 68 65  yer go until the
1670: 79 20 72 6f 6c 6c 20 66 6f 72 20 30 20 70 6f 69  y roll for 0 poi
1680: 6e 74 73 0a 20 20 20 20 20 20 20 20 77 68 69 6c  nts.        whil
1690: 65 20 73 65 6c 66 2e 61 63 74 69 76 65 5f 70 6c  e self.active_pl
16a0: 61 79 65 72 20 3d 3d 20 30 3a 0a 20 20 20 20 20  ayer == 0:.     
16b0: 20 20 20 20 20 20 20 73 65 6c 66 2e 74 69 63 6b         self.tick
16c0: 28 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 47  ().            G
16d0: 61 6d 65 2e 69 6e 63 72 65 6d 65 6e 74 5f 74 69  ame.increment_ti
16e0: 63 6b 28 29 0a 20 20 20 20 20 20 20 20 23 20 4e  ck().        # N
16f0: 6f 77 20 6c 65 74 20 74 68 65 20 72 65 73 74 20  ow let the rest 
1700: 64 6f 20 74 68 65 20 73 61 6d 65 0a 20 20 20 20  do the same.    
1710: 20 20 20 20 77 68 69 6c 65 20 73 65 6c 66 2e 61      while self.a
1720: 63 74 69 76 65 5f 70 6c 61 79 65 72 20 21 3d 20  ctive_player != 
1730: 30 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  0:.            s
1740: 65 6c 66 2e 74 69 63 6b 28 29 0a 20 20 20 20 20  elf.tick().     
1750: 20 20 20 20 20 20 20 47 61 6d 65 2e 69 6e 63 72         Game.incr
1760: 65 6d 65 6e 74 5f 74 69 63 6b 28 29 0a 0a 20 20  ement_tick()..  
1770: 20 20 64 65 66 20 6c 6f 73 65 72 73 28 73 65 6c    def losers(sel
1780: 66 29 3a 0a 20 20 20 20 20 20 20 20 69 66 20 73  f):.        if s
1790: 65 6c 66 2e 74 65 61 6d 31 5f 73 63 6f 72 65 20  elf.team1_score 
17a0: 3e 20 73 65 6c 66 2e 74 65 61 6d 32 5f 73 63 6f  > self.team2_sco
17b0: 72 65 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  re:.            
17c0: 72 65 74 75 72 6e 20 73 65 6c 66 2e 70 6c 61 79  return self.play
17d0: 65 72 73 5b 31 3a 3a 32 5d 0a 20 20 20 20 20 20  ers[1::2].      
17e0: 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20 20 20    else:.        
17f0: 20 20 20 20 72 65 74 75 72 6e 20 73 65 6c 66 2e      return self.
1800: 70 6c 61 79 65 72 73 5b 30 3a 3a 32 5d 0a 20 20  players[0::2].  
1810: 20 20 0a 20 20 20 20 64 65 66 20 77 69 6e 6e 65    .    def winne
1820: 72 73 28 73 65 6c 66 29 3a 0a 20 20 20 20 20 20  rs(self):.      
1830: 20 20 69 66 20 73 65 6c 66 2e 74 65 61 6d 31 5f    if self.team1_
1840: 73 63 6f 72 65 20 3e 20 73 65 6c 66 2e 74 65 61  score > self.tea
1850: 6d 32 5f 73 63 6f 72 65 3a 0a 20 20 20 20 20 20  m2_score:.      
1860: 20 20 20 20 20 20 72 65 74 75 72 6e 20 73 65 6c        return sel
1870: 66 2e 70 6c 61 79 65 72 73 5b 30 3a 3a 32 5d 0a  f.players[0::2].
1880: 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20          else:.  
1890: 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e            return
18a0: 20 73 65 6c 66 2e 70 6c 61 79 65 72 73 5b 31 3a   self.players[1:
18b0: 3a 32 5d 0a 20 20 20 20 0a 20 20 20 20 64 65 66  :2].    .    def
18c0: 20 73 77 61 70 5f 66 6f 72 5f 77 69 6e 6e 65 72   swap_for_winner
18d0: 73 28 73 65 6c 66 2c 20 6e 65 77 5f 70 6c 61 79  s(self, new_play
18e0: 65 72 73 29 3a 0a 20 20 20 20 20 20 20 20 69 66  ers):.        if
18f0: 20 73 65 6c 66 2e 74 65 61 6d 31 5f 73 63 6f 72   self.team1_scor
1900: 65 20 3e 20 73 65 6c 66 2e 74 65 61 6d 32 5f 73  e > self.team2_s
1910: 63 6f 72 65 3a 0a 20 20 20 20 20 20 20 20 20 20  core:.          
1920: 20 20 23 20 54 65 61 6d 20 31 20 28 65 76 65 6e    # Team 1 (even
1930: 73 29 20 77 6f 6e 0a 20 20 20 20 20 20 20 20 20  s) won.         
1940: 20 20 20 77 69 6e 6e 65 72 73 20 3d 20 73 65 6c     winners = sel
1950: 66 2e 70 6c 61 79 65 72 73 5b 30 3a 3a 32 5d 0a  f.players[0::2].
1960: 20 20 20 20 20 20 20 20 20 20 20 20 23 20 50 6c              # Pl
1970: 61 79 65 72 20 31 20 6d 6f 76 65 20 74 6f 20 73  ayer 1 move to s
1980: 70 6f 74 20 30 0a 20 20 20 20 20 20 20 20 20 20  pot 0.          
1990: 20 20 73 65 6c 66 2e 70 6c 61 79 65 72 73 5b 30    self.players[0
19a0: 5d 20 3d 20 73 65 6c 66 2e 70 6c 61 79 65 72 73  ] = self.players
19b0: 5b 31 5d 0a 20 20 20 20 20 20 20 20 65 6c 73 65  [1].        else
19c0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 23 20  :.            # 
19d0: 54 65 61 6d 20 32 20 28 6f 64 64 73 29 20 77 6f  Team 2 (odds) wo
19e0: 6e 0a 20 20 20 20 20 20 20 20 20 20 20 20 77 69  n.            wi
19f0: 6e 6e 65 72 73 20 3d 20 73 65 6c 66 2e 70 6c 61  nners = self.pla
1a00: 79 65 72 73 5b 31 3a 3a 32 5d 0a 20 20 20 20 20  yers[1::2].     
1a10: 20 20 20 20 20 20 20 23 20 50 6c 61 79 65 72 20         # Player 
1a20: 32 20 6d 6f 76 65 20 74 6f 20 73 70 6f 74 20 33  2 move to spot 3
1a30: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 65 6c  .            sel
1a40: 66 2e 70 6c 61 79 65 72 73 5b 33 5d 20 3d 20 73  f.players[3] = s
1a50: 65 6c 66 2e 70 6c 61 79 65 72 73 5b 32 5d 0a 20  elf.players[2]. 
1a60: 20 20 20 20 20 20 20 23 20 52 65 70 6c 61 63 65         # Replace
1a70: 20 6d 69 64 64 6c 65 20 74 77 6f 20 70 6c 61 79   middle two play
1a80: 65 72 73 0a 20 20 20 20 20 20 20 20 73 65 6c 66  ers.        self
1a90: 2e 70 6c 61 79 65 72 73 5b 31 3a 33 5d 20 3d 20  .players[1:3] = 
1aa0: 6e 65 77 5f 70 6c 61 79 65 72 73 0a 20 20 20 20  new_players.    
1ab0: 20 20 20 20 72 65 74 75 72 6e 20 77 69 6e 6e 65      return winne
1ac0: 72 73 0a 0a 20 20 20 20 64 65 66 20 73 77 61 70  rs..    def swap
1ad0: 5f 66 6f 72 5f 6c 6f 73 65 72 73 28 73 65 6c 66  _for_losers(self
1ae0: 2c 20 6e 65 77 5f 70 6c 61 79 65 72 73 29 3a 0a  , new_players):.
1af0: 20 20 20 20 20 20 20 20 69 66 20 73 65 6c 66 2e          if self.
1b00: 74 65 61 6d 31 5f 73 63 6f 72 65 20 3c 20 73 65  team1_score < se
1b10: 6c 66 2e 74 65 61 6d 32 5f 73 63 6f 72 65 3a 0a  lf.team2_score:.
1b20: 20 20 20 20 20 20 20 20 20 20 20 20 23 20 54 65              # Te
1b30: 61 6d 20 31 20 28 65 76 65 6e 73 29 20 6c 6f 73  am 1 (evens) los
1b40: 74 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 6f  t.            lo
1b50: 73 65 72 73 20 3d 20 73 65 6c 66 2e 70 6c 61 79  sers = self.play
1b60: 65 72 73 5b 30 3a 3a 32 5d 0a 20 20 20 20 20 20  ers[0::2].      
1b70: 20 20 20 20 20 20 23 20 50 6c 61 79 65 72 20 31        # Player 1
1b80: 20 6d 6f 76 65 20 74 6f 20 73 70 6f 74 20 30 0a   move to spot 0.
1b90: 20 20 20 20 20 20 20 20 20 20 20 20 73 65 6c 66              self
1ba0: 2e 70 6c 61 79 65 72 73 5b 30 5d 20 3d 20 73 65  .players[0] = se
1bb0: 6c 66 2e 70 6c 61 79 65 72 73 5b 31 5d 0a 20 20  lf.players[1].  
1bc0: 20 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20        else:.    
1bd0: 20 20 20 20 20 20 20 20 23 20 54 65 61 6d 20 32          # Team 2
1be0: 20 28 6f 64 64 73 29 20 6c 6f 73 74 0a 20 20 20   (odds) lost.   
1bf0: 20 20 20 20 20 20 20 20 20 6c 6f 73 65 72 73 20           losers 
1c00: 3d 20 73 65 6c 66 2e 70 6c 61 79 65 72 73 5b 31  = self.players[1
1c10: 3a 3a 32 5d 0a 20 20 20 20 20 20 20 20 20 20 20  ::2].           
1c20: 20 23 20 50 6c 61 79 65 72 20 32 20 6d 6f 76 65   # Player 2 move
1c30: 20 74 6f 20 73 70 6f 74 20 33 0a 20 20 20 20 20   to spot 3.     
1c40: 20 20 20 20 20 20 20 73 65 6c 66 2e 70 6c 61 79         self.play
1c50: 65 72 73 5b 33 5d 20 3d 20 73 65 6c 66 2e 70 6c  ers[3] = self.pl
1c60: 61 79 65 72 73 5b 32 5d 0a 20 20 20 20 20 20 20  ayers[2].       
1c70: 20 23 20 52 65 70 6c 61 63 65 20 6d 69 64 64 6c   # Replace middl
1c80: 65 20 74 77 6f 20 70 6c 61 79 65 72 73 0a 20 20  e two players.  
1c90: 20 20 20 20 20 20 73 65 6c 66 2e 70 6c 61 79 65        self.playe
1ca0: 72 73 5b 31 3a 33 5d 20 3d 20 6e 65 77 5f 70 6c  rs[1:3] = new_pl
1cb0: 61 79 65 72 73 0a 20 20 20 20 20 20 20 20 72 65  ayers.        re
1cc0: 74 75 72 6e 20 6c 6f 73 65 72 73 0a 0a 20 20 20  turn losers..   
1cd0: 20 64 65 66 20 6e 6f 74 63 68 5f 77 69 6e 73 28   def notch_wins(
1ce0: 73 65 6c 66 29 3a 0a 20 20 20 20 20 20 20 20 66  self):.        f
1cf0: 6f 72 20 70 6c 61 79 65 72 20 69 6e 20 73 65 6c  or player in sel
1d00: 66 2e 77 69 6e 6e 65 72 73 28 29 3a 0a 20 20 20  f.winners():.   
1d10: 20 20 20 20 20 20 20 20 20 70 6c 61 79 65 72 2e           player.
1d20: 72 6f 75 6e 64 5f 77 69 6e 73 5b 47 61 6d 65 2e  round_wins[Game.
1d30: 63 75 72 72 65 6e 74 5f 72 6f 75 6e 64 28 29 20  current_round() 
1d40: 2d 20 31 5d 20 3d 20 31 0a 20 20 20 20 0a 20 20  - 1] = 1.    .  
1d50: 20 20 64 65 66 20 70 72 65 70 5f 6e 65 77 5f 72    def prep_new_r
1d60: 6f 75 6e 64 28 73 65 6c 66 29 3a 0a 20 20 20 20  ound(self):.    
1d70: 20 20 20 20 73 65 6c 66 2e 74 65 61 6d 31 5f 73      self.team1_s
1d80: 63 6f 72 65 20 3d 20 30 0a 20 20 20 20 20 20 20  core = 0.       
1d90: 20 73 65 6c 66 2e 74 65 61 6d 32 5f 73 63 6f 72   self.team2_scor
1da0: 65 20 3d 20 30 0a 20 20 20 20 20 20 20 20 73 65  e = 0.        se
1db0: 6c 66 2e 61 63 74 69 76 65 5f 70 6c 61 79 65 72  lf.active_player
1dc0: 20 3d 20 2d 31 0a 20 20 20 20 20 20 20 20 66 6f   = -1.        fo
1dd0: 72 20 70 6c 61 79 65 72 20 69 6e 20 73 65 6c 66  r player in self
1de0: 2e 70 6c 61 79 65 72 73 3a 0a 20 20 20 20 20 20  .players:.      
1df0: 20 20 20 20 20 20 70 6c 61 79 65 72 2e 70 72 65        player.pre
1e00: 70 5f 6e 65 77 5f 72 6f 75 6e 64 28 29 0a 20 20  p_new_round().  
1e10: 20 20 0a 20 20 20 20 64 65 66 20 67 65 74 5f 70    .    def get_p
1e20: 6c 61 79 65 72 5f 73 69 74 75 61 74 69 6f 6e 28  layer_situation(
1e30: 73 65 6c 66 2c 20 70 6c 61 79 65 72 29 3a 0a 20  self, player):. 
1e40: 20 20 20 20 20 20 20 70 6c 61 79 65 72 5f 69 6e         player_in
1e50: 64 65 78 20 3d 20 73 65 6c 66 2e 70 6c 61 79 65  dex = self.playe
1e60: 72 73 2e 69 6e 64 65 78 28 70 6c 61 79 65 72 29  rs.index(player)
1e70: 0a 20 20 20 20 20 20 20 20 69 66 20 70 6c 61 79  .        if play
1e80: 65 72 5f 69 6e 64 65 78 20 25 20 32 20 3d 3d 20  er_index % 2 == 
1e90: 30 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 6f  0:.            o
1ea0: 70 70 6f 6e 65 6e 74 73 20 3d 20 73 65 6c 66 2e  pponents = self.
1eb0: 70 6c 61 79 65 72 73 5b 31 3a 3a 32 5d 0a 20 20  players[1::2].  
1ec0: 20 20 20 20 20 20 20 20 20 20 6f 70 70 6f 6e 65            oppone
1ed0: 6e 74 5f 73 63 6f 72 65 20 3d 20 73 65 6c 66 2e  nt_score = self.
1ee0: 74 65 61 6d 32 5f 73 63 6f 72 65 0a 20 20 20 20  team2_score.    
1ef0: 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20 20      else:.      
1f00: 20 20 20 20 20 20 6f 70 70 6f 6e 65 6e 74 73 20        opponents 
1f10: 3d 20 73 65 6c 66 2e 70 6c 61 79 65 72 73 5b 30  = self.players[0
1f20: 3a 3a 32 5d 0a 20 20 20 20 20 20 20 20 20 20 20  ::2].           
1f30: 20 6f 70 70 6f 6e 65 6e 74 5f 73 63 6f 72 65 20   opponent_score 
1f40: 3d 20 73 65 6c 66 2e 74 65 61 6d 31 5f 73 63 6f  = self.team1_sco
1f50: 72 65 0a 20 20 20 20 20 20 20 20 74 65 61 6d 6d  re.        teamm
1f60: 61 74 65 20 3d 20 73 65 6c 66 2e 70 6c 61 79 65  ate = self.playe
1f70: 72 73 5b 74 65 61 6d 6d 61 74 65 5f 6c 6f 6f 6b  rs[teammate_look
1f80: 75 70 5b 70 6c 61 79 65 72 5f 69 6e 64 65 78 5d  up[player_index]
1f90: 5d 0a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  ]..        retur
1fa0: 6e 20 7b 27 74 65 61 6d 6d 61 74 65 27 3a 20 74  n {'teammate': t
1fb0: 65 61 6d 6d 61 74 65 2c 20 0a 20 20 20 20 20 20  eammate, .      
1fc0: 20 20 20 20 20 20 20 20 20 20 27 6f 70 70 6f 6e            'oppon
1fd0: 65 6e 74 73 27 3a 20 6f 70 70 6f 6e 65 6e 74 73  ents': opponents
1fe0: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
1ff0: 20 20 27 6f 70 70 6f 6e 65 6e 74 5f 73 63 6f 72    'opponent_scor
2000: 65 27 3a 20 6f 70 70 6f 6e 65 6e 74 5f 73 63 6f  e': opponent_sco
2010: 72 65 7d 0a 0a 0a 64 65 66 20 61 73 73 69 67 6e  re}...def assign
2020: 5f 74 65 61 6d 73 28 70 6c 61 79 65 72 5f 6c 69  _teams(player_li
2030: 73 74 29 3a 0a 20 20 20 20 70 6c 61 79 65 72 73  st):.    players
2040: 5f 70 65 72 5f 74 61 62 6c 65 20 3d 20 34 0a 20  _per_table = 4. 
2050: 20 20 20 74 61 62 6c 65 73 20 3d 20 5b 5d 0a 20     tables = []. 
2060: 20 20 20 72 61 6e 64 6f 6d 2e 73 65 65 64 28 29     random.seed()
2070: 0a 0a 20 20 20 20 69 66 20 6c 65 6e 28 70 6c 61  ..    if len(pla
2080: 79 65 72 5f 6c 69 73 74 29 20 25 20 70 6c 61 79  yer_list) % play
2090: 65 72 73 5f 70 65 72 5f 74 61 62 6c 65 20 21 3d  ers_per_table !=
20a0: 20 30 3a 0a 20 20 20 20 20 20 20 20 70 72 69 6e   0:.        prin
20b0: 74 28 22 57 72 6f 6e 67 20 6e 75 6d 62 65 72 20  t("Wrong number 
20c0: 6f 66 20 70 6c 61 79 65 72 73 21 22 29 0a 20 20  of players!").  
20d0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 74 61 62        return tab
20e0: 6c 65 73 0a 20 20 20 20 65 6c 73 65 3a 0a 20 20  les.    else:.  
20f0: 20 20 20 20 20 20 74 61 62 6c 65 5f 63 6f 75 6e        table_coun
2100: 74 20 3d 20 6c 65 6e 28 70 6c 61 79 65 72 5f 6c  t = len(player_l
2110: 69 73 74 29 20 2f 2f 20 70 6c 61 79 65 72 73 5f  ist) // players_
2120: 70 65 72 5f 74 61 62 6c 65 0a 20 20 20 20 20 20  per_table.      
2130: 20 20 72 61 6e 64 6f 6d 2e 73 68 75 66 66 6c 65    random.shuffle
2140: 28 70 6c 61 79 65 72 5f 6c 69 73 74 29 0a 20 20  (player_list).  
2150: 20 20 20 20 20 20 74 61 62 6c 65 73 20 3d 20 5b        tables = [
2160: 54 61 62 6c 65 28 29 20 66 6f 72 20 5f 20 69 6e  Table() for _ in
2170: 20 72 61 6e 67 65 28 74 61 62 6c 65 5f 63 6f 75   range(table_cou
2180: 6e 74 29 5d 0a 0a 20 20 20 20 20 20 20 20 66 6f  nt)]..        fo
2190: 72 20 6e 20 69 6e 20 72 61 6e 67 65 28 74 61 62  r n in range(tab
21a0: 6c 65 5f 63 6f 75 6e 74 29 3a 0a 20 20 20 20 20  le_count):.     
21b0: 20 20 20 20 20 20 20 66 69 72 73 74 20 3d 20 6e         first = n
21c0: 20 2a 20 70 6c 61 79 65 72 73 5f 70 65 72 5f 74   * players_per_t
21d0: 61 62 6c 65 0a 20 20 20 20 20 20 20 20 20 20 20  able.           
21e0: 20 73 74 6f 70 5f 62 65 66 6f 72 65 20 3d 20 66   stop_before = f
21f0: 69 72 73 74 20 2b 20 70 6c 61 79 65 72 73 5f 70  irst + players_p
2200: 65 72 5f 74 61 62 6c 65 0a 20 20 20 20 20 20 20  er_table.       
2210: 20 20 20 20 20 74 61 62 6c 65 73 5b 6e 5d 2e 70       tables[n].p
2220: 6c 61 79 65 72 73 20 3d 20 70 6c 61 79 65 72 5f  layers = player_
2230: 6c 69 73 74 5b 66 69 72 73 74 3a 73 74 6f 70 5f  list[first:stop_
2240: 62 65 66 6f 72 65 5d 0a 20 20 20 20 20 20 20 20  before].        
2250: 20 20 20 20 74 61 62 6c 65 73 5b 6e 5d 2e 74 61      tables[n].ta
2260: 62 6c 65 5f 6e 75 6d 62 65 72 20 3d 20 6e 20 2b  ble_number = n +
2270: 20 31 0a 20 20 20 20 20 20 20 20 0a 20 20 20 20   1.        .    
2280: 20 20 20 20 72 65 74 75 72 6e 20 74 61 62 6c 65      return table
2290: 73 0a 0a 64 65 66 20 6c 6f 61 64 5f 70 6c 61 79  s..def load_play
22a0: 65 72 73 28 66 69 6c 65 6e 61 6d 65 29 3a 0a 20  ers(filename):. 
22b0: 20 20 20 70 6c 61 79 65 72 73 20 3d 20 5b 5d 0a     players = [].
22c0: 0a 20 20 20 20 77 69 74 68 20 6f 70 65 6e 28 66  .    with open(f
22d0: 69 6c 65 6e 61 6d 65 29 20 61 73 20 74 73 76 66  ilename) as tsvf
22e0: 69 6c 65 3a 0a 20 20 20 20 20 20 20 20 74 73 76  ile:.        tsv
22f0: 72 65 61 64 65 72 20 3d 20 63 73 76 2e 72 65 61  reader = csv.rea
2300: 64 65 72 28 74 73 76 66 69 6c 65 29 0a 20 20 20  der(tsvfile).   
2310: 20 20 20 20 20 66 6f 72 20 6c 69 6e 65 20 69 6e       for line in
2320: 20 74 73 76 72 65 61 64 65 72 3a 0a 20 20 20 20   tsvreader:.    
2330: 20 20 20 20 20 20 20 20 70 6c 61 79 65 72 73 2e          players.
2340: 61 70 70 65 6e 64 28 50 6c 61 79 65 72 28 6c 69  append(Player(li
2350: 6e 65 5b 30 5d 2c 6c 69 6e 65 5b 31 5d 2c 30 2c  ne[0],line[1],0,
2360: 30 2c 30 29 29 0a 20 20 20 20 0a 20 20 20 20 72  0,0)).    .    r
2370: 65 74 75 72 6e 20 70 6c 61 79 65 72 73 0a 0a 63  eturn players..c
2380: 6c 61 73 73 20 47 61 6d 65 3a 0a 20 20 20 20 63  lass Game:.    c
2390: 75 72 5f 74 69 63 6b 20 3d 20 31 0a 20 20 20 20  ur_tick = 1.    
23a0: 63 75 72 5f 72 6f 75 6e 64 20 3d 20 31 0a 20 20  cur_round = 1.  
23b0: 20 20 0a 20 20 20 20 64 65 66 20 5f 5f 69 6e 69    .    def __ini
23c0: 74 5f 5f 28 73 65 6c 66 2c 20 70 6c 61 79 65 72  t__(self, player
23d0: 66 69 6c 65 29 3a 0a 20 20 20 20 20 20 20 20 73  file):.        s
23e0: 65 6c 66 2e 70 6c 61 79 65 72 73 20 3d 20 6c 6f  elf.players = lo
23f0: 61 64 5f 70 6c 61 79 65 72 73 28 70 6c 61 79 65  ad_players(playe
2400: 72 66 69 6c 65 29 0a 20 20 20 20 20 20 20 20 73  rfile).        s
2410: 65 6c 66 2e 74 61 62 6c 65 73 20 3d 20 61 73 73  elf.tables = ass
2420: 69 67 6e 5f 74 65 61 6d 73 28 73 65 6c 66 2e 70  ign_teams(self.p
2430: 6c 61 79 65 72 73 29 0a 0a 20 20 20 20 64 65 66  layers)..    def
2440: 20 74 69 63 6b 28 73 65 6c 66 29 3a 0a 20 20 20   tick(self):.   
2450: 20 20 20 20 20 67 6c 6f 62 61 6c 20 66 75 7a 7a       global fuzz
2460: 79 64 69 65 5f 68 6f 6c 64 65 72 0a 20 20 20 20  ydie_holder.    
2470: 20 20 20 20 66 6f 72 20 74 61 62 6c 65 20 69 6e      for table in
2480: 20 73 65 6c 66 2e 74 61 62 6c 65 73 3a 0a 20 20   self.tables:.  
2490: 20 20 20 20 20 20 20 20 20 20 74 61 62 6c 65 2e            table.
24a0: 74 69 63 6b 28 29 0a 20 20 20 20 20 20 20 20 0a  tick().        .
24b0: 20 20 20 20 20 20 20 20 62 75 6e 63 6f 5f 72 6f          bunco_ro
24c0: 6c 6c 65 72 73 20 3d 20 5b 70 20 66 6f 72 20 70  llers = [p for p
24d0: 20 69 6e 20 73 65 6c 66 2e 70 6c 61 79 65 72 73   in self.players
24e0: 20 69 66 20 70 2e 72 6f 6c 6c 65 64 5f 62 75 6e   if p.rolled_bun
24f0: 63 6f 20 69 73 20 54 72 75 65 5d 0a 20 20 20 20  co is True].    
2500: 20 20 20 20 0a 20 20 20 20 20 20 20 20 23 20 49      .        # I
2510: 66 20 6d 75 6c 74 69 70 6c 65 20 70 65 6f 70 6c  f multiple peopl
2520: 65 20 72 6f 6c 6c 65 64 20 42 75 6e 63 6f 20 74  e rolled Bunco t
2530: 68 69 73 20 74 69 63 6b 2c 20 61 6e 64 20 6f 6e  his tick, and on
2540: 65 20 6f 66 20 74 68 65 6d 20 61 6c 72 65 61 64  e of them alread
2550: 79 20 68 61 73 20 74 68 65 0a 20 20 20 20 20 20  y has the.      
2560: 20 20 23 20 66 75 7a 7a 79 20 64 69 65 2c 20 74    # fuzzy die, t
2570: 68 65 79 20 72 65 74 61 69 6e 20 69 74 2e 0a 20  hey retain it.. 
2580: 20 20 20 20 20 20 20 23 20 4f 74 68 65 72 77 69         # Otherwi
2590: 73 65 2c 20 74 68 65 20 6c 61 73 74 20 70 65 72  se, the last per
25a0: 73 6f 6e 20 69 6e 20 74 68 65 20 6c 69 73 74 20  son in the list 
25b0: 67 65 74 73 20 74 68 65 20 66 75 7a 7a 79 20 64  gets the fuzzy d
25c0: 69 65 2e 0a 20 20 20 20 20 20 20 20 69 66 20 62  ie..        if b
25d0: 75 6e 63 6f 5f 72 6f 6c 6c 65 72 73 3a 0a 20 20  unco_rollers:.  
25e0: 20 20 20 20 20 20 20 20 20 20 69 66 20 6c 65 6e            if len
25f0: 28 62 75 6e 63 6f 5f 72 6f 6c 6c 65 72 73 29 20  (bunco_rollers) 
2600: 3d 3d 20 31 3a 0a 20 20 20 20 20 20 20 20 20 20  == 1:.          
2610: 20 20 20 20 20 20 69 66 20 62 75 6e 63 6f 5f 72        if bunco_r
2620: 6f 6c 6c 65 72 73 5b 30 5d 20 69 73 20 6e 6f 74  ollers[0] is not
2630: 20 66 75 7a 7a 79 64 69 65 5f 68 6f 6c 64 65 72   fuzzydie_holder
2640: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  :.              
2650: 20 20 20 20 20 20 6c 6f 67 28 22 61 6c 6c 22 2c        log("all",
2660: 66 22 7b 62 75 6e 63 6f 5f 72 6f 6c 6c 65 72 73  f"{bunco_rollers
2670: 5b 30 5d 7d 20 63 6c 61 69 6d 65 64 20 74 68 65  [0]} claimed the
2680: 20 66 75 7a 7a 79 20 64 69 65 21 22 29 0a 20 20   fuzzy die!").  
2690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
26a0: 20 20 66 75 7a 7a 79 64 69 65 5f 68 6f 6c 64 65    fuzzydie_holde
26b0: 72 20 3d 20 62 75 6e 63 6f 5f 72 6f 6c 6c 65 72  r = bunco_roller
26c0: 73 5b 30 5d 0a 20 20 20 20 20 20 20 20 20 20 20  s[0].           
26d0: 20 20 20 20 20 65 6c 73 65 3a 0a 20 20 20 20 20       else:.     
26e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c                 l
26f0: 6f 67 28 22 61 6c 6c 22 2c 66 22 7b 62 75 6e 63  og("all",f"{bunc
2700: 6f 5f 72 6f 6c 6c 65 72 73 5b 30 5d 7d 20 72 6f  o_rollers[0]} ro
2710: 6c 6c 65 64 20 61 20 42 75 6e 63 6f 20 62 75 74  lled a Bunco but
2720: 20 61 6c 72 65 61 64 79 20 68 61 73 20 74 68 65   already has the
2730: 20 66 75 7a 7a 79 20 64 69 65 21 22 29 0a 20 20   fuzzy die!").  
2740: 20 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a            else:.
2750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2760: 66 6f 72 20 6c 75 63 6b 79 64 75 63 6b 20 69 6e  for luckyduck in
2770: 20 62 75 6e 63 6f 5f 72 6f 6c 6c 65 72 73 3a 0a   bunco_rollers:.
2780: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2790: 20 20 20 20 69 66 20 6c 75 63 6b 79 64 75 63 6b      if luckyduck
27a0: 20 69 73 20 6e 6f 74 20 66 75 7a 7a 79 64 69 65   is not fuzzydie
27b0: 5f 68 6f 6c 64 65 72 3a 0a 20 20 20 20 20 20 20  _holder:.       
27c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
27d0: 20 6c 6f 67 28 6c 75 63 6b 79 64 75 63 6b 2c 66   log(luckyduck,f
27e0: 22 7b 6c 75 63 6b 79 64 75 63 6b 7d 20 61 74 74  "{luckyduck} att
27f0: 65 6d 70 74 65 64 20 74 6f 20 63 6c 61 69 6d 20  empted to claim 
2800: 74 68 65 20 66 75 7a 7a 79 20 64 69 65 21 22 29  the fuzzy die!")
2810: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
2820: 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20   .              
2830: 20 20 69 66 20 66 75 7a 7a 79 64 69 65 5f 68 6f    if fuzzydie_ho
2840: 6c 64 65 72 20 6e 6f 74 20 69 6e 20 62 75 6e 63  lder not in bunc
2850: 6f 5f 72 6f 6c 6c 65 72 73 3a 0a 20 20 20 20 20  o_rollers:.     
2860: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 66                 f
2870: 75 7a 7a 79 64 69 65 5f 68 6f 6c 64 65 72 20 3d  uzzydie_holder =
2880: 20 62 75 6e 63 6f 5f 72 6f 6c 6c 65 72 73 5b 2d   bunco_rollers[-
2890: 31 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  1].             
28a0: 20 20 20 20 20 20 20 6c 6f 67 28 66 75 7a 7a 79         log(fuzzy
28b0: 64 69 65 5f 68 6f 6c 64 65 72 2c 20 66 22 7b 66  die_holder, f"{f
28c0: 75 7a 7a 79 64 69 65 5f 68 6f 6c 64 65 72 7d 20  uzzydie_holder} 
28d0: 73 69 65 7a 65 64 20 74 68 65 20 66 75 7a 7a 79  siezed the fuzzy
28e0: 20 64 69 65 21 21 22 29 0a 20 20 20 20 20 20 20   die!!").       
28f0: 20 20 20 20 20 20 20 20 20 65 6c 73 65 3a 0a 20           else:. 
2900: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2910: 20 20 20 6c 6f 67 28 66 75 7a 7a 79 64 69 65 5f     log(fuzzydie_
2920: 68 6f 6c 64 65 72 2c 20 66 22 7b 66 75 7a 7a 79  holder, f"{fuzzy
2930: 64 69 65 5f 68 6f 6c 64 65 72 7d 20 72 65 74 61  die_holder} reta
2940: 69 6e 65 64 20 74 68 65 20 66 75 7a 7a 79 20 64  ined the fuzzy d
2950: 69 65 21 21 22 29 0a 20 20 20 20 20 20 20 20 20  ie!!").         
2960: 20 20 20 0a 20 20 20 20 20 20 20 20 20 20 20 20     .            
2970: 66 6f 72 20 70 6c 61 79 65 72 20 69 6e 20 62 75  for player in bu
2980: 6e 63 6f 5f 72 6f 6c 6c 65 72 73 3a 0a 20 20 20  nco_rollers:.   
2990: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 6c 61               pla
29a0: 79 65 72 2e 72 6f 6c 6c 65 64 5f 62 75 6e 63 6f  yer.rolled_bunco
29b0: 20 3d 20 46 61 6c 73 65 20 23 20 52 65 73 65 74   = False # Reset
29c0: 20 66 6c 61 67 0a 20 20 20 20 0a 20 20 20 20 20   flag.    .     
29d0: 20 20 20 73 65 6c 66 2e 69 6e 63 72 65 6d 65 6e     self.incremen
29e0: 74 5f 74 69 63 6b 28 29 0a 20 20 20 20 0a 20 20  t_tick().    .  
29f0: 20 20 40 63 6c 61 73 73 6d 65 74 68 6f 64 0a 20    @classmethod. 
2a00: 20 20 20 64 65 66 20 63 75 72 72 65 6e 74 5f 74     def current_t
2a10: 69 63 6b 28 63 6c 73 29 3a 0a 20 20 20 20 20 20  ick(cls):.      
2a20: 20 20 72 65 74 75 72 6e 20 63 6c 73 2e 63 75 72    return cls.cur
2a30: 5f 74 69 63 6b 0a 20 20 20 20 0a 20 20 20 20 40  _tick.    .    @
2a40: 63 6c 61 73 73 6d 65 74 68 6f 64 0a 20 20 20 20  classmethod.    
2a50: 64 65 66 20 69 6e 63 72 65 6d 65 6e 74 5f 74 69  def increment_ti
2a60: 63 6b 28 63 6c 73 29 3a 0a 20 20 20 20 20 20 20  ck(cls):.       
2a70: 20 63 6c 73 2e 63 75 72 5f 74 69 63 6b 20 2b 3d   cls.cur_tick +=
2a80: 20 31 0a 0a 20 20 20 20 40 63 6c 61 73 73 6d 65   1..    @classme
2a90: 74 68 6f 64 0a 20 20 20 20 64 65 66 20 63 75 72  thod.    def cur
2aa0: 72 65 6e 74 5f 72 6f 75 6e 64 28 63 6c 73 29 3a  rent_round(cls):
2ab0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
2ac0: 63 6c 73 2e 63 75 72 5f 72 6f 75 6e 64 0a 0a 20  cls.cur_round.. 
2ad0: 20 20 20 40 63 6c 61 73 73 6d 65 74 68 6f 64 0a     @classmethod.
2ae0: 20 20 20 20 64 65 66 20 69 6e 63 72 65 6d 65 6e      def incremen
2af0: 74 5f 72 6f 75 6e 64 28 63 6c 73 29 3a 0a 20 20  t_round(cls):.  
2b00: 20 20 20 20 20 20 63 6c 73 2e 63 75 72 5f 72 6f        cls.cur_ro
2b10: 75 6e 64 20 2b 3d 20 31 0a 0a 20 20 20 20 64 65  und += 1..    de
2b20: 66 20 70 72 69 6e 74 5f 73 74 61 74 75 73 28 73  f print_status(s
2b30: 65 6c 66 29 3a 0a 20 20 20 20 20 20 20 20 66 6f  elf):.        fo
2b40: 72 20 6e 2c 20 74 61 62 6c 65 20 69 6e 20 65 6e  r n, table in en
2b50: 75 6d 65 72 61 74 65 28 73 65 6c 66 2e 74 61 62  umerate(self.tab
2b60: 6c 65 73 29 3a 0a 20 20 20 20 20 20 20 20 20 20  les):.          
2b70: 20 20 70 72 69 6e 74 28 66 22 3d 3d 20 54 41 42    print(f"== TAB
2b80: 4c 45 20 7b 6e 2b 31 7d 20 3d 3d 20 54 65 61 6d  LE {n+1} == Team
2b90: 20 31 3a 7b 74 61 62 6c 65 2e 74 65 61 6d 31 5f   1:{table.team1_
2ba0: 73 63 6f 72 65 7d 20 70 74 73 2c 20 54 65 61 6d  score} pts, Team
2bb0: 20 32 3a 7b 74 61 62 6c 65 2e 74 65 61 6d 32 5f   2:{table.team2_
2bc0: 73 63 6f 72 65 7d 20 70 74 73 22 29 0a 20 20 20  score} pts").   
2bd0: 20 20 20 20 20 20 20 20 20 66 6f 72 20 70 6c 61           for pla
2be0: 79 65 72 20 69 6e 20 74 61 62 6c 65 2e 70 6c 61  yer in table.pla
2bf0: 79 65 72 73 3a 0a 20 20 20 20 20 20 20 20 20 20  yers:.          
2c00: 20 20 20 20 20 20 70 72 69 6e 74 28 66 22 20 20        print(f"  
2c10: 20 20 7b 70 6c 61 79 65 72 2e 6e 61 6d 65 7d 20    {player.name} 
2c20: 7b 70 6c 61 79 65 72 2e 72 6f 75 6e 64 5f 73 63  {player.round_sc
2c30: 6f 72 65 73 5b 47 61 6d 65 2e 63 75 72 72 65 6e  ores[Game.curren
2c40: 74 5f 72 6f 75 6e 64 28 29 20 2d 20 31 5d 7d 20  t_round() - 1]} 
2c50: 70 6f 69 6e 74 73 2c 20 73 74 72 65 61 6b 20 7b  points, streak {
2c60: 70 6c 61 79 65 72 2e 6d 61 78 5f 73 74 72 65 61  player.max_strea
2c70: 6b 7d 20 62 75 6e 63 6f 73 20 7b 73 75 6d 28 70  k} buncos {sum(p
2c80: 6c 61 79 65 72 2e 72 6f 75 6e 64 5f 62 75 6e 63  layer.round_bunc
2c90: 6f 5f 63 6f 75 6e 74 73 29 7d 22 29 0a 20 20 20  o_counts)}").   
2ca0: 20 0a 20 20 20 20 64 65 66 20 61 76 65 72 61 67   .    def averag
2cb0: 65 5f 74 6f 74 61 6c 5f 73 63 6f 72 65 28 73 65  e_total_score(se
2cc0: 6c 66 29 3a 0a 20 20 20 20 20 20 20 20 61 6c 6c  lf):.        all
2cd0: 5f 73 63 6f 72 65 73 20 3d 20 5b 73 75 6d 28 70  _scores = [sum(p
2ce0: 2e 72 6f 75 6e 64 5f 73 63 6f 72 65 73 29 20 66  .round_scores) f
2cf0: 6f 72 20 70 20 69 6e 20 73 65 6c 66 2e 70 6c 61  or p in self.pla
2d00: 79 65 72 73 5d 0a 20 20 20 20 20 20 20 20 72 65  yers].        re
2d10: 74 75 72 6e 20 73 75 6d 28 61 6c 6c 5f 73 63 6f  turn sum(all_sco
2d20: 72 65 73 29 20 2f 20 6c 65 6e 28 61 6c 6c 5f 73  res) / len(all_s
2d30: 63 6f 72 65 73 29 0a 0a 20 20 20 20 64 65 66 20  cores)..    def 
2d40: 6d 65 64 69 61 6e 5f 74 6f 74 61 6c 5f 73 63 6f  median_total_sco
2d50: 72 65 28 73 65 6c 66 29 3a 0a 20 20 20 20 20 20  re(self):.      
2d60: 20 20 61 6c 6c 5f 73 63 6f 72 65 73 20 3d 20 5b    all_scores = [
2d70: 73 75 6d 28 70 2e 72 6f 75 6e 64 5f 73 63 6f 72  sum(p.round_scor
2d80: 65 73 29 20 66 6f 72 20 70 20 69 6e 20 73 65 6c  es) for p in sel
2d90: 66 2e 70 6c 61 79 65 72 73 5d 0a 20 20 20 20 20  f.players].     
2da0: 20 20 20 0a 20 20 20 20 20 20 20 20 72 65 74 75     .        retu
2db0: 72 6e 20 6d 65 64 69 61 6e 28 61 6c 6c 5f 73 63  rn median(all_sc
2dc0: 6f 72 65 73 29 0a 0a 20 20 20 20 64 65 66 20 70  ores)..    def p
2dd0: 72 65 70 5f 6e 65 78 74 5f 72 6f 75 6e 64 28 73  rep_next_round(s
2de0: 65 6c 66 29 3a 0a 20 20 20 20 20 20 20 20 23 20  elf):.        # 
2df0: 6c 6f 73 65 72 73 20 66 72 6f 6d 20 68 65 61 64  losers from head
2e00: 20 74 61 62 6c 65 20 6d 6f 76 65 20 74 6f 20 6e   table move to n
2e10: 65 78 74 20 74 61 62 6c 65 0a 20 20 20 20 20 20  ext table.      
2e20: 20 20 68 65 61 64 74 61 62 6c 65 5f 6c 6f 73 65    headtable_lose
2e30: 72 73 20 3d 20 73 65 6c 66 2e 74 61 62 6c 65 73  rs = self.tables
2e40: 5b 30 5d 2e 6c 6f 73 65 72 73 28 29 0a 20 20 20  [0].losers().   
2e50: 20 20 20 20 20 6c 6f 67 5f 74 61 62 6c 65 5f 6d       log_table_m
2e60: 6f 76 65 28 68 65 61 64 74 61 62 6c 65 5f 6c 6f  ove(headtable_lo
2e70: 73 65 72 73 2c 20 22 6c 6f 73 74 22 2c 20 73 65  sers, "lost", se
2e80: 6c 66 2e 74 61 62 6c 65 73 5b 30 5d 2c 20 73 65  lf.tables[0], se
2e90: 6c 66 2e 74 61 62 6c 65 73 5b 31 5d 29 0a 20 20  lf.tables[1]).  
2ea0: 20 20 20 20 20 20 69 66 20 63 61 6c 6c 61 62 6c        if callabl
2eb0: 65 28 74 61 62 6c 65 5f 6d 6f 76 65 5f 63 61 6c  e(table_move_cal
2ec0: 6c 62 61 63 6b 29 3a 0a 20 20 20 20 20 20 20 20  lback):.        
2ed0: 20 20 20 20 66 6f 72 20 70 6c 61 79 65 72 20 69      for player i
2ee0: 6e 20 68 65 61 64 74 61 62 6c 65 5f 6c 6f 73 65  n headtable_lose
2ef0: 72 73 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  rs:.            
2f00: 20 20 20 20 74 61 62 6c 65 5f 6d 6f 76 65 5f 63      table_move_c
2f10: 61 6c 6c 62 61 63 6b 28 70 6c 61 79 65 72 2c 20  allback(player, 
2f20: 22 6c 6f 73 74 22 2c 20 73 65 6c 66 2e 74 61 62  "lost", self.tab
2f30: 6c 65 73 5b 30 5d 2c 20 73 65 6c 66 2e 74 61 62  les[0], self.tab
2f40: 6c 65 73 5b 31 5d 29 0a 20 20 20 20 20 20 20 20  les[1]).        
2f50: 72 6f 75 6e 64 5f 77 69 6e 6e 65 72 73 20 3d 20  round_winners = 
2f60: 73 65 6c 66 2e 74 61 62 6c 65 73 5b 31 5d 2e 73  self.tables[1].s
2f70: 77 61 70 5f 66 6f 72 5f 77 69 6e 6e 65 72 73 28  wap_for_winners(
2f80: 68 65 61 64 74 61 62 6c 65 5f 6c 6f 73 65 72 73  headtable_losers
2f90: 29 0a 0a 20 20 20 20 20 20 20 20 23 20 77 69 6e  )..        # win
2fa0: 6e 65 72 73 20 66 72 6f 6d 20 6f 74 68 65 72 20  ners from other 
2fb0: 74 61 62 6c 65 73 20 6d 6f 76 65 20 74 6f 20 6e  tables move to n
2fc0: 65 78 74 20 74 61 62 6c 65 0a 20 20 20 20 20 20  ext table.      
2fd0: 20 20 66 6f 72 20 6e 20 69 6e 20 72 61 6e 67 65    for n in range
2fe0: 28 32 2c 20 6c 65 6e 28 73 65 6c 66 2e 74 61 62  (2, len(self.tab
2ff0: 6c 65 73 29 29 3a 0a 20 20 20 20 20 20 20 20 20  les)):.         
3000: 20 20 20 6c 6f 67 5f 74 61 62 6c 65 5f 6d 6f 76     log_table_mov
3010: 65 28 72 6f 75 6e 64 5f 77 69 6e 6e 65 72 73 2c  e(round_winners,
3020: 20 22 77 6f 6e 22 2c 20 73 65 6c 66 2e 74 61 62   "won", self.tab
3030: 6c 65 73 5b 6e 2d 31 5d 2c 20 73 65 6c 66 2e 74  les[n-1], self.t
3040: 61 62 6c 65 73 5b 6e 5d 29 0a 20 20 20 20 20 20  ables[n]).      
3050: 20 20 20 20 20 20 69 66 20 63 61 6c 6c 61 62 6c        if callabl
3060: 65 28 74 61 62 6c 65 5f 6d 6f 76 65 5f 63 61 6c  e(table_move_cal
3070: 6c 62 61 63 6b 29 3a 0a 20 20 20 20 20 20 20 20  lback):.        
3080: 20 20 20 20 20 20 20 20 66 6f 72 20 70 6c 61 79          for play
3090: 65 72 20 69 6e 20 72 6f 75 6e 64 5f 77 69 6e 6e  er in round_winn
30a0: 65 72 73 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ers:.           
30b0: 20 20 20 20 20 20 20 20 20 74 61 62 6c 65 5f 6d           table_m
30c0: 6f 76 65 5f 63 61 6c 6c 62 61 63 6b 28 70 6c 61  ove_callback(pla
30d0: 79 65 72 2c 20 22 77 6f 6e 22 2c 20 73 65 6c 66  yer, "won", self
30e0: 2e 74 61 62 6c 65 73 5b 6e 2d 31 5d 2c 20 73 65  .tables[n-1], se
30f0: 6c 66 2e 74 61 62 6c 65 73 5b 6e 5d 29 0a 20 20  lf.tables[n]).  
3100: 20 20 20 20 20 20 20 20 20 20 72 6f 75 6e 64 5f            round_
3110: 77 69 6e 6e 65 72 73 20 3d 20 73 65 6c 66 2e 74  winners = self.t
3120: 61 62 6c 65 73 5b 6e 5d 2e 73 77 61 70 5f 66 6f  ables[n].swap_fo
3130: 72 5f 77 69 6e 6e 65 72 73 28 72 6f 75 6e 64 5f  r_winners(round_
3140: 77 69 6e 6e 65 72 73 29 0a 20 20 20 20 20 20 20  winners).       
3150: 20 0a 20 20 20 20 20 20 20 20 23 20 6c 61 73 74   .        # last
3160: 20 73 65 74 20 6f 66 20 77 69 6e 6e 65 72 73 20   set of winners 
3170: 6d 6f 76 65 73 20 74 6f 20 68 65 61 64 20 74 61  moves to head ta
3180: 62 6c 65 0a 20 20 20 20 20 20 20 20 6c 6f 67 5f  ble.        log_
3190: 74 61 62 6c 65 5f 6d 6f 76 65 28 72 6f 75 6e 64  table_move(round
31a0: 5f 77 69 6e 6e 65 72 73 2c 20 22 77 6f 6e 22 2c  _winners, "won",
31b0: 20 73 65 6c 66 2e 74 61 62 6c 65 73 5b 2d 31 5d   self.tables[-1]
31c0: 2c 20 73 65 6c 66 2e 74 61 62 6c 65 73 5b 30 5d  , self.tables[0]
31d0: 29 0a 20 20 20 20 20 20 20 20 69 66 20 63 61 6c  ).        if cal
31e0: 6c 61 62 6c 65 28 74 61 62 6c 65 5f 6d 6f 76 65  lable(table_move
31f0: 5f 63 61 6c 6c 62 61 63 6b 29 3a 0a 20 20 20 20  _callback):.    
3200: 20 20 20 20 20 20 20 20 66 6f 72 20 70 6c 61 79          for play
3210: 65 72 20 69 6e 20 72 6f 75 6e 64 5f 77 69 6e 6e  er in round_winn
3220: 65 72 73 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ers:.           
3230: 20 20 20 20 20 74 61 62 6c 65 5f 6d 6f 76 65 5f       table_move_
3240: 63 61 6c 6c 62 61 63 6b 28 70 6c 61 79 65 72 2c  callback(player,
3250: 20 22 77 6f 6e 22 2c 20 73 65 6c 66 2e 74 61 62   "won", self.tab
3260: 6c 65 73 5b 2d 31 5d 2c 20 73 65 6c 66 2e 74 61  les[-1], self.ta
3270: 62 6c 65 73 5b 30 5d 29 0a 20 20 20 20 20 20 20  bles[0]).       
3280: 20 73 65 6c 66 2e 74 61 62 6c 65 73 5b 30 5d 2e   self.tables[0].
3290: 73 77 61 70 5f 66 6f 72 5f 6c 6f 73 65 72 73 28  swap_for_losers(
32a0: 72 6f 75 6e 64 5f 77 69 6e 6e 65 72 73 29 0a 0a  round_winners)..
32b0: 20 20 20 20 20 20 20 20 66 6f 72 20 74 61 62 6c          for tabl
32c0: 65 20 69 6e 20 73 65 6c 66 2e 74 61 62 6c 65 73  e in self.tables
32d0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 74 61  :.            ta
32e0: 62 6c 65 2e 70 72 65 70 5f 6e 65 77 5f 72 6f 75  ble.prep_new_rou
32f0: 6e 64 28 29 0a 0a 20 20 20 20 20 20 20 20 73 65  nd()..        se
3300: 6c 66 2e 69 6e 63 72 65 6d 65 6e 74 5f 72 6f 75  lf.increment_rou
3310: 6e 64 28 29 0a 0a 20 20 20 20 64 65 66 20 70 6c  nd()..    def pl
3320: 61 79 5f 6f 6e 65 5f 72 6f 75 6e 64 28 73 65 6c  ay_one_round(sel
3330: 66 29 3a 0a 20 20 20 20 20 20 20 20 23 20 47 6f  f):.        # Go
3340: 20 75 6e 74 69 6c 20 6f 6e 65 20 6f 66 20 74 68   until one of th
3350: 65 20 68 65 61 64 20 74 61 62 6c 65 20 74 65 61  e head table tea
3360: 6d 73 20 72 65 61 63 68 65 73 20 32 31 20 70 74  ms reaches 21 pt
3370: 73 0a 20 20 20 20 20 20 20 20 77 68 69 6c 65 20  s.        while 
3380: 6d 61 78 28 73 65 6c 66 2e 74 61 62 6c 65 73 5b  max(self.tables[
3390: 30 5d 2e 74 65 61 6d 31 5f 73 63 6f 72 65 2c 20  0].team1_score, 
33a0: 73 65 6c 66 2e 74 61 62 6c 65 73 5b 30 5d 2e 74  self.tables[0].t
33b0: 65 61 6d 32 5f 73 63 6f 72 65 29 20 3c 20 32 31  eam2_score) < 21
33c0: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 65  :.            se
33d0: 6c 66 2e 74 69 63 6b 28 29 0a 0a 20 20 20 20 20  lf.tick()..     
33e0: 20 20 20 6c 6f 67 28 22 61 6c 6c 22 2c 20 22 42     log("all", "B
33f0: 55 4e 43 4f 21 21 20 41 20 74 65 61 6d 20 61 74  UNCO!! A team at
3400: 20 74 68 65 20 48 65 61 64 20 54 61 62 6c 65 20   the Head Table 
3410: 68 61 73 20 68 69 74 20 32 31 20 70 6f 69 6e 74  has hit 21 point
3420: 73 2e 22 29 0a 20 20 20 20 20 20 20 20 0a 20 20  s.").        .  
3430: 20 20 20 20 20 20 23 20 46 69 6e 69 73 68 20 75        # Finish u
3440: 70 20 73 63 6f 72 69 6e 67 20 66 6f 72 20 61 6e  p scoring for an
3450: 79 20 70 6c 61 79 65 72 73 20 74 68 61 74 20 68  y players that h
3460: 61 76 65 20 75 6e 73 63 6f 72 65 64 20 72 6f 6c  ave unscored rol
3470: 6c 73 0a 20 20 20 20 20 20 20 20 66 6f 72 20 74  ls.        for t
3480: 61 62 6c 65 20 69 6e 20 73 65 6c 66 2e 74 61 62  able in self.tab
3490: 6c 65 73 3a 0a 20 20 20 20 20 20 20 20 20 20 20  les:.           
34a0: 20 63 75 72 70 6c 61 79 65 72 20 3d 20 74 61 62   curplayer = tab
34b0: 6c 65 2e 70 6c 61 79 65 72 73 5b 74 61 62 6c 65  le.players[table
34c0: 2e 61 63 74 69 76 65 5f 70 6c 61 79 65 72 5d 0a  .active_player].
34d0: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 63              if c
34e0: 75 72 70 6c 61 79 65 72 2e 63 75 72 72 65 6e 74  urplayer.current
34f0: 5f 72 6f 6c 6c 3a 0a 20 20 20 20 20 20 20 20 20  _roll:.         
3500: 20 20 20 20 20 20 20 6c 6f 67 28 63 75 72 70 6c         log(curpl
3510: 61 79 65 72 2c 20 66 22 7b 63 75 72 70 6c 61 79  ayer, f"{curplay
3520: 65 72 7d 20 66 69 6e 69 73 68 69 6e 67 20 75 70  er} finishing up
3530: 20 5b 74 68 65 69 72 5d 20 74 75 72 6e 22 29 0a   [their] turn").
3540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3550: 77 68 69 6c 65 20 63 75 72 70 6c 61 79 65 72 2e  while curplayer.
3560: 63 75 72 72 65 6e 74 5f 72 6f 6c 6c 3a 0a 20 20  current_roll:.  
3570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3580: 20 20 74 61 62 6c 65 2e 74 69 63 6b 28 29 0a 20    table.tick(). 
3590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
35a0: 20 20 20 73 65 6c 66 2e 69 6e 63 72 65 6d 65 6e     self.incremen
35b0: 74 5f 74 69 63 6b 28 29 0a 20 20 20 20 20 20 20  t_tick().       
35c0: 20 0a 20 20 20 20 20 20 20 20 23 20 53 65 74 74   .        # Sett
35d0: 6c 65 20 74 69 65 73 20 61 74 20 65 61 63 68 20  le ties at each 
35e0: 74 61 62 6c 65 20 62 79 20 64 6f 69 6e 67 20 61  table by doing a
35f0: 20 72 6f 6c 6c 2d 6f 66 66 20 61 73 20 6d 61 6e   roll-off as man
3600: 79 20 74 69 6d 65 73 20 61 73 20 6e 65 65 64 65  y times as neede
3610: 64 0a 20 20 20 20 20 20 20 20 66 6f 72 20 74 61  d.        for ta
3620: 62 6c 65 20 69 6e 20 73 65 6c 66 2e 74 61 62 6c  ble in self.tabl
3630: 65 73 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20  es:.            
3640: 6c 6f 67 28 27 61 6c 6c 27 2c 20 66 22 7b 74 61  log('all', f"{ta
3650: 62 6c 65 7d 3a 20 54 65 61 6d 20 31 20 7b 74 61  ble}: Team 1 {ta
3660: 62 6c 65 2e 74 65 61 6d 31 5f 73 63 6f 72 65 7d  ble.team1_score}
3670: 20 70 74 73 2c 20 54 65 61 6d 20 32 20 7b 74 61   pts, Team 2 {ta
3680: 62 6c 65 2e 74 65 61 6d 32 5f 73 63 6f 72 65 7d  ble.team2_score}
3690: 20 70 74 73 22 29 0a 20 20 20 20 20 20 20 20 20   pts").         
36a0: 20 20 20 77 68 69 6c 65 20 74 61 62 6c 65 2e 74     while table.t
36b0: 65 61 6d 31 5f 73 63 6f 72 65 20 3d 3d 20 74 61  eam1_score == ta
36c0: 62 6c 65 2e 74 65 61 6d 32 5f 73 63 6f 72 65 3a  ble.team2_score:
36d0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
36e0: 20 6c 6f 67 28 27 61 6c 6c 27 2c 20 66 22 7b 74   log('all', f"{t
36f0: 61 62 6c 65 7d 20 68 61 76 69 6e 67 20 61 20 72  able} having a r
3700: 6f 6c 6c 2d 6f 66 66 20 74 6f 20 72 65 73 6f 6c  oll-off to resol
3710: 76 65 20 61 20 74 69 65 22 29 0a 20 20 20 20 20  ve a tie").     
3720: 20 20 20 20 20 20 20 20 20 20 20 74 61 62 6c 65             table
3730: 2e 72 6f 6c 6c 5f 6f 66 66 28 29 0a 20 20 20 20  .roll_off().    
3740: 20 20 20 20 20 20 20 20 20 20 20 20 6c 6f 67 28              log(
3750: 27 61 6c 6c 27 2c 20 66 22 7b 74 61 62 6c 65 7d  'all', f"{table}
3760: 3a 20 54 65 61 6d 20 31 20 7b 74 61 62 6c 65 2e  : Team 1 {table.
3770: 74 65 61 6d 31 5f 73 63 6f 72 65 7d 20 70 74 73  team1_score} pts
3780: 2c 20 54 65 61 6d 20 32 20 7b 74 61 62 6c 65 2e  , Team 2 {table.
3790: 74 65 61 6d 32 5f 73 63 6f 72 65 7d 20 70 74 73  team2_score} pts
37a0: 22 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 0a  ").            .
37b0: 20 20 20 20 20 20 20 20 20 20 20 20 74 61 62 6c              tabl
37c0: 65 2e 6e 6f 74 63 68 5f 77 69 6e 73 28 29 0a 20  e.notch_wins(). 
37d0: 20 20 20 20 20 20 20 0a 20 20 20 20 64 65 66 20         .    def 
37e0: 70 72 69 7a 65 73 28 73 65 6c 66 29 3a 0a 20 20  prizes(self):.  
37f0: 20 20 20 20 20 20 70 72 69 7a 65 6c 69 73 74 20        prizelist 
3800: 3d 20 7b 7d 0a 20 20 20 20 20 20 20 20 73 63 6f  = {}.        sco
3810: 72 65 73 20 3d 20 5b 73 75 6d 28 70 2e 72 6f 75  res = [sum(p.rou
3820: 6e 64 5f 73 63 6f 72 65 73 29 20 66 6f 72 20 70  nd_scores) for p
3830: 20 69 6e 20 73 65 6c 66 2e 70 6c 61 79 65 72 73   in self.players
3840: 5d 0a 20 20 20 20 20 20 20 20 77 69 6e 73 20 3d  ].        wins =
3850: 20 5b 73 75 6d 28 70 2e 72 6f 75 6e 64 5f 77 69   [sum(p.round_wi
3860: 6e 73 29 20 66 6f 72 20 70 20 69 6e 20 73 65 6c  ns) for p in sel
3870: 66 2e 70 6c 61 79 65 72 73 5d 0a 20 20 20 20 20  f.players].     
3880: 20 20 20 6c 6f 73 73 65 73 20 3d 20 5b 47 61 6d     losses = [Gam
3890: 65 2e 63 75 72 72 65 6e 74 5f 72 6f 75 6e 64 28  e.current_round(
38a0: 29 20 2d 20 77 20 66 6f 72 20 77 20 69 6e 20 77  ) - w for w in w
38b0: 69 6e 73 5d 0a 20 20 20 20 20 20 20 20 62 75 6e  ins].        bun
38c0: 63 6f 73 20 3d 20 5b 73 75 6d 28 70 2e 72 6f 75  cos = [sum(p.rou
38d0: 6e 64 5f 62 75 6e 63 6f 5f 63 6f 75 6e 74 73 29  nd_bunco_counts)
38e0: 20 66 6f 72 20 70 20 69 6e 20 73 65 6c 66 2e 70   for p in self.p
38f0: 6c 61 79 65 72 73 5d 0a 20 20 20 20 20 20 20 20  layers].        
3900: 63 6f 6e 74 72 69 62 5f 70 63 74 73 20 3d 20 5b  contrib_pcts = [
3910: 70 2e 61 76 65 72 61 67 65 5f 63 6f 6e 74 72 69  p.average_contri
3920: 62 5f 70 63 74 28 29 20 66 6f 72 20 70 20 69 6e  b_pct() for p in
3930: 20 73 65 6c 66 2e 70 6c 61 79 65 72 73 5d 0a 20   self.players]. 
3940: 20 20 20 20 20 20 20 72 6f 6c 6c 73 20 3d 20 5b         rolls = [
3950: 73 75 6d 28 70 2e 72 6f 75 6e 64 5f 72 6f 6c 6c  sum(p.round_roll
3960: 5f 63 6f 75 6e 74 73 29 20 66 6f 72 20 70 20 69  _counts) for p i
3970: 6e 20 73 65 6c 66 2e 70 6c 61 79 65 72 73 5d 0a  n self.players].
3980: 20 20 20 20 20 20 20 20 73 74 72 65 61 6b 73 20          streaks 
3990: 3d 20 5b 70 2e 6d 61 78 5f 73 74 72 65 61 6b 20  = [p.max_streak 
39a0: 66 6f 72 20 70 20 69 6e 20 73 65 6c 66 2e 70 6c  for p in self.pl
39b0: 61 79 65 72 73 5d 0a 20 20 20 20 20 20 20 20 66  ayers].        f
39c0: 75 7a 7a 79 5f 73 74 72 65 61 6b 73 20 3d 20 5b  uzzy_streaks = [
39d0: 70 2e 6d 61 78 5f 66 75 7a 7a 79 64 69 65 5f 73  p.max_fuzzydie_s
39e0: 74 72 65 61 6b 20 66 6f 72 20 70 20 69 6e 20 73  treak for p in s
39f0: 65 6c 66 2e 70 6c 61 79 65 72 73 5d 0a 20 20 20  elf.players].   
3a00: 20 20 20 20 20 61 76 67 5f 64 69 66 66 73 20 3d       avg_diffs =
3a10: 20 5b 73 75 6d 28 70 2e 72 6f 75 6e 64 5f 73 63   [sum(p.round_sc
3a20: 6f 72 65 73 29 20 2d 20 73 65 6c 66 2e 61 76 65  ores) - self.ave
3a30: 72 61 67 65 5f 74 6f 74 61 6c 5f 73 63 6f 72 65  rage_total_score
3a40: 28 29 20 66 6f 72 20 70 20 69 6e 20 73 65 6c 66  () for p in self
3a50: 2e 70 6c 61 79 65 72 73 5d 0a 20 20 20 20 20 20  .players].      
3a60: 20 20 6d 65 64 69 61 6e 5f 64 69 66 66 73 20 3d    median_diffs =
3a70: 20 5b 73 75 6d 28 70 2e 72 6f 75 6e 64 5f 73 63   [sum(p.round_sc
3a80: 6f 72 65 73 29 20 2d 20 73 65 6c 66 2e 6d 65 64  ores) - self.med
3a90: 69 61 6e 5f 74 6f 74 61 6c 5f 73 63 6f 72 65 28  ian_total_score(
3aa0: 29 20 66 6f 72 20 70 20 69 6e 20 73 65 6c 66 2e  ) for p in self.
3ab0: 70 6c 61 79 65 72 73 5d 0a 20 20 20 20 20 20 20  players].       
3ac0: 20 73 6d 61 6c 6c 65 73 74 5f 61 76 67 5f 64 69   smallest_avg_di
3ad0: 66 66 20 3d 20 61 76 67 5f 64 69 66 66 73 5b 6c  ff = avg_diffs[l
3ae0: 69 73 74 28 6d 61 70 28 61 62 73 2c 61 76 67 5f  ist(map(abs,avg_
3af0: 64 69 66 66 73 29 29 2e 69 6e 64 65 78 28 6d 69  diffs)).index(mi
3b00: 6e 28 6c 69 73 74 28 6d 61 70 28 61 62 73 2c 61  n(list(map(abs,a
3b10: 76 67 5f 64 69 66 66 73 29 29 29 29 5d 0a 20 20  vg_diffs))))].  
3b20: 20 20 20 20 20 20 73 6d 61 6c 6c 65 73 74 5f 6d        smallest_m
3b30: 65 64 69 61 6e 5f 64 69 66 66 20 3d 20 6d 65 64  edian_diff = med
3b40: 69 61 6e 5f 64 69 66 66 73 5b 6c 69 73 74 28 6d  ian_diffs[list(m
3b50: 61 70 28 61 62 73 2c 6d 65 64 69 61 6e 5f 64 69  ap(abs,median_di
3b60: 66 66 73 29 29 2e 69 6e 64 65 78 28 6d 69 6e 28  ffs)).index(min(
3b70: 6c 69 73 74 28 6d 61 70 28 61 62 73 2c 6d 65 64  list(map(abs,med
3b80: 69 61 6e 5f 64 69 66 66 73 29 29 29 29 5d 0a 0a  ian_diffs))))]..
3b90: 20 20 20 20 20 20 20 20 23 20 42 75 69 6c 64 20          # Build 
3ba0: 61 20 6c 69 73 74 20 6f 66 20 70 72 69 7a 65 73  a list of prizes
3bb0: 20 61 6e 64 20 77 69 6e 6e 65 72 73 2c 20 61 6c   and winners, al
3bc0: 6c 6f 77 69 6e 67 20 66 6f 72 20 74 69 65 73 0a  lowing for ties.
3bd0: 20 20 20 20 20 20 20 20 70 72 69 7a 65 6c 69 73          prizelis
3be0: 74 5b 22 48 69 67 68 65 73 74 20 53 63 6f 72 65  t["Highest Score
3bf0: 22 5d 20 3d 20 66 22 7b 27 2c 20 27 2e 6a 6f 69  "] = f"{', '.joi
3c00: 6e 28 5b 73 74 72 28 70 29 20 66 6f 72 20 70 20  n([str(p) for p 
3c10: 69 6e 20 73 65 6c 66 2e 70 6c 61 79 65 72 73 20  in self.players 
3c20: 69 66 20 73 75 6d 28 70 2e 72 6f 75 6e 64 5f 73  if sum(p.round_s
3c30: 63 6f 72 65 73 29 20 3d 3d 20 6d 61 78 28 73 63  cores) == max(sc
3c40: 6f 72 65 73 29 5d 29 7d 20 28 7b 6d 61 78 28 73  ores)])} ({max(s
3c50: 63 6f 72 65 73 29 7d 29 22 0a 20 20 20 20 20 20  cores)})".      
3c60: 20 20 70 72 69 7a 65 6c 69 73 74 5b 22 4c 6f 77    prizelist["Low
3c70: 65 73 74 20 53 63 6f 72 65 22 5d 20 3d 20 66 22  est Score"] = f"
3c80: 7b 27 2c 20 27 2e 6a 6f 69 6e 28 5b 73 74 72 28  {', '.join([str(
3c90: 70 29 20 66 6f 72 20 70 20 69 6e 20 73 65 6c 66  p) for p in self
3ca0: 2e 70 6c 61 79 65 72 73 20 69 66 20 73 75 6d 28  .players if sum(
3cb0: 70 2e 72 6f 75 6e 64 5f 73 63 6f 72 65 73 29 20  p.round_scores) 
3cc0: 3d 3d 20 6d 69 6e 28 73 63 6f 72 65 73 29 5d 29  == min(scores)])
3cd0: 7d 20 28 7b 6d 69 6e 28 73 63 6f 72 65 73 29 7d  } ({min(scores)}
3ce0: 29 22 0a 20 20 20 20 20 20 20 20 70 72 69 7a 65  )".        prize
3cf0: 6c 69 73 74 5b 22 4d 6f 73 74 20 57 69 6e 73 22  list["Most Wins"
3d00: 5d 20 3d 20 66 22 7b 27 2c 20 27 2e 6a 6f 69 6e  ] = f"{', '.join
3d10: 28 5b 73 74 72 28 70 29 20 66 6f 72 20 70 20 69  ([str(p) for p i
3d20: 6e 20 73 65 6c 66 2e 70 6c 61 79 65 72 73 20 69  n self.players i
3d30: 66 20 73 75 6d 28 70 2e 72 6f 75 6e 64 5f 77 69  f sum(p.round_wi
3d40: 6e 73 29 20 3d 3d 20 6d 61 78 28 77 69 6e 73 29  ns) == max(wins)
3d50: 5d 29 7d 20 28 7b 6d 61 78 28 77 69 6e 73 29 7d  ])} ({max(wins)}
3d60: 29 22 0a 20 20 20 20 20 20 20 20 70 72 69 7a 65  )".        prize
3d70: 6c 69 73 74 5b 22 4d 6f 73 74 20 4c 6f 73 73 65  list["Most Losse
3d80: 73 22 5d 20 3d 20 66 22 7b 27 2c 20 27 2e 6a 6f  s"] = f"{', '.jo
3d90: 69 6e 28 5b 73 74 72 28 70 29 20 66 6f 72 20 70  in([str(p) for p
3da0: 20 69 6e 20 73 65 6c 66 2e 70 6c 61 79 65 72 73   in self.players
3db0: 20 69 66 20 47 61 6d 65 2e 63 75 72 72 65 6e 74   if Game.current
3dc0: 5f 72 6f 75 6e 64 28 29 20 2d 20 73 75 6d 28 70  _round() - sum(p
3dd0: 2e 72 6f 75 6e 64 5f 77 69 6e 73 29 20 3d 3d 20  .round_wins) == 
3de0: 6d 61 78 28 6c 6f 73 73 65 73 29 5d 29 7d 20 28  max(losses)])} (
3df0: 7b 6d 61 78 28 6c 6f 73 73 65 73 29 7d 29 22 0a  {max(losses)})".
3e00: 20 20 20 20 20 20 20 20 70 72 69 7a 65 6c 69 73          prizelis
3e10: 74 5b 22 4d 6f 73 74 20 42 75 6e 63 6f 73 22 5d  t["Most Buncos"]
3e20: 20 3d 20 66 22 7b 27 2c 20 27 2e 6a 6f 69 6e 28   = f"{', '.join(
3e30: 5b 73 74 72 28 70 29 20 66 6f 72 20 70 20 69 6e  [str(p) for p in
3e40: 20 73 65 6c 66 2e 70 6c 61 79 65 72 73 20 69 66   self.players if
3e50: 20 73 75 6d 28 70 2e 72 6f 75 6e 64 5f 62 75 6e   sum(p.round_bun
3e60: 63 6f 5f 63 6f 75 6e 74 73 29 20 3d 3d 20 6d 61  co_counts) == ma
3e70: 78 28 62 75 6e 63 6f 73 29 5d 29 7d 20 28 7b 6d  x(buncos)])} ({m
3e80: 61 78 28 62 75 6e 63 6f 73 29 7d 29 22 0a 20 20  ax(buncos)})".  
3e90: 20 20 20 20 20 20 70 72 69 7a 65 6c 69 73 74 5b        prizelist[
3ea0: 22 48 69 67 68 65 73 74 20 54 65 61 6d 20 43 6f  "Highest Team Co
3eb0: 6e 74 72 69 62 75 74 6f 72 22 5d 20 3d 20 66 22  ntributor"] = f"
3ec0: 7b 27 2c 20 27 2e 6a 6f 69 6e 28 5b 73 74 72 28  {', '.join([str(
3ed0: 70 29 20 66 6f 72 20 70 20 69 6e 20 73 65 6c 66  p) for p in self
3ee0: 2e 70 6c 61 79 65 72 73 20 69 66 20 70 2e 61 76  .players if p.av
3ef0: 65 72 61 67 65 5f 63 6f 6e 74 72 69 62 5f 70 63  erage_contrib_pc
3f00: 74 28 29 20 3d 3d 20 6d 61 78 28 63 6f 6e 74 72  t() == max(contr
3f10: 69 62 5f 70 63 74 73 29 5d 29 7d 20 28 7b 6d 61  ib_pcts)])} ({ma
3f20: 78 28 63 6f 6e 74 72 69 62 5f 70 63 74 73 29 3a  x(contrib_pcts):
3f30: 2e 32 25 7d 29 22 0a 20 20 20 20 20 20 20 20 70  .2%})".        p
3f40: 72 69 7a 65 6c 69 73 74 5b 22 4d 6f 73 74 20 52  rizelist["Most R
3f50: 6f 6c 6c 73 22 5d 20 3d 20 66 22 7b 27 2c 20 27  olls"] = f"{', '
3f60: 2e 6a 6f 69 6e 28 5b 73 74 72 28 70 29 20 66 6f  .join([str(p) fo
3f70: 72 20 70 20 69 6e 20 73 65 6c 66 2e 70 6c 61 79  r p in self.play
3f80: 65 72 73 20 69 66 20 73 75 6d 28 70 2e 72 6f 75  ers if sum(p.rou
3f90: 6e 64 5f 72 6f 6c 6c 5f 63 6f 75 6e 74 73 29 20  nd_roll_counts) 
3fa0: 3d 3d 20 6d 61 78 28 72 6f 6c 6c 73 29 5d 29 7d  == max(rolls)])}
3fb0: 20 28 7b 6d 61 78 28 72 6f 6c 6c 73 29 7d 29 22   ({max(rolls)})"
3fc0: 0a 20 20 20 20 20 20 20 20 70 72 69 7a 65 6c 69  .        prizeli
3fd0: 73 74 5b 22 4c 6f 6e 67 65 73 74 20 52 6f 6c 6c  st["Longest Roll
3fe0: 20 53 74 72 65 61 6b 22 5d 20 3d 20 66 22 7b 27   Streak"] = f"{'
3ff0: 2c 20 27 2e 6a 6f 69 6e 28 5b 73 74 72 28 70 29  , '.join([str(p)
4000: 20 66 6f 72 20 70 20 69 6e 20 73 65 6c 66 2e 70   for p in self.p
4010: 6c 61 79 65 72 73 20 69 66 20 70 2e 6d 61 78 5f  layers if p.max_
4020: 73 74 72 65 61 6b 20 3d 3d 20 6d 61 78 28 73 74  streak == max(st
4030: 72 65 61 6b 73 29 5d 29 7d 20 28 7b 6d 61 78 28  reaks)])} ({max(
4040: 73 74 72 65 61 6b 73 29 7d 29 22 0a 20 20 20 20  streaks)})".    
4050: 20 20 20 20 70 72 69 7a 65 6c 69 73 74 5b 22 46      prizelist["F
4060: 65 77 65 73 74 20 52 6f 6c 6c 73 22 5d 20 3d 20  ewest Rolls"] = 
4070: 66 22 7b 27 2c 20 27 2e 6a 6f 69 6e 28 5b 73 74  f"{', '.join([st
4080: 72 28 70 29 20 66 6f 72 20 70 20 69 6e 20 73 65  r(p) for p in se
4090: 6c 66 2e 70 6c 61 79 65 72 73 20 69 66 20 73 75  lf.players if su
40a0: 6d 28 70 2e 72 6f 75 6e 64 5f 72 6f 6c 6c 5f 63  m(p.round_roll_c
40b0: 6f 75 6e 74 73 29 20 3d 3d 20 6d 69 6e 28 72 6f  ounts) == min(ro
40c0: 6c 6c 73 29 5d 29 7d 20 28 7b 6d 69 6e 28 72 6f  lls)])} ({min(ro
40d0: 6c 6c 73 29 7d 29 22 0a 20 20 20 20 20 20 20 20  lls)})".        
40e0: 70 72 69 7a 65 6c 69 73 74 5b 22 4c 61 73 74 20  prizelist["Last 
40f0: 46 75 7a 7a 79 20 44 69 65 20 48 6f 6c 64 65 72  Fuzzy Die Holder
4100: 22 5d 20 3d 20 66 75 7a 7a 79 64 69 65 5f 68 6f  "] = fuzzydie_ho
4110: 6c 64 65 72 2e 6e 61 6d 65 0a 20 20 20 20 20 20  lder.name.      
4120: 20 20 70 72 69 7a 65 6c 69 73 74 5b 22 4c 6f 6e    prizelist["Lon
4130: 67 65 73 74 20 54 69 6d 65 20 77 69 74 68 20 46  gest Time with F
4140: 75 7a 7a 79 20 44 69 65 22 5d 20 3d 20 66 22 7b  uzzy Die"] = f"{
4150: 27 2c 20 27 2e 6a 6f 69 6e 28 5b 73 74 72 28 70  ', '.join([str(p
4160: 29 20 66 6f 72 20 70 20 69 6e 20 73 65 6c 66 2e  ) for p in self.
4170: 70 6c 61 79 65 72 73 20 69 66 20 70 2e 6d 61 78  players if p.max
4180: 5f 66 75 7a 7a 79 64 69 65 5f 73 74 72 65 61 6b  _fuzzydie_streak
4190: 20 3d 3d 20 6d 61 78 28 66 75 7a 7a 79 5f 73 74   == max(fuzzy_st
41a0: 72 65 61 6b 73 29 5d 29 7d 20 28 7b 6d 61 78 28  reaks)])} ({max(
41b0: 66 75 7a 7a 79 5f 73 74 72 65 61 6b 73 29 7d 29  fuzzy_streaks)})
41c0: 22 0a 20 20 20 20 20 20 20 20 70 72 69 7a 65 6c  ".        prizel
41d0: 69 73 74 5b 22 4d 6f 73 74 20 41 76 65 72 61 67  ist["Most Averag
41e0: 65 20 54 6f 74 61 6c 20 53 63 6f 72 65 22 5d 20  e Total Score"] 
41f0: 3d 20 66 22 7b 27 2c 20 27 2e 6a 6f 69 6e 28 5b  = f"{', '.join([
4200: 73 74 72 28 70 29 20 66 6f 72 20 70 20 69 6e 20  str(p) for p in 
4210: 73 65 6c 66 2e 70 6c 61 79 65 72 73 20 69 66 20  self.players if 
4220: 61 62 73 28 73 75 6d 28 70 2e 72 6f 75 6e 64 5f  abs(sum(p.round_
4230: 73 63 6f 72 65 73 29 20 2d 20 73 65 6c 66 2e 61  scores) - self.a
4240: 76 65 72 61 67 65 5f 74 6f 74 61 6c 5f 73 63 6f  verage_total_sco
4250: 72 65 28 29 29 20 3d 3d 20 61 62 73 28 73 6d 61  re()) == abs(sma
4260: 6c 6c 65 73 74 5f 61 76 67 5f 64 69 66 66 29 5d  llest_avg_diff)]
4270: 29 7d 20 28 7b 73 6d 61 6c 6c 65 73 74 5f 61 76  )} ({smallest_av
4280: 67 5f 64 69 66 66 7d 29 22 0a 20 20 20 20 20 20  g_diff})".      
4290: 20 20 70 72 69 7a 65 6c 69 73 74 5b 22 43 6c 6f    prizelist["Clo
42a0: 73 65 73 74 20 74 6f 20 4d 65 64 69 61 6e 20 54  sest to Median T
42b0: 6f 74 61 6c 20 53 63 6f 72 65 22 5d 20 3d 20 66  otal Score"] = f
42c0: 22 7b 27 2c 20 27 2e 6a 6f 69 6e 28 5b 73 74 72  "{', '.join([str
42d0: 28 70 29 20 66 6f 72 20 70 20 69 6e 20 73 65 6c  (p) for p in sel
42e0: 66 2e 70 6c 61 79 65 72 73 20 69 66 20 61 62 73  f.players if abs
42f0: 28 73 75 6d 28 70 2e 72 6f 75 6e 64 5f 73 63 6f  (sum(p.round_sco
4300: 72 65 73 29 20 2d 20 73 65 6c 66 2e 6d 65 64 69  res) - self.medi
4310: 61 6e 5f 74 6f 74 61 6c 5f 73 63 6f 72 65 28 29  an_total_score()
4320: 29 20 3d 3d 20 61 62 73 28 73 6d 61 6c 6c 65 73  ) == abs(smalles
4330: 74 5f 6d 65 64 69 61 6e 5f 64 69 66 66 29 5d 29  t_median_diff)])
4340: 7d 20 28 7b 73 6d 61 6c 6c 65 73 74 5f 6d 65 64  } ({smallest_med
4350: 69 61 6e 5f 64 69 66 66 7d 29 22 0a 0a 20 20 20  ian_diff})"..   
4360: 20 20 20 20 20 72 65 74 75 72 6e 20 70 72 69 7a       return priz
4370: 65 6c 69 73 74 0a 20 20 20 20 0a 6c 6f 67 5f 64  elist.    .log_d
4380: 62 20 3d 20 73 71 6c 69 74 65 33 2e 63 6f 6e 6e  b = sqlite3.conn
4390: 65 63 74 28 22 62 75 6e 63 6f 2e 73 71 6c 69 74  ect("bunco.sqlit
43a0: 65 22 29 0a 6c 6f 67 5f 64 62 63 20 3d 20 6c 6f  e").log_dbc = lo
43b0: 67 5f 64 62 2e 63 75 72 73 6f 72 28 29 0a 0a 64  g_db.cursor()..d
43c0: 65 66 20 72 75 6e 5f 71 75 65 72 79 28 2a 61 72  ef run_query(*ar
43d0: 67 73 29 3a 0a 20 20 20 20 6c 6f 67 5f 64 62 63  gs):.    log_dbc
43e0: 2e 65 78 65 63 75 74 65 28 2a 61 72 67 73 29 0a  .execute(*args).
43f0: 20 20 20 20 6c 6f 67 5f 64 62 2e 63 6f 6d 6d 69      log_db.commi
4400: 74 28 29 0a 0a 72 75 6e 5f 71 75 65 72 79 28 27  t()..run_query('
4410: 44 52 4f 50 20 54 41 42 4c 45 20 49 46 20 45 58  DROP TABLE IF EX
4420: 49 53 54 53 20 60 62 75 6e 63 6f 5f 6c 6f 67 60  ISTS `bunco_log`
4430: 27 29 0a 72 75 6e 5f 71 75 65 72 79 28 27 43 52  ').run_query('CR
4440: 45 41 54 45 20 54 41 42 4c 45 20 60 62 75 6e 63  EATE TABLE `bunc
4450: 6f 5f 6c 6f 67 60 20 28 69 64 20 50 52 49 4d 41  o_log` (id PRIMA
4460: 52 59 20 4b 45 59 2c 20 74 69 63 6b 5f 6e 75 6d  RY KEY, tick_num
4470: 62 65 72 2c 20 72 6f 75 6e 64 2c 20 70 6c 61 79  ber, round, play
4480: 65 72 5f 6e 61 6d 65 2c 20 74 79 70 65 2c 20 6d  er_name, type, m
4490: 65 73 73 61 67 65 29 27 29 0a 0a 64 65 66 20 6c  essage)')..def l
44a0: 6f 67 5f 72 6f 6c 6c 28 70 6c 61 79 65 72 2c 20  og_roll(player, 
44b0: 64 69 63 65 2c 20 73 63 6f 72 65 29 3a 0a 20 20  dice, score):.  
44c0: 20 20 6d 73 67 20 3d 20 66 22 7b 70 6c 61 79 65    msg = f"{playe
44d0: 72 2e 6e 61 6d 65 7d 20 63 6f 6d 70 72 65 68 65  r.name} comprehe
44e0: 6e 64 65 64 20 74 68 61 74 20 5b 74 68 65 69 72  nded that [their
44f0: 5d 20 72 6f 6c 6c 20 6f 66 20 7b 64 69 63 65 7d  ] roll of {dice}
4500: 20 3d 20 7b 73 63 6f 72 65 7d 20 70 6f 69 6e 74   = {score} point
4510: 73 22 0a 20 20 20 20 71 75 65 72 79 20 3d 20 22  s".    query = "
4520: 22 22 49 4e 53 45 52 54 20 49 4e 54 4f 20 62 75  ""INSERT INTO bu
4530: 6e 63 6f 5f 6c 6f 67 28 74 69 63 6b 5f 6e 75 6d  nco_log(tick_num
4540: 62 65 72 2c 20 72 6f 75 6e 64 2c 20 70 6c 61 79  ber, round, play
4550: 65 72 5f 6e 61 6d 65 2c 20 74 79 70 65 2c 20 6d  er_name, type, m
4560: 65 73 73 61 67 65 29 20 0a 20 20 20 20 20 20 20  essage) .       
4570: 20 20 20 20 20 20 20 20 20 56 41 4c 55 45 53 28           VALUES(
4580: 3f 2c 20 3f 2c 20 3f 2c 20 3f 2c 20 3f 29 22 22  ?, ?, ?, ?, ?)""
4590: 22 0a 20 20 20 20 72 75 6e 5f 71 75 65 72 79 28  ".    run_query(
45a0: 71 75 65 72 79 2c 20 28 47 61 6d 65 2e 63 75 72  query, (Game.cur
45b0: 72 65 6e 74 5f 74 69 63 6b 28 29 2c 20 47 61 6d  rent_tick(), Gam
45c0: 65 2e 63 75 72 72 65 6e 74 5f 72 6f 75 6e 64 28  e.current_round(
45d0: 29 2c 20 73 74 72 28 70 6c 61 79 65 72 29 2c 20  ), str(player), 
45e0: 27 72 6f 6c 6c 27 2c 20 6d 73 67 29 29 0a 0a 64  'roll', msg))..d
45f0: 65 66 20 6c 6f 67 5f 74 61 62 6c 65 5f 6d 6f 76  ef log_table_mov
4600: 65 28 70 6c 61 79 65 72 73 2c 20 72 65 61 73 6f  e(players, reaso
4610: 6e 2c 20 74 61 62 6c 65 5f 66 72 6f 6d 2c 20 74  n, table_from, t
4620: 61 62 6c 65 5f 74 6f 29 3a 0a 20 20 20 20 6d 65  able_to):.    me
4630: 73 73 61 67 65 20 3d 20 66 22 48 61 76 69 6e 67  ssage = f"Having
4640: 20 7b 72 65 61 73 6f 6e 7d 20 74 68 65 20 6c 61   {reason} the la
4650: 73 74 20 72 6f 75 6e 64 2c 20 7b 70 6c 61 79 65  st round, {playe
4660: 72 73 5b 30 5d 2e 6e 61 6d 65 7d 20 61 6e 64 20  rs[0].name} and 
4670: 7b 70 6c 61 79 65 72 73 5b 31 5d 2e 6e 61 6d 65  {players[1].name
4680: 7d 20 6d 6f 76 65 20 66 72 6f 6d 20 7b 74 61 62  } move from {tab
4690: 6c 65 5f 66 72 6f 6d 7d 20 74 6f 20 7b 74 61 62  le_from} to {tab
46a0: 6c 65 5f 74 6f 7d 2e 22 0a 20 20 20 20 71 75 65  le_to}.".    que
46b0: 72 79 20 3d 20 22 22 22 49 4e 53 45 52 54 20 49  ry = """INSERT I
46c0: 4e 54 4f 20 62 75 6e 63 6f 5f 6c 6f 67 28 74 69  NTO bunco_log(ti
46d0: 63 6b 5f 6e 75 6d 62 65 72 2c 20 72 6f 75 6e 64  ck_number, round
46e0: 2c 20 70 6c 61 79 65 72 5f 6e 61 6d 65 2c 20 74  , player_name, t
46f0: 79 70 65 2c 20 6d 65 73 73 61 67 65 29 20 0a 20  ype, message) . 
4700: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 56                 V
4710: 41 4c 55 45 53 28 3f 2c 20 3f 2c 20 3f 2c 20 3f  ALUES(?, ?, ?, ?
4720: 2c 20 3f 29 22 22 22 0a 20 20 20 20 72 75 6e 5f  , ?)""".    run_
4730: 71 75 65 72 79 28 71 75 65 72 79 2c 20 28 47 61  query(query, (Ga
4740: 6d 65 2e 63 75 72 72 65 6e 74 5f 74 69 63 6b 28  me.current_tick(
4750: 29 2c 20 47 61 6d 65 2e 63 75 72 72 65 6e 74 5f  ), Game.current_
4760: 72 6f 75 6e 64 28 29 2c 20 27 61 6c 6c 27 2c 20  round(), 'all', 
4770: 27 67 65 6e 65 72 61 6c 27 2c 20 6d 65 73 73 61  'general', messa
4780: 67 65 29 29 0a 0a 64 65 66 20 6c 6f 67 28 70 6c  ge))..def log(pl
4790: 61 79 65 72 2c 20 6d 65 73 73 61 67 65 29 3a 0a  ayer, message):.
47a0: 20 20 20 20 71 75 65 72 79 20 3d 20 22 22 22 49      query = """I
47b0: 4e 53 45 52 54 20 49 4e 54 4f 20 62 75 6e 63 6f  NSERT INTO bunco
47c0: 5f 6c 6f 67 28 74 69 63 6b 5f 6e 75 6d 62 65 72  _log(tick_number
47d0: 2c 20 72 6f 75 6e 64 2c 20 70 6c 61 79 65 72 5f  , round, player_
47e0: 6e 61 6d 65 2c 20 74 79 70 65 2c 20 6d 65 73 73  name, type, mess
47f0: 61 67 65 29 20 0a 20 20 20 20 20 20 20 20 20 20  age) .          
4800: 20 20 20 20 20 20 56 41 4c 55 45 53 28 3f 2c 20        VALUES(?, 
4810: 3f 2c 20 3f 2c 20 3f 2c 20 3f 29 22 22 22 0a 20  ?, ?, ?, ?)""". 
4820: 20 20 20 72 75 6e 5f 71 75 65 72 79 28 71 75 65     run_query(que
4830: 72 79 2c 20 28 47 61 6d 65 2e 63 75 72 72 65 6e  ry, (Game.curren
4840: 74 5f 74 69 63 6b 28 29 2c 20 47 61 6d 65 2e 63  t_tick(), Game.c
4850: 75 72 72 65 6e 74 5f 72 6f 75 6e 64 28 29 2c 20  urrent_round(), 
4860: 73 74 72 28 70 6c 61 79 65 72 29 2c 20 27 67 65  str(player), 'ge
4870: 6e 65 72 61 6c 27 2c 20 6d 65 73 73 61 67 65 29  neral', message)
4880: 29 0a                                            ).