exercism bowling challenge

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

exercism bowling challenge

Pharo Smalltalk Users mailing list
hello,

I need now to make code that calculates the full score of a bowling game like one of the tests shown.

test09_ConsecutiveStrikesEachGetTheTwoRollBonus
    | result |
    result := bowlingCalculator
        scoreAfterRolling: #(10 10 10 5 3 0 0 0 0 0 0 0 0 0 0 0 0).
    self assert: result equals: 81

What I thougt of solving this is to make a class BowlingCalculator and a class Frame
and first convert the numbers to a frame.

the Frame class should then have two instance variables throw1 and throw2 where throw2 can be null if the first throw is 10.

Then to calculate the total score I can check if the first number is 10
if so, take the next frame and sum them up.
if not, check if the total of a frame is 10
if so, take the first number out of the next frame and sum them up
if both are not true , then sum only the frame

and then in all cases goto the next frame.

Can this plan be working or is there improvements to this plan.

Roelof

Reply | Threaded
Open this post in threaded view
|

Re: exercism bowling challenge

Pharo Smalltalk Users mailing list
Op 21-9-2020 om 18:49 schreef Roelof Wobben via Pharo-users:
hello,

I need now to make code that calculates the full score of a bowling game like one of the tests shown.

test09_ConsecutiveStrikesEachGetTheTwoRollBonus
    | result |
    result := bowlingCalculator
        scoreAfterRolling: #(10 10 10 5 3 0 0 0 0 0 0 0 0 0 0 0 0).
    self assert: result equals: 81

What I thougt of solving this is to make a class BowlingCalculator and a class Frame
and first convert the numbers to a frame.

the Frame class should then have two instance variables throw1 and throw2 where throw2 can be null if the first throw is 10.

Then to calculate the total score I can check if the first number is 10
if so, take the next frame and sum them up.
if not, check if the total of a frame is 10
if so, take the first number out of the next frame and sum them up
if both are not true , then sum only the frame

and then in all cases goto the next frame.

Can this plan be working or is there improvements to this plan.

Roelof


No respons after 3 days. Pity
Reply | Threaded
Open this post in threaded view
|

Re: exercism bowling challenge

DavidBajger
Hi Roelof,
I always wonder, what kind of answer you expect from your prior statement.
To your question: "Can this plan be working or is there improvements to this
plan." I can have this answer: Yes, it could be both: working or fail, but
you don't know before you try.

This exercise is a bit tricky:
1) I can recommend to use also LastFrame class, which has specific handling
of bonuses in last round of game (subclass of Frame). Bowling game can be
then initialized with array 9 Frame instances and last instance could be
LastFrame. I used specific test methods on frame classes like:
#isFrameComplete, #isLastFrame, #isSpare, #isStrike, #isOpen.
2) Beware that Bowling game should know only necessary things and delegate
responsibility to its frames. Game itself knows that only if all frames are
completed, game ends.
3) Total score is sum of all throws+bonuses of individual frames, etc.

Does it help to start with exercise?
David





-----
David Bajger
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html
David Bajger
Reply | Threaded
Open this post in threaded view
|

Re: exercism bowling challenge

Pharo Smalltalk Users mailing list
Op 24-9-2020 om 13:42 schreef DavidBajger:

> Hi Roelof,
> I always wonder, what kind of answer you expect from your prior statement.
> To your question: "Can this plan be working or is there improvements to this
> plan." I can have this answer: Yes, it could be both: working or fail, but
> you don't know before you try.
>
> This exercise is a bit tricky:
> 1) I can recommend to use also LastFrame class, which has specific handling
> of bonuses in last round of game (subclass of Frame). Bowling game can be
> then initialized with array 9 Frame instances and last instance could be
> LastFrame. I used specific test methods on frame classes like:
> #isFrameComplete, #isLastFrame, #isSpare, #isStrike, #isOpen.
> 2) Beware that Bowling game should know only necessary things and delegate
> responsibility to its frames. Game itself knows that only if all frames are
> completed, game ends.
> 3) Total score is sum of all throws+bonuses of individual frames, etc.
>
> Does it help to start with exercise?
> David
>
>
>
>
>
> -----
> David Bajger
> --
> Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html

Thanks,

Maybe I have to make it more clear.
What I trying to ask and what you have answered. Do I use the right
classes or too much classes there.
So if my idea of using these classes are right.

What you wrote is what I had in mind with 2  classes but the idea of a
lastFrame could also be working.
and I also agree with you about the responsibilities of the classes.

Roelof
Reply | Threaded
Open this post in threaded view
|

Re: exercism bowling challenge

