No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

No se trata de lo que quieres comprar, sino de quién quieres ser. Invierte en tu educación con el precio especial

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

11 Días
5 Hrs
40 Min
14 Seg
Curso de Ruby

Curso de Ruby

Simón Soriano

Simón Soriano

Test de nuestras acciones

30/39
Recursos

Aportes 10

Preguntas 6

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

$ bundle exec ruby test/actions_test.rb
Run options: --seed 7615

# Running:

E

Finished in 0.002508s, 398.7877 runs/s, 0.0000 assertions/s.

  1) Error:
ActionsTest#test_move_snake:
NoMethodError: undefined method `calc_next_position' for Actions:Module
    D:/desarrollo/Estudio/cursobasicoderuby/mysnake/src/actions/actions.rb:4:in `move_snake'
    test/actions_test.rb:29:in `test_move_snake'

1 runs, 0 assertions, 0 failures, 1 errors, 0 skips

Lo he revisado muchas veces y no encuentro error alguno!

¿No se va un error en el minuto 2:40? Cuando se hace CMD + v para la inicialización del estado expected_state creo que se va un error porque se vuelve a inicializar el initial_state, lo que se transforma en falsos positivos porque siempre van a ser iguales ambos estados

Con comentarios para ver que hace cada cosa.

actions.rb

module Actions  #En este modulo se realizan las todas las acciones consecutivos a cada evento(avanzar, voltear).

  def self.move_snake(state) #creamos el metodo para confirmar si el movimiento sera factible.
    next_direction = state.next_direction #variable next_direction toma los datos de la direccion que tomara la culebra
    next_position = calc_next_position(state) # # Entrega la siguiente posicion dado siguiente movimiento ingresado
    if position_isvalid?(state, next_position) #Verificar que la siguiente posicion es factible.
      move_snake_to(state, next_position) # # Metodo asigna la nueva posicion de la serpiente actualizada
    else
      end_game(state) # en caso de no ser posicion factible fin del juego
    end
  end

  private

  def self.calc_next_position(state) # Entrega la siguiente posicion dado siguiente movimiento ingresado
    curr_position = state.snake.positions.first # curr_position toma el valor de la posicion actual de la serpiente
    case state.next_direction # Evalua la posicion hacia donde ira al culebra
    when Model::Direction::UP # Evalua si culebra va hacia arriba
      return Model::Coord.new(curr_position.row - 1,curr_position.col) #Devuelve el calculo de la siguiente posicion dado el movimiento hacia arriba
    when Model::Direction::RIGHT # Evalua si culebra va hacia la derecha
      return Model::Coord.new(curr_position.row,curr_position.col + 1) #Devuelve el calculo de la siguiente posicion dado el movimiento hacia arriba
    when Model::Direction::DOWN # Evalua si culebra va hacia abajo
      return Model::Coord.new(curr_position.row + 1,curr_position.col) #Devuelve el calculo de la siguiente posicion dado el movimiento hacia arriba
    when Model::Direction::LEFT# Evalua si culebra va hacia izquierda
      return Model::Coord.new(curr_position.row,curr_position.col - 1) #Devuelve el calculo de la siguiente posicion dado el movimiento hacia arriba
    end
  end

  def self.position_isvalid?(state, position) #Verifica si la siguiente posicion sale de la grilla o si esta repitiendo alguna posicion de la culebra ya existente.
    is_valid = ((position.row >= state.grid.rows || position.row < 0) || (position.col >= state.grid.cols || position.col < 0)) # Verificar que este dentro en la grilla
    # Verificar que no este superponiendo a la serpiente
    return false if is_valid # retorna falso si is_valid resulta ser true
    return !(state.snake.positions.include? position) #Si la is_valid es falso evalua si en la lista de posiciones de la culebra se repite la siguiente posicion 
  end

  def self.move_snake_to(state,next_position) # Le asigna la nueva posicion de la serpiente actualizada
    new_positions = [next_position] + state.snake.positions[0...-1] # variable new_positions toma el valor de las posiciones de la snake menos la ultima (cola) y le agrega la siguiente
    state.snake.positions = new_positions # se asigna la nueva posicion de la serpiente 
    return state # retorna los datos del estado con sus variables actualizadas
  end

  def self.end_game(state) # Metodo para verificar si se acabo el juego (si se rompieron alguna de las condiciones para seguir)
    state.game_fishined = true # Cambia variable a true
    return state # retorna estado actualizado
  end

end

state.rb

module Model
  module Direction
    UP = :up
    RIGHT =  :right
    DOWN = :down
    LEFT = :left
  end

  class Coord < Struct.new(:row, :col) # crea clase coordenadas con row y col inicializados con setters y getter
  end

  class Food < Coord # clase food hereda de clase coord
  end

  class Snake < Struct.new(:positions) # posiciones cabeza de serpiente y cola
  end

  class Grid < Struct.new(:rows, :cols)# crea clase coordenadas con rows y cols inicializados con setters y getter
  end

  class State < Struct.new(:snake, :food, :grid, :next_direction, :game_fishined) # crea clase coordenadas con snake, food  y grid inicializados con setters y getter
  end

  def self.initial_state # definicion de estado inicial
    Model::State.new(
      Model::Snake.new([      # coordenadas de cabeza y cola o inicio y fin
        Model::Coord.new(1, 1),
        Model::Coord.new(0, 1)
                      ]),
      Model::Food.new(4, 4), # inicializamos coordenada de comida
      Model::Grid.new(8, 12), # coordenada de grid
      Model::Direction::DOWN, # coordenada de Grid
      false
    )
  end

end

app.rb

require_relative "view/ruby2d" # importamos los metodos del archivo state.rb
require_relative "model/state" # importamos los metodos del archivo state.rb

class App

 def Start
  view = View::Ruby2dView.new  # variable view instancia de la clase Ruby2dView
  initial_state = Model::initial_state # variable initial_state que almacena los datos del estado inicial.
  view.render(initial_state) # se renderiza el estado inicial con los datos asignados.
  end

  def init_timer
    loop do
      sleep 0.5
      #trigger movement
    end
  end

end

actions_test.rb

require "minitest/autorun"
require_relative "../src/actions/actions" #
require_relative "../src/model/state"

class ActionsTest < Minitest::Test
  def test_move_snake
    initial_state = Model::State.new(
      Model::Snake.new([      # coordenadas de cabeza y cola o inicio y fin
        Model::Coord.new(1, 1),
        Model::Coord.new(0, 1)
                      ]),
      Model::Food.new(4, 4), # inicializamos coordenada de comida
      Model::Grid.new(8,12), # coordenada de grid
      Model::Direction::DOWN, # coordenada de Grid
      false
    )

    expected_state = initial_state = Model::State.new(
      Model::Snake.new([      # coordenadas de cabeza y cola o inicio y fin
        Model::Coord.new(2, 1),
        Model::Coord.new(1, 1)
                      ]),
      Model::Food.new(4, 4), # inicializamos coordenada de comida
      Model::Grid.new(8,12), # coordenada de grid
      Model::Direction::DOWN, # coordenada de Grid
      false
    )

    actual_state = Actions::move_snake(initial_state)
    assert_equal actual_state, expected_state
  end
end

Para que sirve self?

Si les marca este error:

syntax error, unexpected integer literal, expecting ')' (SyntaxError)
        curr_position.col +1)
                          ^~
/Users/jesuspacheco/Documents/Cursos/Ruby/snake/src/actions/actions.rb:32: syntax error, unexpected `when', expecting `end'
    when Model::Direction::LEFT
    ^~~~
