Permalink
Browse files

Refactor struct, cli

  • Loading branch information...
Anatoliy Chakkaev
Anatoliy Chakkaev committed Nov 19, 2010
1 parent 49a3c53 commit bf50a84baad17bd97bb3256dbc14e22c7b5e9196
View
4 app.js
@@ -16,7 +16,7 @@ var session_key = 'connect.sidw';
app.configure(function(){
app.use(express.staticProvider(__dirname + '/public'));
- app.set('views', __dirname + '/views');
+ app.set('views', __dirname + '/app/views');
app.use(express.cookieDecoder());
app.use(express.session({ store: store, key: session_key }));
app.use(facebooker.connect);
@@ -36,7 +36,7 @@ app.configure('production', function(){
// Controller
-var c = require('./lib/controller.js');
+var c = require('./app/controller.js');
// Routes
@@ -1,4 +1,4 @@
-var m = require('./models.js');
+var m = require('../lib/models.js');
module.exports = {
loadUser: function (req, res, next) {
@@ -27,12 +27,13 @@ module.exports = {
},
index: function (req, res) {
console.log(req.just_connected ? 'just connected' : 'not just connected');
- res.render('index.jade', { locals: {
- title: 'Reversi game',
- player: req.player,
- user: req.session.fb.user,
- opponent: {id: 1, name: 'name'},
- secret: req.cookies['connect.sidw']
+ res.render('index.jade', { locals:
+ { title: 'Reversi game'
+ , player: req.player
+ , user: req.session.fb.user
+ , opponent: req.player.game.cached_opponent
+ , starter: req.player.game.cached_starter
+ , secret: req.cookies['connect.sidw']
}
});
},
View
@@ -0,0 +1,137 @@
+/**
+ * Class Game
+ **/
+function Game() { };
+
+Game.attributes =
+{ type: 'string'
+, color: 'string'
+, position: 'string'
+, starter: 'player'
+, cached_starter: 'json'
+, opponent: 'player'
+, cached_opponent: 'json'
+};
+
+/**
+ * Static class methods
+ **/
+
+Game.find_free_or_create = function (params, callback) {
+
+ function create_game() {
+ exports.Game.create(params, function () {
+ callback.apply(this);
+ });
+ }
+
+ this.connection.rpop('wait:' + params.type, function (err, value) {
+ if (value) {
+ exports.Game.find(value, function (err) {
+ if (err) {
+ create_game();
+ } else {
+ callback.apply(this);
+ }
+ });
+ } else {
+ create_game();
+ }
+ });
+};
+
+/**
+ * Instance methods
+ **/
+Game.prototype = {
+ initialize: function () {
+ if (this.type) {
+ var game = require('../../lib/games/' + this.type);
+ if (!this.color) {
+ this.color = 'b';
+ }
+ this.game = new game.createGame(this);
+ }
+ },
+ join: function (player, callback) {
+ var self = this;
+ if (this.starter) {
+ console.log('Клиент ' + player.id + ' присоединяется к игре вторым');
+ self.set_opponent(player, function () {
+ player.update_attribute('color', 'w', callback);
+ console.log('Уведомляем ожидающего клиента ' + self.starter + ' что началась игра: ');
+ self.connection.publish('player:' + self.starter + ':channel',
+ JSON.stringify({
+ action: 'opponent_connected',
+ user: this.cached_opponent
+ })
+ );
+ });
+ } else {
+ // push game to waiting queue
+ self.connection.lpush('wait:' + this.type, this.id);
+ self.set_starter(player, function () {
+ player.update_attribute('color', 'b', callback);
+ });
+ }
+ },
+ set_starter: function (player, callback) {
+ this.generic_user_setter('starter', player, callback);
+ },
+ set_opponent: function (player, callback) {
+ this.generic_user_setter('opponent', player, callback);
+ },
+ generic_user_setter: function (role, player, callback) {
+ var self = this;
+ self.update_attribute(role, player.id, function () {
+ player.get('user', function (user) {
+ self.update_attribute('cached_' + role, user.public_params(), function () {
+ callback.call(self);
+ });
+ });
+ });
+ },
+ state: function (player) {
+ if (!this.opponent) return 'wait_opponent';
+ if (this.game.board.terminal_board) return 'end_game';
+ if (this.color == player.color) {
+ return 'move';
+ } else {
+ return 'wait';
+ }
+ },
+ boardToJSON: function () {
+ return JSON.stringify(this.game.board.position);
+ },
+ move: function (player, coords, callback) {
+ var game = this;
+ var pwned = game.game.pwned_by();
+ if (this.game.move(coords)) {
+ this.position = this.boardToJSON();
+ this.color = this.game.pwned_by();
+ this.save(function () {
+ game.connection.publish('player:' +
+ (
+ pwned != player.color ?
+ player.id :
+ (
+ player.id == game.opponent ?
+ game.starter :
+ game.opponent
+ )
+ ) + ':channel', JSON.stringify({
+ action: 'move',
+ coords: coords
+ })
+ );
+ if (game.game.board.terminal_board) {
+ var response = JSON.stringify({action: 'end', info: game.game.board.board_stats});
+ game.connection.publish('player:' + this.opponent + ':channel', response);
+ game.connection.publish('player:' + this.starter + ':channel', response);
+ }
+ });
+ }
+ }
+};
+
+exports.Game = Game;
View
@@ -0,0 +1,67 @@
+function Player() {
+};
+Player.attributes = {
+ game_id: 'int',
+ color: 'string',
+ user: 'user'
+};
+
+Player.prototype = {
+ connect: function (socket) {
+ var player = this;
+ player.pubsub_client = exports.Player.redis.createClient();
+ player.channel = 'player:' + player.id + ':channel';
+ console.log('client #', player.id, 'subscribed to channel', this.channel);
+ player.pubsub_client.subscribeTo(player.channel, function (channel, message) {
+ console.log('publish to channel', player.channel, 'detected by subscriber', player.id);
+ socket.send(message.toString());
+ });
+ },
+ disconnect: function () {
+ console.log('free channel', this.channel);
+ this.pubsub_client.unsubscribeFrom(this.channel);
+ console.log('close connection to database');
+ this.pubsub_client.close();
+ },
+ perform: function (message) {
+ console.log('player', this.id, 'perform');
+ var player = this;
+ switch (message.action) {
+ case 'move':
+ this.game.reload(function () {
+ this.move(player, message.coords);
+ });
+ break;
+ default:
+ console.log(message);
+ break;
+ }
+ },
+ loadGame: function loadGame(type, callback) {
+ var user = this;
+ if (this.game_id) {
+ exports.Game.find(this.game_id, function () {
+ user.game = this;
+ if (this.game.board.terminal_board) {
+ user.update_attribute('game_id', 0, function () {
+ user.loadGame(type, callback);
+ });
+ } else {
+ callback();
+ }
+ });
+ } else {
+ exports.Game.find_free_or_create({type: type}, function () {
+ user.join(this, callback);
+ });
+ }
+ },
+ join: function (game, callback) {
+ this.update_attribute('game_id', game.id, function () {
+ this.game = game;
+ game.join(this, callback);
+ });
+ }
+};
+
+exports.Player = Player;
View
@@ -0,0 +1,16 @@
+function User() {
+
+};
+
+User.attributes = {
+ info: 'json'
+};
+
+User.prototype.public_params = function () {
+ return {
+ id: this.id,
+ name: this.info.name
+ };
+};
+
+exports.User = User;
View
@@ -0,0 +1,32 @@
+:javascript
+ | var BOARD = {
+ | player: '#{player.color}',
+ | color: '#{player.game.color || 'b'}',
+ | state: '#{player.game.state(player)}',
+ | position: #{player.game.boardToJSON()},
+ | secret: '#{secret}'
+ | };
+
+//script( src: 'http://cdn.socket.io/stable/socket.io.js' )
+script( src: 'socket.io.js' )
+script( src: 'jquery.js?' + (new Date).getTime())
+script( src: 'reversi.js?' + (new Date).getTime())
+script( src: 'reversi-cli.js?' + (new Date).getTime())
+
+#starter.user_bar( style: starter ? '' : 'display:none' )
+ .avatar
+ img( src: 'https://graph.facebook.com/' + starter.id + '/picture?type=large')
+ small.username
+ #{starter.name}
+ .color.black black
+
+#board
+ .info
+ canvas( width: '300', height: '300' )
+
+#opponent_info.user_bar( style: opponent ? '' : 'display:none' )
+ .avatar
+ img( src: 'https://graph.facebook.com/' + (opponent ? opponent.id : 1) + '/picture?type=large')
+ small.username
+ #{opponent ? opponent.name : ''}
+ .color.white white
File renamed without changes.
View
@@ -1,4 +1,3 @@
-console.log(exports);
var m = require('./models.js');
function top_redirect_to(url, res) {
Oops, something went wrong.

0 comments on commit bf50a84

Please sign in to comment.