Last active
August 29, 2015 14:11
-
-
Save jcrubino/965d9a2ee869ed82636f to your computer and use it in GitHub Desktop.
Battleship NG in Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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