Pharo Smalltalk Users mailing list
Op 24-9-2020 om 13:52 schreef Roelof Wobben via Pharo-users:

> Op 24-9-2020 om 13:42 schreef DavidBajger:
>> Hi Roelof,
>> I always wonder, what kind of answer you expect from your prior
>> statement.
>> To your question: "Can this plan be working or is there improvements
>> to this
>> plan." I can have this answer: Yes, it could be both: working or
>> fail, but
>> you don't know before you try.
>>
>> This exercise is a bit tricky:
>> 1) I can recommend to use also LastFrame class, which has specific
>> handling
>> of bonuses in last round of game (subclass of Frame). Bowling game
>> can be
>> then initialized with array 9 Frame instances and last instance could be
>> LastFrame. I used specific test methods on frame classes like:
>> #isFrameComplete, #isLastFrame, #isSpare, #isStrike, #isOpen.
>> 2) Beware that Bowling game should know only necessary things and
>> delegate
>> responsibility to its frames. Game itself knows that only if all
>> frames are
>> completed, game ends.
>> 3) Total score is sum of all throws+bonuses of individual frames, etc.
>>
>> Does it help to start with exercise?

I forget to say it helpes me  to see if i m thinking the "right" way
Reply | Threaded
Open this post in threaded view
|

Re: exercism bowling challenge

Richard O'Keefe
In reply to this post by Pharo Smalltalk Users mailing list
Since the problem can be solved, and has been solved, in programming languages that do not support object-oriented programming, there is obviously no unique "right" factoring of this problem into classes.  I'll be honest with you: this is the only Pharo exercism I have not tackled, and the reason is that I just found the problem specification too ugly to care about.  I had better get over that.

The two primary difficulties are
(a) the game is described one ROLL at a time, but scored one FRAME at a time.
(b) the rolls are recorded from past to future, but the score can only be
calculated from future to past.
The fact that there may be one extra roll at the end which is not technically
part of any of the 10 frames is just icing on the cake.

But this is *algorithmic* trickiness, not *world model* trickiness.

Let's imagine a Frame class.
- You get the first roll of the frame.  Fewer than 10 pins are knocked down.
  You cannot complete initialising the Frame yet.
- All 10 pins are knocked down.  You cannot determine the *score* of the
  frame yet.  This casts some doubt on the idea of the score being part
  of the state of the frame.  The score actually depends on the next two
  THROWS (rolls), not the next frame or the next two frames.  This casts
  much doubt on the idea of the concept "frame" being useful for the
  analysis.  At the very least, you will need to manipulate BOTH frames
  AND throws (rolls).
It looks as though a Frame class may just make things harder.
Since the only thing there is to know about a Throw is how many pins
were knocked down, it doesn't look as though a Throw class is much use
either.  This leaves us with a BowlingGame class that just keeps tracks
of rolls and then runs a moderately complex algorithm when it is asked
for the score.

Long past my bed-time or I would get stuck into it.

On Thu, 24 Sep 2020 at 23:53, Roelof Wobben via Pharo-users <[hidden email]> wrote:
Op 24-9-2020 om 13:42 schreef DavidBajger:
> Hi Roelof,
> I always wonder, what kind of answer you expect from your prior statement.
> To your question: "Can this plan be working or is there improvements to this
> plan." I can have this answer: Yes, it could be both: working or fail, but
> you don't know before you try.
>
> This exercise is a bit tricky:
> 1) I can recommend to use also LastFrame class, which has specific handling
> of bonuses in last round of game (subclass of Frame). Bowling game can be
> then initialized with array 9 Frame instances and last instance could be
> LastFrame. I used specific test methods on frame classes like:
> #isFrameComplete, #isLastFrame, #isSpare, #isStrike, #isOpen.
> 2) Beware that Bowling game should know only necessary things and delegate
> responsibility to its frames. Game itself knows that only if all frames are
> completed, game ends.
> 3) Total score is sum of all throws+bonuses of individual frames, etc.
>
> Does it help to start with exercise?
> David
>
>
>
>
>
> -----
> David Bajger
> --
> Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html

Thanks,

Maybe I have to make it more clear.
What I trying to ask and what you have answered. Do I use the right
classes or too much classes there.
So if my idea of using these classes are right.

What you wrote is what I had in mind with 2  classes but the idea of a
lastFrame could also be working.
and I also agree with you about the responsibilities of the classes.

Roelof
Reply | Threaded
Open this post in threaded view
|

Re: exercism bowling challenge

Pharo Smalltalk Users mailing list
Hello Richard,

Thanks for your feedback and I hope you slept well and did not dream about this one.
And this exercise is exactly why I ask so many questions how I can make this work the OOP way.

Hopefully it's getting better with v3 where I heared the languages have more freedom to change challenges and test to make it more workable in the language you work with

Roelof



Op 24-9-2020 om 15:16 schreef Richard O'Keefe:
Since the problem can be solved, and has been solved, in programming languages that do not support object-oriented programming, there is obviously no unique "right" factoring of this problem into classes.  I'll be honest with you: this is the only Pharo exercism I have not tackled, and the reason is that I just found the problem specification too ugly to care about.  I had better get over that.

The two primary difficulties are
(a) the game is described one ROLL at a time, but scored one FRAME at a time.
(b) the rolls are recorded from past to future, but the score can only be
calculated from future to past.
The fact that there may be one extra roll at the end which is not technically
part of any of the 10 frames is just icing on the cake.

But this is *algorithmic* trickiness, not *world model* trickiness.

Let's imagine a Frame class.
- You get the first roll of the frame.  Fewer than 10 pins are knocked down.
  You cannot complete initialising the Frame yet.
- All 10 pins are knocked down.  You cannot determine the *score* of the
  frame yet.  This casts some doubt on the idea of the score being part
  of the state of the frame.  The score actually depends on the next two
  THROWS (rolls), not the next frame or the next two frames.  This casts
  much doubt on the idea of the concept "frame" being useful for the
  analysis.  At the very least, you will need to manipulate BOTH frames
  AND throws (rolls).
It looks as though a Frame class may just make things harder.
Since the only thing there is to know about a Throw is how many pins
were knocked down, it doesn't look as though a Throw class is much use
either.  This leaves us with a BowlingGame class that just keeps tracks
of rolls and then runs a moderately complex algorithm when it is asked
for the score.

Long past my bed-time or I would get stuck into it.

On Thu, 24 Sep 2020 at 23:53, Roelof Wobben via Pharo-users <[hidden email]> wrote:
Op 24-9-2020 om 13:42 schreef DavidBajger:
> Hi Roelof,
> I always wonder, what kind of answer you expect from your prior statement.
> To your question: "Can this plan be working or is there improvements to this
> plan." I can have this answer: Yes, it could be both: working or fail, but
> you don't know before you try.
>
> This exercise is a bit tricky:
> 1) I can recommend to use also LastFrame class, which has specific handling
> of bonuses in last round of game (subclass of Frame). Bowling game can be
> then initialized with array 9 Frame instances and last instance could be
> LastFrame. I used specific test methods on frame classes like:
> #isFrameComplete, #isLastFrame, #isSpare, #isStrike, #isOpen.
> 2) Beware that Bowling game should know only necessary things and delegate
> responsibility to its frames. Game itself knows that only if all frames are
> completed, game ends.
> 3) Total score is sum of all throws+bonuses of individual frames, etc.
>
> Does it help to start with exercise?
> David
>
>
>
>
>
> -----
> David Bajger
> --
> Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html

Thanks,

Maybe I have to make it more clear.
What I trying to ask and what you have answered. Do I use the right
classes or too much classes there.
So if my idea of using these classes are right.

What you wrote is what I had in mind with 2  classes but the idea of a
lastFrame could also be working.
and I also agree with you about the responsibilities of the classes.

Roelof

Reply | Threaded
Open this post in threaded view
|

Re: exercism bowling challenge

Sean P. DeNigris
Administrator
In reply to this post by Richard O'Keefe
Richard O'Keefe wrote
> there is obviously no unique "right" factoring of this problem into
> classes.

This. And, in my experience, with non-trivial problems, some (many?) times
you just have to try to implement an idea to see if it's really going to
work because it's just too hard to see all the way into the future.



-----
Cheers,
Sean
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html
Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: exercism bowling challenge

Richard Sargent
Administrator
On Thu, Sep 24, 2020, 18:08 Sean P. DeNigris <[hidden email]> wrote:
Richard O'Keefe wrote
> there is obviously no unique "right" factoring of this problem into
> classes.

This. And, in my experience, with non-trivial problems, some (many?) times
you just have to try to implement an idea to see if it's really going to
work because it's just too hard to see all the way into the future.

It's hard to see the future, but there are tricks to help.

For something like this, work out a few games on paper. Get a sense of how the numbers play together.

Then, anthropomorphise the problem. Imagine yourself to be a film director or some other kind of manager. You don't want to do the work; that's what your staff is for. Who do you need to train to do the work? How many jobs are there to do? Can multiple people doing the same task get the job done faster?

Ultimately, the job of a programmer is to delegate the work to others, and to teach them how to do their jobs. That teaching part is actually writing code. The different people doing different tasks correspond to the objects in in an OO solution.

