From 631feab417813ab53ae20a001a57cdf575cf2a91 Mon Sep 17 00:00:00 2001 From: Uno Polak Date: Sun, 5 Jan 2014 12:03:03 -0600 Subject: [PATCH] Added a working betting system, splits the pool amongst winners weighted by their contribution (always at least one more). --- lib/currency.js | 152 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 123 insertions(+), 29 deletions(-) diff --git a/lib/currency.js b/lib/currency.js index 16c06f4..6c8570e 100644 --- a/lib/currency.js +++ b/lib/currency.js @@ -120,6 +120,7 @@ function Currency(irc, db, options) { __self.bets_board = []; __self.bets_viewers = []; __self.bets_payout = false; + __self.bets_total = 0; } //-------- Methods --------- @@ -211,8 +212,11 @@ Currency.prototype.commands = function (data) { case 'close': __self.bets(false, null); break; + case 'pool': + __self.bets('pool', null); + break; case 'winner': - //__self.bets('winner'); + __self.bets('winner', data[6]); break; } } @@ -346,7 +350,7 @@ Currency.prototype.commands = function (data) { // place a bet if (__self.bets_status === true) { for (var i = 0; i < __self.bets_board.length; i++) { - if (data[3].slice(1) === '!' + __self.bets_board[i]) { + if (data[3].slice(1) === '!' + __self.bets_board[i].name) { if (isNaN(parseInt(data[4], 10)) === false) { if (data[4] >= 0 && data[4] % 1 === 0) { __self.collect_bets(__self.irc.caller(data[0]), __self.bets_board[i], parseInt(data[4], 10)); @@ -1261,16 +1265,20 @@ Currency.prototype.bets = function(status, data) { // clear previous board / bets __self.bets_board = []; __self.bets_viewers = []; + __self.bets_total = 0; // create new betting board - __self.bets_board = data.join().split(',').filter(function(n){return n}).slice(6); + __self.bets_board = data.join().split(',').filter(function(n){return n}).slice(6).map(function(n){return {name: n, num: 0, total: 0};}); + for (var i = 0; i < __self.bets_board.length; i++) { + __self.bets_board[i].idx = i; + } // create chat message on how to place a bet for (var i = 0; i < __self.bets_board.length; i++) { if (i !== __self.bets_board.length - 1) { - wager_msg += '"!' + __self.bets_board[i] + '" / '; + wager_msg += '"!' + __self.bets_board[i].name + '" / '; } else { - wager_msg += '"!' + __self.bets_board[i] + '"'; + wager_msg += '"!' + __self.bets_board[i].name + '"'; } } @@ -1300,20 +1308,49 @@ Currency.prototype.bets = function(status, data) { // close out bets __self.bets_status = false; + // deduct bets from viewers amounts + __self.bets_deduct_bets(); + // output to chat if (__self.bets_viewers.length > 0) { __self.irc.emit('message', {message:__self.pre_text + 'Betting is now closed'}); + for (var i = 0; i < __self.bets_board.length; i++) { + __self.irc.emit('message', {message:'+ ' + __self.bets_board[i].name + ' with ' + __self.bets_board[i].num + ' bets totaling ' + __self.bets_board[i].total}); + } } else { __self.irc.emit('message', {message:__self.pre_text + 'Betting closed, no bets were placed'}); } - - // deduct bets from viewers amounts - __self.bets_deduct_bets(); + } + break; + case 'pool': + if (__self.bets_board.length > 0) { + __self.irc.emit('message', {message:__self.pre_text + 'Current betting pool is:'}); + for (var i = 0; i < __self.bets_board.length; i++) { + __self.irc.emit('message', {message:'+ ' + __self.bets_board[i].name + ' with ' + __self.bets_board[i].num + ' bets totaling ' + __self.bets_board[i].total}); + } + } else { + __self.irc.emit('message', {message:__self.pre_text + 'No current bet.'}); } break; case 'winner': - // set payout to complete - __self.bets_payout = false; + if (!__self.bets_status) { + if (__self.bets_payout) { + for (var i = 0; i < __self.bets_board.length; i++) { + if (data == __self.bets_board[i].name) { + __self.bets_award_winner(__self.bets_board[i]); + __self.irc.emit('message', {message:__self.pre_text + 'Betting payed out to ' + data}); + } + } + // Clear the board + __self.bets_board = []; + __self.bets_viewers = []; + __self.bets_total = 0; + } else { + __self.irc.emit('message', {message:__self.pre_text + 'Betting has already payed out'}); + } + } else { + __self.irc.emit('message', {message:__self.pre_text + 'Betting must be closed before you can have a winner'}); + } break; } }; @@ -1321,34 +1358,91 @@ Currency.prototype.bets = function(status, data) { Currency.prototype.collect_bets = function (caller, bet, amount) { var __self = this, has_bet = false; - if (__self.bets_viewers.length > 0) { - for (var i = 0; i < __self.bets_viewers.length; i++) { - if (__self.bets_viewers[i].viewer === caller) { - has_bet = true; - if (amount >= 1) { - __self.bets_viewers[i].bet = bet; - __self.bets_viewers[i].amount = amount; - } else if (amount === 0 && bet === __self.bets_viewers[i].bet) { - __self.bets_viewers.splice(i, 1); + // Bound amount by positive currency + __self.query_coins(caller, function (rows) { + for (var i = 0; i < rows.length; i++) { + amount = Math.min(amount, rows[i].points); + } + if (__self.bets_viewers.length > 0) { + for (var i = 0; i < __self.bets_viewers.length; i++) { + if (__self.bets_viewers[i].viewer === caller) { + has_bet = true; + if (amount >= 1) { + __self.bets_board[__self.bets_viewers[i].bet].num -= 1; + __self.bets_board[__self.bets_viewers[i].bet].total -= __self.bets_viewers[i].amount; + __self.bets_viewers[i].bet = bet.idx; + __self.bets_viewers[i].amount = amount; + __self.bets_board[bet.idx].num += 1; + __self.bets_board[bet.idx].total += amount; + } else { + __self.bets_board[__self.bets_viewers[i].bet].num -= 1; + __self.bets_board[__self.bets_viewers[i].bet].total -= __self.bets_viewers[i].amount; + __self.bets_viewers.splice(i, 1); + } + break; + } + } + if (!has_bet && amount >= 1 && amount !== 0) { + __self.bets_viewers.push({viewer: caller, bet: bet.idx, amount: amount}); + __self.bets_board[bet.idx].num += 1; + __self.bets_board[bet.idx].total += amount; + } + } else { + if (amount >= 1 && amount !== 0) { + __self.bets_viewers.push({viewer: caller, bet: bet.idx, amount: amount}); + __self.bets_board[bet.idx].num += 1; + __self.bets_board[bet.idx].total += amount; } - break; } + console.log(__self.bets_viewers); + }); +}; + +Currency.prototype.bets_deduct_bets = function () { + var __self = this; + + if (__self.bets_viewers.length > 0) { + // Don't trust the on-the-fly numbers + for (var i = 0; i < __self.bets_board.length; i++) { + __self.bets_board[i].num = 0; + __self.bets_board[i].total = 0; } - if (!has_bet && amount >= 1 && amount !== 0) { - __self.bets_viewers.push({viewer: caller, bet: bet, amount: amount}); - } - } else { - if (amount >= 1 && amount !== 0) { - __self.bets_viewers.push({viewer: caller, bet: bet, amount: amount}); + __self.bets_total = 0; + // Remove the points and add them to an escrow + for (var i = 0; i < __self.bets_viewers.length; i++) { + sql = ''; + sql += 'UPDATE viewers '; + sql += 'SET points = points - ' + __self.bets_viewers[i].amount + ' '; + sql += 'WHERE user = \'' + __self.bets_viewers[i].viewer + '\''; + __self.db.execute(sql, function() {}); + __self.bets_board[__self.bets_viewers[i].bet].num += 1; + __self.bets_board[__self.bets_viewers[i].bet].total += __self.bets_viewers[i].amount; + __self.bets_total += __self.bets_viewers[i].amount; } } - console.log(__self.bets_viewers); }; -Currency.prototype.bets_deduct_bets = function () { +Currency.prototype.bets_award_winner = function (winner) { + var __self = this; + if (__self.bets_payout) { + // set payout to complete + __self.bets_payout = false; + } + // Remove the points and add them to an escrow + if (__self.bets_viewers.length > 0) { + for (var i = 0; i < __self.bets_viewers.length; i++) { + if (__self.bets_viewers[i].bet == winner.idx) { + sql = ''; + sql += 'UPDATE viewers '; + sql += 'SET points = points + ' + Math.ceil(__self.bets_total * __self.bets_viewers[i].amount / __self.bets_board[__self.bets_viewers[i].bet].total) + ' '; + sql += 'WHERE user = \'' + __self.bets_viewers[i].viewer + '\''; + __self.db.execute(sql, function() {}); + } + } + } }; module.exports = function (irc, db, options) { return new Currency(irc, db, options); -}; \ No newline at end of file +};