Finalized Code With Comments



clc
clear

% Directions
fprintf('Ship 1 = 5 units long\n Ship 2 = 4 units long\n Ship 3 and 4 = 3 units long\n Ship 5 = 2 units long\n')
fprintf('First, place your above ships on your board, using on screen prompts\n Second, on your turn, guess a coordinate of where you think your\n')
fprintf('If all points of a ship are hit, then that ship is sunk, the first person to sink all of the opponent''s ships is the winner\n')
fprintf('Don''t close out of any dialog boxes\n')
fprintf('Can YOU beat the computer?\n')

 

 

%no obnoxious error messages
warning('off','all');
set(0,'DefaultFigureWindowStyle','docked');
%define vertical and horizontal values
devmode=0;
V=1;
v=1;
h=2;
H=2;
Occupied=zeros(10,10);
PlyOcu=zeros(10,10);
%for loop setting up the matrix of the user inputs
for i = 1:5
%shows what ship you're on
fprintf('\nThis is ship %.0d',i);
K(i)=i;
%asks user for direction
A(i)=input('\nInput ship direction, V is vertical, H is horizontal: ');
%floor gets rid of decimals
ShipDirection(i)=floor(A(i));
%Making sure they put V or H
while (ShipDirection(i)~=1) && (ShipDirection(i)~=2)
%cheat code!
if K==1 %so the cheat text doesn't appear more than once
if A(1) == 0.1127 %the cheat code
fprintf('\nCheats Enabled!\n') %display if cheat is activated
devmode = 1;
end
end
%prompts user for re-input if it isnt 1 or 2
ShipDirection(i)=input('Re-input ship direction, V is vertical, H is horizontal: ');
end

%prompts user to input ship row
B(i)=input('Input ship row: ');
ShipRow(i)=floor(B(i));
%making sure values are 1 through 10
while (ShipRow(i)<1)||(ShipRow(i)>10)
SRT(i)=input('Re-input ship row: ');
%floors to get rid of decimals
ShipRow(i)=floor(SRT(i));
end

%If Vertical input, making sure ship does not go out of bounds, since
%each ship length is 5,4,3,3,or 2 the ship is out of bounds if the row
%given is more than 11-ShipLength
if i==1
if ShipDirection(i)==1
while ShipRow(i)>6
ShipRow(i)=input('OUT OF BOUNDS, Re-input ship row(1-6): ');
end
end
elseif i==2
if ShipDirection(i)==1
while ShipRow(i)>7
ShipRow(i)=input('OUT OF BOUNDS, Re-input ship row(1-7): ');
end
end
elseif i==3
if ShipDirection(i)==1
while ShipRow(i)>8
ShipRow(i)=input('OUT OF BOUNDS, Re-input ship row(1-8): ');
end
end
elseif i==4
if ShipDirection(i)==1
while ShipRow(i)>8
ShipRow(i)=input('OUT OF BOUNDS, Re-input ship row(1-8): ');
end
end
elseif i==5
if ShipDirection(i)==1
while ShipRow(i)>9
ShipRow(i)=input('OUT OF BOUNDS, Re-input ship row(1-9): ');
end
end
end

%prompts user to input column
C(i)=input('Input ship column: ');
%floors inputs
ShipColumn(i)=floor(C(i));
%make sure values are 1 through 10
while (ShipColumn(i)<1)||(ShipColumn(i)>10)
SCT(i)=input('Re-input ship column: ');
ShipColumn(i)=floor(SCT(i));
end

%If horizontal input, making sure ship does not go out of bounds. see
%explanation above, except this is with columns instead of rows
if i==1
if ShipDirection(i)==2
while ShipColumn(i)>6
ShipColumn(i)=input('OUT OF BOUNDS, Re-input ship column(1-6): ');
end
end
elseif i==2
if ShipDirection(i)==2
while ShipColumn(i)>7
ShipColumn(i)=input('OUT OF BOUNDS, Re-input ship column(1-7): ');
end
end
elseif i==3
if ShipDirection(i)==2
while ShipColumn(i)>8
ShipColumn(i)=input('OUT OF BOUNDS, Re-input ship column(1-8): ');
end
end
elseif i==4
if ShipDirection(i)==2
while ShipColumn(i)>8
ShipColumn(i)=input('OUT OF BOUNDS, Re-input ship column(1-8): ');
end
end
elseif i==5
if ShipDirection(i)==2
while ShipColumn(i)>9
ShipColumn(i)=input('OUT OF BOUNDS, Re-input ship row(1-9): ');
end
end
end

