#!/usr/bin/env python
#
# BattleShip


import random


#--------------------------Fields------------------------------

emptyField =3D [ "  _A_B_C_D_E_F_G_H_I_J_",
               " 1|_|_|_|_|_|_|_|_|_|_|",
               " 2|_|_|_|_|_|_|_|_|_|_|",
               " 3|_|_|_|_|_|_|_|_|_|_|",
               " 4|_|_|_|_|_|_|_|_|_|_|",
               " 5|_|_|_|_|_|_|_|_|_|_|",
               " 6|_|_|_|_|_|_|_|_|_|_|",
               " 7|_|_|_|_|_|_|_|_|_|_|",
               " 8|_|_|_|_|_|_|_|_|_|_|",
               " 9|_|_|_|_|_|_|_|_|_|_|",
               "10|_|_|_|_|_|_|_|_|_|_|" ]

TESTcompsField =3D [ "  _A_B_C_D_E_F_G_H_I_J_",
               " 1|_|_|_|o|_|_|o|_|_|_|",
               " 2|_|_|_|o|_|_|o|_|_|o|",
               " 3|_|o|_|o|_|_|o|_|_|_|",
               " 4|_|_|_|o|_|_|_|_|_|_|",
               " 5|_|_|_|_|_|_|_|_|_|o|",
               " 6|_|_|_|_|_|o|o|o|_|_|",
               " 7|o|_|_|_|_|_|_|_|_|_|",
               " 8|_|_|_|_|_|_|_|_|_|_|",
               " 9|_|_|o|o|_|_|_|o|_|_|",
               "10|_|_|_|_|_|_|_|o|_|_|" ]

TESTyourField  =3D [ "  _A_B_C_D_E_F_G_H_I_J_",
               " 1|_|o|_|_|_|_|_|o|_|_|",
               " 2|_|_|_|_|_|_|_|_|_|o|",
               " 3|_|_|_|o|o|o|o|_|_|_|",
               " 4|_|_|_|_|_|_|_|_|_|_|",
               " 5|_|o|o|o|_|_|_|_|_|o|",
               " 6|_|_|_|_|_|_|_|_|_|o|",
               " 7|o|_|_|_|_|_|_|_|_|_|",
               " 8|o|_|_|o|_|_|_|o|_|_|",
               " 9|_|_|_|_|_|_|_|o|_|_|",
               "10|_|o|o|_|_|_|_|o|_|_|" ]

compsField =3D [ "  _A_B_C_D_E_F_G_H_I_J_",
               " 1|_|_|_|_|_|_|_|_|_|_|",
               " 2|_|_|_|_|_|_|_|_|_|_|",
               " 3|_|_|_|_|_|_|_|_|_|_|",
               " 4|_|_|_|_|_|_|_|_|_|_|",
               " 5|_|_|_|_|_|_|_|_|_|_|",
               " 6|_|_|_|_|_|_|_|_|_|_|",
               " 7|_|_|_|_|_|_|_|_|_|_|",
               " 8|_|_|_|_|_|_|_|_|_|_|",
               " 9|_|_|_|_|_|_|_|_|_|_|",
               "10|_|_|_|_|_|_|_|_|_|_|" ]

yourField  =3D [ "  _A_B_C_D_E_F_G_H_I_J_",
               " 1|_|_|_|_|_|_|_|_|_|_|",
               " 2|_|_|_|_|_|_|_|_|_|_|",
               " 3|_|_|_|_|_|_|_|_|_|_|",
               " 4|_|_|_|_|_|_|_|_|_|_|",
               " 5|_|_|_|_|_|_|_|_|_|_|",
               " 6|_|_|_|_|_|_|_|_|_|_|",
               " 7|_|_|_|_|_|_|_|_|_|_|",
               " 8|_|_|_|_|_|_|_|_|_|_|",
               " 9|_|_|_|_|_|_|_|_|_|_|",
               "10|_|_|_|_|_|_|_|_|_|_|" ]

yourShots =3D  [ "  _A_B_C_D_E_F_G_H_I_J_",
               " 1|_|_|_|_|_|_|_|_|_|_|",
               " 2|_|_|_|_|_|_|_|_|_|_|",
               " 3|_|_|_|_|_|_|_|_|_|_|",
               " 4|_|_|_|_|_|_|_|_|_|_|",
               " 5|_|_|_|_|_|_|_|_|_|_|",
               " 6|_|_|_|_|_|_|_|_|_|_|",
               " 7|_|_|_|_|_|_|_|_|_|_|",
               " 8|_|_|_|_|_|_|_|_|_|_|",
               " 9|_|_|_|_|_|_|_|_|_|_|",
               "10|_|_|_|_|_|_|_|_|_|_|" ]



