Home > Enterprise >  Battleship game - how to let players place their boats?
Battleship game - how to let players place their boats?

Time:03-02

I'm creating a battleship game in Ruby. Currently, players have 2 boats (size 3 and size 4) and I arbitrarily placed the boats by myself in the code.

Each player has its own board (array1/array2): I put a 0 when the spot is empty and 1 when there's a boat.

My question is, how can I make the players to place their ships on their board by themselves? My idea was to ask them to enter the first point of each boat and then ask them the side (north, east, south and west) to set the orientation. Obviously, a ship can't be placed out of bounds nor on the same space as another ship.

How can I make sure of that with my code? I have no idea where to start...

Thanks!

# Board for player 1
board1 = []
for i in 0..4
  board1[i] = []
  (0..4).each do
    board1[i].append('O')
  end
end

# Board for player 2
board2 = []
for i in 0..4
  board2[i] = []
  (0..4).each do
    board2[i].append('O')
  end
end

# Display the boards
def display_board(board)
  for row in board
    puts row.map { |k| "#{k}" }.join('  ')
  end
end

# Generation of the player boards
array1 = [  [0, 1, 1, 1, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0] ]
array2 = [  [0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 1], [0, 0, 1, 0, 1], [0, 0, 1, 0, 1] ]

# A player wins when he/she reaches 7 points (2 ships each to place on their grid : a small ship (3x1 side) and a large one (4x1 size))
solution = 7

# We set the number of points at 0 at the start of the game
wins_p1 = 0
wins_p2 = 0

#Starting of the game and printing the board 
while true do
  puts 'Welcome!'
  puts 'Enter start or stop'
  starting = gets.chomp
  puts "\n"

  case starting.downcase
  when 'start'
    puts 'Enter the name of P1'
    name_p1 = gets.chomp
    puts "\n"
    puts 'Enter the name of P2'
    name_p2 = gets.chomp
    puts "\n"

    while wins_p1 < solution || wins_p2 < solution
      puts "--- #{name_p1.upcase}'S TURN ---"
      puts 'Enter line number (between 1 and 5):'
      row_p1 = gets.chomp.to_i-1
      puts 'Enter column number (between 1 and 5):'
      column_p1 = gets.chomp.to_i-1

      case array1[row_p1][column_p1]
      when 1
        board1[row_p1][column_p1] = 'X'
        wins_p1  = 1
      when 0
        board1[row_p1][column_p1] = '-'
      when 'X', '-'
        next
      end

      puts "\n"
      puts '--------------'
      display_board(board1)
      puts '--------------'
      puts '----------------------'
      puts "#{name_p1} has #{wins_p1} point#{"s" if wins_p1 > 1}."
      puts '----------------------'
      puts "\n"

    break if wins_p1 == solution

      puts "--- #{name_p2.upcase}'S TURN ---"
      puts 'Enter line number (between 1 and 5):' 
      row_p2 = gets.chomp.to_i-1
      puts 'Enter column number (between 1 and 5):' 
      column_p2 = gets.chomp.to_i-1

      case array2[row_p2][column_p2]
      when 1
        board2[row_p2][column_p2] = 'X'
        wins_p2  = 1
      when 0
        board2[row_p2][column_p2] = '-'
      when 'X', '-'
        next
      end

      puts "\n"
      puts '--------------'
      display_board(board2)
      puts '--------------'
      puts '----------------------'
      puts "#{name_p2} a #{wins_p2} point#{"s" if wins_p2 > 1}."
      puts '----------------------'
      puts "\n"
      break if wins_p2 == solution
    end

    puts "#{name_p1}, you are the winner!" if wins_p1 == solution
    puts "#{name_p2}, you are the winner!" if wins_p2 == solution
    puts "\n"
    break

  when 'stop'
    puts 'See you soon!'
    break
  else
    puts 'Enter start or stop only!'
    puts "\n"
  end
end

CodePudding user response:

Going with your idea.

  • Get user input (x,y) for start of ship
  • Make sure that space is free (0)
  • Create a function that checks if a ship of size N (3 or 4) would fit in each orientation. For example in pseudocode (and this can be generalized with a direction parameter):
def wouldFitEast(board, anArray, posX, posY):
    steps = 0
    while (steps < N)
        posX = posX   1
        if !validArrayIndex(posX, posY) or anArray[posX][posY] == 1
            return false;
        steps = steps   1
    return true;
  • if there is at least one direction the ship will fit, then ask which direction the user would like, otherwise, they need to pick a different location
  •  Tags:  
  • ruby
  • Related