Bunco Simulator

Check-in [341cdc]
Overview
Comment:Send SMS updates to players with phone numbers (closes [245ddedf96])
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 341cdc9adcc2a27d7d7db8e69044e7126edbd66193f5ef6fa6600f4a9507bde1
User & Date: joel on 2018-11-22 22:26:42
Original Comment: Send SMS updates to players with phone numbers (closes [30cde4e9a1])
Other Links: manifest | tags
References
2018-11-22
22:28 Closed ticket [245dde]: Ability to send SMS to players with results of each round plus 4 other changes artifact: 7d4abe user: joel
Context
2018-11-23
20:29
Ignore archive folder check-in: d0bc5a user: joel tags: trunk
2018-11-22
22:26
Send SMS updates to players with phone numbers (closes [245ddedf96]) check-in: 341cdc user: joel tags: trunk
17:49
Update ignore-glob check-in: a1e1f8 user: joel tags: trunk
Changes

Modified bunco.py from [bbae10] to [a97ef9].

1
2
3
4
5
6
7
8


9
10
11
12
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
# Test
import csv, random, sqlite3
from statistics import median

teammate_lookup = { 0: 2, 1: 3, 2: 0, 3: 1 }

fuzzydie_holder = 'x'



def TurnInProgress():
    return -1

def roll_dice():
    dice = []
    for _ in range(3):
        dice.append(random.randint(1,6))
    return dice

class Player:
    def __init__(self, name, dex, math, speed):
        self.name = name

        self.dex = dex
        self.math_comprehension = math
        self.roll_speed = speed
        self.max_streak = 0
        self.round_bunco_counts = [0]
        self.round_scores = [0]
        self.round_roll_counts = [0]








>
>










|

>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Test
import csv, random, sqlite3
from statistics import median

teammate_lookup = { 0: 2, 1: 3, 2: 0, 3: 1 }

fuzzydie_holder = 'x'

table_move_callback = None

def TurnInProgress():
    return -1

def roll_dice():
    dice = []
    for _ in range(3):
        dice.append(random.randint(1,6))
    return dice

class Player:
    def __init__(self, name, phone, dex, math, speed):
        self.name = name
        self.smsnumber = phone
        self.dex = dex
        self.math_comprehension = math
        self.roll_speed = speed
        self.max_streak = 0
        self.round_bunco_counts = [0]
        self.round_scores = [0]
        self.round_roll_counts = [0]
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283

def load_players(filename):
    players = []

    with open(filename) as tsvfile:
        tsvreader = csv.reader(tsvfile)
        for line in tsvreader:
            players.append(Player(line[0],0,0,0))
    
    return players

class Game:
    cur_tick = 1
    cur_round = 1
    







|







272
273
274
275
276
277
278
279
280
281
282
283
284
285
286

def load_players(filename):
    players = []

    with open(filename) as tsvfile:
        tsvreader = csv.reader(tsvfile)
        for line in tsvreader:
            players.append(Player(line[0],line[1],0,0,0))
    
    return players

class Game:
    cur_tick = 1
    cur_round = 1
    
349
350
351
352
353
354
355



356
357
358
359
360



361
362
363
364



365
366
367
368
369
370
371
        
        return median(all_scores)

    def prep_next_round(self):
        # losers from head table move to next table
        headtable_losers = self.tables[0].losers()
        log_table_move(headtable_losers, "lost", self.tables[0], self.tables[1])



        round_winners = self.tables[1].swap_for_winners(headtable_losers)

        # winners from other tables move to next table
        for n in range(2, len(self.tables)):
            log_table_move(round_winners, "won", self.tables[n-1], self.tables[n])



            round_winners = self.tables[n].swap_for_winners(round_winners)
        
        # last set of winners moves to head table
        log_table_move(round_winners, "won", self.tables[-1], self.tables[0])



        self.tables[0].swap_for_losers(round_winners)

        for table in self.tables:
            table.prep_new_round()

        self.increment_round()








>
>
>





>
>
>




>
>
>







352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
        
        return median(all_scores)

    def prep_next_round(self):
        # losers from head table move to next table
        headtable_losers = self.tables[0].losers()
        log_table_move(headtable_losers, "lost", self.tables[0], self.tables[1])
        if callable(table_move_callback):
            for player in headtable_losers:
                table_move_callback(player, "lost", self.tables[0], self.tables[1])
        round_winners = self.tables[1].swap_for_winners(headtable_losers)

        # winners from other tables move to next table
        for n in range(2, len(self.tables)):
            log_table_move(round_winners, "won", self.tables[n-1], self.tables[n])
            if callable(table_move_callback):
                for player in round_winners:
                    table_move_callback(player, "won", self.tables[n-1], self.tables[n])
            round_winners = self.tables[n].swap_for_winners(round_winners)
        
        # last set of winners moves to head table
        log_table_move(round_winners, "won", self.tables[-1], self.tables[0])
        if callable(table_move_callback):
            for player in round_winners:
                table_move_callback(player, "won", self.tables[-1], self.tables[0])
        self.tables[0].swap_for_losers(round_winners)

        for table in self.tables:
            table.prep_new_round()

        self.increment_round()

Modified bunco_app.py from [36d781] to [4468a7].

1
2

3

4
5
6
7



8
9
10
11
12
13
14









15
16
17
18
19
20
21
import bunco
import xlsxwriter

from blessings import Terminal


t = Terminal()
g = bunco.Game("players.csv")




def plural(str,n,suffix="s"):
    return str + suffix if n > 1 else str

def print_center(before, string, after):
    col = int((t.width - len(string)) / 2) - 1
    print(f"{t.move_x(col)}{before}{string}{after}")










def display_dashboard():
    print(t.clear,t.move(0,0))
    print_center(t.bold_red,"B U N C O   S I M U L A T O R", t.normal)
    print(f"{t.red}{'-'*t.width}{t.normal}\n")
    
    # Print column headings for rounds
    rounds = [str(n + 1).rjust(4) for n in range(g.current_round())]


>

>




>
>
>







>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import bunco
import xlsxwriter
import creds # local
from blessings import Terminal
from twilio.rest import Client

t = Terminal()
g = bunco.Game("players.csv")

enable_sms = False
last_status = 'Off to a great start!'

def plural(str,n,suffix="s"):
    return str + suffix if n > 1 else str

def print_center(before, string, after):
    col = int((t.width - len(string)) / 2) - 1
    print(f"{t.move_x(col)}{before}{string}{after}")

def status(text):
    global last_status
    row = 6 + (len(g.tables) * 5)
    print(t.move(row, 0), end='')
    print(t.clear_eol, end='')
    print_center(f"{t.bold_green}",f"[ {text} ]", t.normal)
    print(t.clear_eos)
    last_status = text

def display_dashboard():
    print(t.clear,t.move(0,0))
    print_center(t.bold_red,"B U N C O   S I M U L A T O R", t.normal)
    print(f"{t.red}{'-'*t.width}{t.normal}\n")
    
    # Print column headings for rounds
    rounds = [str(n + 1).rjust(4) for n in range(g.current_round())]
29
30
31
32
33
34
35

36

37





38
39
40
41
42
43
44
45
46
47





48
49
50
51
52
53
54
            if player is bunco.fuzzydie_holder:
                print(f"🎲",end='')
            print(f"{t.move_x(3)}{t.cyan}{player}{t.normal}",end='')
            for n in range(g.current_round()):
                print(t.move_x(18+(4*n)),end='')
                print(str(player.round_scores[n]).rjust(4),end='')
            print('')



g.play_one_round()





display_dashboard()

def do1():
    g.prep_next_round()
    g.play_one_round()
    display_dashboard()

def summary(n):
    return summary_text(g.players[n])






def summary_text(player):
    for table in g.tables:
        if player in table.players:
            curtable = table
            break
    
    sitch = curtable.get_player_situation(player)







>

>
|
>
>
>
>
>
|
|
<

|
<




>
>
>
>
>







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

61
62

63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
            if player is bunco.fuzzydie_holder:
                print(f"🎲",end='')
            print(f"{t.move_x(3)}{t.cyan}{player}{t.normal}",end='')
            for n in range(g.current_round()):
                print(t.move_x(18+(4*n)),end='')
                print(str(player.round_scores[n]).rjust(4),end='')
            print('')
    status(last_status)

def do1():
    g.play_one_round()
    if enable_sms:
        status("Sending results by SMS to players…")
        for player in g.players:
            sms(player.smsnumber, summary_text(player))
    
    display_dashboard()
    status("Prepping for next round…")

    g.prep_next_round()
    status("Ready for another round!")


def summary(n):
    return summary_text(g.players[n])

def sms(number, message):
    if enable_sms and number:
        cli = Client(creds.SID, creds.token)
        cli.messages.create(to=number, from_=creds.sender, body=message)

def summary_text(player):
    for table in g.tables:
        if player in table.players:
            curtable = table
            break
    
    sitch = curtable.get_player_situation(player)
67
68
69
70
71
72
73







74
75
76
77
78
79
80

    ts = [f"Round {g.current_round()} @ {curtable} with {sitch['teammate']}:",
          f"You made {player.round_roll_counts[g.current_round()-1]} rolls,",
          f"adding {player.personal_roll_scores[g.current_round()-1]} pts{buncos}",
          f"to your team score of {player.round_scores[g.current_round()-1]},",
          f"{winloss} {foe_names}’s score of {sitch['opponent_score']}."]
    return " ".join(ts)








def excel_sheet(title):
    wb = xlsxwriter.Workbook('bunco.xlsx')
    ws = wb.add_worksheet('Overview')
    style = {}

    col_heading = wb.add_format({'font_name': 'Back Issues BB', 







>
>
>
>
>
>
>







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

    ts = [f"Round {g.current_round()} @ {curtable} with {sitch['teammate']}:",
          f"You made {player.round_roll_counts[g.current_round()-1]} rolls,",
          f"adding {player.personal_roll_scores[g.current_round()-1]} pts{buncos}",
          f"to your team score of {player.round_scores[g.current_round()-1]},",
          f"{winloss} {foe_names}’s score of {sitch['opponent_score']}."]
    return " ".join(ts)

def sms_table_move(player, wonlost, table_from, table_to):
    if player.smsnumber:
        message = f"Having {wonlost} the last round, you move from {table_from} to {table_to}."
        sms(player.smsnumber, message)

bunco.table_move_callback = sms_table_move

def excel_sheet(title):
    wb = xlsxwriter.Workbook('bunco.xlsx')
    ws = wb.add_worksheet('Overview')
    style = {}

    col_heading = wb.add_format({'font_name': 'Back Issues BB',