As the other Richard seemed to suggest, this isn't an object rich problem. It's largely a question of how to implement an algorithm.

Working examples on paper will help with internalising how to do it.

Reply | Threaded
Open this post in threaded view
|

Re: exercism bowling challenge

Pharo Smalltalk Users mailing list
>
> As the other Richard seemed to suggest, this isn't an object rich
> problem. It's largely a question of how to implement an algorithm.
>
> Working examples on paper will help with internalising how to do it.
>

Oops, and I thinking of a solution with 3  classes.

the given class
a class Frame which is responsibility is to convert the numbers into
frames and validate it
a class ScoreBoard which is responsibility is too calculate the score

Roelof
Reply | Threaded
Open this post in threaded view
|

Re: exercism bowling challenge

DavidBajger
In reply to this post by Richard O'Keefe
Hi Richard,
I want to reply to some of your insights here, because I think it is sometimes a matter of personal preference on a problem solution, so I want to compete with your opinion here. I might be totally wrong, when I see your way of solution and tell just 'you were right, your solution is more elegant'. For me it is an approach discussion.



čt 24. 9. 2020 v 15:16 odesílatel Richard O'Keefe <[hidden email]> napsal:
Since the problem can be solved, and has been solved, in programming languages that do not support object-oriented programming, there is obviously no unique "right" factoring of this problem into classes.  I'll be honest with you: this is the only Pharo exercism I have not tackled, and the reason is that I just found the problem specification too ugly to care about.  I had better get over that.

We are using OO language to isolate problems into particular objects and their responsibility. I would say there is no "ugly problem to care about". Sometimes it can be the "right" factoring of a problem into classes and sometimes it is too hard and that is the point. I think this exercise is about finding the right place to delegate problems in fitting classes that are small enough. Of course, it can be resolved by one "long method" with a total of less lines of code. But in general I like more verbosity over one compact algorithm that wouldn't tell readers too much. This is a personal preference.
 

The two primary difficulties are
(a) the game is described one ROLL at a time, but scored one FRAME at a time.
(b) the rolls are recorded from past to future, but the score can only be
calculated from future to past.

Way of evaluation is definitely relevant. Key thing for me was to realize "I always need to evaluate the current state of things", the same way, when you play bowling. 
- Each frame should be able to tell, if it is completed from the point of actual throw. So, why not just pass throws by game into the current frame, that would tell, if it is completed or not?
- Frame can calculate score immediately, but bonuses can be later. Maybe it isn't 'the throw thing' to care about. It is a matter of the game, that can tell when is the right moment to evaluate bonuses. Game can delegate such information to the passed frames at the right moment (maybe after each thow, or maybe when the current frame is completed?). But maybe my previous sentence can be interpreted as:  "this is a big hammer for this solution already". 

 
The fact that there may be one extra roll at the end which is not technically
part of any of the 10 frames is just icing on the cake.

But this is *algorithmic* trickiness, not *world model* trickiness.

Let's imagine a Frame class.
- You get the first roll of the frame.  Fewer than 10 pins are knocked down.
  You cannot complete initialising the Frame yet.

Well, why not just initialize frame by "collection of 1-2 (maybe 3) throws"? Depending on the actual state of collection, frame just tells the game "I have enough throws, so you can pass throws to my neighbor". Rules for completeness can be different, based on circumstances. For me, it is a matter of frame responsibility to deal with this.
 
- All 10 pins are knocked down.  You cannot determine the *score* of the
  frame yet.  This casts some doubt on the idea of the score being part
  of the state of the frame.  The score actually depends on the next two
  THROWS (rolls), not the next frame or the next two frames.  This casts
  much doubt on the idea of the concept "frame" being useful for the
  analysis.  At the very least, you will need to manipulate BOTH frames
  AND throws (rolls).

When bowling in real, you can determine the score of the current frame. But bonuses are computed later, so maybe the game should tell (after each throw), when to evaluate bonus.  "Hey, my passed frames, I'm passing you this information, so evaluate your bonus now". 

 
It looks as though a Frame class may just make things harder.
Since the only thing there is to know about a Throw is how many pins
were knocked down, it doesn't look as though a Throw class is much use
either.  This leaves us with a BowlingGame class that just keeps tracks
of rolls and then runs a moderately complex algorithm when it is asked
for the score.

