# More games at calcplex.com
w='quit'
v='cells'
u='BATTLESHIP'
t=Exception
i='win'
h='grid'
g=str
Y='sunk'
X='miss'
W=False
V=set
R='tried'
Q='ships'
P='len'
L=len
K=True
H='targets'
G='hits'
E=range
import random as Z
try:import ti_draw as B,ti_system as M;S=K
except ImportError:S=W
D=10
x=('CARRIER',5),(u,4),('CRUISER',3),('SUB',3),('DESTROYER',2)
y='EASY','NORMAL','HARD'
def j(rnd,size=D):
	B=rnd;A=size;F=[[0]*A for B in E(A)];J=[]
	for(L,(M,C))in enumerate(x,start=1):
		while K:
			N=B.randint(0,1)==0
			if N:H=B.randint(0,A-1);I=B.randint(0,A-C);D=[(H,I+A)for A in E(C)]
			else:H=B.randint(0,A-C);I=B.randint(0,A-1);D=[(H+A,I)for A in E(C)]
			if all(F[A][B]==0 for(A,B)in D):
				for(O,R)in D:F[O][R]=L
				J.append({'name':M,v:V(D),G:V(),P:C});break
	return{h:F,Q:J,'size':A}
def k(state,r,c):
	B=state;C=B[h][r][c]
	if C==0:return X
	A=B[Q][C-1];A[G].add((r,c))
	if L(A[G])==A[P]:return Y
	return'hit'
def l(state):return sum(1 for A in state[Q]if L(A[G])<A[P])
def m(state):return all(L(A[G])==A[P]for A in state[Q])
def T(state):
	B=V()
	for A in state[Q]:
		if L(A[G])==A[P]:B|=A[v]
	return B
def z():return{R:V(),H:[],G:[]}
def A0(r,c,size):return 0<=r<size and 0<=c<size
def A1(ai,mode,rnd,size=D):
	if mode>0:
		while ai[H]:
			B=ai[H].pop()
			if B not in ai[R]:return B
	A=[(A,B)for A in E(size)for B in E(size)if(A,B)not in ai[R]]
	if mode>=2:
		C=[A for A in A if(A[0]+A[1])%2==0]
		if C:A=C
	return A[rnd.randint(0,L(A)-1)]
def A2(ai,rc,result,mode,size=D):
	J=result;A=ai;A[R].add(rc)
	if mode==0:return
	if J==X:return
	if J==Y:A[G]=[];A[H]=[];return
	A[G].append(rc);B,C=rc;D=None
	for(K,L)in A[G]:
		if(K,L)!=rc:
			if K==B:D='h'
			elif L==C:D='v'
	if D=='h':A[H]=[A for A in A[H]if A[0]==B];I=[(B,C-1),(B,C+1)]
	elif D=='v':A[H]=[A for A in A[H]if A[1]==C];I=[(B-1,C),(B+1,C)]
	else:I=[(B-1,C),(B+1,C),(B,C-1),(B,C+1)]
	for(E,F)in I:
		if A0(E,F,size)and(E,F)not in A[R]and(E,F)not in A[H]:A[H].append((E,F))
C=14
n=44
J,N=6,173
a=26,58,110
o=18,40,78
A3=150,160,180
b=230,70,55
A4=120,30,30
p=90,100,120
A5=250,230,70
I=8,14,26
def c(k):
	try:return int(k)
	except(ValueError,TypeError):return 0