%if ship 1 is vertical, these points are plotted
if i == 1
if ShipDirection(i) == 1
Occupied(ShipRow(i),ShipColumn(i))=1;
Occupied((ShipRow(i)+1),ShipColumn(i))=2;
Occupied((ShipRow(i)+2),ShipColumn(i))=2;
Occupied((ShipRow(i)+3),ShipColumn(i))=2;
Occupied((ShipRow(i)+4),ShipColumn(i))=3;
PlyOcu(ShipRow(i),ShipColumn(i))=i;
PlyOcu((ShipRow(i)+1),ShipColumn(i))=i;
PlyOcu((ShipRow(i)+2),ShipColumn(i))=i;
PlyOcu((ShipRow(i)+3),ShipColumn(i))=i;
PlyOcu((ShipRow(i)+4),ShipColumn(i))=i;
%if ship 2 is horizontal, these points are plotted
elseif ShipDirection(i) == 2
Occupied(ShipRow(i),(ShipColumn(i)))=4;
Occupied(ShipRow(i),(ShipColumn(i)+1))=5;
Occupied(ShipRow(i),(ShipColumn(i)+2))=5;
Occupied(ShipRow(i),(ShipColumn(i)+3))=5;
Occupied(ShipRow(i),(ShipColumn(i)+4))=6;
PlyOcu(ShipRow(i),(ShipColumn(i)))=i;
PlyOcu(ShipRow(i),(ShipColumn(i)+1))=i;
PlyOcu(ShipRow(i),(ShipColumn(i)+2))=i;
PlyOcu(ShipRow(i),(ShipColumn(i)+3))=i;
PlyOcu(ShipRow(i),(ShipColumn(i)+4))=i;
end
%%%%%
%same for ship 2
elseif i == 2
if ShipDirection(i) == 1
%if there is overalap, prompts user for re-input
while (Occupied(ShipRow(i),ShipColumn(i))~=0) || (Occupied((ShipRow(i)+1),ShipColumn(i))~=0) || (Occupied((ShipRow(i)+2),ShipColumn(i))~=0) || (Occupied((ShipRow(i)+3),ShipColumn(i))~=0)
ShipRow(i)=input('COLLIDES WITH ANOTHER SHIP, Re-input ship row: ');
while ShipRow(i)>7
ShipRow(i)=input('OUT OF BOUNDS, Re-input ship row(1-7): ');
end
ShipColumn(i)=input('Re-input ship column: ');
end
%plots points if vertical for ship 2
Occupied(ShipRow(i),ShipColumn(i))=1;
Occupied((ShipRow(i)+1),ShipColumn(i))=2;
Occupied((ShipRow(i)+2),ShipColumn(i))=2;
Occupied((ShipRow(i)+3),ShipColumn(i))=3;
PlyOcu(ShipRow(i),ShipColumn(i))=i;
PlyOcu((ShipRow(i)+1),ShipColumn(i))=i;
PlyOcu((ShipRow(i)+2),ShipColumn(i))=i;
PlyOcu((ShipRow(i)+3),ShipColumn(i))=i;
elseif ShipDirection(i) == 2
%if there is overalap, prompts user for re-input
while (Occupied(ShipRow(i),ShipColumn(i))~=0) || (Occupied(ShipRow(i),(ShipColumn(i)+1))~=0) || (Occupied(ShipRow(i),(ShipColumn(i)+2))~=0) || (Occupied(ShipRow(i),(ShipColumn(i)+3))~=0)
ShipRow(i)=input('COLLIDES WITH ANOTHER SHIP, Re-input ship row: ');
ShipColumn(i)=input('Re-input ship column: ');
while ShipColumn(i)>7
ShipColumn(i)=input('OUT OF BOUNDS, Re-input ship column(1-7): ');
end
end
%plots points if horizontal for ship 2
Occupied(ShipRow(i),(ShipColumn(i)))=4;
Occupied(ShipRow(i),(ShipColumn(i)+1))=5;
Occupied(ShipRow(i),(ShipColumn(i)+2))=5;
Occupied(ShipRow(i),(ShipColumn(i)+3))=6;
PlyOcu(ShipRow(i),(ShipColumn(i)))=i;
PlyOcu(ShipRow(i),(ShipColumn(i)+1))=i;
PlyOcu(ShipRow(i),(ShipColumn(i)+2))=i;
PlyOcu(ShipRow(i),(ShipColumn(i)+3))=i;
end
%%%%%
%PROCESS REPEATS FOR EACH SHIP
elseif i == 3
if ShipDirection(i) == 1
while (Occupied(ShipRow(i),ShipColumn(i))~=0) || (Occupied((ShipRow(i)+1),ShipColumn(i))~=0) || (Occupied((ShipRow(i)+2),ShipColumn(i))~=0)
ShipRow(i)=input('COLLIDES WITH ANOTHER SHIP, Re-input ship row: ');
while ShipRow(i)>8
ShipRow(i)=input('OUT OF BOUNDS, Re-input ship row(1-8): ');
end
ShipColumn(i)=input('Re-input ship column: ');
end
Occupied(ShipRow(i),ShipColumn(i))=1;
Occupied((ShipRow(i)+1),ShipColumn(i))=2;
Occupied((ShipRow(i)+2),ShipColumn(i))=3;
PlyOcu(ShipRow(i),ShipColumn(i))=i;
PlyOcu((ShipRow(i)+1),ShipColumn(i))=i;
PlyOcu((ShipRow(i)+2),ShipColumn(i))=i;

