Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
1
Task/Minesweeper-game/MATLAB/minesweeper-game-1.m
Normal file
1
Task/Minesweeper-game/MATLAB/minesweeper-game-1.m
Normal file
|
|
@ -0,0 +1 @@
|
|||
xpbombs
|
||||
243
Task/Minesweeper-game/MATLAB/minesweeper-game-2.m
Normal file
243
Task/Minesweeper-game/MATLAB/minesweeper-game-2.m
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
function Minesweeper
|
||||
|
||||
% Game parameters (should be modified by user)
|
||||
nRows = 6;
|
||||
nCols = 4;
|
||||
percentMines = 0.15;
|
||||
|
||||
% Create minefield
|
||||
nMines = ceil(percentMines*nRows*nCols);
|
||||
field = makeGrid(nRows, nCols, nMines);
|
||||
|
||||
% Create timer for updating in axes title
|
||||
stopwatch = timer('TimerFcn', {@updateTime, field}, ...
|
||||
'ExecutionMode', 'fixedRate', 'Period', 1, 'StartDelay', 1, ...
|
||||
'TasksToExecute', 999);
|
||||
|
||||
% Specify callbacks
|
||||
set(gcf, 'CloseRequestFcn', {@cleanUp, stopwatch})
|
||||
set(gca, 'ButtonDownFcn', {@onClick, field, stopwatch})
|
||||
|
||||
|
||||
end
|
||||
|
||||
function field = makeGrid(nRows, nCols, nMines)
|
||||
% Create minefield with unit squares
|
||||
% Use quadrant IV to make indexing semi-consistent
|
||||
% i.e. square in ith row, jth column has lower-right corner at (j, -i)
|
||||
figure
|
||||
set(gcf, 'Color', [1 1 1])
|
||||
axis([0 nCols -nRows 0])
|
||||
axis square
|
||||
axis manual
|
||||
hold on
|
||||
set(gca, 'GridLineStyle', '-')
|
||||
grid on
|
||||
set(gca, 'XTick', 0:nCols)
|
||||
set(gca, 'YTick', -nRows:0)
|
||||
set(gca, 'XTickLabel', [])
|
||||
set(gca, 'YTickLabel', [])
|
||||
set(gca, 'Color', [0.6 0.6 0.6])
|
||||
setTitle(nMines, ': )', 0)
|
||||
xlabel('left-click to dig, right-click to mark')
|
||||
|
||||
% Set up field structure
|
||||
% text will contain the handles to the labels in each square
|
||||
% One character per square (or other functions will break)
|
||||
% . Nothing noted
|
||||
% M Marked as mine
|
||||
% ? Marked as unknown
|
||||
% 1-8 Digits indicate how many mines this square touches
|
||||
% * Mine (game over)
|
||||
% (blank) Square has been (dug) and is not mined nor touching any mines
|
||||
% squares will contain handles to the colored "fill" objects
|
||||
% fill objects will be deleted once square is "dug"
|
||||
% Use ishandle() to determine if square is not yet dug
|
||||
% mines will contain a logical array indicating positions of mines
|
||||
% true Mine
|
||||
% false No mine
|
||||
% Later versions of MATLAB use gobjects() to preallocate text and squares
|
||||
field = struct('text', zeros(nRows, nCols), ...
|
||||
'squares', zeros(nRows, nCols), ...
|
||||
'mines', false(nRows, nCols));
|
||||
|
||||
% Create individual square color and label objects
|
||||
for r = 1:nRows
|
||||
for c = 1:nCols
|
||||
field.squares(r, c) = ...
|
||||
fill([c-1 c-1 c c c-1], [-r+1 -r -r -r+1 -r+1], [0.9 0.9 0.9]);
|
||||
set(field.squares(r, c), 'HitTest', 'off')
|
||||
field.text(r, c) = text(c-0.5, -r+0.5, '.');
|
||||
set(field.text(r, c), 'FontSize', 12, 'FontWeight', 'bold', ...
|
||||
'HorizontalAlignment', 'center', 'HitTest', 'off');
|
||||
end
|
||||
end
|
||||
|
||||
% Place mines randomly without repeats
|
||||
k = 0;
|
||||
while k < nMines
|
||||
idx = randi(nRows*nCols);
|
||||
if ~field.mines(idx)
|
||||
field.mines(idx) = true;
|
||||
k = k+1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function onClick(obj, event, field, stopwatch)
|
||||
if strcmp(stopwatch.Running, 'off')
|
||||
start(stopwatch)
|
||||
end
|
||||
|
||||
pt = get(obj, 'CurrentPoint');
|
||||
r = ceil(-pt(1, 2));
|
||||
c = ceil(pt(1, 1));
|
||||
|
||||
if r > 0 && c > 0 && r <= size(field.squares, 1) && ... % Not yet been "dug"
|
||||
c <= size(field.squares, 2) && ishandle(field.squares(r, c))
|
||||
buttons = {'normal' 'alt' 'extend'};
|
||||
btn = find(strcmp(get(get(obj, 'Parent'), 'SelectionType'), buttons));
|
||||
labels = '.M?'; % Unmarked, mine flag, unknown flag
|
||||
currLabel = get(field.text(r, c), 'String');
|
||||
|
||||
if btn == 1 % Left click
|
||||
if currLabel ~= labels(2); % Don't dig if flagged as mine
|
||||
if field.mines(r, c) % Mine there -> you lose
|
||||
gameLost(field, stopwatch, r, c)
|
||||
else % No mine -> free to dig
|
||||
minesLeft = countMineFlags(field);
|
||||
digSquare(field, r, c)
|
||||
if all(all(ishandle(field.squares) == field.mines))
|
||||
gameWon(field, stopwatch)
|
||||
else
|
||||
faceTimer = timer('StartDelay', 0.5, ...
|
||||
'StartFcn', {@setTitleOnTimer, minesLeft, ...
|
||||
': o', stopwatch.TasksExecuted}, ...
|
||||
'TimerFcn', {@setTitleOnTimer, minesLeft, ...
|
||||
': )', stopwatch.TasksExecuted}, ...
|
||||
'StopFcn', @deleteTimer);
|
||||
start(faceTimer)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
elseif btn == 2 % Right-click
|
||||
% Rotate through labels list to the next one
|
||||
switch find(currLabel == labels)
|
||||
case 1
|
||||
newLabel = labels(2);
|
||||
case 2
|
||||
newLabel = labels(3);
|
||||
case 3
|
||||
newLabel = labels(1);
|
||||
end
|
||||
set(field.text(r, c), 'String', newLabel);
|
||||
setTitle(countMineFlags(field), ': )', stopwatch.TasksExecuted)
|
||||
|
||||
elseif btn == 3 % Middle-click
|
||||
% Mark/unmark unknown flag
|
||||
if currLabel == labels(1)
|
||||
set(field.text(r, c), 'String', labels(3));
|
||||
elseif currLabel == labels(3)
|
||||
set(field.text(r, c), 'String', labels(1));
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function updateTime(obj, event, field)
|
||||
setTitle(countMineFlags(field), ': )', obj.TasksExecuted)
|
||||
end
|
||||
|
||||
function deleteTimer(obj, event)
|
||||
delete(obj)
|
||||
end
|
||||
|
||||
function setTitleOnTimer(obj, event, mines, face, time)
|
||||
setTitle(mines, face, time)
|
||||
end
|
||||
|
||||
function setTitle(mines, face, time)
|
||||
title(sprintf('%03d Mines %s Timer %03d', mines, face, time))
|
||||
end
|
||||
|
||||
function minesLeft = countMineFlags(field)
|
||||
% Determine how many mines are unmarked (negative means too many mines marked)
|
||||
minesLeft = sum(field.mines(:));
|
||||
for k = 1:numel(field.text)
|
||||
if get(field.text(k), 'String') % Not an empty string
|
||||
minesLeft = minesLeft-(get(field.text(k), 'String') == 'M');
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function digSquare(field, r, c)
|
||||
% If square is touching one or more mines then indicate the number
|
||||
% Otherwise indicate no mines and dig surrounding squares recursively
|
||||
% Assumes current square is clear of mines
|
||||
delete(field.squares(r, c))
|
||||
[nRows, nCols] = size(field.mines);
|
||||
surrR = [r-1 r r+1 r-1 r+1 r-1 r r+1];
|
||||
surrC = [c-1 c-1 c-1 c c c+1 c+1 c+1];
|
||||
toDelete = surrR < 1 | surrR > nRows | surrC < 1 | surrC > nCols;
|
||||
surrR(toDelete) = [];
|
||||
surrC(toDelete) = [];
|
||||
nearMines = sum(field.mines(sub2ind([nRows nCols], surrR, surrC)));
|
||||
label = sprintf('%d', nearMines);
|
||||
textColor = [0 0 0 ; 0 0 1 ; 0 1 0 ; 1 0 0 ; 0.5 0.1 0.9 ; ...
|
||||
0.6 0 0 ; 0.2 0.5 0.3 ; 0.2 0.2 0.1 ; 0 0 0];
|
||||
if ~nearMines
|
||||
label = '';
|
||||
for k = 1:length(surrR)
|
||||
if ~field.mines(surrR(k), surrC(k)) && ...
|
||||
ishandle(field.squares(surrR(k), surrC(k))) && ...
|
||||
~strcmp(get(field.text(k), 'String'), 'M')
|
||||
digSquare(field, surrR(k), surrC(k))
|
||||
end
|
||||
end
|
||||
end
|
||||
set(field.text(r, c), 'String', label, 'Color', textColor(nearMines+1, :))
|
||||
end
|
||||
|
||||
function gameLost(field, stopwatch, r, c)
|
||||
stop(stopwatch)
|
||||
setTitle(countMineFlags(field), 'X (', stopwatch.TasksExecuted)
|
||||
set(field.squares(r, c), 'FaceColor', [1 0 0])
|
||||
for k = 1:numel(field.text)
|
||||
if field.mines(k) && any(get(field.text(k), 'String') == '.?')
|
||||
set(field.text(k), 'String', '*', 'FontSize', 20)
|
||||
elseif ~field.mines(k) && ishandle(field.squares(k)) && ...
|
||||
get(field.text(k), 'String') == 'M'
|
||||
set(field.text(k), 'String', 'X', 'Color', [1 0 0])
|
||||
end
|
||||
end
|
||||
set(gca, 'HitTest', 'off')
|
||||
queryPlayAgain('Game over')
|
||||
end
|
||||
|
||||
function gameWon(field, stopwatch)
|
||||
% Flag any leftover mines and indicate win
|
||||
stop(stopwatch)
|
||||
set(field.text(ishandle(field.squares)), 'String', 'M')
|
||||
setTitle(0, 'B )', stopwatch.TasksExecuted)
|
||||
set(gca, 'HitTest', 'off')
|
||||
queryPlayAgain('Minefield cleared!')
|
||||
end
|
||||
|
||||
function queryPlayAgain(msg)
|
||||
% Ask player if they want to play again
|
||||
% Reset game by closing and reopening figure
|
||||
choice = questdlg(sprintf('%s\nWould you like to play again?', msg), ...
|
||||
'', 'Yes', 'No', 'No');
|
||||
if strcmp(choice, 'Yes')
|
||||
close
|
||||
Minesweeper
|
||||
end
|
||||
end
|
||||
|
||||
function cleanUp(obj, event, stopwatch)
|
||||
% Stop and close down all necessary processes
|
||||
stop(stopwatch)
|
||||
delete(stopwatch)
|
||||
delete(obj)
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue