Play a game of Dice Cricket

12

Dice Cricket is a game I was introduced to as a child and have used as a way to pass time for years since. I couldn't find a Wikipedia page so I'll explain the rules below.

Dice Cricket Rules

Premise

Dice Cricket is a game similar to scoring a game of cricket as you watch it but rather than watching and recording the result, you are rolling a die and recording the result.

The results are recorded in a table as displayed at the bottom.

Display

Dice Cricket uses a specific display to show all the information happening.

The table has 11 rows. Each row represents a batter. The layout of the row is explained below.

+------+------------------------------+---------+-----+
| Name |    Runs                      | How Out |Score|
+------+------------------------------+---------+-----+
  • Name: The name must be a string made up entirely of letters, upper or lower case
  • Runs: A batter can face 30 balls. Each ball can be one of 1 2 4 6 . /. This will be explained in more detail below
  • How Out: The way the batter was out. Can be any of Bowled, LBW (Leg Before Wicket), Caught, Retired or Not Out
  • Score: The sum of all numbers in Runs

How the Game Works

In a game, there are always 2 batters out on the pitch. The first player is by default the current batter and the second in the "off" batter.

A game is made up of "balls": each ball in a cricket match is represented by a dice roll. Each roll does a different command:

  • 1,2,4 and 6 make the batter score that much. If 1 is rolled, the current batter becomes the "off" batter and the "off" batter becomes the current
  • 3 is a "dot ball", meaning that nothing happens. It is represented in the Runs section as a . and scores 0. A 0 may not be used to represent it.
  • 5 is a wicket. If 5 is rolled, the current batter is "out", This means that a / is added to the runs and from then on, the batter cannot score anymore runs. The batter is then swapped with the next batter who has not batted. The How Out section is a random choice of the possible ways to get out: Bowled, LBW, Caught