elseif ShipDirection(i) == 2
while (Occupied(ShipRow(i),ShipColumn(i))~=0) || (Occupied(ShipRow(i),(ShipColumn(i)+1))~=0) || (Occupied(ShipRow(i),(ShipColumn(i)+2))~=0)
ShipRow(i)=input('COLLIDES WITH ANOTHER SHIP, Re-input ship row: ');
ShipColumn(i)=input('Re-input ship column: ');
while ShipColumn(i)>8
ShipColumn(i)=input('OUT OF BOUNDS, Re-input ship column(1-8): ');
end
end
Occupied(ShipRow(i),(ShipColumn(i)))=4;
Occupied(ShipRow(i),(ShipColumn(i)+1))=5;
Occupied(ShipRow(i),(ShipColumn(i)+2))=6;
PlyOcu(ShipRow(i),(ShipColumn(i)))=i;
PlyOcu(ShipRow(i),(ShipColumn(i)+1))=i;
PlyOcu(ShipRow(i),(ShipColumn(i)+2))=i;
end
%%%%%%
elseif i == 4
if ShipDirection(i) == 1
while (Occupied(ShipRow(i),ShipColumn(i))~=0) || (Occupied((ShipRow(i)+1),ShipColumn(i))~=0) || (Occupied((ShipRow(i)+2),ShipColumn(i))~=0)
ShipRow(i)=input('COLLIDES WITH ANOTHER SHIP, Re-input ship row: ');
while ShipRow(i)>8
ShipRow(i)=input('OUT OF BOUNDS, Re-input ship row(1-8): ');
end
ShipColumn(i)=input('Re-input ship column: ');
end
Occupied(ShipRow(i),ShipColumn(i))=1;
Occupied((ShipRow(i)+1),ShipColumn(i))=2;
Occupied((ShipRow(i)+2),ShipColumn(i))=3;
PlyOcu(ShipRow(i),ShipColumn(i))=i;
PlyOcu((ShipRow(i)+1),ShipColumn(i))=i;
PlyOcu((ShipRow(i)+2),ShipColumn(i))=i;
elseif ShipDirection(i) == 2
while (Occupied(ShipRow(i),ShipColumn(i))~=0) || (Occupied(ShipRow(i),(ShipColumn(i)+1))~=0) || (Occupied(ShipRow(i),(ShipColumn(i)+2))~=0)
ShipRow(i)=input('COLLIDES WITH ANOTHER SHIP, Re-input ship row: ');
ShipColumn(i)=input('Re-input ship column: ');
while ShipColumn(i)>8
ShipColumn(i)=input('OUT OF BOUNDS, Re-input ship column(1-8): ');
end
end
Occupied(ShipRow(i),(ShipColumn(i)))=4;
Occupied(ShipRow(i),(ShipColumn(i)+1))=5;
Occupied(ShipRow(i),(ShipColumn(i)+2))=6;
PlyOcu(ShipRow(i),(ShipColumn(i)))=i;
PlyOcu(ShipRow(i),(ShipColumn(i)+1))=i;
PlyOcu(ShipRow(i),(ShipColumn(i)+2))=i;
end
%%%%%
elseif i == 5
if ShipDirection(i) == 1
while (Occupied(ShipRow(i),ShipColumn(i))~=0) || (Occupied((ShipRow(i)+1),ShipColumn(i))~=0)
ShipRow(i)=input('COLLIDES WITH ANOTHER SHIP, Re-input ship row: ');
while ShipRow(i)>9
ShipRow(i)=input('OUT OF BOUNDS, Re-input ship row(1-9): ');
end
ShipColumn(i)=input('Re-input ship column: ');
end
Occupied(ShipRow(i),ShipColumn(i))=1;
Occupied((ShipRow(i)+1),ShipColumn(i))=3;
PlyOcu(ShipRow(i),ShipColumn(i))=i;
PlyOcu((ShipRow(i)+1),ShipColumn(i))=i;
elseif ShipDirection(i) == 2
while (Occupied(ShipRow(i),ShipColumn(i))~=0) || (Occupied(ShipRow(i),(ShipColumn(i)+1))~=0)
ShipRow(i)=input('COLLIDES WITH ANOTHER SHIP, Re-input ship row: ');
ShipColumn(i)=input('Re-input ship column: ');
while ShipColumn(i)>9
ShipColumn(i)=input('OUT OF BOUNDS, Re-input ship column(1-9): ');
end
end
Occupied(ShipRow(i),(ShipColumn(i)))=4;
Occupied(ShipRow(i),(ShipColumn(i)+1))=6;
PlyOcu(ShipRow(i),(ShipColumn(i)))=i;
PlyOcu(ShipRow(i),(ShipColumn(i)+1))=i;
end
end
end
Occupied;

%the final matrix setup, using .' to rotate it to correct orientation
PLoc=[K;ShipDirection;ShipRow;ShipColumn].';

