Skip to content Skip to sidebar Skip to footer

Selecting Items In An Array By Using 2 Coordinates And Fill It

I'm making a Battleship game bot for a Discord server. I haven't implemented the Discord part yet and I'm still at making the game's logic. This is the code: import numpy as np imp

Solution 1:

I did the first case and few minor changes:

  • improved regex
  • use '##' as default value for board cell
  • print board changed into function
import numpy as np
import re

waters = np.full((10,10), '##','U2')
headers = ['A','B','C','D','E','F','G','H','I','J']

#PRINTS THE BOARDdefprintBoard():
    for i,header inenumerate(headers):
        if i == 0:
            print('    ',end='')
        print(header + '  ',end='')
        if i == len(headers)-1: print()

    for x,line inenumerate(waters):
        print('%2d'%(x),end='')
        [print(' '+pos,end='') for pos in line]
        print()

printBoard()

board_x_coord = {
    "A":0,
    "B":1,
    "C":2,
    "D":3,
    "E":4,
    "F":5,
    "G":6,
    "H":7,
    "I":8,
    "J":9
}

ship_type = [
    ["CV","Carrier",5],
    ["BB","Battleship",4],
    ["CA","Cruiser",3],
    ["SS","Submarine",3],
    ["DD","Destroyer",2],
]

defboard_coord_to_npcoord(ship,coord):
    try:
        result = re.findall(r'([A-J])(\d)([A-J])(\d)',coord)[0]
        x_crd_a = board_x_coord.get(result[0])
        y_crd_a = int(result[1])
        x_crd_b = board_x_coord.get(result[2])
        y_crd_b = int(result[3])
        vertical = ship[2] == abs(x_crd_b - x_crd_a + 1) and y_crd_a == y_crd_b
        horizontal = ship[2] == abs(y_crd_b - y_crd_a + 1) and x_crd_a == x_crd_b
        valid = vertical or horizontal
        if valid == False:
            print('Invalid length')
            returnFalseif vertical:
            waters[y_crd_a][x_crd_a:x_crd_b + 1] = ship[0] 
            print(waters[y_crd_a][x_crd_a:x_crd_b])
            printBoard()
        print('X: %s , Y: %s , X: %s , Y: %s' %(x_crd_a,y_crd_a,x_crd_b,y_crd_b))
        returnTrueexcept ValueError:
        print('Error. Try again.')
        returnFalsefor ship in ship_type:
    whileTrue:
        print('Coordinates for %s (%s): ' %(ship[1],ship[2]),end='')
        if board_coord_to_npcoord(ship,input()): break

Solution 2:

I changed the inputs. Now it accepts 1 coordinate (X,Y) and orientation (H,V). If H, it will fill from the left to right starting from the given coordinate and also the same for V but this time it's up to bottom.

And also it doesn't care if there're space in the input Ex. A 0 H it will still be valid as long as the pattern is matched.

import re
import numpy as np

classPlaceToBoardError(Exception):
    pass

waters = np.full((10, 10), 'WW','U2')
headers = ['A','B','C','D','E','F','G','H','I','J']

ship_type = [
    ["CV","Carrier",5],
    ["BB","Battleship",4],
    ["CA","Cruiser",3],
    ["SS","Submarine",3],
    ["DD","Destroyer",2],
]

board_x_coord = {
    "a":0,
    "b":1,
    "c":2,
    "d":3,
    "e":4,
    "f":5,
    "g":6,
    "h":7,
    "i":8,
    "j":9
}

defprintBoard():
    for i,header inenumerate(headers):
        if i == 0:
            print('    ',end='')
        print(header + '  ',end='')
        if i == len(headers)-1: print()

    for x,line inenumerate(waters):
        print('%2d'%(x),end='')
        [print(' '+pos,end='') for pos in line]
        print()

defcollision_detect(selected_waters):
    ifany(water != 'WW'for water in selected_waters): 
            returnTruereturnFalsedefplace_to_board(ship,coord):
    try:
        pattern = r'(?i)\s*([a-j])\s*(\d)\s*([hv])'
        result = re.match(pattern,coord)
        if result == None: 
            raise PlaceToBoardError('Invalid coordinates. Please try again.')
        x_coord = board_x_coord.get(result[0][0].lower())
        y_coord = int(result[0][1])
        orientation = result[0][2].lower()

        if orientation == 'h':
            selected_waters = waters[y_coord,x_coord:ship[2]+x_coord]
            if collision_detect(selected_waters): 
                raise PlaceToBoardError('A ship is already placed in those waters. Please try again.')
            iflen(selected_waters) == ship[2]:
                waters[y_coord,x_coord:ship[2]+x_coord] = ship[0]
            else:
                raise PlaceToBoardError('Not enough space. Please try again.')
        elif orientation == 'v':
            selected_waters = waters[y_coord:ship[2]+y_coord:,x_coord]
            if collision_detect(selected_waters): 
                raise PlaceToBoardError('A ship is already placed in those waters. Please try again.')
            iflen(selected_waters) == ship[2]:
                waters[y_coord:ship[2]+y_coord:,x_coord] = ship[0]
            else:
                raise PlaceToBoardError('Not enough space. Please try again.')
        returnTrueexcept PlaceToBoardError as ptbe:
        print(ptbe)
        returnFalse
printBoard()
for ship in ship_type:
    whileTrue:
        print('Coordinates for %s (%s): ' %(ship[1],ship[2]),end='')
        if place_to_board(ship,input()): 
            printBoard()
            break

Post a Comment for "Selecting Items In An Array By Using 2 Coordinates And Fill It"