Satoshi Mines Source Code


SUBMITTED BY: Guest

DATE: Feb. 17, 2014, 5:40 a.m.

FORMAT: JavaScript

SIZE: 20.9 kB

HITS: 1551

  1. // Default options for the loading spinner
  2. var spin_opts = {
  3. lines: 13,
  4. length: 2,
  5. width: 2,
  6. radius: 5,
  7. corners: 1,
  8. rotate: 0,
  9. direction: 1,
  10. color: '#fff'
  11. };
  12. var sound_enabled = true;
  13. $game_html = $('<div class="game"><div class="game_left"><ul class="board"><li data-tile="1" class="tile"></li><li data-tile="2" class="tile"></li><li data-tile="3" class="tile"></li><li data-tile="4" class="tile"></li><li data-tile="5" class="tile"></li><li data-tile="6" class="tile"></li><li data-tile="7" class="tile"></li><li data-tile="8" class="tile"></li><li data-tile="9" class="tile"></li><li data-tile="10" class="tile"></li><li data-tile="11" class="tile"></li><li data-tile="12" class="tile"></li><li data-tile="13" class="tile"></li><li data-tile="14" class="tile"></li><li data-tile="15" class="tile"></li><li data-tile="16" class="tile"></li><li data-tile="17" class="tile"></li><li data-tile="18" class="tile"></li><li data-tile="19" class="tile"></li><li data-tile="20" class="tile"></li><li data-tile="21" class="tile"></li><li data-tile="22" class="tile"></li><li data-tile="23" class="tile"></li><li data-tile="24" class="tile"></li><li data-tile="25" class="tile"></li></ul></div><div class="game_right"><div class="control standings"><div class="col-left"><p class="standing_label">Next tile worth:</p><p class="stand_next"><span id="next"></span></p></div><div class="col-right"><button class="cashout">Cashout</button><p class="standing_label">In play:</p><p class="stand_stake"><span id="stake"></span></p></div></div><div class="messages"></div></div></div>');
  14. var win = new Howl({urls: [webroot+'sound/win.mp3', webroot+'sound/win.ogg', webroot+'sound/win.wav']});
  15. var lose = new Howl({urls: [webroot+'sound/lose.mp3', webroot+'sound/lose.ogg', webroot+'sound/lose.wav']});
  16. var busy = false;
  17. var consecutive_zeros = 0;
  18. /* SATOSHIMINES.JS V0.81 */
  19. function Game(bet, game_hash, num_mines){
  20. num_mines = typeof num_mines !== 'undefined' ? num_mines : 3;
  21. var game_hash_qs = (typeof game_hash==='undefined')?'':'&game_hash='+game_hash;
  22. var _this = this;
  23. var timer = 0;
  24. var timer_int = setInterval(function(){
  25. timer++;
  26. }, 100);
  27. // A new game
  28. busy = true;
  29. $.ajax({
  30. url: webroot+'action/newgame.php',
  31. data: 'player_hash='+playerhash+'&bet='+bet+game_hash_qs+'&num_mines='+num_mines,
  32. type: 'POST',
  33. dataType: 'json'
  34. }).done(function(jqxhr){
  35. busy = false;
  36. clearInterval(timer_int);
  37. clean_feed();
  38. if (jqxhr.status == 'success'){
  39. ga('send', 'event', 'game', 'new', 'wait', timer);
  40. var returnedBet = parseFloat(jqxhr.bet);
  41. returnedBet = (isNaN(returnedBet))?0:returnedBet;
  42. if (jqxhr.gametype != 'practice' && bet != 0){
  43. updateBalance(returnedBet * -1);
  44. }
  45. _this.betNumber = parseInt(jqxhr.betNumber);
  46. _this.game_hash = jqxhr.game_hash;
  47. _this.bet = jqxhr.bet;
  48. _this.stake = jqxhr.stake;
  49. _this.next = jqxhr.next;
  50. _this.id = jqxhr.id;
  51. _this.jqel = $game_html.clone();
  52. if (jqxhr.gametype == 'practice'){
  53. _this.jqel.addClass('practice_game');
  54. }
  55. // Mark tiles that have already been guessed
  56. if (typeof jqxhr.guesses !== 'undefined' && jqxhr.guesses != null){
  57. var guesses_ar = jqxhr.guesses.split('-');
  58. for(var i=0; i<guesses_ar.length; i++){
  59. _this.jqel.find('li[data-tile="'+guesses_ar[i]+'"]').addClass('pressed').html('<i class="icon-check"></i>');
  60. }
  61. }
  62. _this.changed_stake_recently = false;
  63. _this.jqel.attr('id', 'game_'+_this.game_hash).find('#stake').text('฿'+parseFloat(_this.stake).toFixed(6));
  64. _this.jqel.find('#next').text('฿'+parseFloat(_this.next).toFixed(6));
  65. _this.jqel.hide().addClass('hidegame').css('visibility','hidden').prependTo('.feed').slideDown(300, function(){
  66. $(this).hide().css('visibility','visible').removeClass('hidegame').show();//.fadeIn(400,function(){
  67. // Game is now available in the DOM as jqel.
  68. //$(this).removeClass('hidegame');
  69. _this.jqel.find('.cashout').click(function(e){
  70. e.preventDefault();
  71. if (!busy){
  72. _this.cashout();
  73. }
  74. });
  75. _this.jqel.find('.board li').click(function(e){
  76. e.preventDefault();
  77. if (!busy){
  78. var $tile = $(this);
  79. _this.guess($tile);
  80. }
  81. });
  82. $(this).bind('mouseover', function(){
  83. $('.feed div.game').addClass('faded');
  84. _this.jqel.removeClass('faded');
  85. });
  86. _this.message('A game for ฿'+jqxhr.bet+' has started. Secret hash: <span class="secret_hash">'+jqxhr.secret+'</span>', 'first');
  87. //}).removeClass('hidegame');
  88. });
  89. } else if (jqxhr.status == 'error'){
  90. show_error(jqxhr.message);
  91. }
  92. }).fail(function(){
  93. //alert('jqxhr failed');
  94. show_error('This game could not be retrieved at this time.');
  95. }).always(function(){
  96. setTimeout(function(){
  97. $('#start_game').removeAttr('disabled').spin(false);
  98. }, 500);
  99. });;
  100. // end ajax
  101. }
  102. Game.prototype.message = function(message, msgtype){
  103. //msgtype = (typeof msgtype==='undefined')?'':msgtype;
  104. if(message.length < 1){
  105. return true;
  106. }
  107. var $el = $('<p>'+message+'</p>');
  108. if (arguments.length > 1){
  109. for (var i = 1, len = arguments.length; i<=len; i++){
  110. $el.addClass(arguments[i]);
  111. }
  112. }
  113. $el.hide().prependTo(this.jqel.find('.messages')).slideDown(200);
  114. }
  115. Game.prototype.cashout = function(){
  116. var timer = 0;
  117. var timer_int = setInterval(function(){
  118. timer++;
  119. }, 100);
  120. var _this = this;
  121. _this.jqel.find('button.cashout').attr('disabled','disabled').spin(spin_opts);
  122. $.ajax({
  123. url: webroot+'action/cashout.php',
  124. // terribly insecure. Fix later
  125. data: 'game_hash='+_this.game_hash,
  126. type: 'POST',
  127. dataType: 'json'
  128. }).done(function(jqxhr){
  129. clearInterval(timer_int);
  130. if (jqxhr.status == 'success'){
  131. ga('send', 'event', 'game', 'cashout', 'wait', timer);
  132. updateBalance(parseFloat(jqxhr.win));
  133. _this.jqel.find('.inplay p').html('Won: <span>฿'+jqxhr.win+'</span>');
  134. _this.jqel.find('.cashout').hide();
  135. _this.message(jqxhr.message, 'won');
  136. _this.message('Secret: '+jqxhr.mines+'-'+jqxhr.random_string);
  137. var mines = jqxhr.mines.split('-');
  138. for (i=0; i<mines.length; i++){
  139. _this.jqel.find('li[data-tile="'+mines[i]+'"]').addClass('reveal').html('<i class="icon-alert"></i>');
  140. }
  141. } else if (jqxhr.status == 'error'){
  142. _this.message(jqxhr.message,'error');
  143. }
  144. }).fail(function(){
  145. alert('jqxhr failed');
  146. //$('<li class="error" style="display:none;">This guess could not be completed at this time.</li>').prependTo('.history').slideDown();
  147. }).always(function(){
  148. _this.jqel.find('button.cashout').removeAttr('disabled').spin(false);
  149. });
  150. // end ajax
  151. }
  152. Game.prototype.guess = function($tile){
  153. var timer = 0;
  154. var timer_int = setInterval(function(){
  155. timer++;
  156. }, 100);
  157. var _this = this;
  158. var tile_number = parseInt($tile.attr('data-tile'));
  159. if (tile_number > 0 && tile_number < 26){
  160. var opts = {
  161. lines: 13,
  162. length: 2,
  163. width: 2,
  164. radius: 6,
  165. corners: 1,
  166. rotate: 0,
  167. direction: 1,
  168. color: '#000'
  169. };
  170. $tile.spin(opts);
  171. $tile.addClass('active_tile');
  172. busy = true;
  173. $.ajax({
  174. url: webroot+'action/checkboard.php',
  175. data: 'game_hash='+_this.game_hash+'&guess='+tile_number+'&v04=1',
  176. type: 'POST',
  177. dataType: 'json'
  178. }).done(function(jqxhr){
  179. busy = false;
  180. clearInterval(timer_int);
  181. $tile.spin(false);
  182. $tile.removeClass('active_tile');
  183. _this.betNumber++;
  184. if (jqxhr.status == 'success'){
  185. ga('send', 'event', 'game', 'guess', 'wait', timer);
  186. if (jqxhr.outcome == 'bitcoins'){
  187. _this.change_stake(jqxhr.stake);
  188. _this.jqel.find('#next').html('฿'+jqxhr.next.toFixed(6));
  189. _this.message(jqxhr.message, 'find');
  190. _this.jqel.find('li[data-tile="'+jqxhr.guess+'"]').addClass('pressed').html('<i class="icon-check"></i>');
  191. }
  192. if (jqxhr.outcome == 'bomb'){
  193. _this.message(jqxhr.message, 'bomb');
  194. _this.jqel.find('li[data-tile="'+jqxhr.guess+'"]').addClass('pressed bomb').html('<i class="icon-alert"></i>');
  195. _this.message('Secret: '+jqxhr.bombs+'-'+jqxhr.random_string);
  196. _this.change_stake(0);
  197. _this.jqel.find('.cashout').hide();
  198. var bombs = jqxhr.bombs.split('-');
  199. for (i=0; i<bombs.length; i++){
  200. _this.jqel.find('li[data-tile="'+bombs[i]+'"]').addClass('reveal').html('<i class="icon-alert"></i>');
  201. }
  202. if (sound_enabled){
  203. lose.play();
  204. }
  205. }
  206. } else if (jqxhr.status == 'error'){
  207. //$('<li class="error" style="display:none;">'+jqxhr.message+'</li>').prependTo('.history').slideDown();
  208. _this.message(jqxhr.message, 'error');
  209. }
  210. }).fail(function(){
  211. $tile.removeClass('active_tile').spin(false);
  212. this.message('There was a problem making that guess.', 'error');
  213. //$('<li class="error" style="display:none;">This guess could not be completed at this time.</li>').prependTo('.history').slideDown();
  214. });
  215. } else {
  216. //alert("Hey, wait a minute!");
  217. this.message('Hey, wait a minute.');
  218. }
  219. }
  220. Game.prototype.change_stake = function(stake){
  221. // Set that the bank has been changed recently
  222. // and change it back after 5 seconds
  223. var _this = this;
  224. this.changed_stake_recently = true;
  225. var current_stake = parseFloat($('#stake').text().substr(1));
  226. if (stake > current_stake){
  227. // winnings going UP
  228. _this.animate_stake(current_stake, stake);
  229. } else {
  230. $('#stake').html('฿'+stake.toFixed(6));
  231. }
  232. setTimeout(function(){
  233. _this.changed_stake_recently = false;
  234. }, 5000);
  235. }
  236. Game.prototype.animate_stake = function(old_stake, new_stake){
  237. var _this = this;
  238. if (!old_stake || !new_stake){
  239. return false;
  240. }
  241. var difference = new_stake - old_stake;
  242. //var steps = 0.0001;
  243. var steps = difference / 20;
  244. var current_stake = old_stake;
  245. if (sound_enabled){
  246. win.play();
  247. }
  248. for (var i=0; i<20; i++){
  249. setTimeout(function(){
  250. current_stake += steps;
  251. _this.jqel.find('#stake').html('฿'+current_stake.toFixed(6));
  252. }, 40*i);
  253. }
  254. setTimeout(function(){
  255. _this.jqel.find('#stake').html('฿'+new_stake.toFixed(6));
  256. }, 800);
  257. }
  258. /* Misc functions */
  259. function updateBalance(change){
  260. var currentBalance = parseFloat($('.player .balance .val').text().substr(1));
  261. document.title = '฿'+(currentBalance+change).toFixed(6)+' - Satoshi Mines';
  262. $('.player .balance .val').text('฿'+(currentBalance+change).toFixed(6));
  263. if (currentBalance + change > 0){
  264. $('#cashout_balance').removeClass('disabled');
  265. } else {
  266. $('#cashout_balance').addClass('disabled');
  267. }
  268. }
  269. function show_error(message){
  270. $('<p class="player_error">'+message+'</p>').hide().prependTo('.feed').slideDown(200);
  271. }
  272. function show_success(message){
  273. $('<p class="player_success">'+message+'</p>').hide().prependTo('.feed').slideDown(200);
  274. }
  275. function clean_feed(){
  276. $('.feed>*').not($('.feed>*').slice(0,19)).remove();
  277. }
  278. $(document).ready(function(){
  279. if (document.addEventListener){
  280. document.addEventListener("touchstart", function() {},false);
  281. }
  282. /* Navigation */
  283. $('.nav .links a').click(function(e){
  284. e.preventDefault();
  285. $('.nav .links li').removeClass('selected');
  286. $(this).parent().addClass('selected');
  287. $.ajax({
  288. url: $(this).attr('href'),
  289. type: 'GET',
  290. dataType: 'html',
  291. cache: false
  292. }).done(function(jqxhr){
  293. $('.sub .sub_content').html(jqxhr).parent().slideDown(300);
  294. $('.sub .sub_content form').submit(function(e){
  295. var $button = $(this).find('button');
  296. $button.attr('disabled', 'disabled').spin(spin_opts);
  297. e.preventDefault();
  298. $.ajax({
  299. url: $(this).attr('action'),
  300. type: $(this).attr('method'),
  301. dataType: 'html',
  302. cache: false,
  303. data: $(this).serialize()
  304. }).done(function(form_result){
  305. if(form_result.indexOf('_green') > -1) {
  306. $('.sub .sub_content form').slideUp(400);
  307. $(''+form_result).hide().prependTo('.sub .sub_content .form-container').slideDown(400);
  308. } else {
  309. $(''+form_result).hide().prependTo('.sub .sub_content .form-container form').slideDown(400);
  310. }
  311. }).fail(function(){
  312. $('<p class="player_error">An unknown error occued.</p>').hide().prependTo('.sub .sub_content .form-container').slideDown(400);
  313. }).always(function(){
  314. $button.removeAttr('disabled').spin(false);
  315. });
  316. });
  317. });
  318. });
  319. $('.sub_close').click(function(e){
  320. e.preventDefault();
  321. $(this).parent().slideUp(300, function(){
  322. $(this).find('.sub_content').html('');
  323. $('.nav .links li').removeClass('selected');
  324. });
  325. });
  326. $('.sound').click(function(e){
  327. e.preventDefault();
  328. if(sound_enabled){
  329. $(this).attr('class', 'sound sound_disabled').find('i').attr('class', 'icon-volume-off');
  330. sound_enabled = false;
  331. } else {
  332. $(this).attr('class', 'sound sound_enabled').find('i').attr('class', 'icon-volume-on');
  333. sound_enabled = true;
  334. }
  335. });
  336. /* Game bar */
  337. $('.player_container').waypoint('sticky');
  338. /* QR Code and name */
  339. $('#player_name').blur(function(e){
  340. e.preventDefault();
  341. var player_name = $(this).val();
  342. $.ajax({
  343. url: webroot+'action/nameplayer.php',
  344. data: 'secret='+playerhash+'&player_name='+player_name,
  345. type: 'POST',
  346. dataType: 'json'
  347. }).done(function(jqxhr){
  348. if (jqxhr.status == 'error'){
  349. show_error(jqxhr.message);
  350. }
  351. }).fail(function(){
  352. show_error('There was a problem updating your player name. Please contact the admin if this keeps happening.');
  353. });
  354. });
  355. $('.qrcode').click(function(e){
  356. e.preventDefault();
  357. if ($(this).parent().find('img').length > 0){
  358. $(this).parent().find('div').show();
  359. } else {
  360. $qrimg = $('<div><img width="200" height="200" src="https://blockchain.info/qr?data='+($(this).parent().attr('data-qr'))+'&size=200"><button>close</button></div>');
  361. $qrimg.find('button').click(function(){
  362. $(this).parent().hide();
  363. });
  364. $(this).parent().prepend($qrimg);
  365. }
  366. });
  367. /* New game controls */
  368. var presentHandler = function(e){
  369. e.preventDefault();
  370. if ($(this).hasClass('button_zero')){
  371. consecutive_zeros++;
  372. console.log(consecutive_zeros);
  373. } else {
  374. consecutive_zeros = 0;
  375. }
  376. var player_balance = parseFloat($('.player .balance .val').text().substr(1));
  377. var currentBalance = parseFloat($('.player .bet').val());
  378. if (isNaN(currentBalance)){
  379. currentBalance = 0;
  380. }
  381. if ($(this).text().substr(0, 1) == '+'){
  382. var newval = parseFloat($(this).text());
  383. newval = (newval+currentBalance).toFixed(4);
  384. } else if ($(this).text().substr(0, 1) == '-'){
  385. var newval = parseFloat($(this).text());
  386. newval = (currentBalance+newval).toFixed(4);
  387. } else if ($(this).text() == 'MAX'){
  388. var newval = maxbet;
  389. } else if ($(this).text() == 'MIN'){
  390. var newval = minbet;
  391. } else {
  392. var newval = parseFloat($(this).text()).toFixed(4);
  393. }
  394. if (newval == maxbet && newval > player_balance && player_balance > 0){
  395. newval = player_balance;
  396. }
  397. $('.bet').val(parseFloat(newval));
  398. if (consecutive_zeros >= 5){
  399. edit_presets();
  400. }
  401. }
  402. $('.bets button').bind('click', presentHandler);
  403. $('#start_game').click(function(){
  404. //var bet = parseFloat($('#bet').val(), 10);
  405. //bet = (isNaN(bet))?0:bet;
  406. $(this).attr('disabled', 'disabled').spin(spin_opts);
  407. var bet = $('#bet').val();
  408. var num_mines = $('input[name="num_mines"]:checked').val();
  409. games.push(new Game(bet, undefined, num_mines));
  410. });
  411. /* Edit the preset buttons */
  412. function edit_presets() {
  413. //return false;
  414. consecutive_zeros = 0;
  415. $('ul.bets li').not(':first').each(function(){
  416. $(this).append('<input type="text" value="'+$(this).find('button').text()+'" maxlength="7">').find('button').hide();
  417. });
  418. $('ul.bets li:first button').text('Done').unbind('click').click(function(){
  419. consecutive_zeros = 0;
  420. $('ul.bets li').not(':first').each(function(){
  421. $(this).find('button').text($(this).find('input').val()).show();
  422. $(this).find('button').removeClass('button_plus button_minus');
  423. if ($(this).find('input').val().substr(0,1) == '+'){
  424. $(this).find('button').addClass('button_plus');
  425. } else if ($(this).find('input').val().substr(0,1) == '-'){
  426. $(this).find('button').addClass('button_minus');
  427. }
  428. $(this).find('input').remove();
  429. //$(this).hide();
  430. });
  431. $(this).text('0').unbind('click').bind('click', presentHandler);
  432. //$(this).unbind('click');
  433. });
  434. }
  435. /* Money */
  436. $('#refresh_balance').click(function(e){
  437. e.preventDefault();
  438. $this = $(this);
  439. $this.parent().siblings('.val').addClass('disabled').spin(spin_opts);
  440. busy = true;
  441. $.ajax({
  442. url: webroot+'action/refresh_balance.php',
  443. data: 'secret='+playerhash,
  444. type: 'POST',
  445. dataType: 'json'
  446. }).done(function(jqxhr){
  447. busy = false;
  448. $this.parent().siblings('.val').removeClass('disabled').spin(false);
  449. if (jqxhr.status == 'success'){
  450. document.title = '฿'+jqxhr.balance+' - Satoshi Mines';
  451. $('.player .balance .val').text('฿'+jqxhr.balance);
  452. if (jqxhr.balance > 0){
  453. $('#cashout_balance').removeClass('disabled');
  454. } else {
  455. $('#cashout_balance').addClass('disabled');
  456. }
  457. } else if (jqxhr.status == 'error'){
  458. show_error('There was a problem refreshing your balance: '+jqxhr.message);
  459. }
  460. }).fail(function(){
  461. show_error('A problem occured when trying to refresh your balance. Please try again in a minute, and then contact the admin');
  462. //$('<li class="error" style="display:none;">This guess could not be completed at this time.</li>').prependTo('.history').slideDown();
  463. });
  464. });
  465. $('#cashout_balance').click(function(e){
  466. e.preventDefault();
  467. var currentBalance = parseFloat($('.player .balance .val').text().substr(1));
  468. $('.full_cashout #amount').val(''+currentBalance);
  469. $('.full_cashout .cancel').click(function(e){
  470. e.preventDefault();
  471. $(this).parent().parent().slideUp(200);
  472. });
  473. $('.full_cashout').slideDown(200);
  474. });
  475. $('.full_cashout button').click(function(e){
  476. e.preventDefault();
  477. $this = $(this);
  478. $this.attr('disabled', 'disabled').spin(spin_opts);
  479. var payto_address = $('.full_cashout #payout_address').val();
  480. var amount = $('.full_cashout #amount').val();
  481. busy = true;
  482. $.ajax({
  483. url: webroot+'action/full_cashout.php',
  484. data: 'secret='+playerhash+'&payto_address='+payto_address+'&amount='+amount,
  485. type: 'POST',
  486. dataType: 'json'
  487. }).done(function(jqxhr){
  488. busy = false;
  489. if (jqxhr.status == 'success'){
  490. //$('.player .balance .val').text('฿0.000000');
  491. $('.player .balance .val').text('฿'+(parseFloat(jqxhr.balance)).toFixed(6));
  492. $('.full_cashout').slideUp(200);
  493. show_success(jqxhr.message);
  494. } else if (jqxhr.status == 'error'){
  495. show_error('A problem occured while trying to withdraw: '+jqxhr.message);
  496. } else {
  497. show_error('Unknown error.');
  498. }
  499. }).fail(function(){
  500. show_error('A problem occured when trying to cash out your bitcoins. Please try again in a minute, and then contact the admin');
  501. }).always(function(){
  502. $this.removeAttr('disabled').spin(false);
  503. });
  504. });
  505. });

comments powered by Disqus