Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Game of Life with Objects!

Game of Life with Objects!

Procedural vs. object-oriented CGOL in Ruby. :)

Matt Campbell

October 10, 2013
Tweet

More Decks by Matt Campbell

Other Decks in Programming

Transcript

  1. A F U N I L L U S T R AT I O N U S I N G T H E G A M E O F L I F E
    CUSTOM-BUILD YOUR
    OBJECTS!
    Follow us:
    @flatironschool

    View Slide

  2. LIGHTEN UP!
    PLEASE READ THESE TO YOURSELF…
    It’s hard to explain puns to kleptomaniacs because
    they always take things literally. (Reddit’s
    NascentEcho)
    The rumors have finally stopped flying around here.
    They can't make it through airport security. (Twitter’s
    @funnyoneliners)

    View Slide

  3. WHAT IS CONWAY’S GAME OF LIFE
    EXACTLY?
    •  This story involves at least a
    couple serious nerds…
    •  John Horton Conway came
    across a very complicated
    hypothetical machine –
    originally developed by John
    von Neumann in the 1940s -
    that could build copies of
    itself.
    •  The original mathematical
    model relied on very
    complicated rules playing
    out on a rectangular grid.
    Conway set out to simplify
    the model, and succeeded.

    View Slide

  4. DA RULES OF DA GAME (OF LIFE)
    1. You do not talk about Fight Club.
    2. You do not talk about Fight Club.
    3. Any live cell with fewer than two live neighbors dies,
    as if caused by under-population.
    •  cell.neighbors < 2 ? cell.die! : cell.live!
    4. Any live cell with two or three live neighbors lives on
    to the next generation.
    5. Any live cell with more than three live neighbors
    dies, as if by overcrowding.
    6. Any dead cell with exactly three live neighbors
    becomes a live cell, as if by reproduction.

    View Slide

  5. THIS GAME IS PLAYED OUT, MAN

    View Slide

  6. GOSPER GLIDER GUN
    •  Gosper glider gun is the
    first known gun, and
    indeed the first known
    finite pattern with
    unbounded growth,
    found by Bill Gosper in
    November 1970. It
    consists of two queen
    bee shuttles stabilized
    by two blocks.
    •  This girl makes me
    happy & sad at the
    same time…

    View Slide

  7. WHY DID I CHOOSE THE GAME OF LIFE?
    •  So if a 14-year-old girl can do it on a friggin’
    Raspberry Pi with LEDs, why did I choose the
    Game of Life? The answer may surprise you…

    View Slide

  8. THE GAME OF LIFE CHOSE ME.

    View Slide

  9. OK, MY “ACTUAL” REASONS
    •  My first (procedural) attempt at the Game of Life felt…
    off.
    ü I was regularly losing track of which methods needed which
    arguments, especially when nesting methods inside other
    methods.
    ü I had to be extremely diligent about keeping track, mentally, of
    each line’s return value so I could pass the right thing to the
    next part of my program.
    ü In short, I was passing stuff around like Joe Montana in his
    prime.
    •  What if we just let the various Game components – Cell
    objects, a World object, even the CLI as an object – exist
    independently & “talk” to one another via their own
    attributes?
    •  I hoped this would simplify my code (not to mention
    eliminating those, “How do you not have enough
    arguments?!” moments)

    View Slide

  10. THE OLD CODE: A FUNCTIONAL,
    PROCEDURAL GAME OF LIFE
    •  Let’s read through it and see if we can quickly get a
    sense for what’s going on…
    •  What jumps out at you? Are we following the Ruby
    Way?

    View Slide

  11. DATA CLUMPS
    “Often you’ll see the same
    three or four data items in lots
    of places: fields in a couple
    of classes, parameters in
    many method signatures.
    Bunches of data that hang
    around together really ought
    to be made into their own
    object.” @martinfowler

    View Slide

  12. DESIGN
    @sandimetz
    •  “In the absence of design, unmanaged
    dependencies wreak havoc because objects know
    too much about one another. Changing one object
    forces change upon its collaborators, which in turn,
    forces change upon its collaborators, ad infinitum.”
    •  “During design you wander through a maze of
    requirements where every juncture represents a
    decision point that has consequences for the
    future.”
    •  Totally wish I’d spoken to Sandi Metz about this…
    though she’d probably be like, “Who are you?”

    View Slide

  13. LET’S TRY THIS GAME THING AGAIN
    This time, let’s think about how we might divide the
    Game into its natural compartments…
    Volunteers. Go.


    Raise hands or someone gets hurt.

    View Slide

  14. AN OBJECT-ORIENTED DESIGN
    Matt vs. CGOL, part deux.

    View Slide

  15. CHANGING THE GAME UP
    •  “Changing requirements are the programming
    equivalent of friction and gravity.” @sandimetz
    •  Imagine that we had invented COGL, and lo and
    behold the world falls in love! We decide we want
    to add a feature to our Game of Life…
    •  Since our Game has become so popular, our
    throngs of users want to start using their own
    customized alive/dead icons – talk about 1st world
    problems!
    •  Specifically, instead of 0’s and 1’s, one user (call
    him Greg Eng) wants to go into the source code
    and use white & black squares so it looks super real

    View Slide

  16. YOUR GOAL IS TO CHANGE
    0’s & 1’s to ▣ & ▢
    Pretty straightforward, right?
    Let’s hit the code…

    View Slide

  17. GIVE YOUR USERS CUSTOMIZABLE
    ICONS!
    How would we go about implementing this change?
    I need a couple of volunteers please…

    View Slide

  18. CHANGING ICONS:
    STRESS METRICS
    •  Procedural version:
    •  Total # of lines of code changed: 10+. (#lame)
    •  Increase in systolic/diastolic blood pressure: +9.8/+21.5
    •  OO version:
    •  Total # of lines of code changed: 2. (#notlame)
    •  Increase in systolic/diastolic blood pressure: -4.0/-5.3
    •  Wow! This stuff really works!

    View Slide

  19. FLOG SCORES:
    PROCEDURAL VS. OO
    •  Flog: http://sadi.st/Flog.html
    •  Gives us a sense for how complex our code is.
    •  OO version has more code than than procedural,
    but we are more interested in complexity per
    method – a lower score per method would tell us
    which strategy will be easier to maintain as time
    goes on and things change…

    View Slide

  20. FLOG: PROCEDURAL REPORT CARD
    195.7: flog total
    32.6: flog/method average
    195.7: main total
    108.7: main#neighbors ./game_of_life.rb:43
    41.6: main#run_generation_of_life ./game_of_life.rb:60
    26.6: main#game_of_life ./game_of_life.rb:88
    7.9: main#generate ./game_of_life.rb:9
    7.2: main#living_cell_counter ./game_of_life.rb:21
    3.6: main#none

    View Slide

  21. FLOG: PROCEDURAL REPORT CARD
    (POST-SYMBOL CHANGE)
    208.0: flog total
    29.7: flog/method average
    208.0: main total
    108.7: main#neighbors new_symbols.rb:33
    41.6: main#run_generation_of_life new_symbols.rb:50
    26.3: main#game_of_life new_symbols.rb:89
    12.6: main#pretty_print new_symbols.rb:78
    7.9: main#generate new_symbols.rb:9
    7.2: main#living_cell_counter new_symbols.rb:22
    3.6: main#none

    View Slide

  22. FLOG: OBJECT-ORIENTED REPORT CARD
    243.7: flog total
    16.2: flog/method average #our method complexity has ½‘ed vs. procedural!
    172.0: World total
    125.1: World#living_neighbors_for_cell ./world.rb:27
    19.2: World#initialize ./world.rb:8
    11.8: World#evolve! ./world.rb:52
    10.9: World#not_changing? ./world.rb:70
    3.9: World#find_cell_by_x_and_y ./world.rb:48
    43.3: CLI total
    23.3: CLI#run ./cli.rb:16
    16.4: CLI#pretty_grid ./cli.rb:31
    2.5: CLI#initialize ./cli.rb:11
    18.1: Cell total
    9.5: Cell#next_generation ./cell.rb:33
    5.4: Cell#initialize ./cell.rb:12
    2.2: Cell#neighbors ./cell.rb:20

    View Slide

  23. FLOG: OBJECT-ORIENTED REPORT CARD
    (POST-SYMBOL CHANGE)
    243.2: flog total
    16.2: flog/method average
    172.0: World total
    125.1: World#living_neighbors_for_cell ./world.rb:27
    19.2: World#initialize ./world.rb:8
    11.8: World#evolve! ./world.rb:52
    10.9: World#not_changing? ./world.rb:70
    3.9: World#find_cell_by_x_and_y ./world.rb:48
    45.0: CLIPretty total
    25.0: CLIPretty#run ./cli_pretty.rb:14
    16.4: CLIPretty#pretty_grid ./cli_pretty.rb:29
    2.5: CLIPretty#initialize ./cli_pretty.rb:9
    18.1: Cell total
    9.5: Cell#next_generation ./cell.rb:33
    5.4: Cell#initialize ./cell.rb:12
    2.2: Cell#neighbors ./cell.rb:20

    View Slide

  24. TO WRAP IT UP…
    •  So what have we learned?
    •  It was much, much easier to change a single line of
    code within my CLIPretty class than to write another
    method (which is called in the body of my
    procedural Game method).
    •  By splitting the Game’s components into classes
    according to the natural, intuitive dividing lines,
    we’ve got a design that can handle our 1x109 users’
    icon preferences
    •  Imagine how easy it’d be to now change the rules
    of the game – we just change the a few lines of
    code in our Cell class and voilà!

    View Slide

  25. QUESTIONS?
    I can’t promise you answers.
    But I’d love to hear what you’re thinking!

    View Slide

  26. THANK YOU J

    View Slide