Top Banner
MATLAB Minesweep er Development of a MATLAB GUI
22

MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

Dec 15, 2015

Download

Documents

Derrick Hallum
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

MATLAB Minesweeper

Development of a MATLAB GUI

Page 2: MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

Start with an empty function

function MineSweeper_GUI()

end % of MineSweeper()

While not strictly required, a function that creates the GUI provides flexibility for your program. If you have multiple frames in your interface, functions permit separation of code by allowing a main program to instantiate the frames independently.

Page 3: MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

Create a basic figurefunction MineSweeper_GUI()

fh = figure('Position', [400, 400, 250, 300]);

% Adjust appearanceset(fh, 'Resize', 'off');set(fh, 'MenuBar', 'none');set(fh, 'NumberTitle', 'off');set(fh, 'Name', 'MATLAB MineSweeper');

end % of MineSweeper_GUI()

These are common attributes, although not every GUI will necessarily set them.

Page 4: MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

Provide the controls% Text will be provided and covered up by a button. The button % will disappear when clicked.

% Control to hold text (to display after button is pushed)tbh = uicontrol('Units', 'normalized', 'Style', 'text');set(tbh, 'String', '8', 'FontSize', 16);set(tbh, 'Position', [0, 0, 0.1, 0.1]);

Now that we have one box, let’s make the code repeat it.

Page 5: MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

Provide the rest of textboxes

c = 1;for xpos = 1:9

for ypos = 1:9 % Control to hold text (to display after button is pushed) tb(c) = uicontrol('Style', 'text', 'Units', 'normalized'); set(tb(c), 'String', '8', 'FontSize', 16); set(tb(c), 'Position', [0.11*(xpos-1),0.11*(ypos-1),0.1,0.1]); c = c+1;

end % of for yposend % of for xpos

(We assume a 9x9 grid – this can become a feature selected by the user) These all show the number ‘8’. We will change that after we have a visually complete GUI – then we can make it fully functional.

Page 6: MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

Provide pushbuttons to cover% Cover with buttonsc = 1;for xpos = 1:9 for ypos = 1:9 % These are drawn on the figure, not any panel u(c)=uicontrol('Style', 'pushbutton', 'Units', 'normalized'); set(u(c), 'Position', [0.11*(xpos-1),0.11*(ypos-1), 0.1, 0.1]); c = c + 1; endend

We now have a visually-complete game. Now we can focus on the functionality.

Page 7: MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

Add button functionality

When actions are to be performed as a result of clicking on a control, MATLAB places a call to a “callback function”. It is the responsibility of the programmer to provide that function, and to tell MATLAB how to call that function.

The syntax for this is a little different from typical function usage.

Page 8: MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

Defining a callback function

To define a callback function, simply make a function in the same file as the GUI frame. The name can be any legal function name. The first two parameters of the function are required by MATLAB – you can add any others you wish afterwards:

function my_callback(H, E, a, b, c)...

end % of my_callback()

Page 9: MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

Our callback function% Callback (cb) for PushButtons (pb)function cb_pb(H, E, bh, th, c, sz)

% What string is "under" the button that was pressed?s = get(th(c), 'String'); if strcmp(s, '9') hit_mine(c, sz, bh, th); elseif length(s)==0 || strcmp(s, ' ') hit_empty(c, sz, bh, th); else delete(bh(c)); uicontrol(th(c)); % set focus to current text end % of ifend % of cb_pb

Page 10: MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

Tell MATLAB to use the callback function

% Because clicking a button can mean deleting other buttons in this% program, we want to send the entire array of button handles and text% handles to the callback functions. That is why this loop is AFTER % the original creation loop - if we had tried to set the callbacks in % the creation loop, the early buttons would know nothing about buttons % defined later.

for c = 1:n^2 % Handle a left-click set(u(c), 'callback', {@cb_pb, u, th, cnt, n});end % of for c

Page 11: MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

function MineSweeper_demo()clc;n=9;

fh = figure('Position', [400, 400, 250, 300]); % Adjust appearanceset(fh, 'Resize', 'off');set(fh, 'MenuBar', 'none');set(fh, 'NumberTitle', 'off');set(fh, 'Name', 'MATLAB MineSweeper'); c = 1;for xpos = 1:9 for ypos = 1:9 % Control to hold text (to display after button is pushed) tb(c) = uicontrol('Style', 'text', 'Units', 'normalized'); set(tb(c), 'String', '8', 'FontSize', 16); set(tb(c), 'Position', [0.11*(xpos-1),0.11*(ypos-1),0.1,0.1]); c = c+1; end % of for yposend % of for xpos % Cover with buttonsc = 1;for xpos = 1:9 for ypos = 1:9 % These are drawn on the figure, not any panel u(c)=uicontrol('Style', 'pushbutton', 'Units', 'normalized'); set(u(c), 'Position', [0.11*(xpos-1),0.11*(ypos-1), 0.1, 0.1]); c = c + 1; endend

% Attach callback function for c = 1:n^2 % Handle a left-click set(u(c), 'callback', {@cb_pb, u, tb, c, n});end % of for c end % of MineSweeper_demo()