#-----------------------Other Variables---------------------

totalSpots =3D 20
compsSpots =3D totalSpots
usersSpots =3D totalSpots
turn =3D "user"
sunk =3D 0
target =3D ""
possibleShots =3D []

#-------------------------Functions-------------------------

def printField( field ):
	for line in field:
		print line



def getVertical( shot ):
	if( len(shot) =3D=3D 3 ):
		return 10
	else:
		return ord(shot[1]) - ord('0')
=09


def getHorizontal( shot ):
	return 3 + (ord(shot[0]) - ord('a'))*2



def isShot( shot ):
	if( len(shot) < 2 ):
		return 0
	if( len(shot) > 2 ):
		if( len(shot) =3D=3D 3 ):
			if( shot[0] >=3D 'a' and shot[0] <=3D 'j' and shot[1] =3D=3D '1' and =
shot[2] =3D=3D '0' ):
				return 1
			elif( shot[2] >=3D 'a' and shot[2] <=3D 'j' and shot[0] =3D=3D '1' =
and shot[1] =3D=3D '0' ):
				return 1
			else:
				return 0
		else:
			return 0
		=09
	if( ( ((shot[0] < '1' and shot[0] > '9') and (shot[0] < 'a' and shot[0] =
> 'j')) ) and  ((shot[1] < '1' and shot[1] > '9') and (shot[1] < 'a' and =
shot[1] > 'j')) ):
		return 0
	else:
		return 1

def formatShot( shot ):					#precondition: isShot(shot) =3D=3D 1
	if( shot[0] >=3D 'a' and shot[0] <=3D 'j' ):
		return shot
	if( len(shot) =3D=3D 2 ):
		shot =3D "" + shot[1] + shot[0]
		return shot
	shot =3D "" + shot[2] + shot[0] + shot[1]
	return shot
=09
=09

def askForShot():
	print "Your move, tough guy!: "
	shot =3D raw_input()
	while( isShot(shot) =3D=3D 0 ):
		print "Invalid. Try again: "
		shot =3D raw_input()
	return shot



#returns 1 if a ship is hit
#returns 0 if an empty spot is hit
#returns -1 if the spot has already been shot at
def processShot( shot, field ):
	h_index =3D getHorizontal( shot )
	v_index =3D getVertical( shot )
	spot =3D field[v_index][h_index]
	if( spot =3D=3D 'o' ):
		field[v_index] =3D field[v_index][:h_index] + "X" + =
field[v_index][h_index+1:]
		return 1
	if( spot =3D=3D '.' ):
		return -1
	if( spot =3D=3D '_' ):
		return 0



#returns 1 if a ship is hit
#returns 0 if an empty spot is hit
#returns -1 if the spot has already been shot at
def checkShot( shot, field ):
	h_index =3D getHorizontal( shot )
	v_index =3D getVertical( shot )
	spot =3D field[v_index][h_index]
	if( spot =3D=3D 'o' ):
		return 1
	if( spot =3D=3D '.' or spot =3D=3D 'X' ):
		return -1
	if( spot =3D=3D '_' ):
		return 0



def generateShot():
	v =3D random.randint( 1, 10 )
	h =3D chr( ord('a') + random.randint( 1, 10 ) - 1 )
	return "" + h + str(v)



def shootSameShip( shot, field ):
	v =3D getVertical( shot )
	h =3D getHorizontal( shot )
	directions =3D []
	global possibleShots
=09
	l_shot =3D getShotInDir(shot,"l")
	r_shot =3D getShotInDir(shot,"r")
	u_shot =3D getShotInDir(shot,"u")
	d_shot =3D getShotInDir(shot,"d")
	if( isShot(l_shot) =3D=3D 1 and checkShot(l_shot, field) !=3D -1 ):	=
directions.append("l")
	if( isShot(r_shot) =3D=3D 1 and checkShot(r_shot, field) !=3D -1 ):	=
directions.append("r")
	if( isShot(u_shot) =3D=3D 1 and checkShot(u_shot, field) !=3D -1 ):	=
directions.append("u")
	if( isShot(d_shot) =3D=3D 1 and checkShot(d_shot, field) !=3D -1 ):	=