load battleship
OLoc = Setup(); %setup for the opponents coordinates
OppOcu=zeros(10,10);
for j = 1:5
column = OLoc(j,3); %states initial x coordinate of the specific ship
row = OLoc(j,4); %states initial y coordinate of the specific ship
ShipType = OLoc(j,1); %specific ship type
if ShipType == 1 %relates ship type to its length
ShipLen = 5;
elseif ShipType == 2
ShipLen = 4;
elseif ShipType == 3
ShipLen = 3;
elseif ShipType == 3
ShipLen = 3;
elseif ShipType == 5
ShipLen = 2;
end
BodLen = ShipLen - 2; %creates variable for length of body
ShipOr = OLoc(j,2); %states ship's orientation
if ShipOr == 1 %for ships in vertical direction
ShipFront = Boat_FrontBack_2; %these make variables for the pictures in the vertical orientation
ShipBody = Boat_Mid_vert;
ShipBack = Boat_FrontBack_1;
if devmode == 1
Opponent_Board{(column+BodLen),row} = ShipBody; %a ship body piece can be placed a body length away
end
OppOcu((column+BodLen),row)=ShipType;
if devmode == 1
Opponent_Board{(column+1),row} = ShipBody; %another ship body piece will be placed 1 away from the front
end
OppOcu((column+1),row)=ShipType;
%these pieces go for all ship, if it is ship #5 the front and back
%get placed over by default
if ShipLen == 5 %ship 5 gives problems so it gets a special case for the body
if devmode == 1
Opponent_Board{(column+2),row} = ShipBody;
end
OppOcu((column+2),row)=ShipType;
end
if devmode == 1
Opponent_Board{(column+(ShipLen-1)),row} =ShipBack; %the ship's back will always be this distance from the front
end
OppOcu((column+(ShipLen-1)),row)=ShipType;
elseif ShipOr == 2 %for ships in horizontal direction
ShipFront = Boat_FrontBack_3; %creates variables for pics of horizontal ships
ShipBody = Boat_Mid_hor;
ShipBack = Boat_FrontBack_4;
if devmode == 1
Opponent_Board{column,(row+BodLen)} =ShipBody; %all ships have a body piece a body length away from the front
end
OppOcu(column,(row+BodLen))=ShipType;
if devmode == 1
Opponent_Board{column,(row+1)} = ShipBody; %all ships have a body piece 1 away from the front
end
OppOcu(column,(row+1))=ShipType;
if ShipLen ==5 %again, ship 5 has problems so it needs a special case
if devmode == 1
Opponent_Board{column,(row+2)} = ShipBody;
end
OppOcu(column,(row+2))=ShipType;
end
if devmode == 1
Opponent_Board{column,(row+(ShipLen-1))} =ShipBack; %all ships have a back this far away
end
OppOcu(column,(row+(ShipLen-1)))=ShipType;
end
if devmode == 1
Opponent_Board{column,row} =ShipFront; %the ship's front is in the coordinates from the matrix
end
OppOcu(column,row)=ShipType;
end

OppOcu; clear devmode;

for y = 1:5
%gets starting coordinates of each ship from initialization matrix
xcord = PLoc(y,3);
ycord = PLoc(y,4);
%pulls hsip type from matrix
ShipType = PLoc(y,1);
%sets each ship type a set length
if ShipType == 1
ShipLen = 5;
elseif ShipType == 2
ShipLen = 4;
elseif ShipType == 3
ShipLen = 3;
elseif ShipType == 4
ShipLen = 3;
elseif ShipType == 5
ShipLen = 2;
end

%BodLen is the length of the ship without the front and back
BodLen = ShipLen - 2;
%pulls ship orientation from matrix
ShipOr = PLoc(y,2);

%if ship is vertical, this if statement places each piece on each ship
if ShipOr == 1
ShipFront = Boat_FrontBack_2;
ShipBody = Boat_Mid_vert;
ShipBack = Boat_FrontBack_1;
Player_Board{(xcord+BodLen),ycord} = ShipBody;
Player_Board{(xcord+1),ycord} = ShipBody;
%ship 5 is an exception because it is length 2 and has no middle
if ShipLen == 5
Player_Board{(xcord+2),ycord} = ShipBody;
end
%plotting coordinates
Player_Board{(xcord+(ShipLen-1)),ycord} =ShipBack;%plots coords for ship back

%same process for horizontal ships
elseif ShipOr == 2
ShipFront = Boat_FrontBack_3;
ShipBody = Boat_Mid_hor;
ShipBack = Boat_FrontBack_4;
Player_Board{xcord,(ycord+BodLen)} =ShipBody;
Player_Board{xcord,(ycord+1)} = ShipBody;
%ship 5 is still an exception because it has no middle.
if ShipLen ==5
Player_Board{xcord,(ycord+2)} = ShipBody;
end

Player_Board{xcord,(ycord+(ShipLen-1))} =ShipBack;
end
Player_Board{xcord,ycord} =ShipFront;%plots coordinates for ship front
end

subplot (2,1,1);
imshow([Opponent_Board{1,:};Opponent_Board{2,:};Opponent_Board{3,:};
Opponent_Board{4,:};Opponent_Board{5,:};Opponent_Board{6,:};
Opponent_Board{7,:};Opponent_Board{8,:};Opponent_Board{9,:};
Opponent_Board{10,:}]);
subplot(2,1,2);
imshow([Player_Board{1,:};Player_Board{2,:};Player_Board{3,:};
Player_Board{4,:};Player_Board{5,:};Player_Board{6,:};Player_Board{7,:};
Player_Board{8,:};Player_Board{9,:};Player_Board{10,:}]);
set(1, 'DefaultFigureWindowStyle','docked')

 

%setting END to 0 to start the while loop on line 424
END = 0;

%setting turn counter to 1
turn = 1;

%setting newHit to 0
newHit = 0;

%setting lastHit to 0
lastHit = 0;

% Whether we sunk a ship last turn
ship_sunk_last_turn = 0;

%creating a board matrix with all zeroes
guessBoard = zeros(10, 10);

%creating a board matrix with all zeroes for computer
guessBoardcomp = zeros(10, 10);

%creating vector of possible input values
posInput = 1:10;

 

while END == 0

