logo for matrixlab-examples.com
leftimage for matrixlab-examples.com

Matlab GUI -  Magic Trick!



We are going to develop a Matlab GUI that performs a magic trick!

We’re going to work on an interface to read your mind! Don’t be scared... it’s safe (as far as I know...). It’s an old trick that has been around for at least 40 years (maybe more), but this is my version with Matlab.

It’s the choose-a-card type trick...

Effect: the user sees 21 shuffled cards (absolutely random), arranged along 3 columns. He/she chooses a card but tells nobody... the card is only in his/her mind. The happy user indicates the column where the chosen card is, and does this two more times. Every time the cards are randomly rearranged. After a complicated artificially-inteligent algorithm, and using the most advanced artificial neural networks (??), our program guesses the chosen card... Is computerized ESP possible?   (Download the code here!)


I strongly suggest you read the first and second articles in this series, where I explain in detail how to create a Matlab GUI, and how to use the three most important instructions for GUIs (set, get and guidata). In this article, I’m going to elaborate on how to use the ‘axes’ and ‘radio’ buttons, as well as the associated callback-functions.

First, type ‘guide’ on your command window. Select the default option (blank gui).

 
You can see on the left several buttons that you can drag-and-drop onto your gui ‘canvas’ or layout area.

buttons that can be included in a Matlab GUI

Add an ‘axes’ button and double-click on it to inspect and modify its properties. Set its position to [x y width heigth] = [10 22 8 2.5]. Try to reproduce this figure:

modifying the properties of an axes button

 

Click once on ‘axes1’ and copy-paste (Ctl-C, Ctl-V) this element six more times (vertically). You can align the objects by clicking on the ‘Align Objects’ icon, on the top menu.

 

align objects icon on the GUI canvas

 

Select all of the 7 ‘axes’ and copy-paste two more times (horizontally). You have now 21 axes on a 7x3 matrix. Add then a ‘Static box’ to the right of your ‘canvas’, and you get something similar to this figure:

building up our GUI for the magic trick!

Add more elements (and modify their properties) until you match the figure below:

 our Matlab GUI is almost finished

You have 22 ‘axes’, 3 ‘Static boxes’, 3 ‘Radio buttons’, and 1 ‘Push button’, right? You can modify their sizes by dragging the ‘anchors’ on the corners.

For the 3 ‘Static boxes’, update their properties like this:

Property   Box 1 Box 2 Box 3
Tag text1 text2 text3
String This is a great trick! (empty) (empty)
FontAngle italic normal normal
FontSize 10 8 8
FontWeight bold bold bold
HorizontalAlignment left left right

For the 3 ‘Radio buttons’, just erase their ‘String’ property and reduce their sizes to fit each column.

For the ‘Push button’, update its properties like this:

Property Button
Tag
String
FontAngle
FontSize
FontWeight
ForegroundColor
pushbutton1
Do it again, please!
italic
8
bold
blue

Save the Matlab GUI (I used the name ‘trick1.fig’), and Matlab will produce a template for your figure (named ‘trick1.m’), with appropriate names and comments or suggestions to get the values of the elements on it.

 

For our trick, we’ll need 5 functions that will be handled from our main module (‘trick1.m’). These functions will be:

  • initialize_trick: to shuffle the cards, show them for the first time and perform a reset
  • showcards: to display 21 out of 52 cards available
  • display_instructions: to display instructions on the ‘Static text’ boxes to let the user know what’s going on and what’s next
  • go_on: to keep the trick going once the user selects the column of his/her card
  • rearrange: to pick-up the cards, rearrange and deal them again on the 7x3 matrix


This is the implementation of the function named ‘initialize_trick.m’. These names are going to be associated with a jpg file.

% Copyright 2009 by www.matrixlab-examples.com
function initialize_trick()
global ha cards 

