ruby game with arrays and loops - ruby

Use the river variable that defines the river (see code below).
-: clear water.
C: crocodile.
The first five characters represent the first part of the river.
The second five characters represent the second part of the
river.
Each turn:
Check to see if the player is in the same position as a
crocodile. If they are, puts You were eaten.' and stop the program. putsthe whole river. Include aPwhere the player is. Ask the player if they want to go to left, right or neither. The player entersleft, rightorneither. Make the player float down the river by one river part (one line of digits). Move them to the left, the right, or keep them where they are. Print You survived!` if the player makes it past all parts of the
river without hitting a crocodile.
To stop the game when the user is eaten or survives the
whole river, don't use exit to quit the program because this
will break the automated tests. To exit a while loop early, use
the break keyword.
river = "--P--,--C--,CC-CC,CC-CC"
river1 = river.split(",")
x = 0
y = 2
loop do
puts river1
puts "Type left, right or neither"
input = gets.chomp
if input == "left"
river1[x][y] = "-"
river1[(x += 1)][(y -= 1)] = "P"
elsif input == "right"
river1[x][y] = "-"
river1[(x += 1)][(y -= 1)] = "P"
elsif input == "neither"
puts "You were eaten."
break
end
end
that's the first step which is working but i have no idea how to jump to another parts of the river in the loop. Im totally stuck

Related

Code won't function properly without the Integer method for Ruby to properly identify whether my input is either greater or less than when compared

I am brand new to programming. I am going through the Learn Ruby course on Codecademy. It's taking me through a exercise on experimenting with else/if statements. I'm attempting to run code where you input two integers (n and y) and print a statement based on whether n > y, n < y, or n == y.
As an example, when I input n = 5 and y = 15, it would print out the statement "I'm getting printed because n is greater than y) despite that not being true. Some set of numbers would print the correct statement, some set of numbers (as the one above) always printed the incorrect statement. After about 30 minutes of trying to figure out why it wouldn't work, I attempted adding the Integer method to my code and it works as intended. I'm just trying to understand why it wouldn't work properly prior to that.
Here is my code before:
print "Enter an integer for x:"
n = gets.chomp
print "Enter an integer for y:"
y = gets.chomp
if n < y
print "I'm getting printed because #{n} is less than #{y}"
elsif n > y
print "I'm getting printed because #{n} is greater than #{y}"
else
print "I'm getting printed because #{n} is equal to #{y}"
end
Here is my code after adding the Integer method:
print "Enter an integer for n:"
n = Integer(gets.chomp)
print "Enter an integer for y:"
y = Integer(gets.chomp)
if n < y
print "I'm getting printed because #{n} is less than #{y}"
elsif n > y
print "I'm getting printed because #{n} is greater than #{y}"
else
print "I'm getting printed because #{n} is equal to #{y}"
end
After going back in the lessons, I noticed an example Codecademy provided where they use the Integer method, but they do not go into detail about it. Regardless, I still added it to my code in the same fashion they used it in their example, and now it works properly. Like I said above, I just want to understand why it wouldn't work before and where it was going wrong in my code before I go any further in my lessons.
gets returns the string entered by the user, including the newline character created by pressing enter. gets.chomp removes the newline character at the end of the string, but still leaves the input a string.
And strings are sorted and compared alphabetically. "aa" < "b" correct when comparing strings and in the same sense "11" < "2" is correct for strings containing numbers.
But Integer(gets.chomp) translates the user input from a string containing a number into an integer (an actual number). And therefore the comparison works as expected afterward.
Documentation of the methods in play:
Kernel#gets
String#chomp
Kernel#Integer

Creating a checkerboard using Ruby and "\n" not disappearing

