35
Learning Ruby with RubyWarrior Mr. Big Cat 2011/1/25

Learning Ruby with RubyWarrior

  • Upload
    yc-ling

  • View
    3.073

  • Download
    2

Embed Size (px)

DESCRIPTION

My presentation at Ruby Tuesday Taiwan #16

Citation preview

Page 1: Learning Ruby with RubyWarrior

Learning Ruby withRubyWarrior

Mr. Big Cat2011/1/25

Page 2: Learning Ruby with RubyWarrior

About Me

● 大貓

● I like coding● 大貓共和國: http://gaagaaga.blogspot.com● Twitter&Plurk: miaout17

Page 3: Learning Ruby with RubyWarrior

Outline

● Introducing RubyWarrior● Playing RubyWarrior● Solving RubyWarrior with Metaprogramming

and DSL

Page 4: Learning Ruby with RubyWarrior

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

Who created RubyWarrior?

RubyWarrior is created by Ryan Bates, the

author of Railscasts.

Page 6: Learning Ruby with RubyWarrior

Spoiler Warning!!

Page 7: Learning Ruby with RubyWarrior

How to start?

In your shell:

$ gem install rubywarrior

$ rubywarrior

Demo!

Page 8: Learning Ruby with RubyWarrior

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

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

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

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

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

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

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

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

Pure OO Solution

Demo!

Page 17: Learning Ruby with RubyWarrior

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

What's Metaprogramming?

Page 19: Learning Ruby with RubyWarrior

What's Metaprogramming?

"Writing a program that writes programs."

Page 20: Learning Ruby with RubyWarrior

What's Metaprogramming?

"Writing a program that writes programs."哩咧供殺小?

Page 21: Learning Ruby with RubyWarrior

We use attr_accessor everyday

class Warrior attr_accessor :healthend

w = Warrior.neww.health = 95puts w.health

Page 22: Learning Ruby with RubyWarrior

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

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

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

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

Delegation

Page 27: Learning Ruby with RubyWarrior

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

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

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

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

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

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

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

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

Any Question?