Skip to content

Instantly share code, notes, and snippets.

@ariporad
Created June 1, 2016 22:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ariporad/2503ee489133f599934d28832b082c34 to your computer and use it in GitHub Desktop.
Save ariporad/2503ee489133f599934d28832b082c34 to your computer and use it in GitHub Desktop.
Tweet Tac Toe
'use strict';
const Twitter = require('twitter');
const TicTacToe = require('tictactoe-agent');
const USERNAME = 'USERNAME';
const client = new Twitter({
consumer_key: 'TWITTER CONSUMER KEY',
consumer_secret: 'TWITTER CONSUMER SECRET',
access_token_key: 'TWITTER ACCESS TOKEN',
access_token_secret: 'TWITTER ACCESS SECRET',
});
const games = {};
function doMove(game, player, index) {
let model;
if (typeof index !== 'number') {
model = new TicTacToe.Model(game, player);
index = model.getRecommendation().index;
}
console.log('[DoMove]: ' + player + ' wants to move ' + index + ' with game: ' + game);
game = game.slice(0, index) + player + game.slice(index + 1);
console.log('[DoMove]: With Result: ' + game);
model = new TicTacToe.Model(game, player);
const winner = model.winnerInfo(model.lines());
if (winner) return {
game, winner: winner.winner
};
return {
game, winner: false
};
}
function handleWin(playerWon, tweet) {
if (playerWon) {
client.post('statuses/update', {
status: '@' + tweet.user.screen_name + ': You Win!!!',
in_reply_to_status_id: tweet.id,
}, tweetCallback);
} else {
client.post('statuses/update', {
status: '@' + tweet.user.screen_name + ': You Lost :(',
in_reply_to_status_id: tweet.id,
}, tweetCallback);
}
}
function gameboardToString(game) {
const spots = game.split('');
return [
spots.slice(0, 3),
spots.slice(3, 6),
spots.slice(6, 9),
].map(spots2 => spots2.join('|')).join('\n_____\n');
}
function tweetCallback(error, tweet, response) {
if (!error) {
console.log('Tweeted: ' + tweet.text);
}
}
client.stream('statuses/filter', {
track: '@test4ari'
}, stream => {
stream.on('error', err => {
throw err;
});
stream.on('data', tweet => {
console.log(tweet.text);
const parts = tweet.text.toLowerCase().split(' ');
if (parts[0].slice(0, 10) !== '@' + USERNAME) return;
switch (parts[1]) {
case 'start':
games[tweet.user.id_str] = '---------';
client.post('statuses/update', {
status: '@' + tweet.user.screen_name + ': respond with `@' + USERNAME + ': move X`. X is your move, as a num 1-9, from top left to bottom right. You move first.',
in_reply_to_status_id: tweet.id,
}, tweetCallback);
break;
case 'move':
if (!games[tweet.user.id_str]) return;
const index = parseInt(parts[2]) - 1; // Make it from 1-9 vs. 0-8
let ret = doMove(games[tweet.user.id_str], 'X', index);
if (ret.winner) {
delete games[tweet.used.id_str];
return handleWin(ret.winner === 'X', tweet);
}
ret = doMove(ret.game, 'O');
if (ret.winner) {
delete games[tweet.user.id_str];
return handleWin(ret.winner == 'X', tweet);
}
if (ret.game.indexOf('-') === -1) { // Stalemate!
client.post('statuses/update', {
status: '@' + tweet.user.screen_name + ': Stalemate!!!',
in_reply_to_status_id: tweet.id,
}, tweetCallback);
delete games[tweet.user.id];
return;
}
games[tweet.user.id_str] = ret.game;
client.post('statuses/update', {
status: '@' + tweet.user.screen_name + ': Your move. Gameboard:\n' + gameboardToString(ret.game),
in_reply_to_status_id: tweet.id,
}, tweetCallback);
break;
}
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment