Skip to content

Instantly share code, notes, and snippets.

@jcrubino
Last active August 29, 2015 14:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jcrubino/965d9a2ee869ed82636f to your computer and use it in GitHub Desktop.
Save jcrubino/965d9a2ee869ed82636f to your computer and use it in GitHub Desktop.
Battleship NG in Python
"""
TODO:
move fit function to GameBoard
assert all ships on playing board
game board keeps record of players ships
players call to game board and get proper access to game state and own board.
create frp board
ship observes its own location for hits
posts damage or detroyed signal to location on the board
opponent observes playing board observes hits, destructions, misses
make ships move across board
add airplanes
add ships linearly with board size
"""
import random
board_size = 10
def grid(n):
return [['-' for t in range(n)] for i in range(n)]
def check_cell(check_x,check_y,board):
for y, row in enumerate(board):
for x, cell in enumerate(row):
if y == check_y and x == check_x:
return cell
return -1
def enum_grid(board):
positions = []
for y, row in enumerate(board):
for x, cell in enumerate(row):
positions.append((x,y))
random.shuffle(positions)
for x,y in positions:
yield x,y
def column(matrix, i):
return [row[i] for row in matrix]
class GameBoard(object):
def __init__(self, field):
self.board = field
self.submarine1 = Submarine(1)
x,y = self.submarine1.fit(self.board)
self.submarine1.pos = x,y
self.add_ship(x,y,self.submarine1)
self.submarine2 = Submarine(2)
x,y = self.submarine2.fit(self.board)
self.submarine2.pos = x,y
self.add_ship(x,y,self.submarine2)
self.destroyer1 = Destroyer(1)
x,y = self.destroyer1.fit(self.board)
self.destroyer1.pos = x,y
self.add_ship(x,y, self.destroyer1)
self.destroyer2 = Destroyer(2)
x,y = self.destroyer2.fit(self.board)
self.destroyer2.pos = x,y
self.add_ship(x,y, self.destroyer2)
self.cruiser = Cruiser(1)
x,y = self.cruiser.fit(self.board)
self.cruiser.pos = x,y
self.add_ship(x,y, self.cruiser)
self.battleship = Battleship(1)
x,y = self.battleship.fit(self.board)
self.battleship.pos = x,y
self.add_ship(x,y, self.battleship)
self.carrier = Carrier(1)
x,y = self.carrier.fit(self.board)
self.carrier.pos = x,y
self.add_ship(x,y, self.carrier)
def check(self,x,y):
self.field[y][x]
def update(self, field):
self.field = field
def random_enum(self):
positions = []
for y, row in enumerate(self.field):
for x, cell in enumerate(row):
positions.append((x,y))
random.shuffle(positions)
return iter(positions)
def _mark_pos(self, x, y, sign):
self.board[y][x] = sign
def add_ship(self, x,y, ship):
check = []
points = ship.occupies(x,y)
for x,y in points:
check_x, check_y = x,y
for y, row in enumerate(self.board):
for x, cell in enumerate(row):
if y == check_y and x == check_x:
check.append(cell)
if check != ship.signature:
return -1
else:
for x,y in points:
self._mark_pos(x,y,ship.sign)
return 0
def verify_cells(self,points):
r = []
for x,y in points:
check_x, check_y = x,y
for y, row in enumerate(self.board):
for x, cell in enumerate(row):
if y == check_y and x == check_x:
r.append(cell)
return r
class Ship(object):
def __init__(self, name, x, y):
self.name = name
self.length = x
self.width = y
self.orientation = random.randint(0,1)
self.signature = ['-' for i in range(self.length)]
self.sign = self.name[0:3]
self.pos = (0,0)
self.destroyed = 0
def status(self, board):
s = []
positions = self.occupies(*self.pos)
for x,y in positions:
s.append(check_cell(x,y,board))
if s == ['h' for x in range(self.length)]:
self.destroyed = 1
def occupies(self,x,y):
if self.orientation == 1:
return [(x, y+g) for g in range(self.length)]
else:
return [(x+g, y) for g in range(self.length)]
def fit(self,board):
state = 0
while state == 0:
check = enum_grid(board)
if self.orientation == 1:
for x,y in check:
sample = column(board, y)
for i,c in enumerate(sample):
if sample[i:i+self.length] == self.signature:
return x,y
if self.orientation == 0:
for x,y in check:
sample = board[y]
if sample[x:x+self.length] == self.signature:
return x,y
class Submarine(Ship):
def __init__(self,number):
self.number = number
self.name = "submarine:"+str(number)
self.length = 1
self.width = 1
self.orientation = random.randint(0,1)
self.signature = ['-' for i in range(self.length)]
self.sign = self.name[0:3]+":"+str(number)
class Destroyer(Ship):
def __init__(self,number):
self.number = number
self.name = "destroyer:"+str(number)
self.length = 2
self.width = 1
self.orientation = random.randint(0,1)
self.signature = ['-' for i in range(self.length)]
self.sign = self.name[0:3]+":"+str(number)
class Cruiser(Ship):
def __init__(self,number):
self.number = number
self.name = "cruiser:"+str(number)
self.length = 3
self.width = 1
self.orientation = random.randint(0,1)
self.signature = ['-' for i in range(self.length)]
self.sign = self.name[0:3]+":"+str(number)
class Battleship(Ship):
def __init__(self,number):
self.number = number
self.name = "battleship:"+str(number)
self.length = 4
self.width = 1
self.orientation = random.randint(0,1)
self.signature = ['-' for i in range(self.length)]
self.sign = self.name[0:3]+":"+str(number)
class Carrier(Ship):
def __init__(self,number):
self.number = number
self.name = "carrier:"+str(number)
self.length = 5
self.width = 1
self.orientation = random.randint(0,1)
self.signature = ['-' for i in range(self.length)]
self.sign = self.name[0:3]+":"+str(number)
board = GameBoard(grid(board_size))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment