Skip to content
This repository has been archived by the owner on Jan 4, 2023. It is now read-only.

Commit

Permalink
Implementing pawn capture
Browse files Browse the repository at this point in the history
  • Loading branch information
Lucas-C committed Jan 17, 2018
1 parent b013632 commit cdd0a7b
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 21 deletions.
99 changes: 81 additions & 18 deletions tablut.game.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ protected function getAllDatas()
board_player player,
board_king king,
board_wall wall,
board_limitWin WinPosition
board_limitWin limitWin
FROM board');

return $result;
Expand Down Expand Up @@ -180,29 +180,29 @@ public function move(string $fromDiscId, string $toSquareId)
$this->checkAction('move'); // Check that this state change is possible

$fromDiscPos = explode('_', $fromDiscId);
$fromX = $fromDiscPos[1];
$fromY = $fromDiscPos[2];
$fromX = (int) $fromDiscPos[1];
$fromY = (int) $fromDiscPos[2];
$toSquarePos = explode('_', $toSquareId);
$toX = $toSquarePos[1];
$toY = $toSquarePos[2];
$toX = (int) $toSquarePos[1];
$toY = (int) $toSquarePos[2];

$srcPawnFromDb = self::DbQuery("SELECT board_player, board_king FROM board WHERE board_x = $fromX AND board_y = $fromY")->fetch_assoc();
$srcPawnFromDb = $this->dbPawnAt($fromX, $fromY);
$pawnPlayerId = (int) $srcPawnFromDb['board_player'];
$pawnBoardKing = $srcPawnFromDb['board_king'] ? "'1'" : 'NULL';
$pawnIsKing = $srcPawnFromDb['board_king'] ? "'1'" : 'NULL';
if (self::getActivePlayerId() != $pawnPlayerId) {
throw new feException("This pawn belongs to your opponent: pawnPlayerId=$pawnPlayerId | pawnBoardKing=$pawnBoardKing");
throw new feException("This pawn belongs to your opponent: pawnPlayerId=$pawnPlayerId | pawnIsKing=$pawnIsKing");
}

