0

I have a battleship python assignment due in an hour and I can't figure out where the error is in this code. It seems like when player 2 plays sometimes the coordinates saved in Board.remaining_ships can't be deleted because they aren't there. Please please please help

Here is the error:
Traceback (most recent call last):
File "/Applications/WingIDE.app/Contents/MacOS/src/debug/tserver/_sandbox.py", line 256, in <module>
File "/Applications/WingIDE.app/Contents/MacOS/src/debug/tserver/_sandbox.py", line 40, in bullet_positioning
ValueError: list.remove(x): x not in list


Code:

import random


class Ships(object):

    def __init__(self, ship_num):
        '''ship_num is a list of int containing the numbers
        of ships of size 2, 3, 4 and 5 squares.
        '''
        self.ship_num = ship_num
        self.ship_type = [5, 4, 3, 2]


class Board(object):

    def __init__(self, size):
        ''' (Board, str) -> List
        construct a square board
        self.board with cols =
        rows = size.
        Item board[y][x] has a coodinate
        of [x,y].
        '''
        self.remaining_ships = []
        self.missed = []
        self.hit = []
        self.size = int(size)
        self.board = []
        for row in range(int(size)):
            self.board.append([])
            for col in range(int(size)):
                self.board[row].append(0)

    def bullet_positioning(self, coodinate):

        x = coodinate[0]
        y = coodinate[1]
        self.board[y][x] += 10
        if self.board[y][x] == 11:
            self.remaining_ships.remove(coodinate)
            self.hit.append(coodinate)
        else:
            self.missed.append(coodinate)

    def display(self):
        '''print out the board
        '''
        for row in self.board:
            for item in row:
                if (item == 1) or (item == 0):
                    print [' '],
                elif item == 10:
                    print ['o'],
                else:
                    print ['x'],
            print \


    def check_hit_miss(self, coodinate):
        '''return True if coodinate in board.hit or board.missed,
        return False otherwise.
        '''
        if (coodinate in self.hit) or (coodinate in self.missed):
            return True
        else:
            return False

    def check_empty_point(self, coodinate):
        '''return True if the coodinate is occupied by a ship,
        return False otherwise
        '''
        x = coodinate[0]
        y = coodinate[1]
        return self.board[y][x]

    def ship_placement(self, ships):
        '''(Board, Ships) -> Board
        Return a board with ships randomly placed
        in it. A block has a value of zero if it is
        empty, 1 if is occupied by a ship.
        '''
        new_ships = Ships(ships.ship_num[:])
        new_ships.ship_type = ships.ship_type[:]

        for i in range(len(new_ships.ship_num)):
        #i is the index of ships.ship_num and ships.ship_type.
        #It is to choose number of ships and the type of those ships(lenth).
            while new_ships.ship_num[i] != 0:
                check_point = False
                while not check_point:
                    point = random_point(self)
                    while self.check_empty_point(point):
                        point = random_point(self)
                    x = point[0]
                    y = point[1]
                    #randomly choose a point that is not occupied by a ship.
                    #This is the starting point to place a ship
                    direction = random_direction()
                    #choose a direction to place the ship,
                    #horizontal or vertical.
                    if direction == 'h':
                        if not ((x + new_ships.ship_type[i]) > self.size):
                            new_row = self.board[y]
                            #creat a new list to tempararily store
                            #a modified row.
                            count = 0
                            for j in range(new_ships.ship_type[i]):
                                if not self.check_empty_point([x + j, y]):
                                    new_row[x + j] = 1
                                    count += 1
                                else:
                                    break
                                    #Store 1s in new_row if
                                    #the point on board is empty
                            if count == new_ships.ship_type[i]:
                                self.board[y] = new_row
                                check_point = True
                                new_ships.ship_num[i] -= 1
                                #Check if there's enough space for the ship.
                                #If it's enough, copy the temp row to board.
                                for p in range(new_ships.ship_type[i]):
                                    self.remaining_ships.append([x + p, y])
                                #update the remaining_ships list

                    if direction == 'v':
                        if not ((y + new_ships.ship_type[i]) > self.size):
                            new_col = []
                            for k in range(self.size):
                                new_col.append(self.board[k][x])
                            count = 0
                            for m in range(new_ships.ship_type[i]):
                                if not self.check_empty_point([x, y + m]):
                                    new_col[y + m] = 1
                                    count += 1
                                else:
                                    break
                            if count == new_ships.ship_type[i]:
                                for n in range(self.size):
                                    self.board[n][x] = new_col[n]
                                check_point = True
                                new_ships.ship_num[i] -= 1
                                for q in range(new_ships.ship_type[i]):
                                    self.remaining_ships.append([x, y + q])


