Last active
March 30, 2022 07:09
-
-
Save mdenson-dayspring/adde4b607f575038597abec4cac4c70b to your computer and use it in GitHub Desktop.
Revisions
-
Matthew Denson revised this gist
Mar 30, 2022 . 1 changed file with 38 additions and 44 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -49,51 +49,45 @@ import sys def score_game(pins): return score_frame([], pins) def score_frame(running_score, pins): frame_num = len(running_score) + 1 #terminal cases if len(pins) == 0: return running_score elif frame_num > 10: running_score[9]['pins'].extend(pins) return running_score if frame_num == 1: prev_score = 0 else: prev_score = running_score[len(running_score) - 1]['score'] if len(pins) > 0 and pins[0] == 10: # strike if prev_score == None or len(pins) < 3: score = None else: score = prev_score + pins[0] + pins[1] + pins[2] running_score.append({"frame": frame_num, "pins": pins[:1], "score": score}) return score_frame(running_score, pins[1:]) elif len(pins) > 1 and pins[0] + pins[1] == 10: # spare if prev_score == None or len(pins) < 3: score = None else: score = prev_score + pins[0] + pins[1] + pins[2] running_score.append({"frame": frame_num, "pins": pins[:2], "score": score}) return score_frame(running_score, pins[2:]) else: # open if prev_score == None or len(pins) < 2: score = None else: score = prev_score + pins[0] + pins[1] running_score.append({"frame": frame_num, "pins": pins[:2], "score": score}) return score_frame(running_score, pins[2:]) def print_game(frames): top_bottom = "" -
mdenson-dayspring revised this gist
Mar 30, 2022 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,6 @@ # # An a little over the top Bowling Score app. # Copyright 2022 by Matthew Denson <[email protected]> # # Example Usage: # To score a set of bowls provided in JSON format in stdin. -
mdenson-dayspring created this gist
Mar 30, 2022 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,221 @@ # # An a little over the top Bowling Score app. # Copyright 2020 by Matthew Denson <[email protected]> # # Example Usage: # To score a set of bowls provided in JSON format in stdin. # $ echo "[1,4,4,5,6,4,5,5,10,0,1,7,3,6,4,10,2,8,9]" | python3 bowling.py stdin # +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ # | 1| 2| 3| 4| 5| 6| 7| 8| 9| 10| # +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ # |1 4|4 5|6 /|5 /| X|0 1|7 /|6 /| X|2 / 9| # | | | | | | | | | | | # | 5 | 14 | 29 | 49 | 60 | 61 | 77 | 97 | 117 | 136 | # +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ # # To score a game interactively # $ python3 bowling.py play # Let's play! # +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ # | 1| 2| 3| 4| 5| 6| 7| 8| 9| 10| # +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ # | | | | | | | | | | | # | | | | | | | | | | | # | | | | | | | | | | | # +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ # Your next roll: (0-10,x,X) # 8 # +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ # | 1| 2| 3| 4| 5| 6| 7| 8| 9| 10| # +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ # |8 | | | | | | | | | | # | | | | | | | | | | | # | | | | | | | | | | | # +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ # Your next roll: (0-2,/) # / # +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ # | 1| 2| 3| 4| 5| 6| 7| 8| 9| 10| # +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ # |8 /| | | | | | | | | | # | | | | | | | | | | | # | | | | | | | | | | | # +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ # Your next roll: (0-10,x,X) # ..... import argparse import json import sys def score_game(pins): num_frame = 0 running_score = 0 frames = [] ball = 0 while ball < len(pins) and num_frame < 10: frame = { "frame": num_frame + 1, "pins": [], "score": None } frame_score_complete = False tmp = pins[ball] frame["pins"].append(pins[ball]) if len(pins) > ball + 1 and pins[ball] != 10: ball = ball + 1 tmp = tmp + pins[ball] frame["pins"].append(pins[ball]) if tmp == 10: # spare if len(pins) > ball + 1: tmp = tmp + pins[ball + 1] frame_score_complete = True else: frame_score_complete = True else: # strike if len(pins) > ball + 2: tmp = tmp + pins[ball + 1] tmp = tmp + pins[ball + 2] frame_score_complete = True if num_frame == 9: while ball + 1 < len(pins): ball = ball + 1 frame["pins"].append(pins[ball]) if frame_score_complete: running_score = running_score + tmp frame["score"] = running_score frames.append(frame) ball = ball + 1 num_frame = num_frame + 1 return frames def print_game(frames): top_bottom = "" num = "" bowls = "" space = "" scores = "" for f in frames: top_bottom = top_bottom + "+-----" num = num + "| {frame:>2}".format(frame = f["frame"]) pins = f["pins"] if f["frame"] == 10: # 10th frame (special) pin_str = "" sum = 0 for p in pins: sum = sum + p if p == 10: pin_str = pin_str + "X" sum = 0 elif sum == 10: pin_str = pin_str + "/" sum = 0 else: pin_str = pin_str + str(p) pin_str = pin_str + " " pin_str = pin_str.strip().ljust(5) bowls = bowls + "|" + pin_str elif len(pins) == 1: if pins[0] == 10: bowls = bowls + "| X" else: bowls = bowls + "|" + str(pins[0]) + " " else: if pins[0] + pins[1] == 10: bowls = bowls + "|" + str(pins[0]) + " /" else: bowls = bowls + "|" + str(pins[0]) + " " + str(pins[1]) space = space + "| " if f["score"]: scores = scores + "| {score:^3} ".format(score = f["score"]) else: scores = scores + "| " for f in range(len(frames)+1, 11): top_bottom = top_bottom + "+-----" num = num + "| {frame:>2}".format(frame = f) bowls = bowls + "| " space = space + "| " scores = scores + "| " print(top_bottom + "+") print(num + "|") print(top_bottom + "+") print(bowls + "|") print(space + "|") print(scores + "|") print(top_bottom + "+") def from_stdin(args): print_game(score_game(json.load(sys.stdin))) def interactive_game(args): print("Let's play!") frame_pins = 0 curr_frame = 1 pins = [] done = False while not done: score = score_game(pins) print_game(score) if (len(score) == 10 and score[9]["score"]): done = True else: if len(score) > 0 and score[len(score) - 1]['score'] or frame_pins == 10: frame_pins = 0 first_roll = True elif len(score) > 0: first_roll = False else: first_roll = True keep_reading = True if (first_roll): allowed = "0-10,x,X"; else: max = 10 - frame_pins; allowed = "0-" + str(max) + ",/"; while keep_reading: print("Your next roll: (" + allowed + ")") count = 0 roll = input() if roll in ['0','1','2','3','4','5','6','7','8','9','10','/','x','X']: if roll == '/' and frame_pins > 0: count = 10 - frame_pins keep_reading = False elif roll == 'x' or roll == 'X': if frame_pins == 0: count = 10 keep_reading = False else: count = int(roll) if count + frame_pins <=10: keep_reading = False pins.append(count) frame_pins = frame_pins + count parser = argparse.ArgumentParser() parser.add_argument('--version', action='version', version='1.0.0') subparsers = parser.add_subparsers() stdin_parser = subparsers.add_parser('stdin') stdin_parser.set_defaults(func=from_stdin) play_parser = subparsers.add_parser('play') play_parser.set_defaults(func=interactive_game) if __name__ == '__main__': args = parser.parse_args() args.func(args)