Win a copy of React Cookbook: Recipes for Mastering the React Framework this week in the HTML Pages with CSS and JavaScript forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Rob Spoor
  • Liutauras Vilda
Sheriffs:
  • Jeanne Boyarsky
  • Junilu Lacar
  • Tim Cooke
Saloon Keepers:
  • Tim Holloway
  • Piet Souris
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
Bartenders:
  • Frits Walraven
  • Himai Minh

Test driving the game of Nim

 
Sheriff
Posts: 16578
277
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I was trying my hand at the Nim problem described in this thread: https://coderanch.com/t/744994/java/Nim-game

If you need some background on the game rules, check out the Wikipedia article: https://en.wikipedia.org/wiki/Nim

I never cease to be impressed at how well TDD works and wonder why there aren't more developers trying to learn it. Here's the test class I ended up with by the time I got the basic functionality test-driven to where I could simulate a game.

This is the console output:

Pile: 13, Computer takes 1...
Pile: 12, Human takes 3...
Pile: 9, Computer takes 2...
Pile: 7, Human takes 1...
Pile: 6, Computer takes 2...
Pile: 4, Human takes 1...
Pile: 3, Computer takes 2...
Pile: 1 ==> Computer wins!


I'm opening this thread up for questions and discussion.
 
Marshal
Posts: 8049
569
Mac OS X VI Editor BSD Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Really Nice.


Junilu Lacal wrote:


What's your opinion... Do you think we could find a better name for a method game.marblesLeft(). The name as such isn't bad to me, however, I find a bit of disharmony when it is used in the context of test name should_start_with....

When I start something, I don't think how many of Something I've got left. When I do something with that Something, then I kind of thinking how many I've got left now that I've done something. Not sure if I'm clear, but I think you'd get what I mean.

Would names game.marblesGot() or game.marblesIGot() would still communicate the same idea, but also would read better in the context of game initialization/start? i.e.:

 
Junilu Lacar
Sheriff
Posts: 16578
277
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'd like to put a challenge out there to anyone reading this thread. See if you can use these tests to come up with an implementation of the Nim class.

You can use the @Disabled annotation to disable tests. The nested classes make it convenient to disable a bunch of tests because you can just annotate the nested class itself to disable all the tests within it.

Then we can compare implementations.
 
Junilu Lacar
Sheriff
Posts: 16578
277
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Liutauras Vilda wrote:
What's your opinion... Do you think we could find a better name for a method game.marblesLeft(). The name as such isn't bad to me, however, I find a bit of disharmony when it is used in the context of test name should_start_with....



That's a great point. This is why I love pair/mob programming because you get this kind of feedback. Tell the story and call it out whenever it doesn't make sense.

I made the change and the story the code tells makes much more sense. Thanks, Liu!
 
Junilu Lacar
Sheriff
Posts: 16578
277
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here's what it looks like with the changes. I went with marblesInPile().
 
Liutauras Vilda
Marshal
Posts: 8049
569
Mac OS X VI Editor BSD Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Just checking..

Line 63, shouldn't be > 0 as opposed to > 1?

Given

Staff note (Liutauras Vilda) :

I'm not familiar with this game.

Staff note (Junilu Lacar) :

Check out the Wikipedia article: https://en.wikipedia.org/wiki/Nim and the thread I linked to in the OP

 
Junilu Lacar
Sheriff
Posts: 16578
277
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
A heuristic I applied to some degree while TDD'ing this was James Grenning's ZOMBIES - Zero, One, Many, Boundary conditions, Interfaces, Exceptions, Simple solutions / Simple scenarios.

It's a very useful mnemonic.
 
Junilu Lacar
Sheriff
Posts: 16578
277
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Liutauras Vilda wrote:
Line 63, shouldn't be > 0 as opposed to > 1?


The game ends when there's only 1 marble left in the pile. The winner is the player who moved last, leaving that one marble for the losing player to pick up.
 
Junilu Lacar
Sheriff
Posts: 16578
277
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That question was the smell/sound of a lack of understanding, i.e., technical debt.

What can we do to address it? This is what you have to tune your ear to detect. It's an auditory cue for code smells. (I'll elaborate on that in another reply)

(This is great, by the way, almost as good as we were doing a face-to-face pairing session)
 
Junilu Lacar
Sheriff
Posts: 16578
277
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
One of the thoughts I have about learning how to refactor is that many developers find it very daunting. If you think about it, it is kind of overwhelming. Martin Fowler's book alone has 22/24 (1st ed/2nd ed) code smells listed. The first edition has 73 different refactoring techniques catalogued. I didn't count how many there are in the 2nd edition but there are about as many. Who has the time or ability to learn all that?

So, I teach people to start simple. Start with what you know and the senses you already have. We call them code "smells" but if you really think about it, we're actually using our other senses:

1. Visual cues - long methods, long classes, long parameter lists, arrow code, (mechanically) duplicate code

2. Audible cues - when we discuss the program code and read it out loud, we tell its story. We can hear discrepancies. Questions we ask indicate a lack of clarity. "What does this mean?" "Would it make more sense if it said this instead?" These are all audible cues to refactor the code. I call them "the sound of Technical Debt" being that my definition of technical debt is "a lack of understanding embodied in the program."

3. Temporal cues - the passing of time.

How long does it take to understand a few lines of code? (It shouldn't be more than a few seconds—I set my pain threshold pretty low at 3 seconds).

How long does it take to connect the dots and understand the context around the code? (Shouldn't take more than 30 seconds; any longer than that you need to start pulling things together and consolidating the ideas so they're all close to each other)

How long has it been since we ran the tests? (Should run every 3 minutes or so; any longer than that and you're getting bogged down in details)

How long has it been since we took a break? (Should do focused work in 25 to 50 minutes at a time and take a 5 or 10 minute break between Pomodoros)
 
Junilu Lacar
Sheriff
Posts: 16578
277
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I feel another blog post coming... ;)

Thanks again for engaging in this discussion, Liu. It's great stuff, at least for me.
Staff note (Liutauras Vilda) :

No, it is thanks to you. Pretty late here, I'll have to go now, but I'll get back to this thread tomorrow.

 
Junilu Lacar
Sheriff
Posts: 16578
277
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have this code in Nim.java:

I just added that last line for here, to show how long this program is. Not very long, really.

Lines 99 and 100 determine how the computer's and human player's moves will be obtained.

To make the game interactive and allow the human player to enter their move on console, I could change line 100 to this:

I'm loving the flexibility of this design. The great thing about it is that it's still very testable, as well it should be. After all, I did start writing this from the tests.

The winningMove() method has some "AI" logic that finds the best move to make to guarantee a win. I haven't seen it lose yet against the computer making random moves. I'm going to try to pit the AI logic against itself and see how it goes.
 
I will open the floodgates of his own worst nightmare! All in a tiny ad:
the value of filler advertising in 2021
https://coderanch.com/t/730886/filler-advertising
reply
    Bookmark Topic Watch Topic
  • New Topic