def A(col):A=col;B.set_color(A[0],A[1],A[2])
def F(y,txt):B.draw_text((319-(L(txt)*10-2))//2,y,txt)
def d(y,txt,col):A(I);B.fill_rect(0,y-18,319,22);A(col);F(y,txt)
def U():
	while c(M.get_key(0))!=0:pass
	while K:
		A=c(M.get_key(0))
		if A!=0:
			while c(M.get_key(0))!=0:pass
			return A
def q(gx,r,c):return gx+c*C,n+r*C
def O(gx,r,c,shots,sunk,cursor):
	D,E=q(gx,r,c);G=shots[r][c]
	if(r,c)in sunk:F=A4
	elif G==2:F=b
	elif G==1:F=A3
	else:F=a
	A(o);B.fill_rect(D,E,C,C);A(F);B.fill_rect(D+1,E+1,C-2,C-2)
	if G==1:A((90,100,120));B.fill_rect(D+C//2-2,E+C//2-2,4,4)
	if cursor==(r,c):A(A5);B.fill_rect(D,E,C,2);B.fill_rect(D,E+C-2,C,2);B.fill_rect(D,E,2,C);B.fill_rect(D+C-2,E,2,C)
def e(gx,r,c,state,shots):
	D,E=q(gx,r,c);H=state[h][r][c]!=0;G=shots[r][c];A(o);B.fill_rect(D,E,C,C)
	if G==2:F=b
	elif H:F=p
	else:F=a
	A(F);B.fill_rect(D+1,E+1,C-2,C-2)
	if G==1:A((150,160,180));B.fill_rect(D+C//2-2,E+C//2-2,4,4)
def A6(enemy,player,pshots,cshots,cursor):
	B.clear();A(I);B.fill_rect(0,0,319,209);A((235,150,150));B.draw_text(J+20,41,'ENEMY');A((150,200,235));B.draw_text(N+34,41,'YOU');G=T(enemy)
	for C in E(D):
		for F in E(D):O(J,C,F,pshots,G,cursor);e(N,C,F,player,cshots)
def r(msg,col=(225,232,245)):A(I);B.fill_rect(0,0,319,22);A(col);F(18,msg)
def f(enemy,player):F='left ';E=n+D*C+18;A(I);B.fill_rect(0,E-18,319,22);A((235,150,150));B.draw_text(J,E,F+g(l(enemy)));A((150,200,235));B.draw_text(N,E,F+g(l(player)))
s='BSHPW'
def A7():
	if not S:return[0,0,0]
	try:A=[int(A)for A in list(M.recall_list(s))];return(A+[0,0,0])[:3]
	except t:return[0,0,0]
def A8(v):
	if S:
		try:M.store_list(s,[float(A)for A in v])
		except t:pass
def A9():
	A(I);B.fill_rect(0,0,319,209);A((235,150,150));F(20,'HOW TO PLAY');A((210,222,240));D=['Both 5-ship fleets are hidden','and auto-placed for you.','Move the cursor on the ENEMY','grid and ENTER to fire.','RED = hit, peg = miss. Sink a','ship by hitting all its cells.','Then the CPU fires back at YOUR','grid (right). First to sink the','whole enemy fleet wins.','HARD: the CPU hunts smarter.'];C=46
	for E in D:B.draw_text(6,C,E);C+=16
	A((120,130,160));F(206,'any key = back');U()
def AA(mode,rec):
	C=mode
	def H():
		A(I);B.fill_rect(0,0,319,209);C=15;K=(319-6*C)//2;L=30;M={(0,1),(0,2),(0,3),(2,4),(3,4),(1,0)};N={(0,2),(3,4)}
		for D in E(5):
			for G in E(6):H,J=K+G*C,L+D*C;A((18,40,78));B.fill_rect(H,J,C,C);O=b if(D,G)in N else p if(D,G)in M else a;A(O);B.fill_rect(H+1,J+1,C-2,C-2)
		A((150,200,235));F(130,u);A((150,165,200));F(152,'<- -> mode    up/dn help')
	def G(m):
		d(178,'< '+y[m]+' >',(215,235,245))
		if rec[m]:d(198,'wins  '+g(rec[m]),(150,235,170))
		else:d(198,'ENTER play   CLEAR quit',(120,130,160))
	H();G(C)
	while K:
		D=U()
		if D==45:return
		if D==24:C=(C-1)%3;G(C)
		elif D==26:C=(C+1)%3;G(C)
		elif D in(25,34):A9();H();G(C)
		elif D==105:return C
def AB(mode):
	C=j(Z);B=j(Z);F=[[0]*D for A in E(D)];L=[[0]*D for A in E(D)];b=z();A=D//2,D//2;A6(C,B,F,L,A);r('Your shot -- ENTER to fire');f(C,B)
	while K:
		H=U()
		if H==45:return w
		M,P=A
		if H==25:M=(A[0]-1)%D
		elif H==34:M=(A[0]+1)%D
		elif H==24:P=(A[1]-1)%D
		elif H==26:P=(A[1]+1)%D
		elif H==105:
			Q,R=A
			if F[Q][R]!=0:continue
			V=k(C,Q,R);F[Q][R]=2 if V!=X else 1;I=T(C);O(J,Q,R,F,I,A)
			if V==Y:
				for(W,a)in I:O(J,W,a,F,I,A)
				f(C,B)
			if m(C):return i
			G=A1(b,mode,Z);S=k(B,G[0],G[1]);L[G[0]][G[1]]=2 if S!=X else 1;A2(b,G,S,mode);e(N,G[0],G[1],B,L)
			if S==Y:
				for(W,a)in T(B):e(N,W,a,B,L)
				f(C,B)
			if m(B):return'lose'
			r('you '+V.upper()+'   cpu '+S);continue
		if(M,P)!=A:c=A;A=M,P;I=T(C);O(J,c[0],c[1],F,I,A);O(J,A[0],A[1],F,I,A)
def AC():
	E=A7();C=1
	while K:
		H=AA(C,E)
		if H is None:break
		C=H;D=K
		while D:
			G=AB(C)
			if G==w:D=W;continue
			if G==i:E[C]+=1;A8(E)
			A(I);B.fill_rect(30,70,259,90);A((44,60,96));B.fill_rect(34,74,251,82);A(I);B.fill_rect(37,77,245,76)
			if G==i:A((150,235,170));F(104,'YOU WIN!')
			else:A((235,120,110));F(104,'CPU WINS')
			A((160,175,205));F(132,'ENTER play again');F(150,'<- -> menu   CLEAR quit');J=U()
			if J==45:D=W
			elif J in(24,26):D=W
	B.clear()
if S:AC()