directions.append("d")
=09
	if((isShot(l_shot) =3D=3D 1 and getSpot(l_shot,field) =3D=3D "X" ) or ( =
isShot(r_shot) =3D=3D 1 and  getSpot(r_shot,field) =3D=3D "X" )):
		if( "u" in directions ):	directions.remove("u")
		if( "d" in directions ):	directions.remove("d")

	if((isShot(u_shot) =3D=3D 1 and getSpot(u_shot,field) =3D=3D "X" ) or ( =
isShot(d_shot) =3D=3D 1 and  getSpot(d_shot,field) =3D=3D "X" )):
		if( "l" in directions ):	directions.remove("l")
		if( "r" in directions ):	directions.remove("r")

=09
	for dir in directions:
		newShot =3D getShotInDir(shot, dir)
		if( isShot(newShot) =3D=3D 1 and checkShot(newShot,field) !=3D -1 and =
newShot not in possibleShots ):
			possibleShots.append( newShot )

	for s in possibleShots:
		if(getSpot(s,field) =3D=3D "."):	possibleShots.remove(s)
	ind =3D random.randint(0, len(possibleShots)-1)
	shot =3D possibleShots[ind]
	possibleShots.remove(shot)
	return shot



def getShotInDir( shot, direction ):
	h =3D shot[0]
	v =3D getVertical( shot )

	if( direction =3D=3D "r" ):
		if( h >=3D 'j' ):
			return ""
		else:
			return "" + chr(ord(h)+1) + str(v)
	if( direction =3D=3D "l" ):
		if( h <=3D 'a' ):
			return ""
		else:
			return "" + chr(ord(h)-1) + str(v)
	if( direction =3D=3D "u" ):
		if( v <=3D 1 ):
			return ""
		else:
			return "" + h + str(v-1)
	if( direction =3D=3D "d" ):
		if( v >=3D 10 ):
			return ""
		else:
			return "" + h + str(v+1)



def getSpot( shot, field ):
	v =3D getVertical( shot )
	h =3D getHorizontal( shot )
	return "" + field[v][h]

=09

#returns 1 if the ship is sinks
#returns 0 otherwise
def checkIfSunk( shot, field ):
	right =3D 1
	left =3D 1
	up =3D 1
	down =3D 1
	h =3D getHorizontal( shot )
	v =3D getVertical( shot )

	if( h < 21 and field[v][h + 2] =3D=3D 'o' ):
		return 0
	if( field[v][h - 2] =3D=3D 'o' ):
		return 0
	if( v < 10 and field[v+1][h] =3D=3D 'o' ):
		return 0
	if( field[v-1][h] =3D=3D 'o' ):
		return 0

	if( h < 21 and field[v][h+2] =3D=3D 'X' ):
		right =3D checkIfSunkDir( getShotInDir( shot, "r" ), field, "r" )
	if( h > 3 and field[v][h-2] =3D=3D 'X' ):
		left =3D checkIfSunkDir( getShotInDir( shot, "l" ), field, "l" )
	if( v > 1 and field[v-1][h] =3D=3D 'X' ):
		up =3D checkIfSunkDir( getShotInDir( shot, "u" ), field, "u" )
	if( v < 10 and field[v+1][h] =3D=3D 'X' ):
		down =3D checkIfSunkDir( getShotInDir( shot, "d" ), field, "d" )
	return right*left*up*down
=09


#used by CheckIfSunk, this method is recursive
def checkIfSunkDir( shot, field, direction ):
	if( isShot(shot) =3D=3D 0 ):	return 1
	h =3D getHorizontal( shot )
	v =3D getVertical( shot )

	newShot =3D getShotInDir( shot, direction )
	if( isShot(newShot) =3D=3D 0 ):	return 1
	if( isShot(getShotInDir(newShot, direction)) =3D=3D 1 and getSpot( =
newShot, field ) =3D=3D 'X' ):
		return checkIfSunkDir( newShot, field, direction )
	elif( getSpot( newShot, field ) =3D=3D 'o' ):
		return 0
	else:
		return 1


=09
def dotDiagnal( shot, field ):
	v_index =3D getVertical( shot )
	h_index =3D getHorizontal( shot )
	if( v_index < 10 and h_index < 21 ):
		field[v_index+1] =3D field[v_index+1][:h_index+2] + "." + =
field[v_index+1][h_index+3:]
	if( v_index < 10 and h_index > 3 ):
		field[v_index+1] =3D field[v_index+1][:h_index-2] + "." + =
