Change the facing with a turn_left method in Ruby
I need to create a method turn_left who changes the facing, facing always start in :south (Im implementing a robot who moves into a board) so if i call method turn_left should change the facing to East and then to North and to West and then return to south. Im thinking in something like this:
{
0: S
1: E
2: N
3: W
}
this is my code
# Models the Robor behavior for the game
class Robot
def initialize(attr = {})
# @position = attr[:position]
# @move = attr[:move]
@facing = :south
# @turn_left =
# @turn_right =
# @errors =
end
def position
end
def move
end
def facing
@facing
end
def turn_left
end
def turn_right
end
def errors
end
end
Thank you so much!!!
ruby
add a comment |
I need to create a method turn_left who changes the facing, facing always start in :south (Im implementing a robot who moves into a board) so if i call method turn_left should change the facing to East and then to North and to West and then return to south. Im thinking in something like this:
{
0: S
1: E
2: N
3: W
}
this is my code
# Models the Robor behavior for the game
class Robot
def initialize(attr = {})
# @position = attr[:position]
# @move = attr[:move]
@facing = :south
# @turn_left =
# @turn_right =
# @errors =
end
def position
end
def move
end
def facing
@facing
end
def turn_left
end
def turn_right
end
def errors
end
end
Thank you so much!!!
ruby
oh Im kinda new here I thought that I should select one if works but yea you are right! :)
– Andrea Bazán
Nov 13 '18 at 17:16
Got it! was because my whole platform is building in Rails but yea, this part is just Ruby.
– Andrea Bazán
Nov 13 '18 at 17:35
This is not a precise enough error description for us to help you. What doesn't work? How doesn't it work? What trouble do you have with your code? Do you get an error message? What is the error message? Is the result you are getting not the result you are expecting? What result do you expect and why, what is the result you are getting and how do the two differ? Is the behavior you are observing not the desired behavior? What is the desired behavior and why, what is the observed behavior, and in what way do they differ?
– Jörg W Mittag
Nov 13 '18 at 20:05
add a comment |
I need to create a method turn_left who changes the facing, facing always start in :south (Im implementing a robot who moves into a board) so if i call method turn_left should change the facing to East and then to North and to West and then return to south. Im thinking in something like this:
{
0: S
1: E
2: N
3: W
}
this is my code
# Models the Robor behavior for the game
class Robot
def initialize(attr = {})
# @position = attr[:position]
# @move = attr[:move]
@facing = :south
# @turn_left =
# @turn_right =
# @errors =
end
def position
end
def move
end
def facing
@facing
end
def turn_left
end
def turn_right
end
def errors
end
end
Thank you so much!!!
ruby
I need to create a method turn_left who changes the facing, facing always start in :south (Im implementing a robot who moves into a board) so if i call method turn_left should change the facing to East and then to North and to West and then return to south. Im thinking in something like this:
{
0: S
1: E
2: N
3: W
}
this is my code
# Models the Robor behavior for the game
class Robot
def initialize(attr = {})
# @position = attr[:position]
# @move = attr[:move]
@facing = :south
# @turn_left =
# @turn_right =
# @errors =
end
def position
end
def move
end
def facing
@facing
end
def turn_left
end
def turn_right
end
def errors
end
end
Thank you so much!!!
ruby
ruby
edited Nov 13 '18 at 17:34
Andrea Bazán
asked Nov 13 '18 at 16:50
Andrea BazánAndrea Bazán
488
488
oh Im kinda new here I thought that I should select one if works but yea you are right! :)
– Andrea Bazán
Nov 13 '18 at 17:16
Got it! was because my whole platform is building in Rails but yea, this part is just Ruby.
– Andrea Bazán
Nov 13 '18 at 17:35
This is not a precise enough error description for us to help you. What doesn't work? How doesn't it work? What trouble do you have with your code? Do you get an error message? What is the error message? Is the result you are getting not the result you are expecting? What result do you expect and why, what is the result you are getting and how do the two differ? Is the behavior you are observing not the desired behavior? What is the desired behavior and why, what is the observed behavior, and in what way do they differ?
– Jörg W Mittag
Nov 13 '18 at 20:05
add a comment |
oh Im kinda new here I thought that I should select one if works but yea you are right! :)
– Andrea Bazán
Nov 13 '18 at 17:16
Got it! was because my whole platform is building in Rails but yea, this part is just Ruby.
– Andrea Bazán
Nov 13 '18 at 17:35
This is not a precise enough error description for us to help you. What doesn't work? How doesn't it work? What trouble do you have with your code? Do you get an error message? What is the error message? Is the result you are getting not the result you are expecting? What result do you expect and why, what is the result you are getting and how do the two differ? Is the behavior you are observing not the desired behavior? What is the desired behavior and why, what is the observed behavior, and in what way do they differ?
– Jörg W Mittag
Nov 13 '18 at 20:05
oh Im kinda new here I thought that I should select one if works but yea you are right! :)
– Andrea Bazán
Nov 13 '18 at 17:16
oh Im kinda new here I thought that I should select one if works but yea you are right! :)
– Andrea Bazán
Nov 13 '18 at 17:16
Got it! was because my whole platform is building in Rails but yea, this part is just Ruby.
– Andrea Bazán
Nov 13 '18 at 17:35
Got it! was because my whole platform is building in Rails but yea, this part is just Ruby.
– Andrea Bazán
Nov 13 '18 at 17:35
This is not a precise enough error description for us to help you. What doesn't work? How doesn't it work? What trouble do you have with your code? Do you get an error message? What is the error message? Is the result you are getting not the result you are expecting? What result do you expect and why, what is the result you are getting and how do the two differ? Is the behavior you are observing not the desired behavior? What is the desired behavior and why, what is the observed behavior, and in what way do they differ?
– Jörg W Mittag
Nov 13 '18 at 20:05
This is not a precise enough error description for us to help you. What doesn't work? How doesn't it work? What trouble do you have with your code? Do you get an error message? What is the error message? Is the result you are getting not the result you are expecting? What result do you expect and why, what is the result you are getting and how do the two differ? Is the behavior you are observing not the desired behavior? What is the desired behavior and why, what is the observed behavior, and in what way do they differ?
– Jörg W Mittag
Nov 13 '18 at 20:05
add a comment |
4 Answers
4
active
oldest
votes
How about something like this:
class Robot
FACINGS = [:south, :east, :north, :west]
def initialize(attr = {})
@facing_index = 0 # south
end
def facing
FACINGS[@facing_index]
end
def turn_left
@facing_index += 1
@facing_index %= 4
end
def turn_right
@facing_index -= 1
@facing_index %= 4
end
end
The %= 4
(or, if you really want to generalise this further, %= FACINGS.length
) performs modulo arithmetic to "wrap" the current index back into the range 0-3.
Therefore by incrementing/decrementing this number, you can toggle between the four directions.
I don't know how you intent to implement position
, move
and errors
, but I presume that's beyond the scope of your question.
Thank you so much!! :)
– Andrea Bazán
Nov 13 '18 at 17:09
Just wanted to answer it this way, and refreshed to see answers xD
– 7urkm3n
Nov 13 '18 at 17:11
Yea. Its is because I need to change position according to facing and assigns no errors if it moves succesfully.
– Andrea Bazán
Nov 13 '18 at 17:13
add a comment |
You could store the directions in an array:
def initialize
@dirs = [:S, :W, :N, :E]
end
With the first
entry being the facing direction:
def facing
@dirs.first
end
When the robot turns left, you rotate!
the array counter clockwise:
def turn_left
@dirs.rotate! -1
end
Or clockwise when turning right: (the 1
could be omitted here)
def turn_right
@dirs.rotate! 1
end
Thank you so much Stefan!!! :)
– Andrea Bazán
Nov 13 '18 at 17:10
As you know, and probably considered, an alternative is@right = [:N, :E, :S, :W].cycle; def turn_right; @facing = @right.next; end; def turn_left; 3.times { turn_right }; end; attr_reader :facing
.
– Cary Swoveland
Nov 13 '18 at 19:22
@CarySwoveland if only there were "two-way" enumerators with both,next
andprev
.
– Stefan
Nov 14 '18 at 7:54
Yes, that would be handy.
– Cary Swoveland
Nov 14 '18 at 8:25
add a comment |
left = {:n=>:w, :w=>:s, :s=>:e, :e=>:n}
right = left.invert
#=> {:w=>:n, :s=>:w, :e=>:s, :n=>:e}
pos = :s
pos = left[pos]
#=> :e
pos = right[pos]
#=> :w
For this use case, I like the "old":n=>:w
syntax much more ;-)
– Stefan
Nov 13 '18 at 17:24
Your wish is my command, @Stefan. I agree. (Readers: I formerly hadn: :w
, etc.)
– Cary Swoveland
Nov 13 '18 at 17:32
A downside to this approach is that it's quite limited to one action ("turn left") and its inverse ("turn right"). Implementing something else, like "turn around" or turn by a different amount (if there were more than 4 directions) breaks the otherwise quite elegant design pattern.
– Tom Lord
Nov 13 '18 at 17:39
I mean, of course you can still achieve it - e.g.left[left[pos]]
to turn around. It just loses its elegance.
– Tom Lord
Nov 13 '18 at 17:41
@Tom, that's true, but we could also defineturn_around = { :n=>:s, :s=>:n, :e=>:w, :w=>:e }
.
– Cary Swoveland
Nov 13 '18 at 18:56
|
show 1 more comment
I would go with degrees instead of an enumeration. That way you can manipulate the facing by adding/subtracting n degrees from the current facing.
class Robot
attr_accessor :facing
def initialize(**attrs)
self.facing = attrs[:facing] || 180 # south
end
def rotate!(degrees)
self.facing = (self.facing + degrees) % 360
end
def rotate_left!
rotate!(-90)
end
def rotate_right!
rotate!(90)
end
end
You can then use a relatively simple method to convert degrees to cardinal (compass points):
class Robot
COMPASS_POINTS = %w[N E S W]
# ...
def compass_point
seg_size = 360 / COMPASS_POINTS.size
COMPASS_POINTS[((facing + (seg_size / 2)) % 360) / seg_size]
end
end
This one is taken from the geocoder gem.
This might seem a bit more complicated but lets you store executed commands as rotate: 90
or rotate: -90
if you want to keep track of it. It also lets you rotate the robot a full (stepless) 360 degrees if wanted.
Thats so cool!! Thank you Max!
– Andrea Bazán
Nov 13 '18 at 18:23
rotate!
can just beself.facing = (self.facing + degrees) % 360
– engineersmnky
Nov 13 '18 at 20:26
1
Thanks @engineersmnky, I knew there had to be a smarter way using modulus.
– max
Nov 13 '18 at 21:31
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53285855%2fchange-the-facing-with-a-turn-left-method-in-ruby%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
How about something like this:
class Robot
FACINGS = [:south, :east, :north, :west]
def initialize(attr = {})
@facing_index = 0 # south
end
def facing
FACINGS[@facing_index]
end
def turn_left
@facing_index += 1
@facing_index %= 4
end
def turn_right
@facing_index -= 1
@facing_index %= 4
end
end
The %= 4
(or, if you really want to generalise this further, %= FACINGS.length
) performs modulo arithmetic to "wrap" the current index back into the range 0-3.
Therefore by incrementing/decrementing this number, you can toggle between the four directions.
I don't know how you intent to implement position
, move
and errors
, but I presume that's beyond the scope of your question.
Thank you so much!! :)
– Andrea Bazán
Nov 13 '18 at 17:09
Just wanted to answer it this way, and refreshed to see answers xD
– 7urkm3n
Nov 13 '18 at 17:11
Yea. Its is because I need to change position according to facing and assigns no errors if it moves succesfully.
– Andrea Bazán
Nov 13 '18 at 17:13
add a comment |
How about something like this:
class Robot
FACINGS = [:south, :east, :north, :west]
def initialize(attr = {})
@facing_index = 0 # south
end
def facing
FACINGS[@facing_index]
end
def turn_left
@facing_index += 1
@facing_index %= 4
end
def turn_right
@facing_index -= 1
@facing_index %= 4
end
end
The %= 4
(or, if you really want to generalise this further, %= FACINGS.length
) performs modulo arithmetic to "wrap" the current index back into the range 0-3.
Therefore by incrementing/decrementing this number, you can toggle between the four directions.
I don't know how you intent to implement position
, move
and errors
, but I presume that's beyond the scope of your question.
Thank you so much!! :)
– Andrea Bazán
Nov 13 '18 at 17:09
Just wanted to answer it this way, and refreshed to see answers xD
– 7urkm3n
Nov 13 '18 at 17:11
Yea. Its is because I need to change position according to facing and assigns no errors if it moves succesfully.
– Andrea Bazán
Nov 13 '18 at 17:13
add a comment |
How about something like this:
class Robot
FACINGS = [:south, :east, :north, :west]
def initialize(attr = {})
@facing_index = 0 # south
end
def facing
FACINGS[@facing_index]
end
def turn_left
@facing_index += 1
@facing_index %= 4
end
def turn_right
@facing_index -= 1
@facing_index %= 4
end
end
The %= 4
(or, if you really want to generalise this further, %= FACINGS.length
) performs modulo arithmetic to "wrap" the current index back into the range 0-3.
Therefore by incrementing/decrementing this number, you can toggle between the four directions.
I don't know how you intent to implement position
, move
and errors
, but I presume that's beyond the scope of your question.
How about something like this:
class Robot
FACINGS = [:south, :east, :north, :west]
def initialize(attr = {})
@facing_index = 0 # south
end
def facing
FACINGS[@facing_index]
end
def turn_left
@facing_index += 1
@facing_index %= 4
end
def turn_right
@facing_index -= 1
@facing_index %= 4
end
end
The %= 4
(or, if you really want to generalise this further, %= FACINGS.length
) performs modulo arithmetic to "wrap" the current index back into the range 0-3.
Therefore by incrementing/decrementing this number, you can toggle between the four directions.
I don't know how you intent to implement position
, move
and errors
, but I presume that's beyond the scope of your question.
answered Nov 13 '18 at 17:03
Tom LordTom Lord
15.1k22951
15.1k22951
Thank you so much!! :)
– Andrea Bazán
Nov 13 '18 at 17:09
Just wanted to answer it this way, and refreshed to see answers xD
– 7urkm3n
Nov 13 '18 at 17:11
Yea. Its is because I need to change position according to facing and assigns no errors if it moves succesfully.
– Andrea Bazán
Nov 13 '18 at 17:13
add a comment |
Thank you so much!! :)
– Andrea Bazán
Nov 13 '18 at 17:09
Just wanted to answer it this way, and refreshed to see answers xD
– 7urkm3n
Nov 13 '18 at 17:11
Yea. Its is because I need to change position according to facing and assigns no errors if it moves succesfully.
– Andrea Bazán
Nov 13 '18 at 17:13
Thank you so much!! :)
– Andrea Bazán
Nov 13 '18 at 17:09
Thank you so much!! :)
– Andrea Bazán
Nov 13 '18 at 17:09
Just wanted to answer it this way, and refreshed to see answers xD
– 7urkm3n
Nov 13 '18 at 17:11
Just wanted to answer it this way, and refreshed to see answers xD
– 7urkm3n
Nov 13 '18 at 17:11
Yea. Its is because I need to change position according to facing and assigns no errors if it moves succesfully.
– Andrea Bazán
Nov 13 '18 at 17:13
Yea. Its is because I need to change position according to facing and assigns no errors if it moves succesfully.
– Andrea Bazán
Nov 13 '18 at 17:13
add a comment |
You could store the directions in an array:
def initialize
@dirs = [:S, :W, :N, :E]
end
With the first
entry being the facing direction:
def facing
@dirs.first
end
When the robot turns left, you rotate!
the array counter clockwise:
def turn_left
@dirs.rotate! -1
end
Or clockwise when turning right: (the 1
could be omitted here)
def turn_right
@dirs.rotate! 1
end
Thank you so much Stefan!!! :)
– Andrea Bazán
Nov 13 '18 at 17:10
As you know, and probably considered, an alternative is@right = [:N, :E, :S, :W].cycle; def turn_right; @facing = @right.next; end; def turn_left; 3.times { turn_right }; end; attr_reader :facing
.
– Cary Swoveland
Nov 13 '18 at 19:22
@CarySwoveland if only there were "two-way" enumerators with both,next
andprev
.
– Stefan
Nov 14 '18 at 7:54
Yes, that would be handy.
– Cary Swoveland
Nov 14 '18 at 8:25
add a comment |
You could store the directions in an array:
def initialize
@dirs = [:S, :W, :N, :E]
end
With the first
entry being the facing direction:
def facing
@dirs.first
end
When the robot turns left, you rotate!
the array counter clockwise:
def turn_left
@dirs.rotate! -1
end
Or clockwise when turning right: (the 1
could be omitted here)
def turn_right
@dirs.rotate! 1
end
Thank you so much Stefan!!! :)
– Andrea Bazán
Nov 13 '18 at 17:10
As you know, and probably considered, an alternative is@right = [:N, :E, :S, :W].cycle; def turn_right; @facing = @right.next; end; def turn_left; 3.times { turn_right }; end; attr_reader :facing
.
– Cary Swoveland
Nov 13 '18 at 19:22
@CarySwoveland if only there were "two-way" enumerators with both,next
andprev
.
– Stefan
Nov 14 '18 at 7:54
Yes, that would be handy.
– Cary Swoveland
Nov 14 '18 at 8:25
add a comment |
You could store the directions in an array:
def initialize
@dirs = [:S, :W, :N, :E]
end
With the first
entry being the facing direction:
def facing
@dirs.first
end
When the robot turns left, you rotate!
the array counter clockwise:
def turn_left
@dirs.rotate! -1
end
Or clockwise when turning right: (the 1
could be omitted here)
def turn_right
@dirs.rotate! 1
end
You could store the directions in an array:
def initialize
@dirs = [:S, :W, :N, :E]
end
With the first
entry being the facing direction:
def facing
@dirs.first
end
When the robot turns left, you rotate!
the array counter clockwise:
def turn_left
@dirs.rotate! -1
end
Or clockwise when turning right: (the 1
could be omitted here)
def turn_right
@dirs.rotate! 1
end
edited Nov 13 '18 at 17:10
answered Nov 13 '18 at 17:08
StefanStefan
75.4k894142
75.4k894142
Thank you so much Stefan!!! :)
– Andrea Bazán
Nov 13 '18 at 17:10
As you know, and probably considered, an alternative is@right = [:N, :E, :S, :W].cycle; def turn_right; @facing = @right.next; end; def turn_left; 3.times { turn_right }; end; attr_reader :facing
.
– Cary Swoveland
Nov 13 '18 at 19:22
@CarySwoveland if only there were "two-way" enumerators with both,next
andprev
.
– Stefan
Nov 14 '18 at 7:54
Yes, that would be handy.
– Cary Swoveland
Nov 14 '18 at 8:25
add a comment |
Thank you so much Stefan!!! :)
– Andrea Bazán
Nov 13 '18 at 17:10
As you know, and probably considered, an alternative is@right = [:N, :E, :S, :W].cycle; def turn_right; @facing = @right.next; end; def turn_left; 3.times { turn_right }; end; attr_reader :facing
.
– Cary Swoveland
Nov 13 '18 at 19:22
@CarySwoveland if only there were "two-way" enumerators with both,next
andprev
.
– Stefan
Nov 14 '18 at 7:54
Yes, that would be handy.
– Cary Swoveland
Nov 14 '18 at 8:25
Thank you so much Stefan!!! :)
– Andrea Bazán
Nov 13 '18 at 17:10
Thank you so much Stefan!!! :)
– Andrea Bazán
Nov 13 '18 at 17:10
As you know, and probably considered, an alternative is
@right = [:N, :E, :S, :W].cycle; def turn_right; @facing = @right.next; end; def turn_left; 3.times { turn_right }; end; attr_reader :facing
.– Cary Swoveland
Nov 13 '18 at 19:22
As you know, and probably considered, an alternative is
@right = [:N, :E, :S, :W].cycle; def turn_right; @facing = @right.next; end; def turn_left; 3.times { turn_right }; end; attr_reader :facing
.– Cary Swoveland
Nov 13 '18 at 19:22
@CarySwoveland if only there were "two-way" enumerators with both,
next
and prev
.– Stefan
Nov 14 '18 at 7:54
@CarySwoveland if only there were "two-way" enumerators with both,
next
and prev
.– Stefan
Nov 14 '18 at 7:54
Yes, that would be handy.
– Cary Swoveland
Nov 14 '18 at 8:25
Yes, that would be handy.
– Cary Swoveland
Nov 14 '18 at 8:25
add a comment |
left = {:n=>:w, :w=>:s, :s=>:e, :e=>:n}
right = left.invert
#=> {:w=>:n, :s=>:w, :e=>:s, :n=>:e}
pos = :s
pos = left[pos]
#=> :e
pos = right[pos]
#=> :w
For this use case, I like the "old":n=>:w
syntax much more ;-)
– Stefan
Nov 13 '18 at 17:24
Your wish is my command, @Stefan. I agree. (Readers: I formerly hadn: :w
, etc.)
– Cary Swoveland
Nov 13 '18 at 17:32
A downside to this approach is that it's quite limited to one action ("turn left") and its inverse ("turn right"). Implementing something else, like "turn around" or turn by a different amount (if there were more than 4 directions) breaks the otherwise quite elegant design pattern.
– Tom Lord
Nov 13 '18 at 17:39
I mean, of course you can still achieve it - e.g.left[left[pos]]
to turn around. It just loses its elegance.
– Tom Lord
Nov 13 '18 at 17:41
@Tom, that's true, but we could also defineturn_around = { :n=>:s, :s=>:n, :e=>:w, :w=>:e }
.
– Cary Swoveland
Nov 13 '18 at 18:56
|
show 1 more comment
left = {:n=>:w, :w=>:s, :s=>:e, :e=>:n}
right = left.invert
#=> {:w=>:n, :s=>:w, :e=>:s, :n=>:e}
pos = :s
pos = left[pos]
#=> :e
pos = right[pos]
#=> :w
For this use case, I like the "old":n=>:w
syntax much more ;-)
– Stefan
Nov 13 '18 at 17:24
Your wish is my command, @Stefan. I agree. (Readers: I formerly hadn: :w
, etc.)
– Cary Swoveland
Nov 13 '18 at 17:32
A downside to this approach is that it's quite limited to one action ("turn left") and its inverse ("turn right"). Implementing something else, like "turn around" or turn by a different amount (if there were more than 4 directions) breaks the otherwise quite elegant design pattern.
– Tom Lord
Nov 13 '18 at 17:39
I mean, of course you can still achieve it - e.g.left[left[pos]]
to turn around. It just loses its elegance.
– Tom Lord
Nov 13 '18 at 17:41
@Tom, that's true, but we could also defineturn_around = { :n=>:s, :s=>:n, :e=>:w, :w=>:e }
.
– Cary Swoveland
Nov 13 '18 at 18:56
|
show 1 more comment
left = {:n=>:w, :w=>:s, :s=>:e, :e=>:n}
right = left.invert
#=> {:w=>:n, :s=>:w, :e=>:s, :n=>:e}
pos = :s
pos = left[pos]
#=> :e
pos = right[pos]
#=> :w
left = {:n=>:w, :w=>:s, :s=>:e, :e=>:n}
right = left.invert
#=> {:w=>:n, :s=>:w, :e=>:s, :n=>:e}
pos = :s
pos = left[pos]
#=> :e
pos = right[pos]
#=> :w
edited Nov 13 '18 at 17:31
answered Nov 13 '18 at 17:13
Cary SwovelandCary Swoveland
68.3k53965
68.3k53965
For this use case, I like the "old":n=>:w
syntax much more ;-)
– Stefan
Nov 13 '18 at 17:24
Your wish is my command, @Stefan. I agree. (Readers: I formerly hadn: :w
, etc.)
– Cary Swoveland
Nov 13 '18 at 17:32
A downside to this approach is that it's quite limited to one action ("turn left") and its inverse ("turn right"). Implementing something else, like "turn around" or turn by a different amount (if there were more than 4 directions) breaks the otherwise quite elegant design pattern.
– Tom Lord
Nov 13 '18 at 17:39
I mean, of course you can still achieve it - e.g.left[left[pos]]
to turn around. It just loses its elegance.
– Tom Lord
Nov 13 '18 at 17:41
@Tom, that's true, but we could also defineturn_around = { :n=>:s, :s=>:n, :e=>:w, :w=>:e }
.
– Cary Swoveland
Nov 13 '18 at 18:56
|
show 1 more comment
For this use case, I like the "old":n=>:w
syntax much more ;-)
– Stefan
Nov 13 '18 at 17:24
Your wish is my command, @Stefan. I agree. (Readers: I formerly hadn: :w
, etc.)
– Cary Swoveland
Nov 13 '18 at 17:32
A downside to this approach is that it's quite limited to one action ("turn left") and its inverse ("turn right"). Implementing something else, like "turn around" or turn by a different amount (if there were more than 4 directions) breaks the otherwise quite elegant design pattern.
– Tom Lord
Nov 13 '18 at 17:39
I mean, of course you can still achieve it - e.g.left[left[pos]]
to turn around. It just loses its elegance.
– Tom Lord
Nov 13 '18 at 17:41
@Tom, that's true, but we could also defineturn_around = { :n=>:s, :s=>:n, :e=>:w, :w=>:e }
.
– Cary Swoveland
Nov 13 '18 at 18:56
For this use case, I like the "old"
:n=>:w
syntax much more ;-)– Stefan
Nov 13 '18 at 17:24
For this use case, I like the "old"
:n=>:w
syntax much more ;-)– Stefan
Nov 13 '18 at 17:24
Your wish is my command, @Stefan. I agree. (Readers: I formerly had
n: :w
, etc.)– Cary Swoveland
Nov 13 '18 at 17:32
Your wish is my command, @Stefan. I agree. (Readers: I formerly had
n: :w
, etc.)– Cary Swoveland
Nov 13 '18 at 17:32
A downside to this approach is that it's quite limited to one action ("turn left") and its inverse ("turn right"). Implementing something else, like "turn around" or turn by a different amount (if there were more than 4 directions) breaks the otherwise quite elegant design pattern.
– Tom Lord
Nov 13 '18 at 17:39
A downside to this approach is that it's quite limited to one action ("turn left") and its inverse ("turn right"). Implementing something else, like "turn around" or turn by a different amount (if there were more than 4 directions) breaks the otherwise quite elegant design pattern.
– Tom Lord
Nov 13 '18 at 17:39
I mean, of course you can still achieve it - e.g.
left[left[pos]]
to turn around. It just loses its elegance.– Tom Lord
Nov 13 '18 at 17:41
I mean, of course you can still achieve it - e.g.
left[left[pos]]
to turn around. It just loses its elegance.– Tom Lord
Nov 13 '18 at 17:41
@Tom, that's true, but we could also define
turn_around = { :n=>:s, :s=>:n, :e=>:w, :w=>:e }
.– Cary Swoveland
Nov 13 '18 at 18:56
@Tom, that's true, but we could also define
turn_around = { :n=>:s, :s=>:n, :e=>:w, :w=>:e }
.– Cary Swoveland
Nov 13 '18 at 18:56
|
show 1 more comment
I would go with degrees instead of an enumeration. That way you can manipulate the facing by adding/subtracting n degrees from the current facing.
class Robot
attr_accessor :facing
def initialize(**attrs)
self.facing = attrs[:facing] || 180 # south
end
def rotate!(degrees)
self.facing = (self.facing + degrees) % 360
end
def rotate_left!
rotate!(-90)
end
def rotate_right!
rotate!(90)
end
end
You can then use a relatively simple method to convert degrees to cardinal (compass points):
class Robot
COMPASS_POINTS = %w[N E S W]
# ...
def compass_point
seg_size = 360 / COMPASS_POINTS.size
COMPASS_POINTS[((facing + (seg_size / 2)) % 360) / seg_size]
end
end
This one is taken from the geocoder gem.
This might seem a bit more complicated but lets you store executed commands as rotate: 90
or rotate: -90
if you want to keep track of it. It also lets you rotate the robot a full (stepless) 360 degrees if wanted.
Thats so cool!! Thank you Max!
– Andrea Bazán
Nov 13 '18 at 18:23
rotate!
can just beself.facing = (self.facing + degrees) % 360
– engineersmnky
Nov 13 '18 at 20:26
1
Thanks @engineersmnky, I knew there had to be a smarter way using modulus.
– max
Nov 13 '18 at 21:31
add a comment |
I would go with degrees instead of an enumeration. That way you can manipulate the facing by adding/subtracting n degrees from the current facing.
class Robot
attr_accessor :facing
def initialize(**attrs)
self.facing = attrs[:facing] || 180 # south
end
def rotate!(degrees)
self.facing = (self.facing + degrees) % 360
end
def rotate_left!
rotate!(-90)
end
def rotate_right!
rotate!(90)
end
end
You can then use a relatively simple method to convert degrees to cardinal (compass points):
class Robot
COMPASS_POINTS = %w[N E S W]
# ...
def compass_point
seg_size = 360 / COMPASS_POINTS.size
COMPASS_POINTS[((facing + (seg_size / 2)) % 360) / seg_size]
end
end
This one is taken from the geocoder gem.
This might seem a bit more complicated but lets you store executed commands as rotate: 90
or rotate: -90
if you want to keep track of it. It also lets you rotate the robot a full (stepless) 360 degrees if wanted.
Thats so cool!! Thank you Max!
– Andrea Bazán
Nov 13 '18 at 18:23
rotate!
can just beself.facing = (self.facing + degrees) % 360
– engineersmnky
Nov 13 '18 at 20:26
1
Thanks @engineersmnky, I knew there had to be a smarter way using modulus.
– max
Nov 13 '18 at 21:31
add a comment |
I would go with degrees instead of an enumeration. That way you can manipulate the facing by adding/subtracting n degrees from the current facing.
class Robot
attr_accessor :facing
def initialize(**attrs)
self.facing = attrs[:facing] || 180 # south
end
def rotate!(degrees)
self.facing = (self.facing + degrees) % 360
end
def rotate_left!
rotate!(-90)
end
def rotate_right!
rotate!(90)
end
end
You can then use a relatively simple method to convert degrees to cardinal (compass points):
class Robot
COMPASS_POINTS = %w[N E S W]
# ...
def compass_point
seg_size = 360 / COMPASS_POINTS.size
COMPASS_POINTS[((facing + (seg_size / 2)) % 360) / seg_size]
end
end
This one is taken from the geocoder gem.
This might seem a bit more complicated but lets you store executed commands as rotate: 90
or rotate: -90
if you want to keep track of it. It also lets you rotate the robot a full (stepless) 360 degrees if wanted.
I would go with degrees instead of an enumeration. That way you can manipulate the facing by adding/subtracting n degrees from the current facing.
class Robot
attr_accessor :facing
def initialize(**attrs)
self.facing = attrs[:facing] || 180 # south
end
def rotate!(degrees)
self.facing = (self.facing + degrees) % 360
end
def rotate_left!
rotate!(-90)
end
def rotate_right!
rotate!(90)
end
end
You can then use a relatively simple method to convert degrees to cardinal (compass points):
class Robot
COMPASS_POINTS = %w[N E S W]
# ...
def compass_point
seg_size = 360 / COMPASS_POINTS.size
COMPASS_POINTS[((facing + (seg_size / 2)) % 360) / seg_size]
end
end
This one is taken from the geocoder gem.
This might seem a bit more complicated but lets you store executed commands as rotate: 90
or rotate: -90
if you want to keep track of it. It also lets you rotate the robot a full (stepless) 360 degrees if wanted.
edited Nov 13 '18 at 21:31
answered Nov 13 '18 at 17:59
maxmax
45.3k859103
45.3k859103
Thats so cool!! Thank you Max!
– Andrea Bazán
Nov 13 '18 at 18:23
rotate!
can just beself.facing = (self.facing + degrees) % 360
– engineersmnky
Nov 13 '18 at 20:26
1
Thanks @engineersmnky, I knew there had to be a smarter way using modulus.
– max
Nov 13 '18 at 21:31
add a comment |
Thats so cool!! Thank you Max!
– Andrea Bazán
Nov 13 '18 at 18:23
rotate!
can just beself.facing = (self.facing + degrees) % 360
– engineersmnky
Nov 13 '18 at 20:26
1
Thanks @engineersmnky, I knew there had to be a smarter way using modulus.
– max
Nov 13 '18 at 21:31
Thats so cool!! Thank you Max!
– Andrea Bazán
Nov 13 '18 at 18:23
Thats so cool!! Thank you Max!
– Andrea Bazán
Nov 13 '18 at 18:23
rotate!
can just be self.facing = (self.facing + degrees) % 360
– engineersmnky
Nov 13 '18 at 20:26
rotate!
can just be self.facing = (self.facing + degrees) % 360
– engineersmnky
Nov 13 '18 at 20:26
1
1
Thanks @engineersmnky, I knew there had to be a smarter way using modulus.
– max
Nov 13 '18 at 21:31
Thanks @engineersmnky, I knew there had to be a smarter way using modulus.
– max
Nov 13 '18 at 21:31
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53285855%2fchange-the-facing-with-a-turn-left-method-in-ruby%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
oh Im kinda new here I thought that I should select one if works but yea you are right! :)
– Andrea Bazán
Nov 13 '18 at 17:16
Got it! was because my whole platform is building in Rails but yea, this part is just Ruby.
– Andrea Bazán
Nov 13 '18 at 17:35
This is not a precise enough error description for us to help you. What doesn't work? How doesn't it work? What trouble do you have with your code? Do you get an error message? What is the error message? Is the result you are getting not the result you are expecting? What result do you expect and why, what is the result you are getting and how do the two differ? Is the behavior you are observing not the desired behavior? What is the desired behavior and why, what is the observed behavior, and in what way do they differ?
– Jörg W Mittag
Nov 13 '18 at 20:05