%Getting the x coordinate for the user's guess
guess_x = input('What row would you like to guess? ');

%seeing if x coordinate is just a whole number between 1 and 10
a = ismember(posInput, guess_x);

%if a bad x value is inputted, have user input another x value
while a == 0
%showing error box
error1 = errordlg('You need to just input a whole number between 1 and 10');
child = get(error1,'children');
%Removes ok button
delete(child(1));
drawnow
pause(2);
close(error1);

%asking for new x input
guess_x = input('What row would you like to guess? ');

%seeing if x coordinate is just a whole number between 1 and 10
a = ismember(posInput, guess_x);
end

%Getting the y coordinate for the user's guess
guess_y = input('What column would you like to guess? ');

%seeing if y coordinate is just a whole number between 1 and 10
b = ismember(posInput, guess_y);

%if a bad y value is inputted, have user input another y value
while b == 0
%showing error box
error2 = errordlg('You need to just input a whole number between 1 and 10');
child = get(error2,'children');
%Removes ok button
delete(child(1));
drawnow
pause(2);
close(error2);

%asking for new y input
guess_y = input('What row would you like to guess? ');

%seeing if y coordinate is just a whole number between 1 and 10
b = ismember(posInput, guess_y);
end

%testing to see if the User's guess has already been guessed
if turn >= 2
while guessBoard(guess_x, guess_y) == 1

%showing error box
error3 = errordlg('You already guessed that spot, guess again');
child = get(error3,'children');
%Removes ok button
delete(child(1));
drawnow
pause(2);
close(error3);

%asking for new guess
guess_x = input('What row would you like to guess? ');
guess_y = input('What column would you like to guess? ');
end
end

%setting guess as a 1 on the guessBoard
guessBoard(guess_x, guess_y) = 1;

%seeing if the guess was a hit
if OppOcu (guess_x,guess_y) >= 1

%setting the ship equal to the ship hit
ship = OppOcu (guess_x,guess_y);

%making the hit a zero in the board matrix
OppOcu (guess_x,guess_y) = 0;

%then it was a hit, play hit music
hitSound = audioread('Hit Sound (first 4 sec).wav');
song_HitSound = audioplayer(hitSound,44100);
play(song_HitSound); pause(1);

%show message
HitMsg = msgbox('HIT!');
child = get(HitMsg,'children');
%Removes ok button
delete(child(1));
drawnow
pause(2);close(HitMsg);

%stopping music
stop(song_HitSound);

%put red marker on board at guess
Opponent_Board{(guess_x),guess_y} = Hit;

%reprinting the board
subplot (2,1,1);
imshow([Opponent_Board{1,:};Opponent_Board{2,:};Opponent_Board{3,:};
Opponent_Board{4,:};Opponent_Board{5,:};Opponent_Board{6,:};
Opponent_Board{7,:};Opponent_Board{8,:};Opponent_Board{9,:};
Opponent_Board{10,:}]);
subplot(2,1,2);
imshow([Player_Board{1,:};Player_Board{2,:};Player_Board{3,:};
Player_Board{4,:};Player_Board{5,:};Player_Board{6,:};Player_Board{7,:};
Player_Board{8,:};Player_Board{9,:};Player_Board{10,:}]);
set(1, 'DefaultFigureWindowStyle','docked')

%seeing if the ship number is still in the matrix anywhere
connect = any(OppOcu == ship );
%turning the array 'connect' into a single number
aliveShip = any(connect == 1);

if aliveShip == 0 %ship sunk becuase the number of the ship is not in the matrix anymore
%play sunk music
sinkSound = audioread('Sink Sound.wav');
song_SinkSound = audioplayer(sinkSound,44100);
play(song_SinkSound); pause(.5);

%show message
SunkMsg = msgbox('You sunk a ship!');
child = get(SunkMsg,'children');
%Removes ok button
delete(child(1));
drawnow
pause(2.5);close(SunkMsg);

%stopping music
stop(song_SinkSound);
end

else %then it was a miss
%play miss sound
missSound = audioread('Miss Sound.wav');
song_MissSound = audioplayer(missSound,44100);
play(song_MissSound); pause(1);

%show message
MissMsg = msgbox({'Miss; Better Luck Next Time'});
child = get(MissMsg,'children');
%Removes ok button
delete(child(1));
drawnow
pause(2);close(MissMsg);

%stopping music
stop(song_MissSound);

ShipMiss = Miss;

%put white marker on board at guess
Opponent_Board{guess_x,guess_y} = ShipMiss;

%reprinting the board
subplot (2,1,1);
imshow([Opponent_Board{1,:};Opponent_Board{2,:};Opponent_Board{3,:};
Opponent_Board{4,:};Opponent_Board{5,:};Opponent_Board{6,:};
Opponent_Board{7,:};Opponent_Board{8,:};Opponent_Board{9,:};
Opponent_Board{10,:}]);
subplot(2,1,2);
imshow([Player_Board{1,:};Player_Board{2,:};Player_Board{3,:};
Player_Board{4,:};Player_Board{5,:};Player_Board{6,:};Player_Board{7,:};
Player_Board{8,:};Player_Board{9,:};Player_Board{10,:}]);
set(1, 'DefaultFigureWindowStyle','docked')
end

%seeing is any ships are still in the matrix and thus not sunk
connect2 = any (OppOcu);
%settin the array 'connect2' as a single number
end_of_game = any (connect2 == 1);

