Kix
Kix

Reputation: 25

Is there any better way to optimalize this battleships "shot" function?

I'm trying to make a simple approach to a battleships-bot in python, but I'm having some issues regarding my "shot" function repeating the same coordinates. Here are some of my code:

import numpy as np
import random as rnd

numberlist = [1,3,5,7,9]
numberlist2 = [0,2,4,6,8]

my_shots = np.array([
                   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                   ])
def letter_to_column(letter):
    """Takes in lettervalue, and returns what column it corresponds to,
    zero-indexed.

    Example:
    letter_to_column('A') # => 0
    """
    return "ABCDEFGHIJ".index(letter.upper())
def find_value(coordinatestring):
    """Takes in a coordinatestring in the form "letternumber" and returns wheter it is a boat
    in the coordinate or not
    """

    letter = coordinatestring[0]
    row = int(coordinatestring[1])
    col = letter_to_column(bokstav)

    value = my_shots[row][col]
    return value

This is the function that repeats the places it shoots, I would appreciate if anyone has any solution to how to make the function not repeat the "lettervalues" it has already given.

def shot(letter = "A", number = "0"):
    # Chekcs if I already have shot there
    while find_value(letter + number) == 1:
        letter = rnd.choice("ABCDEFGHIJ")
    # Uses the "chess method" by only shooting on every other route
        if letter_to_column(letter) % 2 == 0:
            number = str(rnd.choice(numberlist2))
        else:
            number = str(rnd.choice(numberlist))

Upvotes: 1

Views: 71

Answers (1)

AirSquid
AirSquid

Reputation: 11938

If the board is "small" like in Battleship, one strategy you could employ is to generate all the shots at once and then just shuffle them. This works like a champ when you have only 100 locations and avoids a clunky "while this_shot != last_shot" type of setup.

import random
letters = list('ABCDEFGHIJ')
nums = range(9)

all_shots = [''.join([str(num), letter]) for num in nums for letter in letters]

random.shuffle(all_shots)

Upvotes: 1

Related Questions