abalone/Move.class.js

229 lines
6.9 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

class Move {
constructor(player, abalone) {
this.id = -1;
this.player = player;
this.abalone = abalone;
this.type = -1; // 1 marble / 2 column / 3 line
this.done = false;
this.repr = ""
this.pieces = []
this.direction = ""
}
add_piece(piece) {
if (piece.player !== this.player) {
// Piece is not owned by current player
return false;
}
else if (this.pieces.length >= 3) {
// Maximum pieces by move reached
return false;
}
else if (this.pieces.indexOf(piece) != -1) {
// Piece is already selected
return false;
}
else if (this.pieces.length == 0) {
// Move set is empty
this.pieces.push(piece);
return true;
}
else if (
Slot.are_aligned(this.pieces.concat([piece]))) {
this.pieces.push(piece);
return true;
}
return false;
}
del_piece(piece) {
let i = this.pieces.indexOf(piece);
if (i == -1) {
return false;
}
this.pieces.splice(i, 1);
return true;
}
set_direction(dir) {
if (['nw','ne','e','se','sw','w'].indexOf(dir) == -1) {
return false;
}
this.direction = dir;
return true;
}
set_type() {
this.sort_pieces();
if (this.pieces.length < 1) {
this.type = -1;
return;
}
else if (this.pieces.length == 1) {
this.type = 1;
return;
}
let coord = this.pieces[1].get_direction_coord(this.direction);
if (coord == false) {
this.type = -1;
return;
}
else if (coord.x == this.pieces[0].coord.x &&
coord.y == this.pieces[0].coord.y) {
this.type = 2;
return;
}
else {
this.type = 3;
return;
}
}
is_possible() {
this.set_type();
if (this.type == -1) {
alert('Select at least one piece');
return false;
}
else if (this.pieces.length > 3) {
alert('Too much marbles are selected');
}
for (let piece of this.pieces) {
let coord = piece.get_direction_coord(this.direction);
if (typeof(coord) == 'undefined') {
return false;
}
let next_slot = this.abalone.board.get_coord(coord);
if (typeof(next_slot) != 'undefined' && next_slot.length > 1) {
// A piece is located in the next slot
if (this.pieces.indexOf(next_slot[1])) {
// The next slot is already in the move
continue;
}
else if (next_slot[1].player == this.player &&
piece == this.pieces[0]) {
// There is another piece of the current player
// It means that we can't move
return false;
}
else {
// This is a sumito case
if (this.sumito()) {
this.sort_pieces();
return this.move_pieces();
}
}
}
else {
// The slot is free, so we move all the pieces in this direction
return this.move_pieces();
}
}
}
move_pieces() {
for (let piece of this.pieces) {
this.abalone.board.pop_coord(piece.coord);
let slot = this.abalone.board.get_slot(piece.coord);
let new_coord = piece.get_direction_coord(this.direction);
if (this.abalone.board.get_slot(new_coord) != false) {
piece.new_coord = new_coord;
}
else {
piece.new_coord = false;
piece.out = true;
}
}
for (let piece of this.pieces) {
if (piece.out == true || piece.new_coord == false) {
this.abalone.add_point(piece);
piece.set_out();
continue;
}
let next_slot = this.abalone.board.get_slot(piece.new_coord);
if (next_slot == false || typeof(next_slot) == 'undefined') {
break;
}
this.abalone.board.push_coord(piece.new_coord, piece);
piece.coord = piece.new_coord;
piece.move(next_slot.element.position(),
next_slot.element.rotation(),
next_slot.element.offsetX());
if (piece.selected) {
piece.set_selected();
}
}
this.abalone.layers.pieces.draw();
return true;
}
sumito() {
if (this.type != 2) {
return false;
}
let new_coord = this.pieces[0].get_direction_coord(this.direction);
let next_slot = this.abalone.board.get_coord(new_coord);
if (next_slot.length <= 1) {
// Free slot! - should not happen in this function
return true;
}
let enemy_piece = next_slot[1];
new_coord = enemy_piece.get_direction_coord(this.direction);
next_slot = this.abalone.board.get_coord(new_coord);
if (next_slot == false || next_slot.length <= 1) {
// It's outside! || it's free
this.pieces.unshift(enemy_piece);
return true;
}
else if (this.pieces.length <= 2) {
// We don't have enough pieces to face 2 enemy marbles
return false;
}
else {
this.pieces.unshift(enemy_piece);
}
enemy_piece = next_slot[1];
new_coord = enemy_piece.get_direction_coord(this.direction);
next_slot = this.abalone.board.get_coord(new_coord);
if (next_slot == false || next_slot.length <= 1) {
this.pieces.unshift(enemy_piece);
return true;
}
return false;
}
sort_pieces() {
let sort_function = false;
switch (this.direction[0]) {
case 'e':
sort_function = function (a, b) {
return parseInt(b.coord.y) - parseInt(a.coord.y);
}
break;
case 'w':
sort_function = function (a, b) {
return parseInt(a.coord.y) - parseInt(b.coord.y);
}
break;
case 'n':
sort_function = function (a, b) {
return a.coord.x.charCodeAt() - b.coord.x.charCodeAt();
}
break;
case 's':
sort_function = function (a, b) {
return b.coord.x.charCodeAt() - a.coord.x.charCodeAt();
}
break;
}
this.pieces.sort(sort_function);
}
}