229 lines
6.9 KiB
JavaScript
229 lines
6.9 KiB
JavaScript
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);
|
||
}
|
||
}
|