field[v_index+1][h_index-1:]
	if( v_index > 1 and h_index < 21 ):
		field[v_index-1] =3D field[v_index-1][:h_index+2] + "." + =
field[v_index-1][h_index+3:]
	if( v_index > 1 and h_index > 3 ):
		field[v_index-1] =3D field[v_index-1][:h_index-2] + "." + =
field[v_index-1][h_index-1:]



def dotAcross( shot, field ):
	v_index =3D getVertical( shot )
	h_index =3D getHorizontal( shot )
	if( v_index < 10 and field[v_index+1][h_index] =3D=3D "_" ):
		field[v_index+1] =3D field[v_index+1][:h_index] + "." + =
field[v_index+1][h_index+1:]
	if( v_index > 1 and field[v_index-1][h_index] =3D=3D "_" ):
		field[v_index-1] =3D field[v_index-1][:h_index] + "." + =
field[v_index-1][h_index+1:]
	if( h_index < 21 and field[v_index][h_index+2] =3D=3D "_" ):
		field[v_index] =3D field[v_index][:h_index+2] + "." + =
field[v_index][h_index+3:]
	if( h_index > 3 and field[v_index][h_index-2] =3D=3D "_" ):
		field[v_index] =3D field[v_index][:h_index-2] + "." + =
field[v_index][h_index-1:]
=09


def dotAlong( shot, field ):
	directions =3D ["r", "l", "u", "d"]
	for dir in directions:
		s =3D getShotInDir( shot, dir )
		if( isShot( s ) =3D=3D 1 ):
			if( getSpot(s, field) =3D=3D "X" ):
				dotAlongDir( s, field, dir )
			elif( getSpot(s, field) =3D=3D "_" ):
				addToField( ".", s,  field )



#takes shot as the place to dot or go in direction dir=20
#(not as the place from which to start and go in the direction)
def dotAlongDir( shot, field, dir ):
	if( isShot(shot) =3D=3D 0 ):
		return
	if( getSpot(shot, field) =3D=3D "X" ):
		dotAlongDir( getShotInDir(shot,dir), field, dir )
	elif( getSpot(shot, field) =3D=3D "_"):
		addToField( ".", shot, field )
=09


def addToField( mark, shot, field ):
	v_index =3D getVertical( shot )
	h_index =3D getHorizontal( shot )
	field[v_index] =3D field[v_index][:h_index] + mark + =
field[v_index][h_index+1:]



#returns a random direction - "r","l","u","d"
def randDir():
	dir =3D ["r","l","u","d"]
	i =3D random.randint(0,3)
	return dir[i]



def generateField( field ):
	ships =3D { "4.1":["","","",""], "3.1":["","",""], "3.2":["","",""], =
"2.1":["",""], "2.2":["",""], "2.3":["",""], "1.1":[""], "1.2":[""], =
"1.3":[""], "1.4":[""] }
=09
	shot =3D ""
	dir =3D ""
	ind =3D 1
	for ship in ships.keys():
		ok =3D 0
		while( ok =3D=3D 0 ):
			shot =3D generateShot()
			dir =3D randDir()
			pos =3D placeShipDir( len(ships[ship]), shot, dir, field )
			if( len(pos) > 0 ):
				ships[ship] =3D pos
				ok =3D 1
		for s in ships[ship]:
			addToField("X", s, field)
			dotDiagnal( s, field )
		dotAlong( s, field )

	y =3D 0
	while( y < len(field) ):
		x =3D 0
		while( x < len(field[y]) ):
			if( field[y][x] =3D=3D '.' ):
				field[y] =3D field[y][:x] + "_" + field[y][x+1:]
			elif( field[y][x] =3D=3D "X" ):
				field[y] =3D field[y][:x] + "o" + field[y][x+1:]
			x =3D x+1
		y =3D y+1



def manuallyMakeField( field ):
	ships =3D { "4.1":["","","",""], "3.1":["","",""], "3.2":["","",""], =
"2.1":["",""], "2.2":["",""], "2.3":["",""], "1.1":[""], "1.2":[""], =
"1.3":[""], "1.4":[""] }
=09
	shot =3D ""
	dir =3D ""
	ind =3D 1
	for ship in ships.keys():
		ok =3D 0
		while( ok =3D=3D 0 ):
			shot =3D raw_input( "Place ship of length " + str(len(ships[ship])) + =
" here: " )
			shot =3D formatShot( shot )
			if( len(ships[ship]) =3D=3D 1 ):	dir =3D randDir()
			else:				dir =3D raw_input( "In direction: " )
			pos =3D placeShipDir( len(ships[ship]), shot, dir, field )
			if( len(pos) > 0 ):
				ships[ship] =3D pos
				ok =3D 1
		for s in ships[ship]:
			addToField("X", s, field)
			dotDiagnal( s, field )
		dotAlong( s, field )
		printField( field )

	y =3D 0
	while( y < len(field) ):
		x =3D 0
		while( x < len(field[y]) ):
			if( field[y][x] =3D=3D '.' ):
				field[y] =3D field[y][:x] + "_" + field[y][x+1:]
			elif( field[y][x] =3D=3D "X" ):
				field[y] =3D field[y][:x] + "o" + field[y][x+1:]
			x =3D x+1
		y =3D y+1