if end_of_game == 0 %no more ships
%play win music
applause = audioread('Applause.wav');
song_applause = audioplayer(applause,44100);
play(song_applause); pause(1);

%show message
WinMsg = msgbox({'You Won!;Congratulations!'});
child = get(WinMsg,'children');
%Removes ok button
delete(child(1));
drawnow
pause(3.8);close(WinMsg);

%stopping music
stop(song_applause);
break
end

%show message
CreepMsg = msgbox('My turn mwahahahahah');
child = get(CreepMsg,'children');
%Removes ok button
delete(child(1));
drawnow
pause(2);close(CreepMsg);

%Computer guessing a spot
[compGuess_x, compGuess_y] = computerTurn(guessBoardcomp, turn, lastHit, newHit, ship_sunk_last_turn);

%storing the previous value of lastHit
Prev_lastHit = lastHit;

%setting guess as a 1 on the guessBoard
guessBoardcomp(compGuess_x, compGuess_y) = 1;

%showing the user the computer's guess
fprintf('I guessed column %.i row %.i\n', compGuess_x, compGuess_y)

%Seeing if the Computer got a hit or not
if PlyOcu (compGuess_x,compGuess_y) >= 1
%setting the ship hit to ship2
ship2 = PlyOcu (compGuess_x, compGuess_y);
lastHit = 1;

%then its a hit, play hit music
hitSound = audioread('Hit Sound (first 4 sec).wav');
song_HitSound = audioplayer(hitSound,44100);
play(song_HitSound); pause(1);

%show message
HitMsg2 = msgbox('I GOT YOU');
child = get(HitMsg2,'children');
%Removes ok button
delete(child(1));
drawnow
pause(2);close(HitMsg2);

%stopping music
stop(song_HitSound);

%put red marker on board for computer guesses
% More complicated than the other one because of the ship images
if Occupied(compGuess_x, compGuess_y)== 3
Player_Board{(compGuess_x),compGuess_y} = Boat_FrontBack_1_hit;
elseif Occupied(compGuess_x, compGuess_y)== 2
Player_Board{(compGuess_x), compGuess_y} = Boat_Mid_vert_hit;
elseif Occupied(compGuess_x, compGuess_y) == 1
Player_Board{(compGuess_x), compGuess_y} = Boat_FrontBack_2_hit;
elseif Occupied(compGuess_x, compGuess_y) == 4
Player_Board{(compGuess_x), compGuess_y} = Boat_FrontBack_3_hit;
elseif Occupied(compGuess_x, compGuess_y) == 5
Player_Board{(compGuess_x), compGuess_y} = Boat_Mid_hor_hit;
elseif Occupied(compGuess_x, compGuess_y) == 6
Player_Board{(compGuess_x), compGuess_y} = Boat_FrontBack_4_hit;
end

%reprinting the board
imshow([Opponent_Board{1,:};Opponent_Board{2,:};Opponent_Board{3,:};
Opponent_Board{4,:};Opponent_Board{5,:};Opponent_Board{6,:};
Opponent_Board{7,:};Opponent_Board{8,:};Opponent_Board{9,:};
Opponent_Board{10,:}]);
subplot(2,1,2);
imshow([Player_Board{1,:};Player_Board{2,:};Player_Board{3,:};
Player_Board{4,:};Player_Board{5,:};Player_Board{6,:};Player_Board{7,:};
Player_Board{8,:};Player_Board{9,:};Player_Board{10,:}]);
set(1, 'DefaultFigureWindowStyle','docked')

%setting the guess to zero on the matrix
PlyOcu(compGuess_x,compGuess_y) = 0;

%seeing if the ship number is still in the matrix anywhere
connect3 = any(PlyOcu == ship2 );
%turning the array 'connect' into a single number
aliveShip2 = any(connect3 == 1);

if aliveShip2 == 0 %ship sunk becuase the number of the ship is not in the matrix anymore

% Set ship_sunk_last_turn to one for computer turn
ship_sunk_last_turn = 1;

%play sunk music
sinkSound = audioread('Sink Sound.wav');
song_SinkSound = audioplayer(sinkSound,44100);
play(song_SinkSound); pause(.5);

%show message
SunkMsg2 = msgbox('ONLY A COUPLE SHIPS LEFT');
child = get(SunkMsg2,'children');
%Removes ok button
delete(child(1));
drawnow
pause(2.5);close(SunkMsg2);

%stopping music
stop(song_SinkSound);
end

else %then it was a miss

% Missed, so no ship was sunk last turn
ship_sunk_last_turn = 0;
lastHit = 0;

%play miss music
missSound = audioread('Miss Sound.wav');
song_MissSound = audioplayer(missSound,44100);
play(song_MissSound); pause(1);

%show message
MissMsg2 = msgbox({'I Missed; I will get you next time'});
child = get(MissMsg2,'children');
%Removes ok button
delete(child(1));
drawnow
pause(2);close(MissMsg2);

%stopping music
stop(song_MissSound);

%put white marker on board at computer guess
Player_Board{(compGuess_x),compGuess_y} = Miss;