$dstSquareFromDb = self::DbQuery("SELECT board_player, board_wall FROM board WHERE board_x = $toX AND board_y = $toY")->fetch_assoc();
if ($dstSquareFromDb['board_wall'] != NULL) {
$dstSquareFromDb = $this->dbPawnAt($toX, $toY);
if ($dstSquareFromDb['board_wall'] != null) {
throw new feException("Cannot move onto a wall");
}
if ($dstSquareFromDb['board_player'] != NULL) {
if ($dstSquareFromDb['board_player'] != null) {
throw new feException("Cannot move onto another pawn");
}

self::DbQuery("UPDATE board SET board_player=NULL, board_king=NULL WHERE board_x = $fromX AND board_y = $fromY");
self::DbQuery("UPDATE board SET board_player='$pawnPlayerId', board_king=$pawnBoardKing WHERE board_x = $toX AND board_y = $toY");
self::DbQuery("UPDATE board SET board_player='$pawnPlayerId', board_king=$pawnIsKing WHERE board_x = $toX AND board_y = $toY");

self::notifyAllPlayers('pawnMoved', clienttranslate('${player_name} moves a pawn'), array(
'player_id' => $pawnPlayerId,
Expand All @@ -213,10 +213,74 @@ public function move(string $fromDiscId, string $toSquareId)
));

// Send another notif if a pawn was eaten
$eatenPawns = $this->findEatenPawns($toX, $toY);
foreach ($eatenPawns as $eatenPawn) {
list($eatenPawnX, $eatenPawnY) = $eatenPawn;
self::DbQuery("UPDATE board SET board_player=NULL, board_king=NULL WHERE board_x = $eatenPawnX AND board_y = $eatenPawnY");
self::notifyAllPlayers('pawnEaten', clienttranslate("Pawn at position x=$eatenPawnX,y=$eatenPawnY has been eaten by player by \${player_name} !"), array(
'player_id' => $pawnPlayerId,
'player_name' => self::getActivePlayerName(),
'eatenPawnX' => $eatenPawnX,
'eatenPawnY' => $eatenPawnY,
'gamedatas' => $this->getAllDatas()
));
}

$this->gamestate->nextState('move');
}

/**
* @param int $x : new position of the pawn moved
* @param int $y : new position of the pawn moved
* @return array(array(int x, int y))
*/
private function findEatenPawns(int $x, int $y)
{
$activePlayer = self::getActivePlayerId();
$positionsToTest = array(
array('victim' => array($x, $y + 1), 'dual' => array($x, $y + 2), 'third' => array($x - 1, $y + 1), 'fourth' => array($x + 1, $y + 1)),
array('victim' => array($x, $y - 1), 'dual' => array($x, $y - 2), 'third' => array($x - 1, $y - 1), 'fourth' => array($x - 1, $y - 1)),
array('victim' => array($x + 1, $y), 'dual' => array($x + 2, $y), 'third' => array($x + 1, $y - 1), 'fourth' => array($x + 1, $y + 1)),
array('victim' => array($x - 1, $y), 'dual' => array($x - 2, $y), 'third' => array($x - 1, $y - 1), 'fourth' => array($x - 1, $y + 1)),
);

$eatenPawns = array();
foreach ($positionsToTest as $pos) {
$victimPawn = $this->dbPawnAtPos($pos['victim']);
if ($victimPawn['board_player'] == null || $victimPawn['board_player'] == $activePlayer) {
continue;
}
$dualPawn = $this->dbPawnAtPos($pos['dual']);
if ($victimPawn['board_king']) {
$thirdPawn = $this->dbPawnAtPos($pos['third']);
$fourthPawn = $this->dbPawnAtPos($pos['fourth']);
if (($dualPawn['board_player'] == $activePlayer || $dualPawn['board_wall'])
&& ($thirdPawn['board_player'] == $activePlayer || $thirdPawn['board_wall'])
&& ($fourthPawn['board_player'] == $activePlayer || $fourthPawn['board_wall'])) {
array_push($eatenPawns, $pos['victim']);
}
} else {
if ($dualPawn['board_player'] == $activePlayer) {
array_push($eatenPawns, $pos['victim']);
}
}
}
return $eatenPawns;
}

private function dbPawnAtPos($pos)
{
list($x, $y) = $pos;
return $this->dbPawnAt($x, $y);
}

private function dbPawnAt($x, $y)
{
if ($x < 1 || $x > 9 || $y < 1 || $y > 9) {
return array('board_player' => null, 'board_king' => null);
}
return self::DbQuery("SELECT board_player, board_king, board_wall FROM board WHERE board_x = $x AND board_y = $y")->fetch_assoc();
}

//////////////////////////////////////////////////////////////////////////////
//////////// Game state arguments
Expand All @@ -236,15 +300,14 @@ public function argPlayerTurn()
public function stNextPlayer()
{
$activePLayer = self::getActivePlayerId();
$next_player_id = self::activeNextPlayer();

$nextPlayerId = self::activeNextPlayer();

$WinKing = self::DbQuery("SELECT board_limitWin FROM board WHERE board_king='1' ")->fetch_assoc()['board_limitWin'];
$MoscovitWin = self::DbQuery("SELECT board_x FROM board WHERE board_king='1' ")->fetch_assoc()['board_x'];
if ($MoscovitWin == null) {
$kingWins = self::DbQuery("SELECT board_limitWin FROM board WHERE board_king='1' ")->fetch_assoc()['board_limitWin'];
$moscovitWin = self::DbQuery("SELECT board_x FROM board WHERE board_king='1' ")->fetch_assoc()['board_x'];
if ($moscovitWin == null) {
self::DbQuery("UPDATE player SET player_score='2' WHERE player_id='$activePLayer'");
$this->gamestate->nextState('endGame');
} elseif ($WinKing == '1') {
} elseif ($kingWins == '1') {
self::DbQuery("UPDATE player SET player_score='1' WHERE player_id='$activePLayer'");
$this->gamestate->nextState('endGame');
} else {
Expand Down
12 changes: 9 additions & 3 deletions tablut.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*
* In this file, you are describing the logic of your user interface, in Javascript language.
*
* Available JS functions reference: http://en.doc.boardgamearena.com/Studio_function_reference
*/

define([
Expand Down Expand Up @@ -214,15 +215,20 @@ define([
// /////////////////////////////////////////////////
// // Reaction to cometD notifications
setupNotifications() {
dojo.subscribe('pawnMoved', this, 'notifPlayerMoved');
dojo.subscribe('pawnMoved', this, 'notifPawnMoved');
dojo.subscribe('pawnEaten', this, 'notifPawnEaten');
// dojo.subscribe('endOfGame', this, 'notifEndOfGame');
// Delay end of game for interface stock stability before switching to game result
this.notifqueue.setSynchronous('endOfGame', END_OF_GAME_DELAY);
},

notifPlayerMoved(notif) {
console.log('notifPlayerMoved', notif);
notifPawnMoved(notif) {
this.movePawn(notif.args.fromDiscId, notif.args.toSquareId);
},

notifPawnEaten(notif) {
const discId = `disc_${ notif.args.eatenPawnX }_${ notif.args.eatenPawnY }`;
dojo.destroy(discId);
},
});
});

0 comments on commit cdd0a7b

Please sign in to comment.