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