I feel as if I am close to a solution and have been tinkering around with this as a newb for some time. Why, for some reason, are my "\n"'s not disappearing when outputted for "next line" and the output has unneeded white space?
Task: Write a function which takes one parameter representing the dimensions of a checkered board. The board will always be square, so 5 means you will need a 5x5 board.
The dark squares will be represented by a unicode white square, while the light squares will be represented by a unicode black square (the opposite colors ensure the board doesn't look reversed on code wars' dark background). It should return a string of the board with a space in between each square and taking into account new lines.
An even number should return a board that begins with a dark square. An odd number should return a board that begins with a light square.
The input is expected to be a whole number that's at least two, and returns false otherwise (Nothing in Haskell).
I am close, and here is what I have so far:
def checkered_board(dimension)
black = "\u25A1 "
white = "\u25A0 "
checkboard = nil
checker_array = []
if dimension < 2 or dimension.is_a? String
return false
else
count = dimension
while count <= dimension && count > 0
if count % 2 == 0
checkboard = ("\u25A1 \u25A0" + "\n")
checker_array << checkboard
count -= 1
else
checkboard = ("\u25A0 \u25A1" + "\n")
checker_array << checkboard
count -= 1
end
end
end
checkboard = checker_array.join(" ")
p checkboard
end
Here is the TDD specs:
Test.assert_equals(checkered_board(0), false)
Test.assert_equals(checkered_board(2), "\u25A1 \u25A0\n\u25A0 \u25A1")
Note: Hidden specs demonstrate that it should respond with false if dimension is not an integer. .is_a? String and .is_a? Integer is not working for me too.
Output appears like so, and is not appearing even:
□ ■
■ □
Thanks for any and all help :).
Try changing:
if dimension < 2 or dimension.is_a? String
to
if !dimension.is_a?(Integer) || dimension < 2
The left most test will be done first. At the moment, if dimension is a String, it is first compared with 2 - which will raise an error - before it is tested as to whether it is a String. You need to check the type of object before you compare it with another object.
Also, I think the check should be whether dimension is not an Integer, rather than whether it is a String. For example, in your original code, what would happen if dimension was an Array?
The join method will concatenate the elements with a space character inserted between them. So this line from the program:
checkboard = checker_array.join(" ")
will result in this string:
"\u25A1 \u25A0\n \u25A0 \u25A1"
Omitting the argument to join should produce the expected output, ie.:
checkboard = checker_array.join
Refer to the documentation on the Array join method.

Recursive method to find matching rows on grid