Long past my bed-time or I would get stuck into it.

 
It depends on how "moderately complex algorithm" will be readable for end users. Sometimes it is a real struggle to determine "what a hell is going on here", because the given method just does too many things in one class. For me, separating throws into frames makes the whole thing more understandable to readers, because they can imagine something from real life (real game). Again, this is personal preference. I've seen few times that "moderately complex algorithms" were extended by other developers into "severe too-complex algorithms". Problem is that developers don't do refactoring at the right time (most probably because of lack of time and time pressure on projects). On the other hand, I understand it isn't a problem of this artificial exercise and agree that focus should be just on existing problem statement and not hypothetical problem.  
I did this exercise some time ago and when I look at it now, honestly I'm not satisfied with my solution, especially the way bonuses are stored and evaluated in normal vs last frame. But here is the thing: it is isolated on one given place and used on one other place, I can rewrite it maybe more easily.

 
On Thu, 24 Sep 2020 at 23:53, Roelof Wobben via Pharo-users <[hidden email]> wrote:
Op 24-9-2020 om 13:42 schreef DavidBajger:
> Hi Roelof,
> I always wonder, what kind of answer you expect from your prior statement.
> To your question: "Can this plan be working or is there improvements to this
> plan." I can have this answer: Yes, it could be both: working or fail, but
> you don't know before you try.
>
> This exercise is a bit tricky:
> 1) I can recommend to use also LastFrame class, which has specific handling
> of bonuses in last round of game (subclass of Frame). Bowling game can be
> then initialized with array 9 Frame instances and last instance could be
> LastFrame. I used specific test methods on frame classes like:
> #isFrameComplete, #isLastFrame, #isSpare, #isStrike, #isOpen.
> 2) Beware that Bowling game should know only necessary things and delegate
> responsibility to its frames. Game itself knows that only if all frames are
> completed, game ends.
> 3) Total score is sum of all throws+bonuses of individual frames, etc.
>
> Does it help to start with exercise?
> David
>
>
>
>
>
> -----
> David Bajger
> --
> Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html

Thanks,

Maybe I have to make it more clear.
What I trying to ask and what you have answered. Do I use the right
classes or too much classes there.
So if my idea of using these classes are right.

What you wrote is what I had in mind with 2  classes but the idea of a
lastFrame could also be working.
and I also agree with you about the responsibilities of the classes.

Roelof
David Bajger
Reply | Threaded
Open this post in threaded view
|

Re: exercism bowling challenge

Richard O'Keefe
It turns out that this problem has appeared elsewhere,
at least twice to my knowledge, and I had already solved
the version at Programming Praxis over a year ago.
I actually wrote two solutions, in different programming
languages.  One of them was 8 lines.  That was the longer.
The Haskell version was just 3 lines.

The Exercism tasks are what they are.  They DO provide
drill in using the more conventional aspects of Smalltalk.
They DON'T provide good drill in object-oriented DESIGN.

This particular problem can be solved clearly and cleanly
with a ByteArray and a handful of integers.

The fact that the test harness enforces the raising of
certain exceptions which are nowhere mentioned in the
specification complicates things rather.  (As does the
fact that the interface enforced by the test harness
contradicts the interface required by the specification.)

Remember, given a list of rolls, Haskell can do the
whole calculation in three straightforward lines.  Getting
the code to work is tricky, not because the calculations
are intrinsically hard, but because the specification is
very confusingly worded.


On Fri, 25 Sep 2020 at 19:23, David Bajger <[hidden email]> wrote:
Hi Richard,
I want to reply to some of your insights here, because I think it is sometimes a matter of personal preference on a problem solution, so I want to compete with your opinion here. I might be totally wrong, when I see your way of solution and tell just 'you were right, your solution is more elegant'. For me it is an approach discussion.



čt 24. 9. 2020 v 15:16 odesílatel Richard O'Keefe <[hidden email]> napsal:
Since the problem can be solved, and has been solved, in programming languages that do not support object-oriented programming, there is obviously no unique "right" factoring of this problem into classes.  I'll be honest with you: this is the only Pharo exercism I have not tackled, and the reason is that I just found the problem specification too ugly to care about.  I had better get over that.

We are using OO language to isolate problems into particular objects and their responsibility. I would say there is no "ugly problem to care about". Sometimes it can be the "right" factoring of a problem into classes and sometimes it is too hard and that is the point. I think this exercise is about finding the right place to delegate problems in fitting classes that are small enough. Of course, it can be resolved by one "long method" with a total of less lines of code. But in general I like more verbosity over one compact algorithm that wouldn't tell readers too much. This is a personal preference.
 

The two primary difficulties are
(a) the game is described one ROLL at a time, but scored one FRAME at a time.
(b) the rolls are recorded from past to future, but the score can only be
calculated from future to past.

