[JavaScript] [作品] 读心术系列之卡片读心术原理及Web实现 6张卡片 卡片读心术小程序
卡片读心术小程序重磅推出!支持自定义卡片并生成图片保存,向你的朋友表演!微信扫描下方小程序码立即体验!
微信小程序 QQ小程序
首先来玩一遍卡片读心术:
https://www.qwqoffice.com/thought-reader-card/
小时候在肯德基买儿童套餐的时候发现一种玩具,里面是6张写着很多数字的卡片,先让观众心里默想一个1~50的数字,然后拿着每张卡片去让测试的人回答卡片上是否有所想的数字。当6张卡片问完之后,表演者就能知道观众所想的数字。
当我知道这个玩具的神奇之处之后,我就拿着它向班里面的每个同学表演,同学们都觉得很神奇,但是并不知道其中的原理。
直到有一天,卡片找不到了,于是我想着靠自己的记忆把这套卡片复原。还好我记得表演的方法,是把观众回答“有”的卡片所代表的数字全部加起来,就是所想的数字。
首先是卡片所代表的数字。因为最后是要把卡片所代表的数字加起来,所以这些数字必须是能组合成1~50之间所有数字的一组数。组成1需要数字1,组成2需要数字2,组成3需要数字1和2,4需要4,5需要1和4,6需要2和4。以此类推,这组数字是【1、2、4、8、16、32】,6个数字刚好对应6张卡片。其实这个和Linux下文件的权限是一样的,文件权限有执行,写入,读取3种,对应数字1,2,4。如果将来还有一个新的权限,那肯定是8。以下是1到20组合所需的数字。
然后是上面这些代表数字,所有需要这些代表数的数字,比如需要1的数字有1、3、5、7、9...,需要2的数字有2、3、6、7、10、11...,假设代表数是n,不难发现,数字的规律是先从n本身开始连续n个数,然后跳过n个数,再连续n个数。如下图:
把这些数字,分别放到6张卡片当中,卡片的原理复原算是完成了,如下图。卡片中最小的数字即代表数。
接下来是Web实现。使用HTML + CSS + jQuery。
代表数,数字范围和结果的变量定义。及卡片颜色和一些用于响应式的变量定义。
JavaScript
var need = [1, 2, 4, 8, 16, 32].sort(randomsort); //组合所需数字 var total = 60; //数字范围 var result = 0; //结果 var colors = ['#009e96', '#22ac38', '#eb6100', '#eb6877', '#8957a1', '#b7aa00'].sort(randomsort); //卡片颜色 var transform, cardMargin, clickCount = 0; var cardHeight;
构造每个卡片上的数字
JavaScript
function get_nums_obj(){
var obj = [];
for( i = 0; i < need.length; i++ ){
var numbers = [];
var pointer = need[i];
for( j = need[i]; j <= total; j++ ){
numbers.push(j.toString());
//如果连续need[i]个数字
if( j - pointer === need[i] - 1 ){
pointer = j + need[i] + 1; //跳过need[i]个数字
j = pointer - 1; //j在下轮循环自动增长,故-1
}
}
obj['N'+need[i]] = numbers.sort(randomsort);
}
return obj;
}
数组的随机排序
JavaScript
function randomsort(a, b){
//用Math.random()函数生成0~1之间的随机数与0.5比较,返回-1或1
return Math.random()>.5 ? -1 : 1;
}
卡片视图的生成
JavaScript
function generate_view(){
var obj = get_nums_obj();
var count = 0;
for( var item in obj ){
var index = item.substring(1);
//$('#card-content .card-inner .card-inner-step').append('<div class="step card" style="background-color:'+colors[count]+';" data-num="'+index+'"></div>');
$('#card-content .card-inner .card-inner-step').append('<div class="step card" style="background-color:'+colors[count]+';"></div>');
$.each(obj[item], function(index, num){
$('#card-content .card-inner .card:last').append('<span class="card-num">'+num+'</span>');
});
count++;
}
}
卡片滚动动画
JavaScript
function scrollCard(){
if( clickCount >= $('#card-content .step').length - 1 ) return;
$('#card-content .card-inner').css('transform', 'translateY(-'+transform+'px)');
transform += cardHeight;
clickCount++;
}
重置
JavaScript
function resetCard(){
clickCount = 0;
result = 0;
need = need.sort(randomsort);
colors = colors.sort(randomsort);
transform = cardHeight;
$('#card-content .card-inner .card-inner-step').html('');
generate_view();
$('#card-content .card-inner').css('transform', 'translateY(0px)');
$('.action-reset').fadeOut(100, function(){
$('.action-start').fadeIn(100);
});
}
卡片高度适应
JavaScript
function resizeStep(){
$('.card-wapper .step').height($('.card-wapper .card:first').height());
$('.card-wapper').height($('.card-wapper .step:first').outerHeight() + cardMargin * 2);
}
初始化
JavaScript
function init(){
generate_view();
cardMargin = parseInt($('.card-wapper .card:first').css('margin-bottom').replace('px', ''));
cardHeight = $('.card-wapper .card:first').outerHeight() + cardMargin * 2;
transform = cardHeight;
resizeStep();
$(window).resize(function(){
resizeStep();
});
//“是”“否”按钮点击
$('.action-ask button').click(function(){
//加上当前卡片数字
if( $(this).hasClass('yes') ){
//result += parseInt($('.card-inner-step .card:eq('+(clickCount-1)+')').data('num'));
result += need[ clickCount-1 ];
}
scrollCard();
if( clickCount >= $('#card-content .step').length - 1 ){
$('#result-num').text(result);
$('.action-ask').fadeOut(100, function(){
$('.action-reset').fadeIn(100);
});
}
});
//开始按钮点击
$('.action-start #start').click(function(){
scrollCard();
$('.action-start').fadeOut(100, function(){
$('.action-ask').fadeIn(100);
});
});
//重置按钮点击
$('.action-reset #reset').click(function(){
resetCard();
});
}
不过这种程序生成的卡片没有实体卡片的效果好,因为当用户点击“是”或“否”的时候,用程序很轻松地就能把一张卡片上的数字全部排除,容易让别人误以为是用了排除法;而实体卡片要用排除法却很难,况且在表演过程中排除数字非常容易让观众看出来。
源码下载:ThoughtReader-Card-20170527.zip
本文链接:https://www.qwqoffice.com/article.php?mod=view&tid=28