%reprinting the board
imshow([Opponent_Board{1,:};Opponent_Board{2,:};Opponent_Board{3,:};
Opponent_Board{4,:};Opponent_Board{5,:};Opponent_Board{6,:};
Opponent_Board{7,:};Opponent_Board{8,:};Opponent_Board{9,:};
Opponent_Board{10,:}]);
subplot(2,1,2);
imshow([Player_Board{1,:};Player_Board{2,:};Player_Board{3,:};
Player_Board{4,:};Player_Board{5,:};Player_Board{6,:};Player_Board{7,:};
Player_Board{8,:};Player_Board{9,:};Player_Board{10,:}]);
set(1, 'DefaultFigureWindowStyle','docked')
end

%if lastHit changed from 0 to 1 newHit should equal 1
if Prev_lastHit == 0 & lastHit == 1
newHit = 1;
else
newHit = 0;
end

%seeing if any ships are still in the matrix and thus not sunk
connect4 = any (PlyOcu);
%setting the array 'connect4' as a single number
end_of_game2 = any (connect4 == 1);

if end_of_game2 == 0 %no more ships
%Getting out of the while loop by chaning the value of END
END = 22;

%play win music
applause = audioread('Applause.wav');
song_applause = audioplayer(applause,44100);
play(song_applause); pause(1);

%show message
WinMsg2 = msgbox({'I Won!; Maybe next time!'});
child = get(WinMsg2,'children');
%Removes ok button
delete(child(1));
drawnow
pause(3.8);close(WinMsg2);

%stopping music
stop(song_applause);
end
turn = turn + 1;
end

 





Computer Function File:

% ENGR 1181.02 SDP - Battleship AI Function
% Group: Q
% Created by: Zach DelVecchio
% Created on: 11/15/18

% Game difficulty
% 1 = Easy, 2 = Hard

% Commenting Scheme
% For/While loops, Nested Ifs - Same line, after the statement, tabbed
% One-of Ifs - Line Before
% Everything else - Line Before

% Evaluates the current game board and previous hits and returns a
% coordinate pair of the next shot
% game_board: Current game_board for the computer (ie what the computer has
% shot at as of now). 10x10 of 0 and 1 for nothing and hit
% difficulty: Difficulty of game (1 or 2)
% turn: Current turn count
% hit_last_turn: Holds whether the last shot was a hit
% new_hit: Holds whether the hit last turn was a new hit

% Ship Information
% 1 = Carrier (5 length)
% 2 = Battleship (4 length)
% 3 = Cruiser (3 length)
% 4 = Submarine (3 length)
% 5 = Destroyer (2 length)

% Quadrant Layout
% |
% 2 | 1
% |
%-------+-------
% |
% 3 | 4
% |

function [final_x, final_y] = computerTurn(game_board, turn, hit_last_turn, new_hit, ship_sunk_last_turn)

% Defined Persistent Variables
% This will hold their values over multiple function calls

% Coordinates of the last hit
persistent prev_shot;

% Coordinates of the first hit in a series of hits
% Always equals prev_shot while new_hit == 1
% Does not change when new_hit == 0
persistent initial_hit;

% Persistent variable for the previous direction fired in
% Cardinal directions (N,S,E,W)
persistent prev_dir;

% Holds the previous state of hit_last_turn
% Used to determine if we ran off a ship before destroying it
persistent prev_hlt_state;

% Set prev_dir to 0 if it has not been set yet
% This only runs on the first turn
% initial_hit and prev_shot do not matter, they are guarenteed set
% before being used
if (isempty(prev_dir))
prev_dir = 0;
end

% Evaluate whether we previously hit something
if (hit_last_turn == 0) % AI hit nothing last turn

if (prev_hlt_state ~= hit_last_turn) % We ran off the end of a ship but did not destroy it

% Return to the initial position and shoot in the opposite direction.
prev_dir = flipDirection(prev_dir);
[final_x, final_y] = moveCoordDirection(prev_dir, initial_hit(1), initial_hit(2));

% This solves the issue with the boats being too close.
while (~isSpaceNew(game_board, final_x, final_y))
prev_dir = randDirection(prev_dir);
[final_x, final_y] = moveCoordDirection(prev_dir, initial_hit(1), initial_hit(2));
end

% Save coordinates for next function call
prev_shot = [final_x, final_y];

% Set prev_hlt_state to hit_last_turn
prev_hlt_state = hit_last_turn;

% Coordinates are set, return
return;

else % AI has not hit anything

% Return a random coordinate using randCoord()
% Ensure that the point has not been chosen before
[final_x, final_y] = randCoord();
while (~isSpaceNew(game_board, final_x, final_y))
[final_x, final_y] = randCoord();
end

% Save coordinates for next function call
prev_shot = [final_x, final_y];

% Set prev_hlt_state to hit_last_turn
prev_hlt_state = hit_last_turn;

% Reset initial_hit
initial_hit = [];

% Coordinates are set, return
return;

end

else % AI hit something last turn
if (new_hit == 1) % hit_last_turn changed from 0 to 1

if (~isempty(initial_hit)) % We ran off the end of a ship but did not destroy it
% and are now at the initial_hit again so continue to shoot
% in this direction. initial_hit is set in this scenario

% Continue shooting in the previous direction
[final_x, final_y] = moveCoordDirection(prev_dir, prev_shot(1), prev_shot(2));

% Save coordinates for the next function call
prev_shot = [final_x, final_y];