I have a grid object which is populated by space objects each containing a value. What I want to do is write a method which takes a space, and a number representing the amount of equal spaces I would like to find, to see if there is anywhere on the grid with x-number of equal spaces in the same direction.
In psuedo-code, the steps I planned are:
Begin at the top-left corner of the grid.
Check each direction (N,S,E,W,NE,NW,SE,SW) for 2 conditions
The space in that direction exists
The value in that space matches the value in the current space
If these conditions all fail I want call the method again, but with the current space as the next space (increasing left >> right & top >> bottom)
If these conditions are satisfied I want to store this value in a list and call the method again to check the matching space only in the direction the current space was found
If the next space finds that its adjacent space does not match, I want to
Quit searching
Return to the first space the method was called with
Check the remaining directions to satify the 2 conditions
Call the method again with the next space if no spaces satisfy (increasing left >> right & top >> bottom)
The function returns when the current space is the bottom right space or the list of matching values is the same length as the value specified
If this were implemented on a tic-tac-toe board like below, I would start at the top left "O". I would check North, fail, check North-East, fail, check East, pass. Once it passes I would move to the next "O" and check only to its East since the current "O" was found to the east of its previous space, which would give me the expected result of finding 3 "O"s.
The other case I want to handle is, if the South-East were checked the space would move to the center, where the center space would check its South-East, notice that "X" does not equal "O", return back to the top-left space, check the remaining directions, then move to the next space down the line and repeat until all spaces are checked or a match is found
My non-recursive implementation of this method is as follows. It loops through each space, and for each space loops through each compass direction and assigns the value repeated 'num' times to the found variable which will return nil if nothing was found, or the value which was repeated 'num' times
def check_for_row_of(num)
found = nil
each_space do |space|
COMPASS.each do |direction|
if num_spaces_in_direction(space.pos, direction) == num
values = get_spaces_by_pattern(space.pos, direction)
found = values.uniq[0] if values.uniq.length == 1 && values.uniq[0] != " "
end
end
end
found
end
If I understood you correctly, I believe the following code answers your question. Please, tell me if it isn't quite what you were thinking.
For ease of reading, I kept the recursive search function separate from the (somewhat clunky) logic that iterates over each cell and direction.
Also, it is worth mentioning that I am calling transpose and reverse on the Array of Arrays so that the grid is easier for humans to read. Lower left is (0, 0) and top right is (2, 2).
def search(grid, x, y, direction, length_to_find, value_to_find=nil)
return true if length_to_find == 0
value_at_location = grid.transpose[x].reverse[y] if grid.transpose[x]
value_to_find ||= value_at_location
return false if value_at_location != value_to_find
y += 1 if direction =~ /N/i
y -= 1 if direction =~ /S/i
x += 1 if direction =~ /E/i
x -= 1 if direction =~ /W/i
search(grid, x, y, direction, length_to_find - 1, value_to_find)
end
def row_of?(grid, length_to_find)
grid.length.times do |row|
grid[0].length.times do |col|
%w[N NE E SE S SW W NW].each do |direction|
if search(grid, row, col, direction, length_to_find)
return true
end
end
end
end
false
end
grid = [
[ "O", "O", "O"],
[ " ", "O", "X"],
[ " ", "X", "X"]
]
puts row_of?(grid, 3)

Paste several images into a bigger one, using conditions and loop (MATLAB)

