Files
zulip/static/js/tictactoe_widget.js
Anders Kaseorg 28f3dfa284 js: Automatically convert var to let and const in most files.
This commit was originally automatically generated using `tools/lint
--only=eslint --fix`.  It was then modified by tabbott to contain only
changes to a set of files that are unlikely to result in significant
merge conflicts with any open pull request, excluding about 20 files.
His plan is to merge the remaining changes with more precise care,
potentially involving merging parts of conflicting pull requests
before running the `eslint --fix` operation.

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-11-03 12:42:39 -08:00

151 lines
3.7 KiB
JavaScript

const render_widgets_tictactoe_widget = require('../templates/widgets/tictactoe_widget.hbs');
const tictactoe_data_holder = function () {
const self = {};
const me = people.my_current_user_id();
const square_values = {};
let num_filled = 0;
let waiting = false;
let game_over = false;
function is_game_over() {
const lines = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[1, 4, 7],
[2, 5, 8],
[3, 6, 9],
[1, 5, 9],
[7, 5, 3],
];
function line_won(line) {
const token = square_values[line[0]];
if (!token) {
return false;
}
return (
square_values[line[1]] === token &&
square_values[line[2]] === token);
}
const board = [1, 2, 3, 4, 5, 6, 7, 8, 9];
function filled(i) {
return square_values[i];
}
return _.any(lines, line_won) || _.all(board, filled);
}
self.get_widget_data = function () {
function square(i) {
return {
val: square_values[i],
idx: i,
disabled: waiting || square_values[i] || game_over,
};
}
const squares = [
[square(1), square(2), square(3)],
[square(4), square(5), square(6)],
[square(7), square(8), square(9)],
];
const token = num_filled % 2 === 0 ? 'X' : 'O';
let move_status = token + "'s turn";
if (game_over) {
move_status = "Game over!";
}
const widget_data = {
squares: squares,
move_status: move_status,
};
return widget_data;
};
self.handle = {
square_click: {
outbound: function (idx) {
const event = {
type: 'square_click',
idx: idx,
num_filled: num_filled,
};
return event;
},
inbound: function (sender_id, data) {
const idx = data.idx;
if (data.num_filled !== num_filled) {
blueslip.info('out of sync', data.num_filled);
return;
}
const token = num_filled % 2 === 0 ? 'X' : 'O';
if (square_values[idx]) {
return;
}
waiting = sender_id === me;
square_values[idx] = token;
num_filled += 1;
game_over = is_game_over();
},
},
};
self.handle_event = function (sender_id, data) {
const type = data.type;
if (self.handle[type]) {
self.handle[type].inbound(sender_id, data);
}
};
return self;
};
exports.activate = function (opts) {
const elem = opts.elem;
const callback = opts.callback;
const tictactoe_data = tictactoe_data_holder();
function render() {
const widget_data = tictactoe_data.get_widget_data();
const html = render_widgets_tictactoe_widget(widget_data);
elem.html(html);
elem.find("button.tictactoe-square").on('click', function (e) {
e.stopPropagation();
const idx = $(e.target).attr('data-idx');
const data = tictactoe_data.handle.square_click.outbound(idx);
callback(data);
});
}
elem.handle_events = function (events) {
_.each(events, function (event) {
tictactoe_data.handle_event(event.sender_id, event.data);
});
render();
};
render();
};
window.tictactoe_widget = exports;