diff --git a/src/Game/Game.php b/src/Game/Game.php
index d0ddb1c..d3db711 100644
--- a/src/Game/Game.php
+++ b/src/Game/Game.php
@@ -171,7 +171,7 @@ class Game {
             if ($this->isCapture($target, $captureableForPawn)) {
                 $candidate->captures = $this->findCapturedPiece($piece, $opponentPieces, $target);
             }
-            if ($piece->canPromote($target)) {
+            if ($piece instanceof Pawn && $piece->promotes($target)) {
                 $candidates = array_merge($candidates, $this->generatePromotionMoves($candidate));
             } else {
                 $candidates[] = $candidate;
@@ -216,23 +216,35 @@ class Game {
             $this->current,
         );
 
+        $game->applyInPlace($move);
+
+        return $game;
+    }
+
+    private function tick(): void {
+        foreach ($this->pieces as $piece) {
+            $piece->tick();
+        }
+    }
+
+    public function applyInPlace(Move $move): void {
+        $this->tick();
+
         if ($move->captures) {
-            $game->removePiece($move->captures);
+            $this->removePiece($move->captures);
         }
         if ($move->promoteTo) {
-            $game->removePiece($move->piece);
+            $this->removePiece($move->piece);
 
             $promoted = $move->piece->promote($move->promoteTo);
             $promoted->move($move->target);
-            $game->pieces[] = $promoted;
+            $this->pieces[] = $promoted;
         } else {
-            $piece = $game->findPiece($move->piece);
+            $piece = $this->findPiece($move->piece);
             $piece->move($move->target);
         }
 
-        $game->current = $game->current->getNext();
-
-        return $game;
+        $this->current = $this->current->getNext();
     }
 
     public function getGameState(bool $onlyIsLegal = false): GameState {
diff --git a/src/Game/Pawn.php b/src/Game/Pawn.php
index bc83e9c..0a8464a 100644
--- a/src/Game/Pawn.php
+++ b/src/Game/Pawn.php
@@ -71,7 +71,7 @@ class Pawn extends Piece {
         return $result;
     }
 
-    public function canPromote(Position $position): bool {
+    public function promotes(Position $position): bool {
         return ($this->side == Side::WHITE) ? ($position->rank == 7) : ($position->rank == 0);
     }
 }
\ No newline at end of file
diff --git a/tests/Game/GameTest.php b/tests/Game/GameTest.php
index 5c36f51..7ec259f 100644
--- a/tests/Game/GameTest.php
+++ b/tests/Game/GameTest.php
@@ -301,4 +301,103 @@ final class GameTest extends TestCase {
             new Queen(new Position(1, 1), Side::WHITE), null,
         ), $legalMoves);
     }
+
+    public function testLegalMoves_enPassantNotPossibleBecauseMoveInBetween() {
+        $subject = new Game(
+            [
+                new King(new Position(0, 1), Side::BLACK),
+                new King(new Position(0, 7), Side::WHITE),
+                new Queen(new Position(1, 3), Side::WHITE),
+                new Pawn(new Position(5, 1), Side::WHITE),
+                new Pawn(new Position(6, 2), Side::WHITE),
+                new Pawn(new Position(6, 3), Side::BLACK, true),
+            ],
+            Side::WHITE
+        );
+        $subject->applyInPlace(new Move(
+            new Pawn(new Position(5, 1), Side::WHITE),
+            new Position(5, 3)
+        ));
+        $subject->applyInPlace(new Move(
+            new King(new Position(0, 1), Side::BLACK),
+            new Position(0, 0)
+        ));
+        $subject->applyInPlace(new Move(
+            new Queen(new Position(1, 3), Side::WHITE),
+            new Position(1, 4)
+        ));
+
+        $legalMoves = $subject->getLegalMoves();
+
+        $this->assertCount(1, $legalMoves);
+
+        $this->assertContainsEqualsOnce(new Move(
+            new King(new Position(0, 0), Side::BLACK),
+            new Position(0, 1),
+        ), $legalMoves);
+    }
+
+    public function testLegalMoves_enPassantNotPossibleBecausePawnDidntMove2Squares() {
+        $subject = new Game(
+            [
+                new King(new Position(0, 0), Side::BLACK),
+                new King(new Position(0, 7), Side::WHITE),
+                new Queen(new Position(1, 3), Side::WHITE),
+                new Pawn(new Position(5, 1), Side::WHITE),
+                new Pawn(new Position(6, 2), Side::WHITE),
+                new Pawn(new Position(6, 3), Side::BLACK, true),
+            ],
+            Side::WHITE
+        );
+        $subject->applyInPlace(new Move(
+            new Pawn(new Position(5, 1), Side::WHITE),
+            new Position(5, 2)
+        ));
+        $subject->applyInPlace(new Move(
+            new King(new Position(0, 0), Side::BLACK),
+            new Position(0, 1)
+        ));
+        $subject->applyInPlace(new Move(
+            new Pawn(new Position(5, 2), Side::WHITE),
+            new Position(5, 3)
+        ));
+
+        $legalMoves = $subject->getLegalMoves();
+
+        $this->assertCount(1, $legalMoves);
+
+        $this->assertContainsEqualsOnce(new Move(
+            new King(new Position(0, 1), Side::BLACK),
+            new Position(0, 0),
+        ), $legalMoves);
+    }
+
+    public function testLegalMoves_enPassantPossible() {
+        $subject = new Game(
+            [
+                new King(new Position(0, 0), Side::BLACK),
+                new King(new Position(0, 7), Side::WHITE),
+                new Queen(new Position(1, 2), Side::WHITE),
+                new Pawn(new Position(5, 1), Side::WHITE),
+                new Pawn(new Position(6, 2), Side::WHITE),
+                new Pawn(new Position(6, 3), Side::BLACK, true),
+            ],
+            Side::WHITE
+        );
+
+        $subject->applyInPlace(new Move(
+            new Pawn(new Position(5, 1), Side::WHITE),
+            new Position(5, 3)
+        ));
+
+        $legalMoves = $subject->getLegalMoves();
+
+        $this->assertCount(1, $legalMoves);
+
+        $this->assertContainsEqualsOnce(new Move(
+            new Pawn(new Position(6, 3), Side::BLACK),
+            new Position(5, 2),
+            new Pawn(new Position(5, 3), Side::WHITE),
+        ), $legalMoves);
+    }
 }
\ No newline at end of file
diff --git a/tests/Game/PawnTest.php b/tests/Game/PawnTest.php
index e3c2454..e2065f1 100644
--- a/tests/Game/PawnTest.php
+++ b/tests/Game/PawnTest.php
@@ -243,4 +243,37 @@ final class PawnTest extends TestCase {
             ]))
         );
     }
+
+    public function testPromotes_no() {
+        $subject = new Pawn(
+            new Position(3, 4),
+            Side::WHITE,
+        );
+
+        $this->assertFalse(
+            $subject->promotes(new Position(3, 5))
+        );
+    }
+
+    public function testPromotes_white() {
+        $subject = new Pawn(
+            new Position(3, 6),
+            Side::WHITE,
+        );
+
+        $this->assertTrue(
+            $subject->promotes(new Position(3, 7))
+        );
+    }
+
+    public function testPromotes_black() {
+        $subject = new Pawn(
+            new Position(3, 1),
+            Side::BLACK,
+        );
+
+        $this->assertTrue(
+            $subject->promotes(new Position(3, 0))
+        );
+    }
 }
\ No newline at end of file