Way of evaluation is definitely relevant. Key thing for me was to realize "I always need to evaluate the current state of things", the same way, when you play bowling. 
- Each frame should be able to tell, if it is completed from the point of actual throw. So, why not just pass throws by game into the current frame, that would tell, if it is completed or not?
- Frame can calculate score immediately, but bonuses can be later. Maybe it isn't 'the throw thing' to care about. It is a matter of the game, that can tell when is the right moment to evaluate bonuses. Game can delegate such information to the passed frames at the right moment (maybe after each thow, or maybe when the current frame is completed?). But maybe my previous sentence can be interpreted as:  "this is a big hammer for this solution already". 

 
The fact that there may be one extra roll at the end which is not technically
part of any of the 10 frames is just icing on the cake.

But this is *algorithmic* trickiness, not *world model* trickiness.

Let's imagine a Frame class.
- You get the first roll of the frame.  Fewer than 10 pins are knocked down.
  You cannot complete initialising the Frame yet.

Well, why not just initialize frame by "collection of 1-2 (maybe 3) throws"? Depending on the actual state of collection, frame just tells the game "I have enough throws, so you can pass throws to my neighbor". Rules for completeness can be different, based on circumstances. For me, it is a matter of frame responsibility to deal with this.
 
- All 10 pins are knocked down.  You cannot determine the *score* of the
  frame yet.  This casts some doubt on the idea of the score being part
  of the state of the frame.  The score actually depends on the next two
  THROWS (rolls), not the next frame or the next two frames.  This casts
  much doubt on the idea of the concept "frame" being useful for the
  analysis.  At the very least, you will need to manipulate BOTH frames
  AND throws (rolls).

When bowling in real, you can determine the score of the current frame. But bonuses are computed later, so maybe the game should tell (after each throw), when to evaluate bonus.  "Hey, my passed frames, I'm passing you this information, so evaluate your bonus now". 

 
It looks as though a Frame class may just make things harder.
Since the only thing there is to know about a Throw is how many pins
were knocked down, it doesn't look as though a Throw class is much use
either.  This leaves us with a BowlingGame class that just keeps tracks
of rolls and then runs a moderately complex algorithm when it is asked
for the score.

Long past my bed-time or I would get stuck into it.

 
It depends on how "moderately complex algorithm" will be readable for end users. Sometimes it is a real struggle to determine "what a hell is going on here", because the given method just does too many things in one class. For me, separating throws into frames makes the whole thing more understandable to readers, because they can imagine something from real life (real game). Again, this is personal preference. I've seen few times that "moderately complex algorithms" were extended by other developers into "severe too-complex algorithms". Problem is that developers don't do refactoring at the right time (most probably because of lack of time and time pressure on projects). On the other hand, I understand it isn't a problem of this artificial exercise and agree that focus should be just on existing problem statement and not hypothetical problem.  
I did this exercise some time ago and when I look at it now, honestly I'm not satisfied with my solution, especially the way bonuses are stored and evaluated in normal vs last frame. But here is the thing: it is isolated on one given place and used on one other place, I can rewrite it maybe more easily.

 
On Thu, 24 Sep 2020 at 23:53, Roelof Wobben via Pharo-users <[hidden email]> wrote:
Op 24-9-2020 om 13:42 schreef DavidBajger:
> Hi Roelof,
> I always wonder, what kind of answer you expect from your prior statement.
> To your question: "Can this plan be working or is there improvements to this
> plan." I can have this answer: Yes, it could be both: working or fail, but
> you don't know before you try.
>
> This exercise is a bit tricky:
> 1) I can recommend to use also LastFrame class, which has specific handling
> of bonuses in last round of game (subclass of Frame). Bowling game can be
> then initialized with array 9 Frame instances and last instance could be
> LastFrame. I used specific test methods on frame classes like:
> #isFrameComplete, #isLastFrame, #isSpare, #isStrike, #isOpen.
> 2) Beware that Bowling game should know only necessary things and delegate
> responsibility to its frames. Game itself knows that only if all frames are
> completed, game ends.
> 3) Total score is sum of all throws+bonuses of individual frames, etc.
>
> Does it help to start with exercise?
> David
>
>
>
>
>
> -----
> David Bajger
> --
> Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html

Thanks,

Maybe I have to make it more clear.
What I trying to ask and what you have answered. Do I use the right
classes or too much classes there.
So if my idea of using these classes are right.

What you wrote is what I had in mind with 2  classes but the idea of a
lastFrame could also be working.
and I also agree with you about the responsibilities of the classes.

Roelof
Reply | Threaded
Open this post in threaded view
|

Re: exercism bowling challenge

Pharo Smalltalk Users mailing list
Hello,

