Skip to main content
  1. Posts/

Day 84 - Beholder on Your Phone pt2

OldDays sms-beholder ruby

Monopoly is in the eye of the beholder.
Monopoly is in the eye of the beholder.

In which we continue to port a very reasonable game to an unreasonable platform.

Test, Code, Repeat
#

Still working on the port of Beholder High, still concentrating on just the text for now. First more tests, to make sure we can take the player name:

spec/sms_beholder_spec.rb
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
  it 'accepts a player name' do
    get '/', From: 'Dude4'
    get '/', From: 'Dude4', Body: 'NameOfDude4'
    get '/', From: 'Dude4'
    get '/', From: 'Dude4'

    expect(last_response.body).to include("You're NameOfDude4, a student at Beholder High.")
  end

  it 'uses the right player name' do
    get '/', From: 'Dude5'
    get '/', From: 'Dude5', Body: 'NumberFive'
    get '/', From: 'Dude6'
    get '/', From: 'Dude6'
    get '/', From: 'Dude5'
    get '/', From: 'Dude5'

    expect(last_response.body).to include("You're NumberFive, a student at Beholder High.")
  end

and we flesh out the code to pass them:

sms_beholder.rb
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class SMSBeholder < Sinatra::Base
  player_data = {}
  game_states = JSON.parse(File.open('script.json', 'r').read)

  get '/' do
    source = params['From']
    body   = params['Body']

    player_data[source] ||= {} 
    player_data[source]['state'] ||= 'SPLASH'

    state = player_data[source]['state']
    puts state

    # Handle input
    if player_data[source].key?('last_state')
      last_state = player_data[source]['last_state']
      if game_states[last_state].key?('textEntry')
        text_entry_key = game_states[last_state]['textEntry']['key']
        player_data[source][text_entry_key] = body
      end
    end

    next_state = game_states[state]['next']
    response = game_states[state]['story']
    player_data[source]['last_state'] = state
    player_data[source]['state'] = next_state
    puts player_data

    # Fill in values in response
    for key in player_data[source].keys
      response.sub!(":#{key}:", player_data[source][key])
    end
    response
  end

So now we have a player_data hash, keyed by message source, to keep player data. We keep the state there, defaulted to SPLASH.

Also, if the last state had a textEntry key, we set that key on the player to the test they entered.

Finally, when sending the text to the player, we can subsitute anything if the form of :some_key: with the value of that key in the player data.

With the end result that we can now pass those tests. Yay!

Cheat Code
#

This is really awkward:

spec/sms_beholder_spec.rb
32
33
34
35
36
  it 'accepts a player name' do
    get '/', From: 'Dude4'
    get '/', From: 'Dude4', Body: 'NameOfDude4'
    get '/', From: 'Dude4'
    get '/', From: 'Dude4'

and will only get worse as we progress. A purist would dictate that this should be addressed in the test code (and I probably will at some point), but let’s use this opportunity to implement a cheat code in the game itself (to be used purely for testing, of course).

We’ll test-drive this as well:

spec/sms_beholder_spec.rb
52
53
54
55
56
  it 'lets you skip to a different state for testing' do
    get '/', From: 'Dude7', SkipToState: 'D1S107'

    expect(last_response.body).to include("Your brooding has distracted you")
  end

and the implementation is simple:

sms_beholder.rb
16
17
    state = player_data[source]['state']
    state = params['SkipToState'] if params.key?('SkipToState')
Good and bad.
Good and bad.

Rubocop has some complaints, and we may want to tackle those. Tomorrow.


Useful Stuff
#


More to come
More to come

Day 84 code