ultimate_tictactoe/game_manager.js

317 lines
8.5 KiB
JavaScript

class GameManager
{
constructor(grid, game_server_connection)
{
this.grid = grid;
this.dummy_player = new Player("test_player", 0,255,0);
this.local_player_a = new Player("red player", 255,0,0);
this.local_player_b = new Player("green player", 0,255,0);
this.is_local_player_a = false;
this.remote_player = new Player("you", 0,255,0);
this.remote_opponent = new Player("remote player", 255,0,0);
this.remote_is_local_turn = false;
this.grid.player_change_listener(this.dummy_player);
// possible modes:
// -- none
// -- local
// -- remote
this.game_mode = "none";
this.use_notification = false;
this.game_server_connection = game_server_connection;
game_server_connection.set_game_manager(this);
this.grid.register_click_callback((i,j,k,l) => this.click_listener(i,j,k,l));
}
click_listener(sub_x, sub_y, x,y)
{
if (this.game_mode == "local")
{
// check whether the game is over:
if (grid.is_won())
{
this.status_change_listener("" + grid.get_won_player().get_name() + " has won.", "Game Over")
this.end_game();
}
else if (grid.is_complete())
{
this.status_change_listener("Draw. Everybody looses!", "Game Over");
this.end_game();
}
else
{
this.toggle_local_player();
this.grid.block_all()
this.grid.subgrids[y][x].unblock();
if (this.grid.subgrids[y][x].is_draw() || this.grid.subgrids[y][x].is_won())
{
this.grid.unblock_all();
}
}
}
else if(this.game_mode == "remote")
{
this.grid.block_all();
if (this.remote_is_local_turn)
{
this.game_server_connection.send_move(sub_x, sub_y, x, y);
}
if (grid.is_won())
{
if (this.remote_is_local_turn)
{
this.status_change_listener("Congratulation, you won!", "Game Over");
}
else
{
this.status_change_listener("You lost!", "Game Over");
}
this.end_game();
}
else if (grid.is_complete())
{
this.status_change_listener("Draw. Everybody looses!", "Game Over");
this.end_game();
}
else
{
this.toggle_remote_player();
if (this.remote_is_local_turn)
{
this.grid.block_all();
this.grid.subgrids[y][x].unblock();
if (this.grid.subgrids[y][x].is_draw()|| this.grid.subgrids[y][x].is_won())
{
this.grid.unblock_all();
}
}
}
}
}
register_game_mode_change_listener(func)
{
this.game_mode_change_listener = func;
}
register_status_change_listener(func)
{
this.status_change_listener = func;
}
set_game_mode(mode)
{
this.game_mode = mode;
this.game_mode_change_listener(mode);
console.log("changed gamemode to " + mode);
}
start_local_game()
{
this.set_game_mode("local");
this.grid.deactivate_all();
this.grid.unblock_all();
this.is_local_player_a = false;
this.status_change_listener("", "local game")
this.toggle_local_player();
}
register_remote_game(player_name)
{
console.log("set player name to: " + player_name);
if (player_name == "")
{
this.status_change_listener("enter your name first!");
return;
}
this.set_game_mode("remote");
this.grid.deactivate_all();
this.grid.block_all();
this.remote_player.set_name(player_name);
this.status_change_listener("connect to server...");
this.game_server_connection.connect(() => {
this.game_server_connection.set_player(this.remote_player);
this.game_server_connection.register();
});
}
register_response_listener(is_accepted)
{
if (this.game_mode != "remote")
{
return;
}
if (is_accepted)
{
this.status_change_listener("Connected. Waiting for matchmaking...");
}
else
{
this.status_change_listener("could not register for matchmaking. Maybe the name is already in use?");
this.set_game_mode("none");
this.grid.deactivate_all();
this.grid.block_all();
}
}
start_game_listener(opponent_name, is_first_move)
{
if (this.game_mode != "remote")
{
return;
}
this.remote_opponent.set_name(opponent_name);
this.remote_is_local_turn = is_first_move;
var status_title = "" + this.remote_player.get_name() + " vs. " + opponent_name;
this.notify("Your game against " + opponent_name + " started");
if (is_first_move)
{
this.grid.deactivate_all();
this.grid.unblock_all();
this.grid.player_change_listener(this.remote_player);
this.status_change_listener("game aginst " + opponent_name + " started. It's your turn", status_title);
}
else
{
this.grid.deactivate_all();
this.grid.block_all();
this.grid.player_change_listener(this.remote_opponent);
this.status_change_listener("game started, it's " + opponent_name + " turn", status_title);
}
}
move_listener(sub_x, sub_y, x, y)
{
if (this.game_mode != "remote" || this.remote_is_local_turn)
{
console.log("received unexpected move");
return;
}
this.grid.block_all();
this.grid.subgrids[sub_y][sub_x].unblock();
this.grid.subgrids[sub_y][sub_x].cells[y][x].on_click();
}
end_game_listener()
{
if (this.game_mode != "remote")
{
return;
}
this.status_change_listener("game was closed by server or opponent", "Game Over");
this.notify("Game is closed");
this.end_game();
}
toggle_local_player()
{
this.is_local_player_a = !this.is_local_player_a;
var next_player = this.is_local_player_a ? this.local_player_a : this.local_player_b;
this.status_change_listener("" + "it's " + next_player.get_name() + "'s turn...");
this.grid.player_change_listener(next_player);
}
toggle_remote_player()
{
this.remote_is_local_turn = !this.remote_is_local_turn;
if (this.remote_is_local_turn)
{
this.status_change_listener("your turn");
this.grid.player_change_listener(this.remote_player);
this.notify("it's your turn");
}
else
{
this.status_change_listener("waiting for " + this.remote_opponent.get_name() + "'s move...");
this.grid.player_change_listener(this.remote_opponent);
}
}
end_game(clicked_by_local_user = false)
{
if (this.game_mode == "remote")
{
this.game_server_connection.close();
if (clicked_by_local_user)
{
this.status_change_listener("you closed the game", "Game Over");
}
}
else if (this.game_mode == "local")
{
this.status_change_listener("game is closed", "Game Over");
}
this.set_game_mode("none");
this.grid.block_all();
}
connection_error_listener()
{
this.status_change_listener("connection error", "Game Over");
this.end_game();
}
activate_notifications()
{
this.use_notification = true;
}
notify(text) {
Notification.requestPermission(function(result) {
if (result === 'granted') {
navigator.serviceWorker.ready.then(function(registration) {
registration.showNotification(text, {
icon: './icon.png',
vibrate: [200, 200],
tag: "tictactoe-notification"
});
});
}
});
}
}