/Users/jesuspacheco/Documents/Cursos/Ruby/snake/src/actions/actions.rb:36: syntax error, unexpected tUMINUS_NUM, expecting ')'
        curr_position.col -1)
                          ^
/Users/jesuspacheco/Documents/Cursos/Ruby/snake/src/actions/actions.rb:62: syntax error, unexpected end-of-input, expecting `end'
	from src/test/actions_test.rb:2:in `<main>'

Se soluciona quitando los espacios en curr_position.col +1), los incrementos y decrementos deben quedar JUNTO a la col y row, es decir así:

when Model::Direction::UP
      #decrementar la fila
      return Model::Coord.new(
        curr_position.row-1,
        curr_position.col)
    when Model::Direction::RIGHT
      #incrementar la col
      return Model::Coord.new(
        curr_position.row,
        curr_position.col+1)
    when Model::Direction::DOWN
      #incrementar la fila
      return Model::Coord.new(
        curr_position.row+1,
        curr_position.col)
    when Model::Direction::LEFT
      #decrementar la col
      return Model::Coord.new(
        curr_position.row,
        curr_position.col-1)
    end

Hola, esta vez si tengo estos errores tratando de correr el test:

He revisado codigo y gemas y no encuentro la vuelta! 😃

test/action_test.rb:13: syntax error, unexpected tCONSTANT, expecting ')'
      Direction::DOWN
test/action_test.rb:15: syntax error, unexpected ')', expecting end
    )
test/action_test.rb:24: syntax error, unexpected tCONSTANT, expecting ')'
      Direction::DOWN
test/action_test.rb:26: syntax error, unexpected ')', expecting end
    )

al fin despues de tanto analizar razones, pude dar con mis errores y pasar la minitest

Al estar utilizando Symbols en lo que es Direction::UP no es necesario el recorrido completo es decir Model::Direction::UP podemos poner directamente el valor de Symbol como :up o :down etc.

¿Por qué sale el error de cannot load such file -- minitest/autorun (LoadError) y se debe agregar en el Gemfile, si en la clase "Testing con MiniTest" se dice lo contrario? Que hace parte del core de ruby y se puede hacer uso así sin más. No me queda claro 🤔

Si corres las pruebas sin utilizar el comando bundle no se necesita añadir la dependencia de minitest

ruby test/actions_test.rb