#head =3D location of beginning of the ship in the form of a shot
def placeShipDir( length, head, dir, field ):
	position =3D []
	while( length > 0 ):
		if( isShot(head) =3D=3D 1 and getSpot(head, field) =3D=3D "_" ):
			position.append( head )
			head =3D getShotInDir( head, dir )
			length =3D length-1
		else:	return []
	return position



#----------------------Test---------------------------





#----------------------Main---------------------------

generateField( compsField )
ans =3D raw_input("Would you like to place your ships mannually? (y/n): =
")
if( ans =3D=3D "y" or ans =3D=3D "Y" ):
	print "Aye, aye, captain! Let us position our armada!"
	manuallyMakeField( yourField )
else:
	print "Aye, aye, captain! The ships will be placed as we planned =
before!"
	generateField( yourField )

print "\n   -----Your Field-----"
for line in yourField:
	print line


while( usersSpots > 0 and compsSpots > 0 ):
	while( turn =3D=3D "user" and usersSpots > 0 and compsSpots > 0):
		print "   --Computer's field--"
		printField( yourShots )
		shot =3D askForShot()
		if (shot =3D=3D "qq"):
			shot =3D "a1"
			usersSpots =3D 0
			turn =3D "computer"
		shot =3D formatShot(shot)
		hit =3D processShot(shot, compsField)
		if( hit !=3D 0 ):
			if( hit =3D=3D 1 ):
				compsSpots =3D compsSpots - 1
				addToField( "X", shot, yourShots )
				print "Nicely done!"
				sunk =3D checkIfSunk( shot, compsField )
				if( sunk =3D=3D 1 ):
					print "Down she goes!"
					dotAcross( shot, compsField )
					dotDiagnal( shot, compsField )
					dotAcross( shot, yourShots )
					dotDiagnal( shot, yourShots )
					dotAlong( shot, compsField )
					dotAlong( shot, yourShots )
				else:
					print "Let us use this confusion and fire again!"
					dotDiagnal( shot, compsField )
					dotDiagnal( shot, yourShots )			=09
			if( hit =3D=3D -1):
				print "No need to fire there, capt'n! Ye know better than that!"
		else:
			addToField( ".", shot, yourShots )
			addToField( ".", shot, compsField )
			turn =3D "computer"
	printField( yourShots )
		=09

	while( turn =3D=3D "computer" and usersSpots > 0 and compsSpots > 0):
		if( target =3D=3D "" ):	shot =3D generateShot()
		else:			shot =3D shootSameShip( target, yourField )
	=09
		hit =3D processShot( shot, yourField )
		if( hit =3D=3D 1 ):
			print "Computer shoots: " + shot
			print "...and hits."
			target =3D shot
			usersSpots =3D usersSpots - 1
			addToField( "X", shot, yourField )
			sunk =3D checkIfSunk( shot, yourField )
			dotDiagnal( shot, yourField )
			if( sunk =3D=3D 1 ):
				dotAcross( shot, yourField )
				dotAlong( shot, yourField )
				print "They got us!"
				target =3D ""
				possibleShots =3D []
			else:
				print "We're on fire, capt'n!"
			printField( yourField )
			raw_input("Press Enter")
		elif( hit =3D=3D 0 ):
			print "Computer shoots: " + shot
			print "...and misses!"
			addToField( ".", shot, yourField )
			turn =3D "user"
			printField( yourField )
			raw_input("Press Enter")
	=09
	=09
=09
if( usersSpots =3D=3D 0 ):
	print "\n---You lose---"
	print "Get some more practice, sea-puppy!"
if( compsSpots =3D=3D 0 ):
	print "\n---You win!---"
	print "You are a true sea-wolf!"
=09
=09
=09






------=_NextPart_000_0026_01CA72FC.83D57550--