% Define the 52 cards to be used
card_deck = {'ad' 'ah' 'as' 'ac' '2d' '2h' '2s' '2c' ...
             '3d' '3h' '3s' '3c' '4d' '4h' '4s' '4c' ...
             '5d' '5h' '5s' '5c' '6d' '6h' '6s' '6c' ...
             '7d' '7h' '7s' '7c' '8d' '8h' '8s' '8c' ...
             '9d' '9h' '9s' '9c' '10d' '10h' '10s' '10c' ...
             'jd' 'jh' 'js' 'jc' 'qd' 'qh' 'qs' 'qc' ...
             'kd' 'kh' 'ks' 'kc'};
card_nr = 52; 

% Select 21 random cards from the deck (7 x 3 matrix)
for i = 1 : 7
   
for j = 1 : 3
       
% Select one random card from the remaining deck
        r = ceil(card_nr .* rand);
        cards{i,j} = card_deck{r}; 

        % Delete that card from the deck
        card_deck(r) = [];       

        % Reduce the card account in the remaining deck
        card_nr = card_nr - 1;
   
end
end
 

% Display cards and first instructions
showcards;
display_instructions(1);  

% Make sure to delete the last guess
str = '';
set(ha(24),
'String',str); 

% Hide button
set(ha(25),'Visible','off'); 

% Make the radio-buttons available
set(ha(26),'Visible','on')
set(ha(27),
'Visible','on')
set(ha(28),
'Visible','on')
 


This is the implementation of the function named ‘showcards.m’. Here we actually associate a jpg file (a card) with its corresponding place on the matrix. We show a plain gray image on the ‘axes22’ position. 

% Copyright 2009 by www.matrixlab-examples.com
function showcards()
global ha cards 

% Take one .jpg file for each 'axes' (21 cards to deal).
for i = 1 : 21
    axes(ha(i));
    [bg] = imread(strcat(cards{i},
'.jpg'));
    image(bg);
    axis
off;
end 

% Delete the guess
axes(ha(22));
[bg] = imread(
'gray.jpg');
image(bg);
axis
off;


This is the implementation of the function named ‘display_instructions
.m’. It launches instructions on the ‘text2’ Static-box, according to the evolution of the trick. 

% Copyright 2009 by www.matrixlab-examples.com
function display_instructions(i)
global ha 

% Display instructions according to evolution of trick
switch i
   
case 1
        str = {
'Step 1: ';
              
'';
              
'Think of a card and select its column below...'};
        set(ha(23),
'String',str);
   
case 2
        str = {
'Step 2: ';
              
'';
              
'Hard to guess...';
              
'';
              
'Could you please select its column again?'};
        set(ha(23),
'String',str);
   
case 3
        str = {
'I cannot see it clearly... ';
              
'';
  
'Please concentrate and select its column only once more...'};
        set(ha(23),
'String',str);
   
case 4
        str =
'';
        set(ha(23),
'String',str);
        str = {
'Ah! Got it! ';
              
'Your card is: '};
        set(ha(24),
'String',str);
end


This is the implementation of the function named ‘go_on.m’. It’s executed each time the user clicks on a radio button to choose a column. After three clicks, the selection is revealed! 

% Copyright 2009 by www.matrixlab-examples.com
function go_on(hObject,handles,c)
global ha cards 

% Take into account the number of choices by the user
handles.t = handles.t + 1;
% Reset the current radio-button
set(hObject,'Value',0); 

% Display the cards in a new order.
rearrange(c);
if handles.t < 4  
    
showcards();
     display_instructions(handles.t);

else
    % Perform the trick!
    display_instructions(4);
    axes(ha(22));
    [bg] = imread(strcat(cards{4,2},
'.jpg'));
    image(bg);
    axis
off;   

    % Make the pushbutton appear
    set(ha(25),'Visible','on')   

    % Make the radio-buttons disappear
    set(ha(26),'Visible','off')
    set(ha(27),
'Visible','off')
    set(ha(28),
'Visible','off')
end 

guidata(hObject,handles);


This is the implementation of the function named ‘rearrange.m’. It takes the three columns of cards, each time the column with the selected card is put in second place. The other two columns are irrelevant for this trick. 

% Copyright 2009 by www.matrixlab-examples.com
function rearrange(c)
global cards 

% Take the cards and the column of the selected card
% is kept as second column

