{"id":3713,"date":"2020-05-28T08:27:37","date_gmt":"2020-05-28T12:27:37","guid":{"rendered":"https:\/\/blogs.mathworks.com\/loren\/?p=3713"},"modified":"2020-09-11T10:25:40","modified_gmt":"2020-09-11T14:25:40","slug":"matlab-and-mind-reading-card-games","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/loren\/2020\/05\/28\/matlab-and-mind-reading-card-games\/","title":{"rendered":"MATLAB and Mind Reading Card Games"},"content":{"rendered":"<div class=\"content\"><!--introduction--><p><a href=\"https:\/\/www.mathworks.com\/videos\/release-highlights-2020a-1584390596825.html\">R2020a<\/a> is upon us! Do you read <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/release-notes.html\">the release notes<\/a>? Today's guest blogger, <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/profile\/authors\/951521\">Toshi Takeuchi<\/a>, apparently does, and he would like to share some new tricks using one of the new features. He also discusses sharing your code as a MATLAB app, since it is not easy to collaborate with people directly these days.<\/p><!--\/introduction--><h3>Contents<\/h3><div><ul><li><a href=\"#70378bae-e59d-4c57-90d3-5bdf328be754\">UTF-8 Support in MATLAB<\/a><\/li><li><a href=\"#2e3d7532-3ec3-414e-af1d-5c979f5c7da0\">Mind Reading Card Magic<\/a><\/li><li><a href=\"#db45c1a2-0da1-4455-8bd5-affb2cadac01\">How Does It Work?<\/a><\/li><li><a href=\"#6d555fdc-8772-4004-bc59-dd1e9e30300e\">Building and Sharing a MATLAB App<\/a><\/li><li><a href=\"#9b3e6aed-1b62-49ba-9c8a-90d3fd72c549\">Summary<\/a><\/li><li><a href=\"#81f0e2e9-9b11-4f23-b2f7-fb1ce83e01a6\">Local Functions<\/a><\/li><\/ul><\/div><h4>UTF-8 Support in MATLAB<a name=\"70378bae-e59d-4c57-90d3-5bdf328be754\"><\/a><\/h4><p>As of R2020a, MATLAB defaults to saving new plain text files using UTF-8. What's the big deal, you say? Das ist eine gro&szlig;e Sache, &#12381;&#12428;&#12399;&#22823;&#12372;&#12392;&#12384;, because you can now use international characters mixed within English easily. Even if you only speak English, you sure do use Greek letters like &#960;, &#963;, or &#946;, right? This also means you can use emojis, too, but I can't show it here because publish to html feature doesn't translate emojis into html entities like <tt>&amp;#128513;<\/tt><\/p><p>Personally, however, I am more excited with the playing card symbols. Let's make a deck of 52 cards.<\/p><pre class=\"codeinput\">deck = [<span class=\"string\">\"&#9824;\"<\/span>,<span class=\"string\">\"&#9829;\"<\/span>,<span class=\"string\">\"&#9830;\"<\/span>,<span class=\"string\">\"&#9827;\"<\/span>] + [<span class=\"string\">\"A\"<\/span>; (2:10)';<span class=\"string\">'J'<\/span>;<span class=\"string\">'Q'<\/span>;<span class=\"string\">'K'<\/span>]\r\n<\/pre><pre class=\"codeoutput\">deck = \r\n  13&times;4 string array\r\n    \"&#9824;A\"     \"&#9829;A\"     \"&#9830;A\"     \"&#9827;A\" \r\n    \"&#9824;2\"     \"&#9829;2\"     \"&#9830;2\"     \"&#9827;2\" \r\n    \"&#9824;3\"     \"&#9829;3\"     \"&#9830;3\"     \"&#9827;3\" \r\n    \"&#9824;4\"     \"&#9829;4\"     \"&#9830;4\"     \"&#9827;4\" \r\n    \"&#9824;5\"     \"&#9829;5\"     \"&#9830;5\"     \"&#9827;5\" \r\n    \"&#9824;6\"     \"&#9829;6\"     \"&#9830;6\"     \"&#9827;6\" \r\n    \"&#9824;7\"     \"&#9829;7\"     \"&#9830;7\"     \"&#9827;7\" \r\n    \"&#9824;8\"     \"&#9829;8\"     \"&#9830;8\"     \"&#9827;8\" \r\n    \"&#9824;9\"     \"&#9829;9\"     \"&#9830;9\"     \"&#9827;9\" \r\n    \"&#9824;10\"    \"&#9829;10\"    \"&#9830;10\"    \"&#9827;10\"\r\n    \"&#9824;J\"     \"&#9829;J\"     \"&#9830;J\"     \"&#9827;J\" \r\n    \"&#9824;Q\"     \"&#9829;Q\"     \"&#9830;Q\"     \"&#9827;Q\" \r\n    \"&#9824;K\"     \"&#9829;K\"     \"&#9830;K\"     \"&#9827;K\" \r\n<\/pre><p>That means we can also use those special characters in the plot as well.<\/p><pre class=\"codeinput\">figure\r\nrectangle(<span class=\"string\">\"Position\"<\/span>,[1 0.5 1 2],<span class=\"string\">'Curvature'<\/span>,0.2)\r\ntext(1.5,1.5,deck(1),<span class=\"string\">\"FontSize\"<\/span>,36,<span class=\"string\">\"HorizontalAlignment\"<\/span>,<span class=\"string\">\"center\"<\/span>)\r\naxis([0 3 0 3])\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2020\/mindReadingMagic_01.png\" alt=\"\"> <h4>Mind Reading Card Magic<a name=\"2e3d7532-3ec3-414e-af1d-5c979f5c7da0\"><\/a><\/h4><p>Let's play the famous 21-card mind reading trick with those cards.<\/p><p>You are entertaining your friends with a card trick. First, shuffle the deck and select first 21 cards from the deck.<\/p><pre class=\"codeinput\">rng(<span class=\"string\">\"default\"<\/span>) <span class=\"comment\">% for repeatability<\/span>\r\npicked = initialize21Cards(deck);\r\n<\/pre><p>Ask a volunteer to choose a card from the stack of 21 cards and remember it, but not tell you what it is.<\/p><pre class=\"codeinput\"><span class=\"comment\">% select a card<\/span>\r\nchosenCard = picked(randi(21))\r\n<\/pre><pre class=\"codeoutput\">chosenCard = \r\n    \"&#9827;8\"\r\n<\/pre><p>Have your volunteer shuffle the deck of 21 cards and return it to you.<\/p><pre class=\"codeinput\">stacked = picked(randperm(21));\r\n<\/pre><p>There are several variations to the steps depending on the effect you want to achieve. Here you will lay out the cards on the table. When you do so, you lay them out into 3 columns of 7 cards. There is a reason to do it this way when you are handling physical cards, but let's use a 3x7 layout to make it easier to plot the cards. We substitute columns with rows.<\/p><pre class=\"codeinput\">plotCardsFaceUp(reshape(stacked,[3 7]),0)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2020\/mindReadingMagic_02.png\" alt=\"\"> <p>Repeat the process 4 times:<\/p><div><ol><li>Deal the cards face up into three rows moving from bottom to top. You should have seven cards in each row.<\/li><li>Ask your volunteer to point to the row the chosen card is in: the bottom row, the middle row or the top row.<\/li><li>Slide each row of cards together to form three piles, preserving the order.<\/li><li>Collect the three piles into one stack in a specific order&#8212;make sure that the pile your volunteer pointed to is always collected second.<\/li><\/ol><\/div><pre class=\"codeinput\"><span class=\"keyword\">for<\/span> ii = 1:4\r\n    placed = reshape(stacked,[3 7]); <span class=\"comment\">% deal the cards face up<\/span>\r\n    selectedRow = find(any(placed == chosenCard,2)); <span class=\"comment\">% row with the card<\/span>\r\n    stacked = restack(placed,selectedRow); <span class=\"comment\">% gather cards into a stack<\/span>\r\n<span class=\"keyword\">end<\/span>\r\n<\/pre><p>Reveal the 11th card in the stack, which should be the chosen card. Hopefully your friends are impressed.<\/p><pre class=\"codeinput\">answer = stacked(11);\r\ncorrectCard = isequal(answer,chosenCard)\r\n<\/pre><pre class=\"codeoutput\">correctCard =\r\n  logical\r\n   1\r\n<\/pre><h4>How Does It Work?<a name=\"db45c1a2-0da1-4455-8bd5-affb2cadac01\"><\/a><\/h4><p><b>Spoiler Alert! The trick is revealed!<\/b><\/p><p>Now let's see why this works. We will keep it simple by using the first 7 cards from the suits of &#9824;, &#9829; and &#9830;. We will choose &#9830;7 for this example.<\/p><pre class=\"codeinput\">picked = [<span class=\"string\">\"&#9824;\"<\/span>,<span class=\"string\">\"&#9829;\"<\/span>,<span class=\"string\">\"&#9830;\"<\/span>]' + [<span class=\"string\">\"A\"<\/span>,(2:7)];\r\nchosenCard = <span class=\"string\">\"&#9830;7\"<\/span>;\r\n<\/pre><p><b>Round # 1<\/b><\/p><p>When you first lay out the cards, you have no idea where the chosen card is. It could be anywhere. Then your volunteer tells you it is in the top rows. You now know that the chosen card is one of those 7 cards. Let's highlight them.<\/p><pre class=\"codeinput\">plotCardsFaceUp(picked,1,<span class=\"string\">\"&#9830;\"<\/span> + [<span class=\"string\">\"A\"<\/span> (2:7)])\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2020\/mindReadingMagic_03.png\" alt=\"\"> <p>Now we collect the cards into a stack in a specific order.<\/p><pre class=\"codeinput\">stacked = restack(picked,3);\r\n<\/pre><p>Because you preserve the order of the respective rows when turning them into piles, and you insert the pile that contains that chosen card in the middle, that card will be placed somewhere between 8th to 14th position.<\/p><pre class=\"codeinput\">stacked(8:14)\r\n<\/pre><pre class=\"codeoutput\">ans = \r\n  1&times;7 string array\r\n    \"&#9830;A\"    \"&#9830;2\"    \"&#9830;3\"    \"&#9830;4\"    \"&#9830;5\"    \"&#9830;6\"    \"&#9830;7\"\r\n<\/pre><p><b>Round #2<\/b><\/p><p>Then you deal the stack into 3 rows again. The cards that used to be ordered along the rows now go column by column. The card is now somewhere in the third through fifth position in the row that contains it. Your volunteer tells you it is in the middle row. Now that reduces the possibilities to 3 cards.<\/p><pre class=\"codeinput\">placed = reshape(stacked,[3 7]);\r\nplotCardsFaceUp(placed,<span class=\"string\">\"&#9830;\"<\/span> + [<span class=\"string\">\"A\"<\/span> [4,7]],2)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2020\/mindReadingMagic_04.png\" alt=\"\"> <p>You gather the rows into a single stack again as before.<\/p><pre class=\"codeinput\">stacked = restack(placed,2);\r\n<\/pre><p>This ensures that the card will be in the 10th through 12th position of the stack.<\/p><pre class=\"codeinput\">stacked(10:12)\r\n<\/pre><pre class=\"codeoutput\">ans = \r\n  1&times;3 string array\r\n    \"&#9830;A\"    \"&#9830;4\"    \"&#9830;7\"\r\n<\/pre><p><b>Round #3<\/b><\/p><p>You lay the cards again. This moves the card in the 4th position in one of the rows. Your volunteer tells you it is in the top row. At this point you know that &#9830;7 is the chosen one.<\/p><pre class=\"codeinput\">placed = reshape(stacked,[3 7]);\r\nplotCardsFaceUp(placed,<span class=\"string\">\"&#9830;7\"<\/span>,3)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2020\/mindReadingMagic_05.png\" alt=\"\"> <p>You gather the rows into a single deck again.<\/p><pre class=\"codeinput\">stacked = restack(placed,3);\r\n<\/pre><p><b>Round #4<\/b><\/p><p>When you lay the card down, you see that the card moved to the 4th position in the middle row.<\/p><pre class=\"codeinput\">placed = reshape(stacked,[3 7]);\r\nanswer = placed(2,4); <span class=\"comment\">% the 4th position in the middle row<\/span>\r\ncorrectCard = isequal(answer,chosenCard)\r\n<\/pre><pre class=\"codeoutput\">correctCard =\r\n  logical\r\n   1\r\n<\/pre><p>At this point you could just point the card, but your volunteer will notice that the card always ends up in the middle row. It is better to collect the cards into a single deck as before and pick the 11th card from the top.<\/p><p>To make it more mysterious, you probably don't want to lay the cards on the table at all. Instead, we can separate the deck into 3 piles of 7 cards and ask your volunteer to peek through them and tell you which pile contains the chosen card. This way, your volunteer will have no visual cue what's going on.<\/p><h4>Building and Sharing a MATLAB App<a name=\"6d555fdc-8772-4004-bc59-dd1e9e30300e\"><\/a><\/h4><p>Now that we worked out this card trick in code, we might as well turn it into a MATLAB app, right? If you are interested, <a href=\"https:\/\/blogs.mathworks.com\/images\/loren\/2020\/buildApp.docx\">follow the instructions here<\/a> and get the <a href=\"https:\/\/blogs.mathworks.com\/images\/loren\/2020\/appCode.txt\">app code<\/a> to build your own app.<\/p><p>Once you build an app, of course you want to share it.<\/p><div><ul><li>If your friends are also MATLAB users, you can simply share the <tt>.mlapp<\/tt> file, but they will probably apprediate it if you <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/packaging-guis-as-apps.html\">package it<\/a> so that it comes with the installer.<\/li><li>How about your friends who doesn't have MATLAB? You can turn this into a standalone desktop app if you use <a href=\"https:\/\/www.mathworks.com\/products\/compiler.html\">MATLAB Compiler<\/a>.<\/li><li>You can also turn it into a <a href=\"https:\/\/www.mathworks.com\/help\/compiler\/web-apps.html\">web app<\/a> that runs on browser and make it available over the web hosted on <a href=\"https:\/\/www.mathworks.com\/products\/matlab-web-app-server.html\">MATLAB Web App Server<\/a>. See <a href=\"https:\/\/www.mathworks.com\/videos\/getting-started-web-apps-with-matlab-compiler-1520291338022.html\">this video<\/a> for more details.<\/li><\/ul><\/div><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2020\/05_app.png\" alt=\"\"> <\/p><h4>Summary<a name=\"9b3e6aed-1b62-49ba-9c8a-90d3fd72c549\"><\/a><\/h4><p>Now that you know you can use playing cards in MATLAB, you can try all sorts of algorithms and card tricks and come up with your own apps. Please share your creations <a href=\"https:\/\/blogs.mathworks.com\/loren\/?p=3713#respond\">here<\/a>!<\/p><h4>Local Functions<a name=\"81f0e2e9-9b11-4f23-b2f7-fb1ce83e01a6\"><\/a><\/h4><pre class=\"codeinput\"><span class=\"keyword\">function<\/span> picked = initialize21Cards(deck)\r\n    shuffledDeck = deck(randperm(numel(deck)));\r\n    picked = shuffledDeck(1:21);\r\n    picked = picked(randperm(21));\r\n<span class=\"keyword\">end<\/span>\r\n<\/pre><pre class=\"codeinput\"><span class=\"keyword\">function<\/span> stacked = restack(placed,selectedRow)\r\n    rows = randperm(3);\r\n    rows = setdiff(rows,selectedRow);\r\n    rows = [rows(1), selectedRow, rows(2)];\r\n    stacked = [placed(rows(1),:),placed(rows(2),:),placed(rows(3),:)];\r\n<span class=\"keyword\">end<\/span>\r\n<\/pre><pre class=\"codeinput\"><span class=\"keyword\">function<\/span> plotCardsFaceUp(cards,varargin)\r\n    <span class=\"keyword\">if<\/span> nargin &gt; 1\r\n        <span class=\"keyword\">for<\/span> ii = 1:length(varargin)\r\n            <span class=\"keyword\">if<\/span> isstring(varargin{ii})\r\n                highlight = varargin{ii};\r\n            <span class=\"keyword\">else<\/span>\r\n                numRound = varargin{ii};\r\n            <span class=\"keyword\">end<\/span>\r\n        <span class=\"keyword\">end<\/span>\r\n    <span class=\"keyword\">end<\/span>\r\n\r\n    [recPos,txtPos,seq,axisLim] = positionCards(cards);\r\n\r\n    <span class=\"keyword\">if<\/span> exist(<span class=\"string\">\"numRound\"<\/span>,<span class=\"string\">\"var\"<\/span>) &amp;&amp; exist(<span class=\"string\">\"highlight\"<\/span>,<span class=\"string\">\"var\"<\/span>)\r\n        plotCards(recPos,txtPos,seq,axisLim,numRound,highlight)\r\n    <span class=\"keyword\">elseif<\/span> exist(<span class=\"string\">\"numRound\"<\/span>,<span class=\"string\">\"var\"<\/span>)\r\n        plotCards(recPos,txtPos,seq,axisLim,numRound)\r\n    <span class=\"keyword\">elseif<\/span> exist(<span class=\"string\">\"highlight\"<\/span>,<span class=\"string\">\"var\"<\/span>)\r\n        plotCards(recPos,txtPos,seq,axisLim,highlight)\r\n    <span class=\"keyword\">else<\/span>\r\n        plotCards(recPos,txtPos,seq,axisLim)\r\n    <span class=\"keyword\">end<\/span>\r\n<span class=\"keyword\">end<\/span>\r\n<\/pre><pre class=\"codeinput\"><span class=\"keyword\">function<\/span> [recPos,txtPos,seq,axisLim] = positionCards(cards)\r\n    [n,m] = size(cards);\r\n    recPos = zeros(n*m,4);\r\n    txtPos = zeros(n*m,2);\r\n    seq = [];\r\n    <span class=\"keyword\">for<\/span> ii = 1:n\r\n        seq = [seq cards(ii,1:m)];\r\n    <span class=\"keyword\">end<\/span>\r\n\r\n    origin = [1.5 1];\r\n    w = 1;\r\n    h = 2;\r\n    spacing = 0.2;\r\n\r\n    <span class=\"keyword\">if<\/span> all([n,m] == 1)\r\n        recPos = [origin w h];\r\n        txtPos = [recPos(:,1)+w\/2 recPos(:,2)+h\/2];\r\n    <span class=\"keyword\">else<\/span>\r\n        <span class=\"keyword\">for<\/span> ii = 1:n\r\n            recPos(m*(ii-1)+1:m*ii,1) = origin(1)+(w+spacing)*((1:m)'-1);\r\n            recPos(m*(ii-1)+1:m*ii,2) = origin(2)+(h+spacing)*(ii-1);\r\n            txtPos(m*(ii-1)+1:m*ii,1) = recPos(m*(ii-1)+1:m*ii,1) + w\/2;\r\n            txtPos(m*(ii-1)+1:m*ii,2) = recPos(m*(ii-1)+1:m*ii,2) + h\/2;\r\n        <span class=\"keyword\">end<\/span>\r\n        recPos(:,3) = w;\r\n        recPos(:,4) = h;\r\n    <span class=\"keyword\">end<\/span>\r\n\r\n    <span class=\"keyword\">if<\/span> all([n,m] ~= 1)\r\n        axisLim = ceil(origin(1)+(w+spacing)*m);\r\n        recPos(:,2) = recPos(:,2) + (axisLim-(h+spacing)*n)\/2 - origin(2);\r\n        txtPos(:,2) = recPos(:,2) + h\/2;\r\n    <span class=\"keyword\">else<\/span>\r\n        axisLim = ceil(origin(2) + (h + spacing) * m);\r\n        recPos(:,1) = (axisLim - w)\/2;\r\n        recPos(:,2) = (axisLim - h)\/2;\r\n        txtPos(:,1) = recPos(:,1) + w\/2;\r\n        txtPos(:,2) = recPos(:,2) + h\/2;\r\n    <span class=\"keyword\">end<\/span>\r\n<span class=\"keyword\">end<\/span>\r\n<\/pre><pre class=\"codeinput\"><span class=\"keyword\">function<\/span> plotCards(recPos,txtPos,seq,axisLim,varargin)\r\n    <span class=\"keyword\">if<\/span> nargin &gt; 4\r\n        <span class=\"keyword\">for<\/span> ii = 1:length(varargin)\r\n            <span class=\"keyword\">if<\/span> isstring(varargin{ii})\r\n                highlight = varargin{ii};\r\n            <span class=\"keyword\">else<\/span>\r\n                numRound = varargin{ii};\r\n            <span class=\"keyword\">end<\/span>\r\n        <span class=\"keyword\">end<\/span>\r\n    <span class=\"keyword\">end<\/span>\r\n\r\n    figure\r\n    <span class=\"keyword\">for<\/span> ii = 1:size(recPos,1)\r\n        <span class=\"keyword\">if<\/span> exist(<span class=\"string\">\"highlight\"<\/span>,<span class=\"string\">\"var\"<\/span>) &amp;&amp; ismember(seq(ii),highlight)\r\n            rectangle(<span class=\"string\">'Position'<\/span>,recPos(ii,:),<span class=\"string\">'Curvature'<\/span>,0.2,<span class=\"string\">\"FaceColor\"<\/span>,<span class=\"string\">\"w\"<\/span>,<span class=\"string\">\"LineWidth\"<\/span>,3)\r\n        <span class=\"keyword\">else<\/span>\r\n            rectangle(<span class=\"string\">'Position'<\/span>,recPos(ii,:),<span class=\"string\">'Curvature'<\/span>,0.2,<span class=\"string\">\"FaceColor\"<\/span>,<span class=\"string\">\"w\"<\/span>)\r\n        <span class=\"keyword\">end<\/span>\r\n        color = <span class=\"string\">'k'<\/span>;\r\n        <span class=\"keyword\">if<\/span> contains(seq(ii),[<span class=\"string\">\"&#9829;\"<\/span>,<span class=\"string\">\"&#9830;\"<\/span>])\r\n            color = <span class=\"string\">'r'<\/span>;\r\n        <span class=\"keyword\">end<\/span>\r\n        <span class=\"keyword\">if<\/span> axisLim == 18\r\n            fontSize = 8;\r\n        <span class=\"keyword\">elseif<\/span> axisLim == 10\r\n            fontSize = 16;\r\n        <span class=\"keyword\">elseif<\/span> axisLim == 4\r\n            fontSize = 36;\r\n        <span class=\"keyword\">else<\/span>\r\n            fontSize = 10;\r\n        <span class=\"keyword\">end<\/span>\r\n        text(txtPos(ii,1),txtPos(ii,2),seq(ii),<span class=\"string\">\"Color\"<\/span>,color,<span class=\"string\">\"FontSize\"<\/span>,fontSize,<span class=\"string\">\"HorizontalAlignment\"<\/span>,<span class=\"string\">\"center\"<\/span>)\r\n    <span class=\"keyword\">end<\/span>\r\n    <span class=\"keyword\">if<\/span> size(recPos,1) == 21\r\n        posX = unique(txtPos(:,1));\r\n        posY = unique(txtPos(:,2));\r\n        text(1,posY(1),<span class=\"string\">\"Bottom\"<\/span>,<span class=\"string\">\"HorizontalAlignment\"<\/span>,<span class=\"string\">\"center\"<\/span>,<span class=\"string\">\"Rotation\"<\/span>,90)\r\n        text(1,posY(2),<span class=\"string\">\"Middle\"<\/span>,<span class=\"string\">\"HorizontalAlignment\"<\/span>,<span class=\"string\">\"center\"<\/span>,<span class=\"string\">\"Rotation\"<\/span>,90)\r\n        text(1,posY(3),<span class=\"string\">\"Top\"<\/span>,<span class=\"string\">\"HorizontalAlignment\"<\/span>,<span class=\"string\">\"center\"<\/span>,<span class=\"string\">\"Rotation\"<\/span>,90)\r\n        text(posX(1),1,<span class=\"string\">\"1\"<\/span>,<span class=\"string\">\"HorizontalAlignment\"<\/span>,<span class=\"string\">\"center\"<\/span>)\r\n        text(posX(2),1,<span class=\"string\">\"2\"<\/span>,<span class=\"string\">\"HorizontalAlignment\"<\/span>,<span class=\"string\">\"center\"<\/span>)\r\n        text(posX(3),1,<span class=\"string\">\"3\"<\/span>,<span class=\"string\">\"HorizontalAlignment\"<\/span>,<span class=\"string\">\"center\"<\/span>)\r\n        text(posX(4),1,<span class=\"string\">\"4\"<\/span>,<span class=\"string\">\"HorizontalAlignment\"<\/span>,<span class=\"string\">\"center\"<\/span>)\r\n        text(posX(5),1,<span class=\"string\">\"5\"<\/span>,<span class=\"string\">\"HorizontalAlignment\"<\/span>,<span class=\"string\">\"center\"<\/span>)\r\n        text(posX(6),1,<span class=\"string\">\"6\"<\/span>,<span class=\"string\">\"HorizontalAlignment\"<\/span>,<span class=\"string\">\"center\"<\/span>)\r\n        text(posX(7),1,<span class=\"string\">\"7\"<\/span>,<span class=\"string\">\"HorizontalAlignment\"<\/span>,<span class=\"string\">\"center\"<\/span>)\r\n    <span class=\"keyword\">end<\/span>\r\n    axis([0 axisLim 0 axisLim])\r\n    <span class=\"keyword\">if<\/span> exist(<span class=\"string\">\"numRound\"<\/span>,<span class=\"string\">\"var\"<\/span>)\r\n        title(<span class=\"string\">\"Round \"<\/span> + numRound)\r\n    <span class=\"keyword\">end<\/span>\r\n    set(gca, <span class=\"string\">'visible'<\/span>, <span class=\"string\">'off'<\/span>)\r\n    set(findall(gca, <span class=\"string\">'type'<\/span>, <span class=\"string\">'text'<\/span>), <span class=\"string\">'visible'<\/span>, <span class=\"string\">'on'<\/span>)\r\n<span class=\"keyword\">end<\/span>\r\n<\/pre><script language=\"JavaScript\"> <!-- \r\n    function grabCode_ff34cee9795e43cdbb2d7174ad636393() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='ff34cee9795e43cdbb2d7174ad636393 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' ff34cee9795e43cdbb2d7174ad636393';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2020 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_ff34cee9795e43cdbb2d7174ad636393()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2020a<br><\/p><\/div><!--\r\nff34cee9795e43cdbb2d7174ad636393 ##### SOURCE BEGIN #####\r\n%% MATLAB and Mind Reading Card Games\r\n% <https:\/\/www.mathworks.com\/videos\/release-highlights-2020a-1584390596825.html\r\n% R2020a> is upon us! Do you read\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/release-notes.html the release\r\n% notes>? Today's guest blogger,\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/profile\/authors\/951521 Toshi\r\n% Takeuchi>, apparently does, and he would like to share some new tricks\r\n% using one of the new features. He also discusses sharing your code as a\r\n% MATLAB app, since it is not easy to collaborate with people directly\r\n% these days.\r\n% \r\n%% UTF-8 Support in MATLAB\r\n% As of R2020a, MATLAB defaults to saving new plain text files using UTF-8.\r\n% What's the big deal, you say? Das ist eine gro\u00dfe Sache, \u305d\u308c\u306f\u5927\u3054\u3068\u3060, because\r\n% you can now use international characters mixed within English easily.\r\n% Even if you only speak English, you sure do use Greek letters like \u03c0, \u03c3,\r\n% or \u03b2, right? This also means you can use emojis, too, but I can't show it\r\n% here because publish to html feature doesn't translate emojis into html\r\n% entities like |&#128513;|\r\n% \r\n% Personally, however, I am more excited with the playing card symbols. Let's \r\n% make a deck of 52 cards. \r\n\r\ndeck = [\"&#x2660;\",\"&#x2665;\",\"&#x2666;\",\"&#x2663;\"] + [\"A\"; (2:10)';'J';'Q';'K']\r\n\r\n%% \r\n% That means we can also use those special characters in the plot as well. \r\n\r\nfigure\r\nrectangle(\"Position\",[1 0.5 1 2],'Curvature',0.2)\r\ntext(1.5,1.5,deck(1),\"FontSize\",36,\"HorizontalAlignment\",\"center\")\r\naxis([0 3 0 3])\r\n\r\n%% Mind Reading Card Magic\r\n% Let's play the famous 21-card mind reading trick with those cards. \r\n% \r\n% You are entertaining your friends with a card trick. First, shuffle the\r\n% deck and select first 21 cards from the deck.\r\n\r\nrng(\"default\") % for repeatability\r\npicked = initialize21Cards(deck);\r\n\r\n%% \r\n% Ask a volunteer to choose a card from the stack of 21 cards and remember\r\n% it, but not tell you what it is.\r\n\r\n% select a card\r\nchosenCard = picked(randi(21))\r\n\r\n%% \r\n% Have your volunteer shuffle the deck of 21 cards and return it to you.\r\n\r\nstacked = picked(randperm(21));\r\n\r\n%% \r\n% There are several variations to the steps depending on the effect you\r\n% want to achieve. Here you will lay out the cards on the table. When you\r\n% do so, you lay them out into 3 columns of 7 cards. There is a reason to\r\n% do it this way when you are handling physical cards, but let's use a 3x7\r\n% layout to make it easier to plot the cards. We substitute columns with\r\n% rows.\r\n\r\nplotCardsFaceUp(reshape(stacked,[3 7]),0)\r\n\r\n%% \r\n% Repeat the process 4 times:\r\n% \r\n% # Deal the cards face up into three rows moving from bottom to top. You should \r\n% have seven cards in each row.\r\n% # Ask your volunteer to point to the row the chosen card is in: the bottom \r\n% row, the middle row or the top row.\r\n% # Slide each row of cards together to form three piles, preserving the order. \r\n% # Collect the three piles into one stack in a specific order\u2014make sure that \r\n% the pile your volunteer pointed to is always collected second.\r\n\r\nfor ii = 1:4\r\n    placed = reshape(stacked,[3 7]); % deal the cards face up\r\n    selectedRow = find(any(placed == chosenCard,2)); % row with the card\r\n    stacked = restack(placed,selectedRow); % gather cards into a stack\r\nend\r\n\r\n%%\r\n% Reveal the 11th card in the stack, which should be the chosen card.\r\n% Hopefully your friends are impressed.\r\n\r\nanswer = stacked(11);\r\ncorrectCard = isequal(answer,chosenCard)\r\n\r\n%% How Does It Work?\r\n% *Spoiler Alert! The trick is revealed!*\r\n% \r\n% Now let's see why this works. We will keep it simple by using the first 7\r\n% cards from the suits of &#x2660;, &#x2665; and &#x2666;. We will choose &#x2666;7 for this example.\r\n\r\npicked = [\"&#x2660;\",\"&#x2665;\",\"&#x2666;\"]' + [\"A\",(2:7)];\r\nchosenCard = \"&#x2666;7\";\r\n\r\n%% \r\n% *Round # 1* \r\n% \r\n% When you first lay out the cards, you have no idea where the chosen card\r\n% is. It could be anywhere. Then your volunteer tells you it is in the top\r\n% rows. You now know that the chosen card is one of those 7 cards. Let's\r\n% highlight them.\r\n\r\nplotCardsFaceUp(picked,1,\"&#x2666;\" + [\"A\" (2:7)])\r\n\r\n%% \r\n% Now we collect the cards into a stack in a specific order. \r\n\r\nstacked = restack(picked,3);\r\n\r\n%% \r\n% Because you preserve the order of the respective rows when turning them\r\n% into piles, and you insert the pile that contains that chosen card in the\r\n% middle, that card will be placed somewhere between 8th to 14th position.\r\n% \r\nstacked(8:14)\r\n\r\n%% \r\n% *Round #2* \r\n% \r\n% Then you deal the stack into 3 rows again. The cards that used to be\r\n% ordered along the rows now go column by column. The card is now somewhere\r\n% in the third through fifth position in the row that contains it. Your\r\n% volunteer tells you it is in the middle row. Now that reduces the\r\n% possibilities to 3 cards.\r\n\r\nplaced = reshape(stacked,[3 7]);\r\nplotCardsFaceUp(placed,\"&#x2666;\" + [\"A\" [4,7]],2)\r\n%% \r\n% You gather the rows into a single stack again as before.  \r\n\r\nstacked = restack(placed,2);\r\n\r\n%%\r\n% This ensures that the card will be in the 10th through 12th position of\r\n% the stack.\r\n\r\nstacked(10:12)\r\n\r\n%% \r\n% *Round #3* \r\n% \r\n% You lay the cards again. This moves the card in the 4th position in one\r\n% of the rows. Your volunteer tells you it is in the top row. At this point\r\n% you know that &#x2666;7 is the chosen one.\r\n\r\nplaced = reshape(stacked,[3 7]);\r\nplotCardsFaceUp(placed,\"&#x2666;7\",3)\r\n\r\n%% \r\n% You gather the rows into a single deck again. \r\n\r\nstacked = restack(placed,3);\r\n\r\n%% \r\n% *Round #4* \r\n% \r\n% When you lay the card down, you see that the card moved to the 4th\r\n% position in the middle row.\r\n\r\nplaced = reshape(stacked,[3 7]);\r\nanswer = placed(2,4); % the 4th position in the middle row\r\ncorrectCard = isequal(answer,chosenCard)\r\n\r\n%% \r\n% At this point you could just point the card, but your volunteer will\r\n% notice that the card always ends up in the middle row. It is better to\r\n% collect the cards into a single deck as before and pick the 11th card\r\n% from the top.\r\n% \r\n% To make it more mysterious, you probably don't want to lay the cards on\r\n% the table at all. Instead, we can separate the deck into 3 piles of 7\r\n% cards and ask your volunteer to peek through them and tell you which pile\r\n% contains the chosen card. This way, your volunteer will have no visual\r\n% cue what's going on.\r\n%\r\n%% Building and Sharing a MATLAB App\r\n% Now that we worked out this card trick in code, we might as well turn it\r\n% into a MATLAB app, right? If you are interested,\r\n% <https:\/\/blogs.mathworks.com\/images\/loren\/2020\/buildApp.docx follow the\r\n% instructions here> and get the\r\n% <https:\/\/blogs.mathworks.com\/images\/loren\/2020\/appCode.txt app code> to\r\n% build your own app.\r\n% \r\n% Once you build an app, of course you want to share it. \r\n%\r\n% * If your friends are also MATLAB users, you can simply share the\r\n% |.mlapp| file, but they will probably apprediate it if you\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/packaging-guis-as-apps.html\r\n% package it> so that it comes with the installer.\r\n% * How about your friends who doesn't have MATLAB? You can turn this into a \r\n% standalone desktop app if you use <https:\/\/www.mathworks.com\/products\/compiler.html \r\n% MATLAB Compiler>. \r\n% * You can also turn it into a\r\n% <https:\/\/www.mathworks.com\/help\/compiler\/web-apps.html web app> that runs\r\n% on browser and make it available over the web hosted on\r\n% <https:\/\/www.mathworks.com\/products\/matlab-web-app-server.html MATLAB Web\r\n% App Server>. See\r\n% <https:\/\/www.mathworks.com\/videos\/getting-started-web-apps-with-matlab-compiler-1520291338022.html\r\n% this video> for more details.\r\n%\r\n% <<05_app.png>>\r\n% \r\n%% Summary\r\n% Now that you know you can use playing cards in MATLAB, you can try all\r\n% sorts of algorithms and card tricks and come up with your own apps.\r\n% Please share your creations\r\n% <https:\/\/blogs.mathworks.com\/loren\/?p=3713#respond here>!\r\n%\r\n%% Local Functions\r\n\r\nfunction picked = initialize21Cards(deck)\r\n    shuffledDeck = deck(randperm(numel(deck)));\r\n    picked = shuffledDeck(1:21);\r\n    picked = picked(randperm(21));\r\nend\r\n%% \r\n% \r\n\r\nfunction stacked = restack(placed,selectedRow)\r\n    rows = randperm(3);\r\n    rows = setdiff(rows,selectedRow);\r\n    rows = [rows(1), selectedRow, rows(2)];\r\n    stacked = [placed(rows(1),:),placed(rows(2),:),placed(rows(3),:)];\r\nend\r\n%% \r\n% \r\n\r\nfunction plotCardsFaceUp(cards,varargin)\r\n    if nargin > 1\r\n        for ii = 1:length(varargin)\r\n            if isstring(varargin{ii})\r\n                highlight = varargin{ii};\r\n            else\r\n                numRound = varargin{ii};\r\n            end\r\n        end\r\n    end\r\n    \r\n    [recPos,txtPos,seq,axisLim] = positionCards(cards);\r\n    \r\n    if exist(\"numRound\",\"var\") && exist(\"highlight\",\"var\")\r\n        plotCards(recPos,txtPos,seq,axisLim,numRound,highlight)\r\n    elseif exist(\"numRound\",\"var\")\r\n        plotCards(recPos,txtPos,seq,axisLim,numRound)\r\n    elseif exist(\"highlight\",\"var\")\r\n        plotCards(recPos,txtPos,seq,axisLim,highlight)\r\n    else\r\n        plotCards(recPos,txtPos,seq,axisLim)\r\n    end\r\nend\r\n%% \r\n% \r\n\r\nfunction [recPos,txtPos,seq,axisLim] = positionCards(cards)\r\n    [n,m] = size(cards);\r\n    recPos = zeros(n*m,4);\r\n    txtPos = zeros(n*m,2);\r\n    seq = [];\r\n    for ii = 1:n\r\n        seq = [seq cards(ii,1:m)];\r\n    end\r\n\r\n    origin = [1.5 1];\r\n    w = 1;\r\n    h = 2;\r\n    spacing = 0.2;\r\n\r\n    if all([n,m] == 1)\r\n        recPos = [origin w h];\r\n        txtPos = [recPos(:,1)+w\/2 recPos(:,2)+h\/2];\r\n    else\r\n        for ii = 1:n\r\n            recPos(m*(ii-1)+1:m*ii,1) = origin(1)+(w+spacing)*((1:m)'-1);\r\n            recPos(m*(ii-1)+1:m*ii,2) = origin(2)+(h+spacing)*(ii-1);\r\n            txtPos(m*(ii-1)+1:m*ii,1) = recPos(m*(ii-1)+1:m*ii,1) + w\/2;\r\n            txtPos(m*(ii-1)+1:m*ii,2) = recPos(m*(ii-1)+1:m*ii,2) + h\/2;\r\n        end\r\n        recPos(:,3) = w;\r\n        recPos(:,4) = h;\r\n    end\r\n    \r\n    if all([n,m] ~= 1)\r\n        axisLim = ceil(origin(1)+(w+spacing)*m);\r\n        recPos(:,2) = recPos(:,2) + (axisLim-(h+spacing)*n)\/2 - origin(2);\r\n        txtPos(:,2) = recPos(:,2) + h\/2;\r\n    else\r\n        axisLim = ceil(origin(2) + (h + spacing) * m);\r\n        recPos(:,1) = (axisLim - w)\/2;\r\n        recPos(:,2) = (axisLim - h)\/2;\r\n        txtPos(:,1) = recPos(:,1) + w\/2;\r\n        txtPos(:,2) = recPos(:,2) + h\/2;\r\n    end\r\nend\r\n%% \r\n% \r\n\r\nfunction plotCards(recPos,txtPos,seq,axisLim,varargin)\r\n    if nargin > 4\r\n        for ii = 1:length(varargin)\r\n            if isstring(varargin{ii})\r\n                highlight = varargin{ii};\r\n            else\r\n                numRound = varargin{ii};\r\n            end\r\n        end\r\n    end\r\n\r\n    figure\r\n    for ii = 1:size(recPos,1)\r\n        if exist(\"highlight\",\"var\") && ismember(seq(ii),highlight)\r\n            rectangle('Position',recPos(ii,:),'Curvature',0.2,\"FaceColor\",\"w\",\"LineWidth\",3)\r\n        else\r\n            rectangle('Position',recPos(ii,:),'Curvature',0.2,\"FaceColor\",\"w\")\r\n        end\r\n        color = 'k';\r\n        if contains(seq(ii),[\"&#x2665;\",\"&#x2666;\"])\r\n            color = 'r';\r\n        end\r\n        if axisLim == 18\r\n            fontSize = 8;\r\n        elseif axisLim == 10\r\n            fontSize = 16;\r\n        elseif axisLim == 4\r\n            fontSize = 36;\r\n        else\r\n            fontSize = 10;\r\n        end\r\n        text(txtPos(ii,1),txtPos(ii,2),seq(ii),\"Color\",color,\"FontSize\",fontSize,\"HorizontalAlignment\",\"center\")\r\n    end\r\n    if size(recPos,1) == 21\r\n        posX = unique(txtPos(:,1));\r\n        posY = unique(txtPos(:,2));\r\n        text(1,posY(1),\"Bottom\",\"HorizontalAlignment\",\"center\",\"Rotation\",90)\r\n        text(1,posY(2),\"Middle\",\"HorizontalAlignment\",\"center\",\"Rotation\",90)\r\n        text(1,posY(3),\"Top\",\"HorizontalAlignment\",\"center\",\"Rotation\",90)\r\n        text(posX(1),1,\"1\",\"HorizontalAlignment\",\"center\")\r\n        text(posX(2),1,\"2\",\"HorizontalAlignment\",\"center\")\r\n        text(posX(3),1,\"3\",\"HorizontalAlignment\",\"center\")\r\n        text(posX(4),1,\"4\",\"HorizontalAlignment\",\"center\")\r\n        text(posX(5),1,\"5\",\"HorizontalAlignment\",\"center\")\r\n        text(posX(6),1,\"6\",\"HorizontalAlignment\",\"center\")\r\n        text(posX(7),1,\"7\",\"HorizontalAlignment\",\"center\")\r\n    end\r\n    axis([0 axisLim 0 axisLim])\r\n    if exist(\"numRound\",\"var\")\r\n        title(\"Round \" + numRound)\r\n    end\r\n    set(gca, 'visible', 'off')\r\n    set(findall(gca, 'type', 'text'), 'visible', 'on')\r\nend\r\n##### SOURCE END ##### ff34cee9795e43cdbb2d7174ad636393\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2020\/05_app.png\" onError=\"this.style.display ='none';\" \/><\/div><!--introduction--><p><a href=\"https:\/\/www.mathworks.com\/videos\/release-highlights-2020a-1584390596825.html\">R2020a<\/a> is upon us! Do you read <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/release-notes.html\">the release notes<\/a>? Today's guest blogger, <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/profile\/authors\/951521\">Toshi Takeuchi<\/a>, apparently does, and he would like to share some new tricks using one of the new features. He also discusses sharing your code as a MATLAB app, since it is not easy to collaborate with people directly these days.... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/loren\/2020\/05\/28\/matlab-and-mind-reading-card-games\/\">read more >><\/a><\/p>","protected":false},"author":39,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[74,33,6],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/3713"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/users\/39"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/comments?post=3713"}],"version-history":[{"count":4,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/3713\/revisions"}],"predecessor-version":[{"id":3721,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/3713\/revisions\/3721"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/media?parent=3713"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/categories?post=3713"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/tags?post=3713"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}