% Set prev_hlt_state to hit_last_turn
prev_hlt_state = hit_last_turn;

% Coordinates are set, return
return;

else % The previous hit was a brand new hit

% Set the initial hit to whatever the last shot was
initial_hit = prev_shot;

% Randomly choose a direction to go in for next shot.
% prev_dir should be 0, so fully random
direction = randDirection(prev_dir);

% Move the x/y coords in the new direction
% Continue to check that the x,y coords are different
% They are returned the same if the position for them to
% move to does not exist.
% If the position does not exist, pick the opposite
% direction, unless this has been chosen already, then
% choose the other direction. (ie If N does not exist, then
% choose S, then E)
[final_x, final_y] = moveCoordDirection(direction, initial_hit(1), initial_hit(2));
while ((final_x == prev_shot(1) && final_y == prev_shot(2)) || ~isSpaceNew(game_board, final_x, final_y))
% Get another direction
prev_dir = randDirection(prev_dir);
[final_x, final_y] = moveCoordDirection(prev_dir, initial_hit(1), initial_hit(2));
end

%fprintf('\nprev_dir: %c\n', direction);

prev_dir = direction;

% Set the previous shot to the new coords
prev_shot = [final_x, final_y];

% Set prev_hlt_state to hit_last_turn
prev_hlt_state = hit_last_turn;

% Coordinates are set, return
return;

end

else % The previous hit was not a brand new hit (1+ previous hits)
% Can only get here if we choose a correct direction
% Since the direction is correct, continue in the same direction

if (ship_sunk_last_turn == 1) % A ship was sunk last turn, so pick a new spot randomly

% Return a random coordinate using randCoord()
% Ensure that the point has not been chosen before
[final_x, final_y] = randCoord();
while (~isSpaceNew(game_board, final_x, final_y))
[final_x, final_y] = randCoord();
end

% Save coordinates for next function call
prev_shot = [final_x, final_y];

% Set prev_hlt_state to hit_last_turn
prev_hlt_state = hit_last_turn;

% Reset initial_hit
initial_hit = [];

% Coordinates are set, return
return;

else % A ship was not sunk last turn, so continue in the same direction

% Shoot again in the previous direction and ensure the
% point exists. If it does not, choose a different
% direction from the initial_hit
[final_x, final_y] = moveCoordDirection(prev_dir, prev_shot(1), prev_shot(2));
if (final_x == prev_shot(1) && final_y == prev_shot(2) && ~isSpaceNew(game_board, final_x, final_y))
% If the shot does not exist, flip the direction from
% the initial_hit
prev_dir = flipDirection(prev_dir);
[final_x, final_y] = moveCoordDirection(prev_dir, initial_hit(1), initial_hit(2));
end

%fprintf('\nprev_dir: %c\n', prev_dir);

% Set prev_hlt_state to hit_last_turn
prev_hlt_state = hit_last_turn;

% Set the previous shot to the new coords
prev_shot = [final_x, final_y];

% Coordinates are set, return
return;

end
end
end
end

% Helper Functions

% Generates a random pair of coordinates and returns them
function [x, y] = randCoord()
x = randi(10);
y = randi(10);
end

% Generate a random direction and returns it (N,E,S,W)
% prev_direction: Previous direction, used to prevent the same direction
% if prev_direction == 0, all directions can be returned
function [direction] = randDirection(prev_direction)
direction = prev_direction;

while (direction == prev_direction)
num = randi(4);
switch num
case 1
direction = 'N';
case 2
direction = 'E';
case 3
direction = 'S';
case 4
direction = 'W';
end
end
end

% Returns an x, y pair one space in the direction specified
function [next_x, next_y] = moveCoordDirection(direction, x, y)
switch direction
case 'N'
if (spaceExists('N', x, y+1))
next_x = x;
next_y = y + 1;
else
next_x = x;
next_y = y;
end
case 'E'
if (spaceExists('E', x+1, y))
next_x = x + 1;
next_y = y;
else
next_x = x;
next_y = y;
end
case 'S'
if (spaceExists('S', x, y-1))
next_x = x;
next_y = y - 1;
else
next_x = x;
next_y = y;
end
case 'W'
if (spaceExists('W', x-1, y))
next_x = x - 1;
next_y = y;
else
next_x = x;
next_y = y;
end
end
end

% Determines if the given space exists and returns 0 if it doesn't,
% 1 if it does
function [bool] = spaceExists(prev_direction, x, y)
switch prev_direction
case 'N'
if (y > 10)
bool = 0;
return;
end
case 'E'
if (x > 10)
bool = 0;
return;
end
case 'S'
if (y < 1)
bool = 0;
return;
end
case 'W'
if (x < 1)
bool = 0;
return;
end
end

% If the spot exists, return 1
bool = 1;
end

% Checks if the space is a new spot (as in not shot at before)
% Returns 0 if it is not and 1 if it is.
function [bool] = isSpaceNew(game_board, x, y)
if (game_board(x, y) >= 1)
bool = 0;
else
bool = 1;
end
end

% Flips the direction given to the opposite (ie N to S, E to W)
% direction: The direction to be flipped
function [direction] = flipDirection(direction)
switch direction
case 'N'
direction = 'S';
case 'E'
direction = 'W';
case 'S'
direction = 'N';
case 'W'
direction = 'E';
end
end