Learning Ruby with RubyWarrior
description
Transcript of Learning Ruby with RubyWarrior
![Page 1: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/1.jpg)
Learning Ruby withRubyWarrior
Mr. Big Cat2011/1/25
![Page 2: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/2.jpg)
About Me
● 大貓
● I like coding● 大貓共和國: http://gaagaaga.blogspot.com● Twitter&Plurk: miaout17
![Page 3: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/3.jpg)
Outline
● Introducing RubyWarrior● Playing RubyWarrior● Solving RubyWarrior with Metaprogramming
and DSL
![Page 4: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/4.jpg)
What is RubyWarrior?
A game designed to teach the Ruby language and artificial intelligence in a fun, interactive way.
![Page 5: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/5.jpg)
Who created RubyWarrior?
RubyWarrior is created by Ryan Bates, the
author of Railscasts.
![Page 6: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/6.jpg)
Spoiler Warning!!
![Page 7: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/7.jpg)
How to start?
In your shell:
$ gem install rubywarrior
$ rubywarrior
Demo!
![Page 8: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/8.jpg)
How to play?
Demo!
Edit Your ScriptEdit Your ScriptRead README and
Edit Your Script
Run RubyWarrior
Jump to the next levelGain New Abilities
Level Passed?
No
Yes
![Page 9: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/9.jpg)
What's Within?
Player
play_turn...
wall?enemy?captive?empty?stairs?ticking?
RubyWarrior::Space
RubyWarrior::Turn
attack!detonate!rescue!
rest!shoot!walk!
direction_ofdistance_of
health
feellistenlook
![Page 10: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/10.jpg)
What's Within?
Player
play_turn...
wall?enemy?captive?empty?stairs?ticking?
RubyWarrior::Space
RubyWarrior::Turn
attack!detonate!rescue!
rest!shoot!walk!
direction_ofdistance_of
health
feellistenlook
![Page 11: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/11.jpg)
What's Within?
Player
play_turn...
wall?enemy?captive?empty?stairs?ticking?
RubyWarrior::Space
RubyWarrior::Turn
attack!detonate!rescue!
rest!shoot!walk!
direction_ofdistance_of
health
feellistenlook
![Page 12: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/12.jpg)
What's Within?
Player
play_turn...
wall?enemy?captive?empty?stairs?ticking?
RubyWarrior::Space
RubyWarrior::Turn
attack!detonate!rescue!
rest!shoot!walk!
direction_ofdistance_of
health
feellistenlook
![Page 13: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/13.jpg)
Epic Mode
Demo!
Level 1
Level 2
Level 3
Level 4
Level 5
Level 6
Level 7
Level 8
Level 9
Level 1
Level 2
Level 3
Level 4
Level 5
Level 6
Level 7
Level 8
Level 9
Beginner Intermediate
EpicMode
EpicMode
![Page 14: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/14.jpg)
My Epic Mode Solution
● An AI logic that pass intermediate epic mode with all-S rank
● Three implementation styles: ● Naive Solution● Pure-OO Solution● Metaprogramming&DSL Solution
![Page 15: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/15.jpg)
Naive SolutionDIRS.each do |dir| if @warrior.feel(dir).ticking? @warrior.rescue!(dir) return endend
return if walk_to_ticking!
DIRS.each do |dir| if should_detonate?(dir) detonate!(dir) return endend
DIRS.each do |dir| if @warrior.feel(dir).enemy? @warrior.attack!(dir) return endend
DIRS.each do |dir| if @warrior.feel(dir).captive? @warrior.rescue!(dir) return endend
walk!(direction_of_stairs)
Demo!
![Page 16: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/16.jpg)
Pure OO Solution
Demo!
![Page 17: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/17.jpg)
Metaprogramming&DSL Solution
● Today we won't focus on how to do metaprogramming and create a DSL
● We focus on how metaprogramming & DSL make our life easier
![Page 18: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/18.jpg)
What's Metaprogramming?
![Page 19: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/19.jpg)
What's Metaprogramming?
"Writing a program that writes programs."
![Page 20: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/20.jpg)
What's Metaprogramming?
"Writing a program that writes programs."哩咧供殺小?
![Page 21: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/21.jpg)
We use attr_accessor everyday
class Warrior attr_accessor :healthend
w = Warrior.neww.health = 95puts w.health
![Page 22: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/22.jpg)
What is attr_accessor?
class Warrior attr_accessor :healthend
w = Warrior.neww.health = 95puts w.health
class Warrior def health @health end def health=(val) @health = val endend
w = Warrior.neww.health = 59puts w.health
attr_acccessor is a METHOD!
![Page 23: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/23.jpg)
Getter/Setter in Java
class Warrior{ public void setHealth(int val) { health = val; } public int getHealth() { return health; } private int health;}
public class AttrAccessor{ public static void main(String[] args) { Warrior s = new Warrior(); s.setHealth(95); System.out.println("Health = " + s.getHealth()); }}
![Page 24: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/24.jpg)
Delegation
class Player
def hurt? return false unless @last_health return @warrior.health < @last_health end
def play_turn(warrior) @warrior = warrior if @warrior.feel.captive? @warrior.rescue! elsif [email protected]? @warrior.attack! elsif @warrior.health == 20 || hurt? @warrior.walk! else @warrior.rest! end @last_health = @warrior.health end
end
![Page 25: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/25.jpg)
Delegation
class Player
def hurt? return false unless @last_health return @warrior.health < @last_health end
def play_turn(warrior) @warrior = warrior if @warrior.feel.captive? @warrior.rescue! elsif [email protected]? @warrior.attack! elsif @warrior.health == 20 || hurt? @warrior.walk! else @warrior.rest! end @last_health = @warrior.health end
end
class Player
def hurt? return false unless @last_health return health < @last_health end
def play_turn(warrior) @warrior = warrior if feel.captive? rescue! elsif !feel.empty? attack! elsif health == 20 || hurt? walk! else rest! end @last_health = health end
end
![Page 26: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/26.jpg)
Delegation
![Page 27: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/27.jpg)
Delegation Implementation
class Player
def health @warrior.health end
def feel @warrior.feel end
def rescue! @warrior.rescue! end
def attack! @warrior.attack! end
def walk! @warrior.walk! end
def rest! @warrior.rest! end
![Page 28: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/28.jpg)
Delegation Implementation
class Player
def health @warrior.health end
def feel @warrior.feel end
def rescue! @warrior.rescue! end
def attack! @warrior.attack! end
def walk! @warrior.walk! end
def rest! @warrior.rest! end
require 'forwardable'
class Player
extend Forwardable
def_delegators :@warrior, :health, :feel, :rescue!, :attack!, :walk!, :rest!
![Page 29: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/29.jpg)
Domain Specific Language(DSL) solution
DIRS.each do |dir| if @warrior.feel(dir).ticking? @warrior.rescue!(dir) return endend
return if walk_to_ticking!
DIRS.each do |dir| if should_detonate?(dir) detonate!(dir) return endend
DIRS.each do |dir| if @warrior.feel(dir).enemy? @warrior.attack!(dir) return endend
DIRS.each do |dir| if @warrior.feel(dir).captive? @warrior.rescue!(dir) return endend
walk!(direction_of_stairs)
require 'player_helper'
class Player
include PlayerHelper
def_strategries do directional(:rescue!, :ticking?) strategy { rest! if rest_when_ticking? } directional(:detonate!, :should_detonate?) directional(:attack!, :enemy?) directional(:rescue!, :captive?) strategy { walk!(direction_of_stairs) } end
Demo!
PlayerHelper
Player
![Page 30: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/30.jpg)
DSL is Everywhere
● Rails Routing
resources :forums, :only => [:index, :show] do resources :posts end
namespace :admin do resources :forums do resources :posts, :except => [:new, :create] end end
![Page 31: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/31.jpg)
DSL is Everywhere
● Rake Task
task :drink do puts "I drink juice"end
task :eat do puts "I eat sandwich"end
task :breakfast => [:drink, :eat] do puts "I ate breakfast"end
![Page 32: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/32.jpg)
Conclusion: The Ruby way I know
Rails
ActiveRecord ActionMailer
ActionPack ActiveSupport
...
PlayerHelper
Player Rails App Rake Task
Rake
My RubyWarrior Script Rails Rake
Implementing high-level logic is incredible simple with easy-to-use API and DSL
Write API and create DSL with metaprogramming techniques
![Page 33: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/33.jpg)
Lecture martial
● Source code is available on githubhttps://github.com/gaagaaga/warrior-tuesday● i-naive● i-oo● i-dsl● dsl-starter
● Slide will be on slideshare (coming soon)
![Page 34: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/34.jpg)
Learning Resource
● For Beginners: ● TryRuby: http://tryruby.org/● RubyWarrior: https://github.com/ryanb/ruby-warrior● The Ruby Programming Language (Book)
● For Intermediate:● Eloquent Ruby (Book)● Metaprogramming Ruby (Book)
![Page 35: Learning Ruby with RubyWarrior](https://reader034.fdocument.pub/reader034/viewer/2022042816/559b480a1a28abc52e8b46bc/html5/thumbnails/35.jpg)
Any Question?