0

I have a problem with my ship generation in the Battleship game! Sometimes when I run the code I get the error:

RuntimeError: maximum recursion depth exceeded while calling a Python object

Here is the code, I give you all if it can help. The problem is in the "pick" function

print "Welcome to Battleships!!!"
board = []
import os
from random import randint

for x in range(10):
    board.append(["O"] * 10)

def print_board(board):
    for row in board:
        print " | ".join(row)


ships = {"battleship" : [5], "cruiser1" : [4], "cruiser2" : [4], "frigate1" : [3], "frigate2" : [3], "frigate3" : [3], "frigate4" : [3], "minesweeper1" : [2], "minesweeper2" : [2], "minesweeper3" : [2], "minesweeper4" : [2]}
numbers1 = []
numbers2 = []
numbers = []
def setup_nums1():
    for count1 in range(6):
        for count2 in range(10):
            number1 = (count1)*100
            number2 = count2
            numbers1.append(number1 + number2)
def setup_nums2():
    for count1 in range(10):
        for count2 in range(6):
            number1 = (count1)*100
            number2 = count2
            numbers2.append(number1 + number2)
def setup_nums():
    for count1 in range(10):
        for count2 in range(10):
            number1 = (count1)*100
            number2 = count2
            numbers.append(number1 + number2)
def pick1(info, ship):
    random = numbers1[randint (0,len(numbers1) - 1)]
    if not info[0] + random in numbers:
        pick1(info, ship)
    elif not info[0] + random - 1 in numbers:
        pick1(info, ship)
    elif not random + 1 in numbers:
        pick1(info, ship)
    elif not random + 2 in numbers:
        pick1(info, ship)
    elif not random in numbers:
        pick1(info, ship)
    else:
        ships[ship].append(random)
        y = info[1]
        print y
        numbers1.remove(y)
        if y in numbers2:
            numbers2.remove(y)
        numbers.remove(y)
        for n in range(info[0] - 1):
            ships[ship].append(y + n  + 1)
            if (y + n + 1) in numbers1:
                numbers1.remove(y + n + 1)
            if (y + n + 1) in numbers2:
                numbers2.remove(y + n + 1)
            numbers.remove(y + n + 1)
def pick2(info, ship):
    random = numbers2[randint (0,len(numbers2) - 1)]
    if not info[0]*100 + random in numbers:
        pick2(info, ship)
    elif not info[0]*100 + random - 100 in numbers:
        pick2(info, ship)
    elif not random + 100 in numbers:
        pick2(info, ship)
    elif not random + 200 in numbers:
        pick2(info, ship)
    elif not random in numbers:
        pick2(info, ship)
    else:
        ships[ship].append(random)
        y = info[1]
        print y
        if y in numbers1:
            numbers1.remove(y)
        if y in numbers2:
            numbers2.remove(y)
        numbers.remove(y)
        for n in range(info[0] - 1):
            ships[ship].append(y + n*100  + 100)
            if (y + n*100 + 100) in numbers1:
                numbers1.remove(y + n*100 + 100)
            if (y + n*100 + 100) in numbers2:
                numbers2.remove(y + n*100 + 100)
            numbers.remove(y + n*100 + 100)
def setup_numbers():
    setup_nums()
    setup_nums1()
    setup_nums2()
def setup_ships(): 
    for ship, info in ships.items():
        direction = randint(1,2)
        if direction == 1:
            pick1(info, ship)               
        elif direction == 2:
            pick2(info, ship)
setup_numbers()
setup_ships()
print numbers1
print numbers2
print ships

Could anyone help me with this?

  • When you have a Python error, please make sure to include the entire stacktrace (the block of lines starting with "Traceback...", all the way down to your error). This helps figure out where the issue is. – Thomas Orozco Jul 30 '14 at 10:42
  • You appear to be calling `pick1(info, ship)` **from within `pick1`** in order to "start again". This is a bad idea. Use a loop instead. – Blorgbeard Jul 30 '14 at 10:43
  • The obvious solution is to switch from recursion to iteration - see e.g. http://stackoverflow.com/a/23294659/3001761 – jonrsharpe Jul 30 '14 at 10:43
  • That doesn't change anything, when I use a loop it just freezes –  Jul 30 '14 at 10:43
  • Then it clearly does change something, right? And you are using several loops already, so you know they *can* work fine. Obviously, the problem was not that you were using a loop, it was **how** you were using it. Recursion is definitely wrong here. Go back to the loop, try to get that working. Ask more question if you can't. – Blorgbeard Jul 30 '14 at 10:45

1 Answers1

0

Change recursion to loop. Here is little bit changed pick1 function:

from collections import deque
def need_to_process_now(info, ship):
    random = numbers1[randint (0,len(numbers1) - 1)]
    if not info[0] + random in numbers:
        return (random, False)
    elif not info[0] + random - 1 in numbers:
        return (random, False)
    elif not random + 1 in numbers:
        return (random, False)
    elif not random + 2 in numbers:
        return (random, False)
    elif not random in numbers:
        return (random, False)

    return (random, True)

def pick1(info, ship):

    infos = deque()
    infos.append((info, ship))
    while len(infos) > 0:
        curr = infos.pop()
        res = need_to_process_now(curr[0], curr[1])
        if not res[1]:
            infos.append(curr)
        else:
            ships[ship].append(res[0])
            y = curr[0][1]
            print y
            numbers1.remove(y)
            if y in numbers2:
                numbers2.remove(y)
            numbers.remove(y)
            for n in range(info[0] - 1):
                ships[ship].append(y + n  + 1)
                if (y + n + 1) in numbers1:
                    numbers1.remove(y + n + 1)
                if (y + n + 1) in numbers2:
                    numbers2.remove(y + n + 1)
                numbers.remove(y + n + 1)

P.S. I think you need to little reformat code, it's not easy read your code.

Edward
  • 304
  • 2
  • 16
  • Thank you, I'm doing my best, it's my first language –  Jul 30 '14 at 11:17
  • Do I need to use the deque module? I don't know it –  Jul 30 '14 at 11:24
  • @user3888569 as you can see `deque` is a part of the module `collections`. Module `collections is pathr of the standard modules. So you don't need to install anything. Here is [documentation](https://docs.python.org/2/library/collections.html) – Edward Jul 30 '14 at 12:07
  • y is printed as [5[...]] idk why also I get an error –  Jul 30 '14 at 12:20
  • Fixed. Try to simplify `pick2()` function. And you will be able to fix errors like this. – Edward Jul 30 '14 at 12:38