switch c
   
case 1
        cards_aux = {cards{:,3} cards{:,1} cards{:,2}};
   
case 2
        cards_aux = {cards{:,3} cards{:,2} cards{:,1}};
   
otherwise
        cards_aux = {cards{:,2} cards{:,3} cards{:,1}};
end 

% Deal the cards with the new order
k = 1;
for i = 1 : 7
   
for j = 1 : 3
        cards{i,j} = cards_aux{k};
        k = k + 1;
   
end
end



This is the main wrapper (‘trick1.m’). I deleted some of the comments automatically written by the Matlab GUI -DE (Development Environment), to simplify the explanation. 

% Copyright 2009 by www.matrixlab-examples.com
function varargout = trick1(varargin)
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct(
'gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @trick1_OpeningFcn, ...
                   'gui_OutputFcn',  @trick1_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});

end 

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});

else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT

% --- Executes just before trick1 is made visible.
function trick1_OpeningFcn(hObject, eventdata, handles,varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to trick1 (see VARARGIN) 

% Choose default command line output for trick1
handles.output = hObject;
global ha
clc
ha(1) = handles.axes1; ha(8) = handles.axes8;   ha(15) = handles.axes15;
ha(2) = handles.axes2; ha(9) = handles.axes9;   ha(16) = handles.axes16;
ha(3) = handles.axes3; ha(10) = handles.axes10; ha(17) = handles.axes17;
ha(4) = handles.axes4; ha(11) = handles.axes11; ha(18) = handles.axes18;
ha(5) = handles.axes5; ha(12) = handles.axes12; ha(19) = handles.axes19;
ha(6) = handles.axes6; ha(13) = handles.axes13; ha(20) = handles.axes20;
ha(7) = handles.axes7; ha(14) = handles.axes14; ha(21) = handles.axes21;

ha(22) = handles.axes22; 

ha(23) = handles.text2;
ha(24) = handles.text3; 

ha(25) = handles.pushbutton1; 

ha(26) = handles.radiobutton1;
ha(27) = handles.radiobutton2;
ha(28) = handles.radiobutton3; 

initialize_trick;
handles.t = 1; 

% Update handles structure
guidata(hObject, handles); 

% UIWAIT makes trick1 wait for user response (see UIRESUME)
% uiwait(handles.figure1);

% --Outputs from this function are returned to the command line.
function varargout = trick1_OutputFcn(hObject, eventdata, handles)

% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA) 

% Get default command line output from handles structure
varargout{1} = handles.output;
 

% --- Executes on button press in radiobutton1.
function radiobutton1_Callback(hObject, eventdata, handles)
% hObject    handle to radiobutton1 (see GCBO)
% handles    structure with handles and user data (see GUIDATA)
% Hint: get(hObject,'Value') returns toggle state of radiobutton1
global ha
go_on(hObject,handles,1); 

% --- Executes on button press in radiobutton2.
function radiobutton2_Callback(hObject, eventdata, handles)
global ha
go_on(hObject,handles,2);
 

% --- Executes on button press in radiobutton3.
function radiobutton3_Callback(hObject, eventdata, handles)
global ha
go_on(hObject,handles,3); 

% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% handles    structure with handles and user data (see GUIDATA)

global ha
initialize_trick;
handles.t = 1; 

% Update handles structure
guidata(hObject, handles);
 



To run the program and see the Matlab GUI, save all these files with their respective names, put them into a single directory, go to that directory with Matlab and just type ‘trick1’ on your command window.

Here's a sample run. 

wr're requested to choose a card...

Let's say that we choose the ace of spades, so we click on the right radio button.

We choose another card, 2nd click...

The cards are reshuffled and we now click on the central radio button...

we choose the right column again, 3rd click

We concentrate once more, to send clearer thoughts through our mental interface... click on the right column again and...

Our great trick has worked! We developed a mental interface!

Nice trick, isn't it? 

Enjoy!                                    (Download here all the necessary files)


 From 'Matlab GUI' to home

 From 'Matlab GUI' to GUI menu

Top



footer for matlab gui page