Maybe developing is not my cup of tea,
I get more and more confused with this discussion.

Roelof


Op 25-9-2020 om 14:37 schreef Richard O'Keefe:
It turns out that this problem has appeared elsewhere,
at least twice to my knowledge, and I had already solved
the version at Programming Praxis over a year ago.
I actually wrote two solutions, in different programming
languages.  One of them was 8 lines.  That was the longer.
The Haskell version was just 3 lines.

The Exercism tasks are what they are.  They DO provide
drill in using the more conventional aspects of Smalltalk.
They DON'T provide good drill in object-oriented DESIGN.

This particular problem can be solved clearly and cleanly
with a ByteArray and a handful of integers.

The fact that the test harness enforces the raising of
certain exceptions which are nowhere mentioned in the
specification complicates things rather.  (As does the
fact that the interface enforced by the test harness
contradicts the interface required by the specification.)

Remember, given a list of rolls, Haskell can do the
whole calculation in three straightforward lines.  Getting
the code to work is tricky, not because the calculations
are intrinsically hard, but because the specification is
very confusingly worded.


On Fri, 25 Sep 2020 at 19:23, David Bajger <[hidden email]> wrote:
Hi Richard,
I want to reply to some of your insights here, because I think it is sometimes a matter of personal preference on a problem solution, so I want to compete with your opinion here. I might be totally wrong, when I see your way of solution and tell just 'you were right, your solution is more elegant'. For me it is an approach discussion.



čt 24. 9. 2020 v 15:16 odesílatel Richard O'Keefe <[hidden email]> napsal:
Since the problem can be solved, and has been solved, in programming languages that do not support object-oriented programming, there is obviously no unique "right" factoring of this problem into classes.  I'll be honest with you: this is the only Pharo exercism I have not tackled, and the reason is that I just found the problem specification too ugly to care about.  I had better get over that.

We are using OO language to isolate problems into particular objects and their responsibility. I would say there is no "ugly problem to care about". Sometimes it can be the "right" factoring of a problem into classes and sometimes it is too hard and that is the point. I think this exercise is about finding the right place to delegate problems in fitting classes that are small enough. Of course, it can be resolved by one "long method" with a total of less lines of code. But in general I like more verbosity over one compact algorithm that wouldn't tell readers too much. This is a personal preference.
 

The two primary difficulties are
(a) the game is described one ROLL at a time, but scored one FRAME at a time.
(b) the rolls are recorded from past to future, but the score can only be
calculated from future to past.

Way of evaluation is definitely relevant. Key thing for me was to realize "I always need to evaluate the current state of things", the same way, when you play bowling. 
- Each frame should be able to tell, if it is completed from the point of actual throw. So, why not just pass throws by game into the current frame, that would tell, if it is completed or not?
- Frame can calculate score immediately, but bonuses can be later. Maybe it isn't 'the throw thing' to care about. It is a matter of the game, that can tell when is the right moment to evaluate bonuses. Game can delegate such information to the passed frames at the right moment (maybe after each thow, or maybe when the current frame is completed?). But maybe my previous sentence can be interpreted as:  "this is a big hammer for this solution already". 

 
The fact that there may be one extra roll at the end which is not technically
part of any of the 10 frames is just icing on the cake.

But this is *algorithmic* trickiness, not *world model* trickiness.

Let's imagine a Frame class.
- You get the first roll of the frame.  Fewer than 10 pins are knocked down.
  You cannot complete initialising the Frame yet.

Well, why not just initialize frame by "collection of 1-2 (maybe 3) throws"? Depending on the actual state of collection, frame just tells the game "I have enough throws, so you can pass throws to my neighbor". Rules for completeness can be different, based on circumstances. For me, it is a matter of frame responsibility to deal with this.
 
- All 10 pins are knocked down.  You cannot determine the *score* of the
  frame yet.  This casts some doubt on the idea of the score being part
  of the state of the frame.  The score actually depends on the next two
  THROWS (rolls), not the next frame or the next two frames.  This casts
  much doubt on the idea of the concept "frame" being useful for the
  analysis.  At the very least, you will need to manipulate BOTH frames
  AND throws (rolls).

When bowling in real, you can determine the score of the current frame. But bonuses are computed later, so maybe the game should tell (after each throw), when to evaluate bonus.  "Hey, my passed frames, I'm passing you this information, so evaluate your bonus now". 

 
It looks as though a Frame class may just make things harder.
Since the only thing there is to know about a Throw is how many pins
were knocked down, it doesn't look as though a Throw class is much use
either.  This leaves us with a BowlingGame class that just keeps tracks
of rolls and then runs a moderately complex algorithm when it is asked
for the score.