I built a binary chessboard (tab):
Now I have to put in several pieces (pawns), just like this:
P_1 and P_2 have the same dimension that each block of the chessboard (301x301 px)
like it follows:
P_1 :
P_2:
In another exercise I had to invert the images of row 2, doing this:
P1_neg=double(P_1)*-1+255;
P2_neg=double(P_2)*-1+255;
I obtain this images:
P1_neg:
P2_neg
In the second row I have to paste two kind of pieces: a black pawn with black background (P_1), and a black pawn with white background (P_2).
Each block of the chessboard has 301x301 pixels, and each piece has the same measurements. I have to use only conditions and loops, but I don't know how paste the pieces there.
So, I know for the second row: when the row (i) it even and the column(j) is odd, I have to paste P_1; and when the row is even and the column is also even I have to paste P_2.
My code, is the following one, I hope you can help me :)
for i=1:8 % from 1 to 8 because it have 8 blocks
for j=1:8
if mod(i,2)==0 && mod (j,2)~=0
%paste P_1 (I don't know how do this)
elseif mod(i,2)==0 && mod(j,2)==0
%paste P_2
end
end
end
figure,imshow() % I don't know if I show the chessboard or I have to save the data in another matrix.
I couldn't upload the chessboard with the original resolution, but here it's the code I use
tab=zeros(2408);
for i=0:7
for j=0:7
if mod(i,2)~=0 && mod(j,2)~=0
for avanza_fila=(i*301)+1:(i+1)*301
for avanza_columna= (j*301)+1:(j+1)*301
tab(avanza_fila,avanza_columna)=255;
end
end
elseif mod(i,2)==0 && mod(j,2)==0
for avanza_fila=(i*301)+1:(i+1)*301
for avanza_columna= (j*301)+1:(j+1)*301
tab(avanza_fila,avanza_columna)=255;
end
end
end
end
end
figure, imshow(tab)
Here's my solution to your problem. I would personally avoid for loops, but you said your assignment needs it. I've created a high resolution version of your board that you can get here:
This board is 2408 x 2408, as each chess piece is 301 x 301, on an 8 x 8 grid. You almost have the logic correct. You just need to figure out how exactly to place the tiles on the board. I wrote two for loops where the first for loop uses rows 2 and 7, and the second for loop goes through columns 1 to 8. For either the second or seventh row, we check to see whether the column is even or odd and place the correct chess piece in its corresponding block. I also converted the board and the images to black and white to get rid of any quantization artifacts, as I saw that in the images you have posted. Also, I have renamed your images to how they're named in your post, so it'll be up to you to change the relevant names according to your code that you have written. I have also made a copy of the board in the code so that we don't want to modify the original board called boardCopy. This copy will contain the placed chess pieces in the board. Without further ado, here's the code:
board = imread('boardHigh.png'); %// High-res board
P_1 = im2bw(imread('P_1.png')); %// Load in the pawn pieces
P_2 = im2bw(imread('P_2.png'));
P1_neg = im2bw(imread('P1_neg.png'));
P2_neg = im2bw(imread('P2_neg.png'));
boardCopy = board; %// Make a copy of the board
for row = [2 7]
for col = 1 : 8
if row == 2
if mod(col,2) ~= 0
boardCopy((row-1)*301 + 1 : row*301, (col-1)*301 + 1 : col*301) = P_2;
else
boardCopy((row-1)*301 + 1 : row*301, (col-1)*301 + 1 : col*301) = P_1;
end
else
if mod(col,2) ~= 0
boardCopy((row-1)*301 + 1 : row*301, (col-1)*301 + 1 : col*301) = P1_neg;
else
boardCopy((row-1)*301 + 1 : row*301, (col-1)*301 + 1 : col*301) = P2_neg;
end
end
end
end
figure;
imshow(boardCopy);
This is the board I get with the chess pieces:
Hope this helps and good luck!

problem with a little ruby script

i just began learning ruby.
now im trying to code a little script which plays the montyhall problem
i got a problem with the last line of the code
numgames = 10000 # Number of games to play
switch = true # Switch your guess?
wins = 0
numgames.times do doors = [0, 0, 0] # Three doors!
doors[rand(3)] = 1 # One of them has a car!
guess = doors.delete_at(rand(3)) # We pick one of them!
doors.delete_at(doors[0] == 0 ? 0 : 1) # Take out one of the remaining doors that is not a car!
wins += switch ? doors[0] : guess end
puts "You decided #{switch ? "" : "not "}to switch, and your win % is #{wins.times ()/numgames}"
In the last line replace
wins.times ()
with
wins
times returns Enumerator, which doesn't play well with division.
Two problems:
First, wins and numgames are integers, and integer division returns an integer:
irb(main):001:0> 6632 / 10000
=> 0
So, change wins = 0 to wins = 0.0. This will force a floating point division, which will return a floating point answer.
Second, wins is a number, not an array. So get rid of wins.times() and wins.size(). Both are wrong.
With these two changes in place, I consistently get around 66% wins, which just goes to show that Marilyn vos Savant is way smarter than I am.
Your wins is an integer so you don't need .times or .size, you do, however, want .to_f to force things into floating point mode:
wins.to_f / numgames
And if you want a percentage, then you'll have to multiply by 100:
wins.to_f / numgames * 100
You should also properly indent your code for readability and break things up with line breaks to make it easier to read and easier for the parser to figure out:
numgames = 10000 # Number of games to play
switch = true # Switch your guess?
wins = 0
numgames.times do
doors = [0, 0, 0] # Three doors!
doors[rand(3)] = 1 # One of them has a car!
guess = doors.delete_at(rand(3)) # We pick one of them!
doors.delete_at(doors[0] == 0 ? 0 : 1) # Take out one of the remaining doors that is not a car!
wins += switch ? doors[0] : guess
end
puts "You decided #{switch ? "" : "not "}to switch, and your win % is #{100 * wins.to_f / numgames}"

Resources