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
  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)
  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.
  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.
  5. 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…
  6. 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…
  7. 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)
  8. 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?
  9. 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
  10. 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?”
  11. 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.
  12. 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
  13. YOUR GOAL IS TO CHANGE 0’s & 1’s to ▣

    & ▢ Pretty straightforward, right? Let’s hit the code…
  14. GIVE YOUR USERS CUSTOMIZABLE ICONS! How would we go about

    implementing this change? I need a couple of volunteers please…
  15. 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!
  16. 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…
  17. 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
  18. 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
  19. 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
  20. 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
  21. 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à!