def get_coodinates(board, player_type):
    '''(Board, Str) -> List
    2 for human player, 1 for computer player.
    '''
    if player_type == '2':
        x = int(raw_input('Please enter the x-coodinate, starting from 0:'))
        while not (0 <= x < board.size):
            print 'x should be a positive number smaller than % d' % board.size
            x = int(raw_input(
                'Please enter the x-coodinate, starting from 0:'))
        y = int(raw_input('Please enter the y-coodinate, starting from 0:'))
        while not (0 <= y < board.size):
            print 'y should be a positive number smaller than % d' % board.size
            y = int(raw_input('Please enter the y-coodinate, staring from 0:'))
        while board.check_hit_miss([x, y]):
            print 'You already hit this point before!'
            x = int(raw_input(
                'Please enter the x-coodinate, starting from 0:'))
            while not(0 <= x < board.size):
                print 'x should be a positive number smaller than % d'\
                      % board.size
                x = int(raw_input(
                    'Please enter the x-xoodinate, stating from 0:'))
            y = int(raw_input(
                'Please enter the y-coodinate, staring from 0:'))
            while not(0 <= y < board.size):
                print 'y should be a positive number smailler than % d'\
                      % board.size
                y = int(raw_input(
                    'Please enter the y-coodinate, staring from 0:'))
        return [x, y]

    elif player_type == '1':
        point = random_point(board)
        while board.check_hit_miss(point):
            point = random_point(board)
        #Choose random points from blocks that are not hit before
        #return [x,y]
        return point


def random_point(board):
    '''Board -> List
    Choose a random point on the board and
    store the x, y coodinates in a list.
    '''
    x = random.randint(0, board.size - 1)
    y = random.randint(0, board.size - 1)
    return [x, y]


def random_direction():
    '''randomly return 'h' or 'v'
    '''
    if random.randint(0, 1):
        return 'h'
    else:
        return 'v'


def get_info():
    '''None -> dic
    Get the number of players, size of the board and number of ships
    in each type. Then store the information in a dictionary.
    '''
    info = {}
    players = raw_input(
        '\nWelcome to Battleship!\n\nPlease enter number of players, 1 or 2:')
    while not ((players == '1' or players == '2')):
        print 'Number of players must be 1 or 2'
        players = raw_input('Please enter number of players, 1 or 2:')
    size = raw_input('Please enter the size of the board:')
    ship_categories = 4
    ship_num = []
    for i in range(ship_categories):
        ships = int(raw_input(
            'Please enter the number of ships with lenth % d:' % (5 - i)))
        ship_num.append(ships)
    info['players'] = players
    info['size'] = size
    info['ship_num'] = ship_num
    return info


if __name__ == '__main__':
    info = get_info()
    ships = Ships(info['ship_num'])
    #b1 for player 1 or computer; b2 for player 2 or human player
    b1 = Board(info['size'])
    b2 = Board(info['size'])
    b1.ship_placement(ships)
    b2.ship_placement(ships)
    while 1:
        print 'Player1\'s board:'
        b1.display()
        print 'Player2\'s board:'
        b2.display()
        print 'Player1\'s turn'
        coodinate1 = get_coodinates(b2, '2')
        print coodinate1
        b2.bullet_positioning(coodinate1)
        print 'Player1\'s board:'
        b1.display()
        print 'Player2\'s board:'
        b2.display()
        if b2.remaining_ships == []:
            print 'Player one wins!'
            break
        print 'Player2\'s turn'
        coodinate2 = get_coodinates(b1, info['players'])
        b1.bullet_positioning(coodinate2)
        print 'Player1\'s board:'
        b1.display()
        print 'Player2\'s board:'
        b2.display()
        if b1.remaining_ships == []:
            print 'Player two wins!'
            break

Edited by Tashalla: n/a

2
Contributors
1
Reply
3
Views
5 Years
Discussion Span
Last Post by woooee
0

You check self.hit and self.miss, not the remaining empty squares (so there is some discrepancy between the lists).

def check_hit_miss(self, coodinate):
        '''return True if coodinate in board.hit or board.missed,
        return False otherwise.
        '''
        if (coodinate in self.hit) or (coodinate in self.missed):
            return True
        else:
            return False
#
# change to
        if coordinate in self.remaining_ships:
This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.