Example for a wicket (this is just for clarity, this isn't how its outputted)

player a is on 4,6,2,6,4
player b is on 6,4,2,6,6
player c hasn't batted
player a is current batter

WICKET!!!

player a is on 4,6,2,6,4,/
player b in on 6,4,2,6,6
player c is on NOTHING
player c is current batter

Every 6 balls, the two batters switch; the current batter becomes the "off" batter and the "off" batter becomes the current batter

If the Runs section is filled (30 balls), the batter is out and the How Out section is set to Retired. A / isn't placed at the end of the Runs box.

Actual Challenge (yes all that was rules of the game)

Your challenge is to output a completed table (like the example at the end), given a list of names. The contents of the output should contain only the table and/or leading or trailing whitespace.

Rules

  • Standard loopholes are disallowed
  • All 11 players should have something in the Runs section.
  • Only 1 player can be Not Out. Every other non-retired player should be out of a choice of [Bowled, LBW, Caught]
  • The names can be any length between 1 and 6 that matches the regex A-Za-z
  • The final line in the table should be the total line (see example)
  • You don't have to align the text in the table in any way, but the row and column separators must be aligned.

Example

Input:
['Fred', 'Sonya', 'David', 'Ben', 'Cody', 'Hazel', 'Nina', 'Kim', 'Cath', 'Lena', 'Will']
Output:
+------+------------------------------+---------+-----+
| Name | Runs                         | How Out |Total|
+------+------------------------------+---------+-----+
|Fred  |.662/                         | Caught  | 14  |
+------+------------------------------+---------+-----+
|Sonya |1164/                         | Caught  | 12  |
+------+------------------------------+---------+-----+
|David |/                             |   LBW   |  0  |
+------+------------------------------+---------+-----+
|Ben   |424/                          |   LBW   | 10  |
+------+------------------------------+---------+-----+
|Cody  |62/                           | Bowled  |  8  |
+------+------------------------------+---------+-----+
|Hazel |/                             |   LBW   |  0  |
+------+------------------------------+---------+-----+
|Nina  |161.6226166..44261442/        | Caught  | 64  |
+------+------------------------------+---------+-----+
|Kim   |11/                           | Caught  |  2  |
+------+------------------------------+---------+-----+
|Cath  |6.21/                         |   LBW   |  9  |
+------+------------------------------+---------+-----+
|Lena  |/                             | Bowled  |  0  |
+------+------------------------------+---------+-----+
|Will  |2                             | Not Out |  2  |
+------+------------------------------+---------+-----+
|               Total Runs                      | 121 |
+-----------------------------------------------+-----+

caird coinheringaahing

Posted 2017-12-14T18:00:12.597

Reputation: 13 702

Sandbox – caird coinheringaahing – 2017-12-14T18:00:52.437

Heh, I used to play a similar variant of this called "Hand cricket". – totallyhuman – 2017-12-14T18:43:14.593

What determines when the game ends? Is it when a batter is out and there is no one left to replace him? – KSmarts – 2017-12-14T19:40:15.693

@KSmarts Correct. – caird coinheringaahing – 2017-12-14T19:55:27.323

1@JonathanAllan Yeah, it isn't a good requirement. Removed – caird coinheringaahing – 2017-12-14T20:05:28.817

Answers

2

Python 3, 650 621 582 572 588 bytes

from random import*
h=str
c=h.center
a='+'.join(map('-'.__mul__,[0,6,30,9,5,0]))+'\n'
b=lambda x,r=6:x.ljust(r,' ')
j=''.join
t=lambda a:sum(map(int,a[:-1].replace(*'.0')))
P=print
def s(i=30):
 while i:x=choice('12.4/6');yield x;i=('/'!=x)*~-i
def f(n,T=0):
 n=[*map(b,n)]
 P(a+f'| Name | Runs{" "*25}| How Out |Total|')
 for x in n[:-1]:S=j(s());T+=t(S);P(a,x,b(S,30),c(choice(['Bowled','LBW','Caught']),9),c(h(t(S)),5),sep='|',end='|\n')
 S=j(s());P(a,n[-1],b(S,30),' Not Out ',c(h(t(S)),5),sep='|',end='|\n');P(a+f'|{15*" "}Total Runs{15*" "}       |{c(h(T),5)}|\n+{47*"-"}+{5*"-"}+')

Try it online!

Well, it's been over 24 hours and this took me about an hour to whip up, so I hope I'm not FGITW'ing anyone, and I haven't golfed in Python in a while, so this was fun (although this is the second time I've answered one of my own questions with a long Python answer)

Please feel free to post golf suggestions, Python isn't my best language for golfing.

-68 bytes thanks to FlipTack!

-8 bytes thanks to Mr. Xcoder

+16 bytes due to a bug

caird coinheringaahing

Posted 2017-12-14T18:00:12.597

Reputation: 13 702

At first glance, I can see quite a few golfs... 1) In one instance you still use print instead of P. 2) sum can directly take a map object, no need to convert it to a list. 3) Rather than writing yield x twice, why not yield x and then break if necessary? 4) T=0 could be placed inside the function header. 5) In your last function, you've used several newlines where you could just use one line with semicolons, for example the first three statements, the last three statements, and the statements in the for loop. – FlipTack – 2017-12-17T09:41:25.177

@FlipTack Nice golfs, and thanks! – caird coinheringaahing – 2017-12-18T15:50:46.450

You can golf s considerably... def s(i=30): and then while i:x=choice('12.4/6');yield x;i=('/'!=x)*~-i. Also, you only call o() once, so there's no need to even declare it, just use the statement directly. – FlipTack – 2017-12-18T17:14:26.647

The same applies to b ^^ – FlipTack – 2017-12-18T17:24:41.167

@FlipTack Added the golfs. Thanks! – caird coinheringaahing – 2017-12-19T15:42:27.940

574 – Mr. Xcoder – 2017-12-19T16:03:02.623

@Mr.Xcoder Managed to save another two bytes from that. Thanks! – caird coinheringaahing – 2017-12-19T16:16:54.050

I think your output has two + characters in the last line which should both be - characters. – Jonathan Frech – 2017-12-19T16:49:41.440

