Vince Parulan
Vince Parulan

Reputation: 1

How do I get random range of index to create a battleship? (Python)

def random_row(board):
    return randrange(0, len(board)-1) 

def random_col(board):
    return randrange(0, len(board[0])-1) 

ship_row = random_row(board)
ship_col = random_col(board)
print ship_row
print ship_col

This is a code for my battleship game from codeacademy. How do I get a random index range instead of just 1 number for ship_row and ship_col? I want my ship to have more than one index because guessing one number is hard and a battleship has multiple tiles right? Thank you and I hope my question is clear enough.

Upvotes: 0

Views: 315

Answers (2)

sberry
sberry

Reputation: 132028

This seemed like a fun thing to try to write up, and while I would normally just try to nudge you in the right direction, today I decided to give you something that will generate a board with placed ships.

It is not optimal, but fine for this application.

Handling hits and sunken ships is left as an exercise:

import collections
import random

DIRECTIONS = ['up', 'down', 'left', 'right']
Ship = collections.namedtuple("Ship", ("name", "size", "count"))
Board = collections.namedtuple("Board", ("w", "h", "map"))

ships = [Ship("battle", 4, 1), Ship('submarine', 3, 1), Ship('destroyer', 3, 1), Ship("patrol", 2, 1), Ship("carrier", 5, 1)]

def create_board(w, h):
    return Board(w, h, [['_'] * w for _ in range(h)])


def place_ships(board, ships):
    for ship in ships:
        for _ in range (ship.count):
            place_ship(board, ship)


def place_ship(board, ship):
    while True:
        _x = random.randint(0, board.w - 1)
        _y = random.randint(0, board.h - 1)
        random.shuffle(DIRECTIONS)
        for direction in DIRECTIONS:
            if maybe_place(board, _x, _y, direction, ship):
                return


def maybe_place(board, x, y, direction, ship):
    if direction == "right":
        right = min(board.w - 1, x + ship.size)
        left = right - ship.size
        slots = [(x, i) for i in range(left, right)]
    elif direction == "left":
        left = max(0, x - ship.size)
        right = left + ship.size
        slots = [(x, i) for i in range(left, right)]
    elif direction == "down":
        bottom = min(board.h - 1, y + ship.size)
        top = bottom - ship.size
        slots = [(i, y) for i in range(top, bottom)]
    elif direction == "up":
        top = max(0, y - ship.size)
        bottom = top + ship.size
        slots = [(i, y) for i in range(top, bottom)]

    if all([board.map[x][y] == '_' for x, y in slots]):
        for x, y in slots:
            board.map[x][y] = ship.name[0]
        return True
    return False


def print_board(board):
    for row in board.map:
        for x in row:
            print x,
        print


if __name__ == "__main__":
    board = create_board(10, 10)
    place_ships(board, ships)
    print_board(board)

Examples of output

_ _ c _ _ _ _ _ _ _
_ _ c _ _ _ _ _ _ _
_ _ c _ _ _ _ _ _ _
_ _ c _ _ _ _ _ _ _
_ _ c _ p p _ _ _ _
_ _ _ _ _ b _ _ _ _
_ _ _ _ _ b _ _ _ _
_ _ _ _ _ b s s s _
_ _ _ _ _ b _ _ _ _
_ _ _ _ _ _ d d d _


_ _ _ c b _ _ _ _ _
_ _ _ c b _ _ _ _ _
_ _ _ c b _ _ _ _ _
_ _ _ c b _ _ _ _ _
_ _ _ c _ _ _ _ _ _
_ _ _ _ _ _ _ _ d _
_ _ _ _ _ _ p p d _
_ _ _ _ _ _ _ _ d _
_ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ s s s _


_ _ _ _ _ c _ _ _ _
_ _ _ _ _ c _ _ _ _
_ _ d d d c _ _ _ _
_ _ _ _ _ c _ _ _ _
_ _ _ _ _ c _ _ _ _
_ _ _ _ _ b b b b _
_ _ _ _ _ _ p s _ _
_ _ _ _ _ _ p s _ _
_ _ _ _ _ _ _ s _ _
_ _ _ _ _ _ _ _ _ _

Upvotes: 0

Anthony Dito
Anthony Dito

Reputation: 3670

The algorithm would be something like this...

If it were a 5x5 board that you needed to get 4 spots in a row you could have two possibilities. You could pick a spot on the board and then count down 4 to get the spaces for a battleship or pick the spot and then count down. The way that I would do this problem is to do a random choice to see if you want to go up and down. Then you could do two more random choices to get the x and the y. You just have to make sure that everything is in range based on the size of the board.

Upvotes: 1

Related Questions