rc3_2021_map/scripts/tictactoe_module.js

307 lines
11 KiB
JavaScript

export class TicTacToe {
gamestate_variable = 'gamestate';
layer_moves = 'moves';
layer_overlay = 'overlay';
layer_game = 'game';
layer_blue = 'blue';
layer_green = 'green';
layer_board = 'board';
layer_exit = 'exit';
popup = 'popup';
board_x = 4;
board_y = 3;
blue_x = 3;
blue_y = 2;
green_x = 3;
green_y = 6;
gamestate = {};
is_player = false;
on_board = false;
on_game = false;
welcome = false;
move_message;
color;
game_message;
constructor(config) {
this.gamestate_variable = config.gamestate_variable || 'gamestate';
this.layer_moves = config.layer_moves || 'moves';
this.layer_overlay = config.layer_overlay || 'overlay';
this.layer_game = config.layer_game || 'game';
this.layer_blue = config.layer_blue || 'blue';
this.layer_green = config.layer_green || 'green';
this.layer_board = config.layer_board || 'board';
this.layer_exit = config.layer_exit || 'exit';
this.popup = config.popup || 'popup';
this.board_x = config.board_x || 4;
this.board_y = config.board_y || 3;
this.blue_x = config.blue_x || 3;
this.blue_y = config.blue_y || 2;
this.green_x = config.green_x || 3;
this.green_y = config.green_y || 6;
WA.onInit().then(() => {
this.waInit();
});
}
applyGameState = function () {
this.is_player = false;
this.color = '';
if (this.gamestate.blue) {
if (this.gamestate.blue == WA.player.id) {
this.color = 'blue';
this.is_player = true;
}
WA.room.setTiles([
{ x: this.blue_x, y: this.blue_y, tile: null, layer: this.layer_blue }
]);
} else {
WA.room.setTiles([
{ x: this.blue_x, y: this.blue_y, tile: 'blue', layer: this.layer_blue }
]);
}
if (this.gamestate.green) {
if (this.gamestate.green == WA.player.id) {
this.color = 'green';
this.is_player = true;
}
WA.room.setTiles([
{ x: this.green_x, y: this.green_y, tile: null, layer: this.layer_green }
]);
} else {
WA.room.setTiles([
{ x: this.green_x, y: this.green_y, tile: 'green', layer: this.layer_green }
]);
}
for (let x = 0; x < 3; x++) {
for (let y = 0; y < 3; y++) {
let index = x + y * 3;
if (this.gamestate.board && this.gamestate.board[index]) {
if (this.gamestate.board[index] == 'blue' || this.gamestate.board[index] == 'green') {
WA.room.setTiles([
{ x: this.board_x + x, y: this.board_y + y, tile: this.gamestate.board[index], layer: this.layer_moves }
]);
}
} else {
WA.room.setTiles([
{ x: this.board_x + x, y: this.board_y + y, tile: null, layer: this.layer_moves }
]);
}
}
}
if (this.gamestate.win) {
let win_text = this.gamestate.win_name + ' wins!';
if (this.is_player) {
if (this.gamestate.win_player == WA.player.id) {
win_text = 'You win!'
} else {
win_text = 'You loose! ' + win_text;
}
this.newGame();
}
this.game_message = WA.ui.openPopup(this.popup, win_text, [{
label: 'New Game',
className: '',
callback: (popup) => {
popup.close();
}
}]);
} else if (this.gamestate.deuce) {
if (this.is_player) {
this.newGame();
}
this.game_message = WA.ui.openPopup(this.popup, 'Deuce!', [{
label: 'New Game',
className: '',
callback: (popup) => {
popup.close();
}
}]);
}
}
newGame = function () {
this.gamestate = {};
WA.state.saveVariable(this.gamestate_variable, this.gamestate);
}
waInit = function () {
this.gamestate = WA.state.loadVariable(this.gamestate_variable) || {};
this.applyGameState();
WA.state.onVariableChange(this.gamestate_variable).subscribe((value) => {
console.log("gamestate", value);
this.gamestate = value || {};
this.applyGameState();
});
WA.room.onEnterLayer(this.layer_game).subscribe(() => {
this.on_game = true;
if (!this.welcome && !this.is_player && (!this.gamestate.blue || !this.gamestate.green)) {
this.welcome = true;
let pickText = 'Pick a color to start game.';
if (this.gamestate.blue) {
pickText = 'Pick green to join game.';
} else if (this.gamestate.green) {
pickText = 'Pick blue to join game.';
}
this.game_message = WA.ui.openPopup(this.popup, pickText, [{
label: 'Ok',
className: '',
callback: (popup) => {
popup.close();
this.game_message = null;
}
}]);
}
});
WA.room.onLeaveLayer(this.layer_game).subscribe(() => {
if (this.game_message) {
this.game_message.close();
this.game_message = null;
}
})
WA.room.onEnterLayer(this.layer_exit).subscribe(() => {
if (this.is_player && this.on_game) {
this.newGame();
}
this.welcome = false;
});
WA.room.onEnterLayer(this.layer_blue).subscribe(() => {
if (!this.gamestate.green || this.gamestate.green != WA.player.id) {
this.gamestate.blue = WA.player.id;
if (this.game_message) {
this.game_message.close();
this.game_message = null;
}
if (this.gamestate.green) {
this.gamestate.current = this.gamestate.green;
}
WA.state.saveVariable(this.gamestate_variable, this.gamestate);
}
});
WA.room.onEnterLayer(this.layer_green).subscribe(() => {
if (!this.gamestate.blue || this.gamestate.blue != WA.player.id) {
this.gamestate.green = WA.player.id;
if (this.game_message) {
this.game_message.close();
this.game_message = null;
}
if (this.gamestate.blue) {
this.gamestate.current = this.gamestate.blue;
}
WA.state.saveVariable(this.gamestate_variable, this.gamestate);
}
});
WA.room.onEnterLayer(this.layer_board).subscribe(() => {
this.on_board = true;
});
WA.room.onLeaveLayer(this.layer_board).subscribe(() => {
this.on_board = false;
});
WA.player.onPlayerMove((event) => {
if (this.on_board && WA.player.id) {
for (let x = 0; x < 3; x++) {
for (let y = 0; y < 3; y++) {
WA.room.setTiles([
{ x: this.board_x + x, y: this.board_y + y, tile: null, layer: this.layer_overlay }
]);
}
}
if (!event.moving && this.on_board && this.gamestate.current == WA.player.id && !this.gamestate.win) {
const x = Math.ceil(event.x / 32) - this.board_x - 1;
const y = Math.ceil(event.y / 32) - this.board_y - 1;
const index = x + y * 3;
if (!this.gamestate.board) {
this.gamestate.board = [];
}
if (index >= 0 && index < 9 && !this.gamestate.board[index]) {
if (this.move_message) {
this.move_message.remove();
}
WA.room.setTiles([
{ x: this.board_x + (index % 3), y: this.board_y + Math.floor(index / 3), tile: this.color + '_overlay', layer: this.layer_overlay }
]);
this.move_message = WA.ui.displayActionMessage({
message: 'Press SPACE or touch here to place move',
callback: () => {
this.gamestate.board[index] = this.color;
if (this.color == 'blue') {
this.gamestate.current = this.gamestate.green;
} else if (this.color == 'green') {
this.gamestate.current = this.gamestate.blue;
}
var wins = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]]
let win_move = false;
for (var i = 0; i < wins.length; i++) {
let win = wins[i];
let matches = 0;
for (var j = 0; j < win.length; j++) {
if (this.gamestate.board[win[j]] === this.color) {
matches++
}
}
if (matches == 3) {
win_move = true;
break;
}
}
if (win_move) {
this.gamestate.win = true;
this.gamestate.win_player = WA.player.id;
this.gamestate.win_name = WA.player.name;
this.gamestate.win_color = this.color;
}
if (!this.gamestate.win) {
let moves = 0;
for (let i = 0; i < 9; i++) {
if (this.gamestate.board[i]) {
moves++;
}
}
if (moves == 9) {
this.gamestate.deuce = true;
}
}
WA.state.saveVariable(this.gamestate_variable, this.gamestate);
}
});
}
} else if (this.move_message) {
this.move_message.remove();
}
}
});
}
}