fprintf('Starting\n');
t1_socket = tcpip('0.0.0.0', 30000, 'NetworkRole', 'server');
t2_socket = tcpip('0.0.0.0', 30002, 'NetworkRole', 'server');
fopen(t1_socket);
fprintf(t1_socket, 'Welcome to Battleship Player 1!\nWaiting for Player 2...\n');
fopen(t2_socket);
fprintf(t2_socket, 'Hello Player 2! Welcome to Battleship!\n');
fprintf(t1_socket, 'Both players connected!');
fprintf(t2_socket, 'Both players connected!');
socks = [t1_socket, t2_socket];
for i = 1:length(socks)
clearSock(socks(i));
end
boards = setupBoards(socks);
[winner_id, boards] = playRound(boards, socks);
while ~winner_id
[winner_id, boardNew] = playRound(boards, socks);
boards = boardNew;
end
for i = 1:length(socks)
clearSock(socks(i));
fprintf(socks(i), 'Player %d Won!\n', winner_id);
fprintf(socks(i), 'Thank you for playing Battleship!\n');
end
fclose(t1_socket);
fclose(t2_socket);
fprintf('Exiting\n');
function [winner_id, boards] = playRound(boards, socks)
fprintf('Starting Round\n');
winner_id = 0;
done = zeros(1, 2);
for p_id = 1:2
clearSock(socks(p_id));
printBoardHidden(socks(p_id),reshape(boards(3 - p_id,:,:),10,10));
fprintf(socks(p_id), 'Hit location: ');
end
hits = [];
while sum(done) < length(done)
[p_id,data] = getSomeInput(socks, ~done);
[err, coord, vert] = parseCoord(data);
if err
fprintf(socks(p_id), 'Bad coordinate, try again: ');
continue
end
done(p_id) = 1;
hits(size(hits, 1) + 1,1:4) = [3 - p_id, coord(1), coord(2), p_id];
clearSock(socks(p_id));
fprintf(socks(p_id), 'Waiting for other players...\n');
end
pause(.1);
for i=1:length(socks)
clearSock(socks(i));
fprintf(socks(i), 'Round Results:\n\n');
end
for i = 1:size(hits,1)
current = boards(hits(i,1), hits(i, 2), hits(i,3));
new = current;
if current == 1
new = 2;
for p_id=1:length(socks)
fprintf(socks(p_id), 'Player %d hit Player %d on [%d, %d] !\n', [hits(i,4), hits(i,1), hits(i,2), hits(i,3)]);
end
else
new = 3;
end
boards(hits(i,1), hits(i, 2), hits(i,3)) = new;
end
for p_id=1:length(socks)
partsLeft = sum(sum(boards(p_id,:,:) == 1));
if partsLeft == 0
winner_id = 3 - p_id;
return
end
end
nhits = size(hits,1);
pause(2 + nhits * 1);
fprintf('Finished Round\n');
end
function boards = setupBoards(socks)
SHIP_SIZES = [5 4 3 3 2];
boards = zeros(2, 10, 10) + 0;
% Delete this later
%boards(:,1:3,1) = 1;
%return
%%%%%%%%%%%%%%%%%%%
for p_id = 1:2
printBoard(socks(p_id),reshape(boards(p_id,:,:),10,10));
fprintf(socks(p_id), 'Location of the first ship (Length %d): ', SHIP_SIZES(1));
end
ship_places = ones(1, 2);
done = zeros(1, 2);
while sum(done) < length(done)
[p_id,data] = getSomeInput(socks, ~done);
[err, coord, vert] = parseCoord(data);
if err
fprintf(socks(p_id), 'Bad coordinate, try again: ');
continue
end
[err,sBoard] = drawShip(coord, vert, SHIP_SIZES(ship_places(p_id)));
if err
fprintf(socks(p_id), 'Collides with wall, try again: ');
continue
end
board = reshape(boards(p_id,:,:),10,10);
if sum(sum(board & sBoard))
fprintf(socks(p_id), 'Collides with another ship, try again: ');
continue
end
board = board + sBoard;
boards(p_id,:,:) = board;
if ship_places(p_id) == length(SHIP_SIZES)
clearSock(socks(p_id));
fprintf(socks(p_id), 'Board set up!\n');
printBoard(socks(p_id),reshape(boards(p_id,:,:),10,10));
fprintf(socks(p_id), '\nWaiting for other players...\n');
done(p_id) = 1;
else
clearSock(socks(p_id));
ship_places(p_id) = 1 + ship_places(p_id);
printBoard(socks(p_id),reshape(boards(p_id,:,:),10,10));
fprintf(socks(p_id), 'Location of next ship (Length %d): ', SHIP_SIZES(ship_places(p_id)));
end
end
end
function clearSock(socket)
% Hex values from `true | clear | xxd`
data = char([hex2dec('1b'), hex2dec('5b'), hex2dec('48'), hex2dec('1b'), hex2dec('5b'), hex2dec('4a')]);
fprintf(socket, '%s', data);
end
function [err,board] = drawShip(coord, vert, len)
err = 1;
board = zeros(10);
if coord(2 - vert) + len > 11
return
end
while len > 0
board(coord(1), coord(2)) = 1;
coord(2 - vert) = coord(2 - vert) + 1;
len = len - 1;
end
err = 0;
end
function [err, coord, vert] = parseCoord(str)
err = 1;
coord = [-1 -1];
vert = 1;
if length(str) ~= 2
return
end
if str(1) >= 'a' & str(1) <= 'j'
vert = 0;
str(1) = char(str(1) - ('a' - 'A'));
end
if str(1) >= 'A' & str(1) <= 'J'
coord(1) = str(1) - 'A' + 1;
else
return
end
if str(2) >= '0' & str(2) <= '9'
coord(2) = str(2) - '0' + 1;
else
return
end
err = 0;
end
function [p_id,data] = getSomeInput(socks, sockmask)
p_id = 0;
data = '';
while 1
for pid = 1:length(socks)
p_id = pid;
if ~sockmask(p_id)
continue
end
if socks(p_id).BytesAvailable > 0
data = fread(socks(p_id), socks(p_id).BytesAvailable);
data = data(1:length(data)-1); % Remove newline
fprintf('Got data from %d: [%s]\n', p_id, data);
return
end
end
end
end
function printBoard(socket, board)
width = size(board,2);
line = char(zeros(1,width + 2) + '-');
asciiBoard = char((board == 1) * 'H' + (board == 0) * ' ' + (board == 2) * 'X' + '.' * (board == 3));
fprintf(socket,'%s\n', line);
for i=1:width
fprintf(socket,'|%s|', convertCharsToStrings(asciiBoard(i,:)),'sync');
fprintf(socket,'%s\n', convertCharsToStrings(char('A' + i - 1)), 'sync');
end
fprintf(socket,'%s\n', convertCharsToStrings(line));
fprintf(socket,' %s\n',convertCharsToStrings(char((1:width) + '0' - 1)));
end
function printBoardHidden(socket, board)
width = size(board,2);
line = char(zeros(1,width + 2) + '-');
asciiBoard = char((board == 1) * ' ' + (board == 0) * ' ' + (board == 2) * 'X' + '.' * (board == 3));
fprintf(socket,'%s\n', line);
for i=1:width
fprintf(socket,'|%s|', convertCharsToStrings(asciiBoard(i,:)),'sync');
fprintf(socket,'%s\n', convertCharsToStrings(char('A' + i - 1)), 'sync');
end
fprintf(socket,'%s\n', convertCharsToStrings(line));
fprintf(socket,' %s\n',convertCharsToStrings(char((1:width) + '0' - 1)));
end