Long past my bed-time or I would get stuck into it.

 
It depends on how "moderately complex algorithm" will be readable for end users. Sometimes it is a real struggle to determine "what a hell is going on here", because the given method just does too many things in one class. For me, separating throws into frames makes the whole thing more understandable to readers, because they can imagine something from real life (real game). Again, this is personal preference. I've seen few times that "moderately complex algorithms" were extended by other developers into "severe too-complex algorithms". Problem is that developers don't do refactoring at the right time (most probably because of lack of time and time pressure on projects). On the other hand, I understand it isn't a problem of this artificial exercise and agree that focus should be just on existing problem statement and not hypothetical problem.  
I did this exercise some time ago and when I look at it now, honestly I'm not satisfied with my solution, especially the way bonuses are stored and evaluated in normal vs last frame. But here is the thing: it is isolated on one given place and used on one other place, I can rewrite it maybe more easily.

 
On Thu, 24 Sep 2020 at 23:53, Roelof Wobben via Pharo-users <[hidden email]> wrote:
Op 24-9-2020 om 13:42 schreef DavidBajger:
> Hi Roelof,
> I always wonder, what kind of answer you expect from your prior statement.
> To your question: "Can this plan be working or is there improvements to this
> plan." I can have this answer: Yes, it could be both: working or fail, but
> you don't know before you try.
>
> This exercise is a bit tricky:
> 1) I can recommend to use also LastFrame class, which has specific handling
> of bonuses in last round of game (subclass of Frame). Bowling game can be
> then initialized with array 9 Frame instances and last instance could be
> LastFrame. I used specific test methods on frame classes like:
> #isFrameComplete, #isLastFrame, #isSpare, #isStrike, #isOpen.
> 2) Beware that Bowling game should know only necessary things and delegate
> responsibility to its frames. Game itself knows that only if all frames are
> completed, game ends.
> 3) Total score is sum of all throws+bonuses of individual frames, etc.
>
> Does it help to start with exercise?
> David
>
>
>
>
>
> -----
> David Bajger
> --
> Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html

Thanks,

Maybe I have to make it more clear.
What I trying to ask and what you have answered. Do I use the right
classes or too much classes there.
So if my idea of using these classes are right.

What you wrote is what I had in mind with 2  classes but the idea of a
lastFrame could also be working.
and I also agree with you about the responsibilities of the classes.

Roelof

Reply | Threaded
Open this post in threaded view
|

Re: exercism bowling challenge

DavidBajger
In reply to this post by Richard O'Keefe
Thanks for your reply! Anyway.. wow, 3 lines of code, I'd like to see that! I
didn't really get into FLP (except some small howeworks on University and
that's alraeady forgotten), so I don't know, what is the advantage here. I
thought that Pharo (Smalltalk) can be considered as functional language too,
because of blocks. If there wouldn't be any exception handling, would Pharo
code be so compact as well (e.g. by using #inject:into:)?





-----
David Bajger
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html
David Bajger
Reply | Threaded
Open this post in threaded view
|

Re: exercism bowling challenge

Russ Whaley
Yes, my thoughts - since I'm not as technical as the rest of you:

BowlingGame class
"runs the game a calls each frame to 'process'"
- frames (1-10 aFrame objects)
- score (aScore object)
- currentFrame

Frame class
"frame handles #throws, pins remaining, and lets Game know when to advance to next frame - frameEnd"
- frame#
- throws (1-3 aThrow objects - aFrame controls 10th frame 3rd throw)
- score (numeric)

Throw class
- frame (the frame I belong to)
- throw# (incremental numeric 1-3)
- pinsKnockedDown (0-10)

Score class
- frames (same as BowlingGame class)
- methods to calculate score, once a frame score has been determined, it is stored on the frame and the score calc simply picks that up and moves forward on each successive score calc (after each throw - called from inside of aFrame)

This will be a fun little diversion.  I'll create a simple UI and engine that will randomly return a number of pinsKnockedDown when pressing the spacebar to roll the next ball.

On Fri, Sep 25, 2020 at 3:11 PM DavidBajger <[hidden email]> wrote:
Thanks for your reply! Anyway.. wow, 3 lines of code, I'd like to see that! I
didn't really get into FLP (except some small howeworks on University and
that's alraeady forgotten), so I don't know, what is the advantage here. I
thought that Pharo (Smalltalk) can be considered as functional language too,
because of blocks. If there wouldn't be any exception handling, would Pharo
code be so compact as well (e.g. by using #inject:into:)?





-----
David Bajger
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html


--
Russ Whaley
[hidden email]