@JonathanFrech Indeed it did. Fixed. – caird coinheringaahing – 2017-12-22T12:35:03.730

-18 bytes – FlipTack – 2017-12-23T09:51:58.833

You can convert the map on line 4 to a generator expression, which let you save the extra parentheses as well. – Amphibological – 2018-07-22T22:23:52.670

0

Charcoal, 277 255 bytes

≔E¹¹⟦⟦⟧⁰S⟧θ≔⮌θηW⊖Lη«≔⊟ηι≔‽12.4/6ζ⊞υζ⊞§ι⁰ζ≔⎇⁼ζ/⁺²‽³⁼³⁰L§ι⁰ζ¿ζ§≔ι¹ζ⊞ηι¿⊖Lη¿⁼¬﹪Lυ⁶¬εF⟦⊟η⊟η⟧⊞ηκ»”|⁴B\[⎇⁻℅↧T`⁵·5KMK⟲M≦»→´⁶_⭆∨R▷↥l⁹KG…≦”Fθ«◨⊟ι⁷◨Σ§ι⁰¦³²§⪪”(3⪪⪫⧴πZJL:∨XI±URD↗Σ9⟦FZ∕↖l⪪”⁷⊟ι◧IΣE⊟ιΣκ⁶⸿⸿»”|QºWPD⟧zNφ[v?Π'vG”◧IΣEυΣι²⁸J±¹±¹FE¹³⁻²⁷⊗ι«B⁵⁵ιB⁴⁹ι¿‹ι²⁷«B³⁹ιB⁸ι

Try it online! Link is to verbose version of code. Explanation:

≔E¹¹⟦⟦⟧⁰S⟧θ

Read in the 11 names (input is flexible: JSON, space separated, or newline separated) and create an array q of 11 batters, represented by their balls (as an array), status (as an integer) and name.

≔⮌θη

Create a reversed copy of the batters h. This represents the batters that are not out. The last two elements are the off and current batters.

W⊖Lη«

Repeat while there are at least two batters available.

≔⊟ηι

Extract the current batter to i.

≔‽12.4/6ζ

Generate a random ball in z.

⊞υζ

Add it to the overall list of balls using the predefined empty list u.

⊞§ι⁰ζ

Add it to the current batter's balls.

≔⎇⁼ζ/⁺²‽³⁼³⁰L§ι⁰ζ

If the ball is a /, then generate a random status 2..4, otherwise if this is the batter's 30th ball then set the status to 1 otherwise 0.

¿ζ§≔ι¹ζ⊞ηι

If the batter is out then store the batter's status otherwise put the batter back in to bat.

¿⊖Lθ¿⁼¬﹪ΣEηLκ⁶¬ζ

If there are at least two batters left, and the batter was out xor 6 balls have been played, then...

F⟦⊟η⊟η⟧⊞ηκ»

...take the off and current batters and put them back in reverse order.

”|⁴B\[⎇⁻℅↧T`⁵·5KMK⟲M≦»→´⁶_⭆∨R▷↥l⁹KG…≦”

Print the header.

Fθ«

Loop over the batters.

◨⊟ι⁷

Print the batter's name.

◨Σ§ι⁰¦³²

Print the batter's balls.

§⪪”(3⪪⪫⧴πZJL:∨XI±URD↗Σ9⟦FZ∕↖l⪪”⁷⊟ι

Print the batter's status by indexing into the string Not OutRetiredBowled Caught LBW split into substrings of length 7.

◧IΣE⊟ιΣκ⁶

Print the batter's score.

⸿⸿»

Move to the start of the next line but one.

”|QºWPD⟧zNφ[v?Π'vG”◧IΣEυΣι²⁸

Print the total.

J±¹±¹FE¹³⁻²⁷⊗ι«B⁵⁵ιB⁴⁹ι¿‹ι²⁷«B³⁹ιB⁸ι

Draw boxes around everything.

Neil

Posted 2017-12-14T18:00:12.597

Reputation: 95 035