Permalink
Browse files

Refactoring and adding baby messages

  • Loading branch information...
1 parent ef23ba5 commit abe7ea7c0c84b2878bdb80b165418d60674f44e6 @jsl committed Jul 21, 2012
Showing with 373 additions and 222 deletions.
  1. +4 −0 Gemfile
  2. +22 −0 LICENSE
  3. +14 −0 README.md
  4. +0 −222 baby.rb
  5. +17 −0 baby_sim.gemspec
  6. +35 −0 lib/baby_sim.rb
  7. +57 −0 lib/baby_sim/baby.rb
  8. +11 −0 lib/baby_sim/cell.rb
  9. +116 −0 lib/baby_sim/field.rb
  10. +50 −0 lib/baby_sim/shoes.rb
  11. +44 −0 lib/baby_sim/thing.rb
  12. +3 −0 lib/baby_sim/version.rb
View
@@ -0,0 +1,4 @@
+source 'https://rubygems.org'
+
+# Specify your gem's dependencies in baby.gemspec
+gemspec
View
@@ -0,0 +1,22 @@
+Copyright (c) 2012 Justin S. Leitgeb
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
@@ -0,0 +1,14 @@
+# Baby Simulator
+
+Simulates a baby in environments full of dangerous or helpful things.
+
+Basic shoes app to demonstrate some meta-programming features of Ruby.
+
+A baby roams around a square apartment containing things that can either help or hurt the baby.
+The demo app comes loaded with an environment containing bananas (helpful) and samurai swords
+(hurtful).
+
+To run, download Shoes for your operating system and open the lib/baby_sim/baby_sim.rb file.
+
+To configure the baby's environment, change the DSL in lib/baby_sim.rb in order to change object
+quantities or add other objects to the environment.
View
@@ -1,222 +0,0 @@
-class Thing
- attr_reader :name, :color, :effect
-
- def initialize(name, color, effect)
- @name = name
- @color = color
- @effect = effect
- end
-end
-
-class Cell
- attr_accessor :contents
-
- def initialize(contents = nil)
- @contents = contents
- end
-end
-
-SWORD = Thing.new('Samurai Sword', "#FF0000", -2)
-BANANA = Thing.new('Banana', "#FFFF00", 2)
-
-class Baby
- attr_reader :health, :color, :name
- attr_accessor :location
-
- def initialize
- @health = 0
- @color = "#999"
- @name = 'Baby'
- @location = [15, 15]
- end
-
- def encounter(thing)
- @health += thing.effect
- end
-
- def status
- if (health > 5)
- "thriving"
-
- elsif (health > 0) && (health < 4)
- "happy"
-
- elsif health == 0
- "ok"
-
- elsif (health > -5) && (health < 0)
- "crying"
-
- elsif health < -4
- "dead"
-
- end
- end
-
- def thriving?
- status == "thriving"
- end
-
- def dead?
- status == "dead"
- end
-
- def finished?
- dead? || thriving?
- end
-end
-
-class Field
- CELL_SIZE = 20
- UNITS_WIDE = 25
- UNITS_TALL = 25
-
-
- attr_reader :cell_size, :offset, :baby
-
- def initialize(app)
- @app = app
- @field = []
- @baby = Baby.new
-
-
- UNITS_TALL.times { @field << Array.new(UNITS_WIDE) { Cell.new } }
- @width, @height = UNITS_WIDE * CELL_SIZE, UNITS_TALL * CELL_SIZE
- @offset = [(@app.width - @width.to_i) / 2, (@app.height - @height.to_i) / 2]
- end
-
- def paint
- 0.upto UNITS_TALL-1 do |y|
- 0.upto UNITS_WIDE-1 do |x|
- @app.nostroke
- render_cell(x, y)
- end
- end
-
- 10.times {
- x, y = random_empty_cell
- add_to_cell(x, y, SWORD)
- }
-
- 50.times {
- x, y = random_empty_cell
- add_to_cell(x, y, BANANA)
- }
-
- add_to_cell(@baby.location.first, @baby.location.last, @baby)
- end
-
- def render_cell(x, y, color = "#AAA", stroke = true)
- @app.stroke "#666" if stroke
- @app.fill color
- @app.rect x*CELL_SIZE, y*CELL_SIZE, CELL_SIZE-1, CELL_SIZE-1
- @app.stroke "#BBB" if stroke
- @app.line x*CELL_SIZE+1, y*CELL_SIZE+1, x*CELL_SIZE+CELL_SIZE-1, y*CELL_SIZE
- @app.line x*CELL_SIZE+1, y*CELL_SIZE+1, x*CELL_SIZE, y*CELL_SIZE+CELL_SIZE-1
- end
-
- def add_to_cell(x, y, thing)
- render_cell(x, y, thing.color, false)
-
- self[x, y] = Cell.new(thing)
-
- @app.nostroke
- @app.para thing.name[0], :left => x*CELL_SIZE + 3, :top => y*CELL_SIZE - 2, :font => '13px', :stroke => "#00A"
- end
-
- def clean_cell(x, y)
- render_cell(x, y)
- self[x, y] = Cell.new
- end
-
- def choose_adjacent_cell(x, y)
- move = Proc.new {|pos| pos += [-1, 0, 1].sample }
- new_x, new_y = [move.call(x), move.call(y)]
- end
-
- def move_baby
- clean_cell(@baby.location.first, @baby.location.last)
-
- @baby.location = random_direction(@baby.location.first, @baby.location.last)
-
- if contents = self[@baby.location.first, @baby.location.last].contents
- @baby.encounter(contents)
- end
-
- add_to_cell(@baby.location.first, @baby.location.last, @baby)
- end
-
- # Returns an available cell adjacent to the given x, y
- def random_direction(x, y)
- new_x = new_y = nil
-
- until [x, y] != [new_x, new_y] && cell_exists?(new_x, new_y)
- new_x, new_y = choose_adjacent_cell(x, y)
- end
-
- [new_x, new_y]
- end
-
- def random_empty_cell
- x = y = nil
-
- until cell_exists?(x, y) && self[x, y].contents.nil?
- x = (1..UNITS_WIDE).to_a.sample
- y = (1..UNITS_TALL).to_a.sample
- end
-
- [x, y]
- end
-
- def cell_exists?(x, y)
- ((0...UNITS_WIDE).include? x) && ((0...UNITS_TALL).include? y)
- end
-
- def [](*args)
- x, y = args
- raise "Cell #{x}:#{y} does not exists!" unless cell_exists?(x, y)
- @field[y][x]
- end
-
- def []=(*args)
- x, y, v = args
- cell_exists?(x, y) ? @field[y][x] = v : false
- end
-end
-
-Shoes.app :width => 730, :height => 730, :title => 'Baby' do
- def render_field
- clear do
- background rgb(50, 50, 90, 0.7)
-
- flow :margin => 4 do
- button("Start over") { new_simulation }
- end
-
- stack do @status = para :stroke => white end
-
- @field.paint
-
- para "Watch out baby!!!", :top => 510, :left => 0, :stroke => white, :font => "11px"
- end
- end
-
- def new_simulation
- @field = Field.new(self)
-
- translate -@old_offset.first, -@old_offset.last unless @old_offset.nil?
- translate @field.offset.first, @field.offset.last
- @old_offset = @field.offset
-
- render_field
-
- a = animate(5) do
- @field.move_baby
- @status.replace "Baby is #{@field.baby.status} (health meter #{@field.baby.health})"
-
- a.stop if @field.baby.finished?
- end
- end
-
- new_simulation
-end
View
@@ -0,0 +1,17 @@
+# -*- encoding: utf-8 -*-
+require File.expand_path('../lib/baby/version', __FILE__)
+
+Gem::Specification.new do |gem|
+ gem.authors = ["Justin S. Leitgeb"]
+ gem.email = ["justin@stackbuilders.com"]
+ gem.description = %q{TODO: Write a gem description}
+ gem.summary = %q{TODO: Write a gem summary}
+ gem.homepage = ""
+
+ gem.files = `git ls-files`.split($\)
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
+ gem.name = "babysim"
+ gem.require_paths = ["lib"]
+ gem.version = BabySim::VERSION
+end
View
@@ -0,0 +1,35 @@
+require 'baby_sim/baby'
+require 'baby_sim/cell'
+require 'baby_sim/field'
+require 'baby_sim/thing'
+require 'baby_sim/version'
+
+
+
+module BabySim
+
+ COLORS = {
+ red: '#FF0000',
+ yellow: '#FFFF00',
+ purple: '##FF00FF',
+ green: '#00FF00'
+ }
+
+ Thing.new('Samurai Sword') do
+ color COLORS[:red]
+ effect -2
+ count 60
+ message "Ouch! That's sharp!"
+ end
+
+ Thing.new('Banana') do
+ color COLORS[:yellow]
+ effect +2
+ count 30
+ message "Yum! Tasty banana."
+ end
+end
+
+require 'baby_sim/shoes'
+
+
View
@@ -0,0 +1,57 @@
+module BabySim
+ class Baby
+ attr_reader :health, :color, :name
+ attr_accessor :location
+
+ def initialize
+ @health = 0
+ @color = "#999"
+ @name = 'Baby'
+ @location = [15, 15]
+
+ @encounter_messages = [ ]
+ end
+
+ def encounter(thing)
+ @health += thing.effect
+ @encounter_messages << thing.message unless thing.message.nil?
+ end
+
+ def last_encounter_message
+ @encounter_messages.last
+ end
+
+ def status
+ if (health > 5)
+ "grown up"
+
+ elsif (health > 0) && (health < 4)
+ "happy"
+
+ elsif health == 0
+ "ok"
+
+ elsif (health > -5) && (health < 0)
+ "crying"
+
+ elsif health < -4
+ "dead"
+
+ end
+ end
+
+ def grown_up?
+ status == "grown up"
+ end
+
+ def dead?
+ status == "dead"
+ end
+
+ def finished?
+ dead? || grown_up?
+ end
+ end
+end
+
+
View
@@ -0,0 +1,11 @@
+module BabySim
+ class Cell
+ attr_accessor :contents
+
+ def initialize(contents = nil)
+ @contents = contents
+ end
+ end
+end
+
+
Oops, something went wrong.

0 comments on commit abe7ea7

Please sign in to comment.