% Callback functionfunction cb_pb(H, E, bh, th, c, sz) % What string is "under" the button?s = get(th(c), 'String'); if strcmp(s, '9') hit_mine(c, sz, bh, th); elseif length(s)==0 || strcmp(s, ' ') hit_empty(c, sz, bh, th); else delete(bh(c)); uicontrol(th(c)); % set focus to current text end end % of cb_pb()

Page 12: MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

Finishing off the code

At this point, most of the GUI code is complete. We now provide code that will perform the tasks desired upon certain events.

If a mine is beneath a clicked button:hit_mine(c, sz, bh, th);

If a space is beneath a clicked button:hit_empty(c, sz, bh, th);

Page 13: MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

hit_mine()% What to do if a mine is hitfunction hit_mine(i, sz, bh, th) % Get rid of ALL buttons and show the minesfor r=1:sz for c=1:sz

% Since using vectors to hold handles v = (c-1)*sz + r; % Is there still a button here? if ishandle(bh(v)) % What is the textbox string? ts = get(th(v), 'String'); % Change textbox to show an image of a mine exploding if strcmp(ts, '9') mineimg = imread('mine10.jpg'); set(bh(v), 'cdata', mineimg); else % Get rid of the button delete(bh(v)); end end end % of for c end % of for r

Page 14: MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

Add a grid for testing hit_mine()

function MineSweeper_demo()

% -----------------------------% Testing valuesn = 9;for i=1:n^2 M(i) = num2str(randi(9,1)); r = randi(2)-1; if r M(i) = ' '; endend% ------------------------------

And we will change this line:set(tb(c), 'String', '8', 'FontSize', 16);

To display the testing values:set(tb(c), 'String', num2str(M(c)), 'FontSize', 16);

Page 15: MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

After adding the test values

Page 16: MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

With the mine images

Page 17: MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

hit_empty()

function hit_empty(pos, sz, bh, th) % Find all of the surrounding empties and remove the buttonsrecursive_remove(pos, pos, sz, bh, th, 1); end % of hit_empty()

(see next slide)

Page 18: MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

recursive_remove()% Remove all buttons over empty strings and over numbers that touch one of% those empty strings (but don't remove over mines)function recursive_remove(from, to, sz, bh, th, level)

if ~(to<=0 || to>sz^2 ||(mod(from, sz)==1 && mod(to, sz)==0) ||(mod(from, sz)==0 && mod(to, sz)==1) to_s = get(th(to), 'String'); from_s = get(th(from), 'String'); % Empty or contains a number (but not a mine) if strcmp(to_s, ' ') || (~strcmp(to_s, ' ') && str2num(to_s)>0 && str2num(to_s)<9) % Does the button still exist? if ishandle(bh(to)) % Remove the button

delete(bh(to)); % If it's empty, recurse to check the surrounding buttons if strcmp(to_s, ' ') level = level + 1;

recursive_remove(to, to-sz-1, sz, bh, th, level); recursive_remove(to, to-sz, sz, bh, th, level);

recursive_remove(to, to-sz+1, sz, bh, th, level); recursive_remove(to, to-1, sz, bh, th, level); recursive_remove(to, to+1, sz, bh, th, level); recursive_remove(to, to+sz-1, sz, bh, th, level); recursive_remove(to, to+sz, sz, bh, th, level); recursive_remove(to, to+sz+1, sz, bh, th, level);

level = level - 1; end end % of if end % of else end % of recursive_remove()

Page 19: MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

Last Details

One other property of the game (other than scoring) involves allowing the user to mark a location as “containing a mine” or “might contain a mine”.

We will do this by allowing the user to right-click on a button and placing “?” for “might be a mine”, or “!” for “containing a mine”.

Page 20: MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

Right-click Callbacks

A separate callback function must be placed for handling “alternative clicks”. Note the added line:

for c = 1:n^2

% Handle a left-click set(u(c), 'callback', {@cb_pb, u, tb, c, n}); % Handle a right-click set(u(cnt), 'ButtonDownFcn', {@right_click, c, u}); end % of for c

Page 21: MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

right_click()% This function is executed when a button is right-clickedfunction right_click(h, e, pos, bh) % The button we pressed is in a figure. Only the figure knows the type of% click that was made:fh = ancestor(h, 'figure')clickType = get(fh, 'SelectionType') % 'Alt' is a right-click%% This will allow using the right-click to cycle through the optionsbs = get(h, 'String');if strcmp(clickType, 'alt') if strcmp(bs, '!') % Option 1: Clear the button label set(bh(pos), 'String', ''); end if strcmp(bs, '') % Option 2: Put a query (?) on the button - user isn't sure set(bh(pos), 'String', '?'); set(bh(pos), 'FontSize', 16, 'ForegroundColor', [1, 0, 0]); end if strcmp(bs, '?') % Option 3 : Put a bang (!) on the button - user thinks this is a mine set(bh(pos), 'String', '!'); set(bh(pos), 'FontSize', 16, 'ForegroundColor', [1, 0, 0]); end end % of if end % of right_click()

Page 22: MATLAB Minesweeper Development of a MATLAB GUI. Start with an empty function function MineSweeper_GUI() end % of MineSweeper() While not strictly required,

Source Code

Function:

http://kindy.egr115.com/MineSweeper.zip