minecraft-pi-ruby 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/README.md +142 -0
- data/lib/blocks.rb +74 -0
- data/lib/connection.rb +31 -0
- data/lib/minecraft-pi-ruby.rb +87 -0
- data/lib/position.rb +52 -0
- data/minecraft-pi-ruby.gemspec +12 -0
- data/test.rb +29 -0
- data/test/minecraft_spec.rb +63 -0
- data/test/position_spec.rb +34 -0
- metadata +55 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.gem
|
data/README.md
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
#Minecraft-Pi Ruby
|
2
|
+
|
3
|
+
##Please note
|
4
|
+
This project is still in the early stages of development. It is not ready for use
|
5
|
+
with students and has not yet been pushed to RubyGems.
|
6
|
+
|
7
|
+
##Overview
|
8
|
+
|
9
|
+
This is a Ruby gem to allow access to the Minecraft Pi Edition API from Ruby.
|
10
|
+
The aim is that the syntax is clear for fledgling coders to read and
|
11
|
+
understand as they work towards creating their own scripts.
|
12
|
+
|
13
|
+
All the fun of Minecraft Pi Edition and all the goodness of Ruby! With Sonic Pi,
|
14
|
+
KidsRuby and Minecraft, there really is no reason not to show you students the
|
15
|
+
joy of Ruby programming!
|
16
|
+
|
17
|
+
##Introduction
|
18
|
+
The Pi Edition of Minecraft needs to be running for the gem to make a connection. Then you can use Ruby
|
19
|
+
code such as:
|
20
|
+
```
|
21
|
+
Minecraft.world do
|
22
|
+
say "Hello from Ruby!"
|
23
|
+
|
24
|
+
position1 = Position.new(0,10,0)
|
25
|
+
position2 = Position.new(10,20,10)
|
26
|
+
make_cuboid(position1, position2, Block::DIAMOND_BLOCK)
|
27
|
+
sleep 2
|
28
|
+
make_cuboid(position1, position2, Block::AIR)
|
29
|
+
|
30
|
+
10.times do |counter|
|
31
|
+
set_block(counter, 20, 0, Block::STONE)
|
32
|
+
set_block(counter, 20, 9, Block::STONE)
|
33
|
+
set_block(0, 20, counter, Block::STONE)
|
34
|
+
set_block(9, 20, counter, Block::STONE)
|
35
|
+
end
|
36
|
+
|
37
|
+
say "Bye from Ruby!"
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
You can also instantiate a Minecraft object instead of writing script inside Ruby blocks.
|
42
|
+
For example:
|
43
|
+
```
|
44
|
+
mc = Minecraft.new
|
45
|
+
mc.say 'Hello to Steve!'
|
46
|
+
mc.make_cuboid(16,18,16,20,20,20,Block::TNT,1)
|
47
|
+
mc.say 'Now go and click on the TNT!'
|
48
|
+
```
|
49
|
+
##Installation
|
50
|
+
|
51
|
+
TODO
|
52
|
+
|
53
|
+
##Usage
|
54
|
+
|
55
|
+
So far, only the following commands have been implemented
|
56
|
+
|
57
|
+
- `say "message"` to display a message on the screen
|
58
|
+
- `set_camera_mode` to either `:fixed`, `:normal` or `:follow`
|
59
|
+
- `set_block` takes 3 values for the x, y and z location, or a Position (`Position.new(x,y,z)`)
|
60
|
+
- `set_blocks` is the same as `make_cuboid`. It takes 2 Positions and an ID for the block (see below), or
|
61
|
+
two sets of x,y,z coordinates followed by the block ID. For example: `make_cuboid(0,0,0,20,20,20,Block::OBSIDIAN)`.
|
62
|
+
- `get_ground_height(x,z)` or just `ground_height(x,z)` return the height of the ground at the (x,z) location
|
63
|
+
- `set_player_position(x,y,z)` or `set_player_position(Position)` moves the player to that position
|
64
|
+
|
65
|
+
###Block IDs
|
66
|
+
|
67
|
+
Blocks can be set using and ID in the form Block::NAME. For example Block::TNT.
|
68
|
+
|
69
|
+
The blocks are:
|
70
|
+
|
71
|
+
- AIR numerical value is 0
|
72
|
+
- STONE numerical value is 1
|
73
|
+
- GRASS numerical value is 2
|
74
|
+
- DIRT numerical value is 3
|
75
|
+
- COBBLESTONE numerical value is 4
|
76
|
+
- WOOD_PLANKS numerical value is 5
|
77
|
+
- SAPLING numerical value is 6
|
78
|
+
- BEDROCK numerical value is 7
|
79
|
+
- WATER_FLOWING numerical value is 8
|
80
|
+
- WATER numerical value is WATER_FLOWING
|
81
|
+
- WATER_STATIONARY numerical value is 9
|
82
|
+
- LAVA_FLOWING numerical value is 10
|
83
|
+
- LAVA numerical value is LAVA_FLOWING
|
84
|
+
- LAVA_STATIONARY numerical value is 11
|
85
|
+
- SAND numerical value is 12
|
86
|
+
- GRAVEL numerical value is 13
|
87
|
+
- GOLD_ORE numerical value is 14
|
88
|
+
- IRON_ORE numerical value is 15
|
89
|
+
- COAL_ORE numerical value is 16
|
90
|
+
- WOOD numerical value is 17
|
91
|
+
- LEAVES numerical value is 18
|
92
|
+
- GLASS numerical value is 20
|
93
|
+
- LAPIS_LAZULI_ORE numerical value is 21
|
94
|
+
- LAPIS_LAZULI_BLOCK numerical value is 22
|
95
|
+
- SANDSTONE numerical value is 24
|
96
|
+
- BED numerical value is 26
|
97
|
+
- COBWEB numerical value is 30
|
98
|
+
- GRASS_TALL numerical value is 31
|
99
|
+
- WOOL numerical value is 35
|
100
|
+
- FLOWER_YELLOW numerical value is 37
|
101
|
+
- FLOWER_CYAN numerical value is 38
|
102
|
+
- MUSHROOM_BROWN numerical value is 39
|
103
|
+
- MUSHROOM_RED numerical value is 40
|
104
|
+
- GOLD_BLOCK numerical value is 41
|
105
|
+
- IRON_BLOCK numerical value is 42
|
106
|
+
- STONE_SLAB_DOUBLE numerical value is 43
|
107
|
+
- STONE_SLAB numerical value is 44
|
108
|
+
- BRICK_BLOCK numerical value is 45
|
109
|
+
- TNT numerical value is 46
|
110
|
+
- BOOKSHELF numerical value is 47
|
111
|
+
- MOSS_STONE numerical value is 48
|
112
|
+
- OBSIDIAN numerical value is 49
|
113
|
+
- TORCH numerical value is 50
|
114
|
+
- FIRE numerical value is 51
|
115
|
+
- STAIRS_WOOD numerical value is 53
|
116
|
+
- CHEST numerical value is 54
|
117
|
+
- DIAMOND_ORE numerical value is 56
|
118
|
+
- DIAMOND_BLOCK numerical value is 57
|
119
|
+
- CRAFTING_TABLE numerical value is 58
|
120
|
+
- FARMLAND numerical value is 60
|
121
|
+
- FURNACE_INACTIVE numerical value is 61
|
122
|
+
- FURNACE_ACTIVE numerical value is 62
|
123
|
+
- DOOR_WOOD numerical value is 64
|
124
|
+
- LADDER numerical value is 65
|
125
|
+
- STAIRS_COBBLESTONE numerical value is 67
|
126
|
+
- DOOR_IRON numerical value is 71
|
127
|
+
- REDSTONE_ORE numerical value is 73
|
128
|
+
- SNOW numerical value is 78
|
129
|
+
- ICE numerical value is 79
|
130
|
+
- SNOW_BLOCK numerical value is 80
|
131
|
+
- CACTUS numerical value is 81
|
132
|
+
- CLAY numerical value is 82
|
133
|
+
- SUGAR_CANE numerical value is 83
|
134
|
+
- FENCE numerical value is 85
|
135
|
+
- GLOWSTONE_BLOCK numerical value is 89
|
136
|
+
- BEDROCK_INVISIBLE numerical value is 95
|
137
|
+
- STONE_BRICK numerical value is 98
|
138
|
+
- GLASS_PANE numerical value is 102
|
139
|
+
- MELON numerical value is 103
|
140
|
+
- FENCE_GATE numerical value is 107
|
141
|
+
- GLOWING_OBSIDIAN numerical value is 246
|
142
|
+
- NETHER_REACTOR_CORE numerical value is 247
|
data/lib/blocks.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
module Block
|
2
|
+
AIR = 0
|
3
|
+
STONE = 1
|
4
|
+
GRASS = 2
|
5
|
+
DIRT = 3
|
6
|
+
COBBLESTONE = 4
|
7
|
+
WOOD_PLANKS = 5
|
8
|
+
SAPLING = 6
|
9
|
+
BEDROCK = 7
|
10
|
+
WATER_FLOWING = 8
|
11
|
+
WATER = WATER_FLOWING
|
12
|
+
WATER_STATIONARY = 9
|
13
|
+
LAVA_FLOWING = 10
|
14
|
+
LAVA = LAVA_FLOWING
|
15
|
+
LAVA_STATIONARY = 11
|
16
|
+
SAND = 12
|
17
|
+
GRAVEL = 13
|
18
|
+
GOLD_ORE = 14
|
19
|
+
IRON_ORE = 15
|
20
|
+
COAL_ORE = 16
|
21
|
+
WOOD = 17
|
22
|
+
LEAVES = 18
|
23
|
+
GLASS = 20
|
24
|
+
LAPIS_LAZULI_ORE = 21
|
25
|
+
LAPIS_LAZULI_BLOCK = 22
|
26
|
+
SANDSTONE = 24
|
27
|
+
BED = 26
|
28
|
+
COBWEB = 30
|
29
|
+
GRASS_TALL = 31
|
30
|
+
WOOL = 35
|
31
|
+
FLOWER_YELLOW = 37
|
32
|
+
FLOWER_CYAN = 38
|
33
|
+
MUSHROOM_BROWN = 39
|
34
|
+
MUSHROOM_RED = 40
|
35
|
+
GOLD_BLOCK = 41
|
36
|
+
IRON_BLOCK = 42
|
37
|
+
STONE_SLAB_DOUBLE = 43
|
38
|
+
STONE_SLAB = 44
|
39
|
+
BRICK_BLOCK = 45
|
40
|
+
TNT = 46
|
41
|
+
BOOKSHELF = 47
|
42
|
+
MOSS_STONE = 48
|
43
|
+
OBSIDIAN = 49
|
44
|
+
TORCH = 50
|
45
|
+
FIRE = 51
|
46
|
+
STAIRS_WOOD = 53
|
47
|
+
CHEST = 54
|
48
|
+
DIAMOND_ORE = 56
|
49
|
+
DIAMOND_BLOCK = 57
|
50
|
+
CRAFTING_TABLE = 58
|
51
|
+
FARMLAND = 60
|
52
|
+
FURNACE_INACTIVE = 61
|
53
|
+
FURNACE_ACTIVE = 62
|
54
|
+
DOOR_WOOD = 64
|
55
|
+
LADDER = 65
|
56
|
+
STAIRS_COBBLESTONE = 67
|
57
|
+
DOOR_IRON = 71
|
58
|
+
REDSTONE_ORE = 73
|
59
|
+
SNOW = 78
|
60
|
+
ICE = 79
|
61
|
+
SNOW_BLOCK = 80
|
62
|
+
CACTUS = 81
|
63
|
+
CLAY = 82
|
64
|
+
SUGAR_CANE = 83
|
65
|
+
FENCE = 85
|
66
|
+
GLOWSTONE_BLOCK = 89
|
67
|
+
BEDROCK_INVISIBLE = 95
|
68
|
+
STONE_BRICK = 98
|
69
|
+
GLASS_PANE = 102
|
70
|
+
MELON = 103
|
71
|
+
FENCE_GATE = 107
|
72
|
+
GLOWING_OBSIDIAN = 246
|
73
|
+
NETHER_REACTOR_CORE = 247
|
74
|
+
end
|
data/lib/connection.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
class Connection
|
4
|
+
def initialize (server = 'localhost', port = 4711)
|
5
|
+
begin
|
6
|
+
@socket = TCPSocket.new server, port
|
7
|
+
rescue
|
8
|
+
puts "Error connecting to Minecraft. Is it running?\n\n"
|
9
|
+
@socket.close if @socket
|
10
|
+
abort("#{$!}")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def send_command(command)
|
15
|
+
if @socket
|
16
|
+
@socket.puts command
|
17
|
+
else
|
18
|
+
puts "Not connected to Minecraft Pi! Is it running?"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def send_with_response(command)
|
23
|
+
send_command command
|
24
|
+
return @socket.gets.chomp
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def Connection.finalize(id)
|
29
|
+
@socket.close if @socket
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require_relative 'connection'
|
2
|
+
require_relative 'position'
|
3
|
+
require_relative 'blocks'
|
4
|
+
|
5
|
+
class Minecraft
|
6
|
+
include Block
|
7
|
+
|
8
|
+
def initialize(connection = nil)
|
9
|
+
@connection = connection
|
10
|
+
@connection ||= Connection.new
|
11
|
+
end
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def control(&script)
|
15
|
+
mc = self.new
|
16
|
+
mc.instance_eval(&script)
|
17
|
+
end
|
18
|
+
|
19
|
+
alias_method :world, :control
|
20
|
+
end
|
21
|
+
|
22
|
+
def say(message)
|
23
|
+
@connection.send_command "chat.post(#{message})"
|
24
|
+
end
|
25
|
+
|
26
|
+
def set_camera_mode(mode)
|
27
|
+
@connection.send_command 'camera.mode.setNormal' if mode == :normal
|
28
|
+
@connection.send_command 'camera.mode.setFixed' if mode == :fixed
|
29
|
+
@connection.send_command 'camera.mode.setFollow' if mode == :follow
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_block(*args)
|
33
|
+
command = "world.setBlock("
|
34
|
+
case args.length
|
35
|
+
when 2
|
36
|
+
command = command + "#{args[0]},#{args[1]})"
|
37
|
+
when 3
|
38
|
+
command += "#{args[0]},#{args[1]},#{args[2]})"
|
39
|
+
when 4
|
40
|
+
command += "#{args[0]},#{args[1]},#{args[2]},#{args[3]})"
|
41
|
+
when 5
|
42
|
+
command += "#{args[0]},#{args[1]},#{args[2]},#{args[3]},#{args[4]})"
|
43
|
+
else
|
44
|
+
return
|
45
|
+
end
|
46
|
+
@connection.send_command command
|
47
|
+
end
|
48
|
+
|
49
|
+
def set_blocks(*args)
|
50
|
+
command = "world.setBlocks("
|
51
|
+
case args.length
|
52
|
+
when 3
|
53
|
+
command += "#{args[0]},#{args[1]},#{args[2]})"
|
54
|
+
when 4
|
55
|
+
command += "#{args[0]},#{args[1]},#{args[2]},#{args[3]})"
|
56
|
+
when 7
|
57
|
+
command += "#{args[0]},#{args[1]},#{args[2]},#{args[3]},#{args[4]},#{args[5]},#{args[6]})"
|
58
|
+
when 8
|
59
|
+
command += "#{args[0]},#{args[1]},#{args[2]},#{args[3]},#{args[4]},#{args[5]},#{args[6]},#{args[7]})"
|
60
|
+
else
|
61
|
+
return
|
62
|
+
end
|
63
|
+
@connection.send_command command
|
64
|
+
end
|
65
|
+
alias_method :make_cuboid, :set_blocks
|
66
|
+
|
67
|
+
def get_ground_height(x,z)
|
68
|
+
return @connection.send_with_response "world.getHeight(#{x},#{z})"
|
69
|
+
#return s
|
70
|
+
end
|
71
|
+
alias_method :ground_height, :get_ground_height
|
72
|
+
|
73
|
+
def set_player_position(*args)
|
74
|
+
command = "player.setPos("
|
75
|
+
case args.length
|
76
|
+
when 1
|
77
|
+
command += "#{args[0].x},#{args[0].y},#{args[0].z})"
|
78
|
+
when 3
|
79
|
+
command += "#{args[0]},#{args[1]},#{args[2]})"
|
80
|
+
else
|
81
|
+
return
|
82
|
+
end
|
83
|
+
@connection.send_command command
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
data/lib/position.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
class Position
|
2
|
+
|
3
|
+
attr_accessor :x, :y, :z
|
4
|
+
|
5
|
+
def initialize (x,y,z)
|
6
|
+
@x=x
|
7
|
+
@y=y
|
8
|
+
@z=z
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
"#{@x},#{@y},#{@z}"
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
def eql?(position)
|
17
|
+
self.class.equal?(position.class) &&
|
18
|
+
@x == position.x &&
|
19
|
+
@y == position.y &&
|
20
|
+
@z == position.z
|
21
|
+
end
|
22
|
+
alias == eql?
|
23
|
+
|
24
|
+
def +(position)
|
25
|
+
@x+=position.x
|
26
|
+
@y+=position.y
|
27
|
+
@z+=position.z
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def -(position)
|
32
|
+
@x-=position.x
|
33
|
+
@y-=position.y
|
34
|
+
@z-=position.z
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
def *(scale)
|
39
|
+
if scale.is_a?(Numeric)
|
40
|
+
@x*=scale
|
41
|
+
@y*=scale
|
42
|
+
@z*=scale
|
43
|
+
elsif scale.is_a?(Position)
|
44
|
+
@x*=scale.x
|
45
|
+
@y*=scale.y
|
46
|
+
@z*=scale.z
|
47
|
+
end
|
48
|
+
|
49
|
+
self
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
Gem::Specification.new do |s|
|
3
|
+
s.name = 'minecraft-pi-ruby'
|
4
|
+
s.description = 'Control Minecraft Pi Edition using the Ruby programming language.'
|
5
|
+
s.version = '0.0.1'
|
6
|
+
s.date = '2014-10-26'
|
7
|
+
s.summary = 'Minecraft Pi Edition Ruby'
|
8
|
+
s.homepage = 'https://github.com/eaglestone/minecraft-pi-ruby'
|
9
|
+
s.authors = ["Tim Eaglestone"]
|
10
|
+
s.email = ["tim.eaglestone@gmail.com"]
|
11
|
+
s.files = `git ls-files`.split("\n")
|
12
|
+
end
|
data/test.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative "lib/minecraft-pi-ruby"
|
2
|
+
|
3
|
+
Minecraft.world do
|
4
|
+
say "Hello from Ruby!"
|
5
|
+
|
6
|
+
position1 = Position.new(0,10,0)
|
7
|
+
position2 = Position.new(10,20,10)
|
8
|
+
make_cuboid(position1, position2, Block::DIAMOND_BLOCK)
|
9
|
+
sleep 2
|
10
|
+
make_cuboid(position1, position2, Block::AIR)
|
11
|
+
|
12
|
+
10.times do |counter|
|
13
|
+
set_block(counter, 20, 0, Block::STONE)
|
14
|
+
set_block(counter, 20, 9, Block::STONE)
|
15
|
+
set_block(0, 20, counter, Block::STONE)
|
16
|
+
set_block(9, 20, counter, Block::STONE)
|
17
|
+
end
|
18
|
+
|
19
|
+
say "Bye from Ruby!"
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
mc = Minecraft.new
|
24
|
+
mc.say 'Hello to Steve!'
|
25
|
+
mc.set_player_position(16,16,16)
|
26
|
+
sleep 2
|
27
|
+
mc.set_player_position(Position.new(28,18,28))
|
28
|
+
mc.make_cuboid(16,18,16,20,20,20,Block::TNT,1)
|
29
|
+
mc.say 'Now go and click on the TNT!'
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require_relative '../lib/minecraft-pi-ruby'
|
3
|
+
require_relative '../lib/position'
|
4
|
+
|
5
|
+
describe Minecraft do
|
6
|
+
|
7
|
+
before do
|
8
|
+
@conn = MiniTest::Mock.new
|
9
|
+
@mc = Minecraft.new(@conn)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "can be created" do
|
13
|
+
Minecraft.new.must_be_instance_of Minecraft
|
14
|
+
end
|
15
|
+
|
16
|
+
it "can have control called on an instant of the class" do
|
17
|
+
Minecraft.must_respond_to 'control'
|
18
|
+
end
|
19
|
+
|
20
|
+
it "responds to world being called on an instance" do
|
21
|
+
Minecraft.must_respond_to 'world'
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should call the cameraFollow API with the right protocol" do
|
25
|
+
@conn.expect :send_command, :return_value, ['camera.mode.setNormal']
|
26
|
+
@mc.set_camera_mode :normal
|
27
|
+
|
28
|
+
assert @conn.verify
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should send the setBock(x,y,z,id) message" do
|
32
|
+
@conn.expect :send_command, :return_value, ['world.setBlock(1,2,3,4)']
|
33
|
+
@mc.set_block(1,2,3,4)
|
34
|
+
|
35
|
+
assert @conn.verify
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should send the setBlock(x,y,z,id) message when called with a Position" do
|
39
|
+
@conn.expect :send_command, :return_value, ['world.setBlock(1,2,3,4)']
|
40
|
+
@mc.set_block(Position.new(1,2,3),4)
|
41
|
+
@conn.verify
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should handle the setBlocks with two positions given" do
|
45
|
+
@conn.expect :send_command, :return_value, ['world.setBlocks(0,0,0,10,10,10,1)']
|
46
|
+
@mc.set_blocks(Position.new(0,0,0),Position.new(10,10,10),1)
|
47
|
+
assert @conn.verify
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should handle setBlocks with individual coords" do
|
51
|
+
@conn.expect :send_command, :return_value, ['world.setBlocks(0,0,0,3,3,3,2)']
|
52
|
+
@mc.set_blocks(0,0,0,3,3,3,2)
|
53
|
+
assert @conn.verify
|
54
|
+
end
|
55
|
+
|
56
|
+
it "gets the ground level" do
|
57
|
+
@conn.expect :send_with_response, 10, ['world.getHeight(4,5)']
|
58
|
+
height = @mc.get_ground_height(4,5)
|
59
|
+
assert @conn.verify
|
60
|
+
height.must_be_kind_of(Numeric)
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require_relative '../lib/position'
|
3
|
+
|
4
|
+
describe Position do
|
5
|
+
before do
|
6
|
+
@pos = Position.new(1,2,3)
|
7
|
+
end
|
8
|
+
it "initialises with 3 integers for x, y and z" do
|
9
|
+
@pos.x.must_equal 1
|
10
|
+
@pos.y.must_equal 2
|
11
|
+
@pos.z.must_equal 3
|
12
|
+
end
|
13
|
+
|
14
|
+
it "returns to_s in a format for sending to server" do
|
15
|
+
@pos.to_s.must_equal "1,2,3"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "is equal to another Position if the coords are the same" do
|
19
|
+
Position.new(1,2,3).must_equal @pos
|
20
|
+
end
|
21
|
+
|
22
|
+
it "adds the dimensions with another position object" do
|
23
|
+
(@pos + @pos).must_equal Position.new(2,4,6)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "subtracts the dimensions with another position object" do
|
27
|
+
(@pos - @pos).must_equal Position.new(0,0,0)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "does scalar multiplication" do
|
31
|
+
(@pos*4).must_equal Position.new(4,8,12)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: minecraft-pi-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Tim Eaglestone
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-10-26 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Control Minecraft Pi Edition using the Ruby programming language.
|
15
|
+
email:
|
16
|
+
- tim.eaglestone@gmail.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- .gitignore
|
22
|
+
- README.md
|
23
|
+
- lib/blocks.rb
|
24
|
+
- lib/connection.rb
|
25
|
+
- lib/minecraft-pi-ruby.rb
|
26
|
+
- lib/position.rb
|
27
|
+
- minecraft-pi-ruby.gemspec
|
28
|
+
- test.rb
|
29
|
+
- test/minecraft_spec.rb
|
30
|
+
- test/position_spec.rb
|
31
|
+
homepage: https://github.com/eaglestone/minecraft-pi-ruby
|
32
|
+
licenses: []
|
33
|
+
post_install_message:
|
34
|
+
rdoc_options: []
|
35
|
+
require_paths:
|
36
|
+
- lib
|
37
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ! '>='
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
44
|
+
none: false
|
45
|
+
requirements:
|
46
|
+
- - ! '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
requirements: []
|
50
|
+
rubyforge_project:
|
51
|
+
rubygems_version: 1.8.23
|
52
|
+
signing_key:
|
53
|
+
specification_version: 3
|
54
|
+
summary: Minecraft Pi Edition Ruby
|
55
|
+
test_files: []
|