diff --git a/core/src/__tests__/__snapshots__/humanVsAi.ts.snap b/core/src/__tests__/__snapshots__/humanVsAi.ts.snap
new file mode 100644
index 0000000..253c082
--- /dev/null
+++ b/core/src/__tests__/__snapshots__/humanVsAi.ts.snap
@@ -0,0 +1,119 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`PlayerHuman vs PlayerAi > Issue #3 1`] = `
+[
+  [
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+  ],
+  [
+    0,
+    0,
+    0,
+    1,
+    0,
+    0,
+    0,
+  ],
+  [
+    0,
+    0,
+    0,
+    1,
+    0,
+    1,
+    0,
+  ],
+  [
+    0,
+    0,
+    0,
+    2,
+    1,
+    2,
+    1,
+  ],
+  [
+    0,
+    0,
+    0,
+    1,
+    2,
+    2,
+    2,
+  ],
+  [
+    0,
+    0,
+    0,
+    1,
+    2,
+    2,
+    1,
+  ],
+]
+`;
+
+exports[`PlayerHuman vs PlayerAi > Issue #3 2`] = `
+[
+  [
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+  ],
+  [
+    0,
+    0,
+    0,
+    1,
+    0,
+    0,
+    0,
+  ],
+  [
+    0,
+    0,
+    0,
+    1,
+    0,
+    1,
+    2,
+  ],
+  [
+    0,
+    0,
+    0,
+    2,
+    1,
+    2,
+    1,
+  ],
+  [
+    0,
+    0,
+    0,
+    1,
+    2,
+    2,
+    2,
+  ],
+  [
+    0,
+    0,
+    0,
+    1,
+    2,
+    2,
+    1,
+  ],
+]
+`;
diff --git a/core/src/__tests__/humanVsAi.ts b/core/src/__tests__/humanVsAi.ts
new file mode 100644
index 0000000..e205dde
--- /dev/null
+++ b/core/src/__tests__/humanVsAi.ts
@@ -0,0 +1,98 @@
+import { TestGame } from '../__testHelpers/test-game'
+import { BoardPiece, BoardBase } from '../board'
+import { TestPlayer } from '../__testHelpers/test-player'
+import { clone } from '../utils'
+import { describe, test, expect } from 'vitest'
+import { PlayerAi } from '../player'
+
+describe('PlayerHuman vs PlayerAi', () => {
+  const testPlayer = new TestPlayer(BoardPiece.PLAYER_1)
+  const aiPlayer = new PlayerAi(BoardPiece.PLAYER_2)
+  const players = [testPlayer, aiPlayer]
+  test('Issue #3', async () => {
+    const board = new BoardBase()
+    const game = new TestGame(players, board)
+
+    /*
+    Next move is Player 2 (AI)
+  
+    Current board:
+
+    0 0 0 0 0 0 0
+    0 0 0 1 0 0 0
+    0 0 0 1 0 1 0
+    0 0 0 2 1 2 1
+    0 0 0 1 2 2 2
+    0 0 0 1 2 2 1
+
+    Should probably choose column 2 to block immediate Player 1 from winning
+    */
+    board.map = [
+      [
+        BoardPiece.EMPTY,
+        BoardPiece.EMPTY,
+        BoardPiece.EMPTY,
+        BoardPiece.EMPTY,
+        BoardPiece.EMPTY,
+        BoardPiece.EMPTY,
+        BoardPiece.EMPTY,
+      ],
+      [
+        BoardPiece.EMPTY,
+        BoardPiece.EMPTY,
+        BoardPiece.EMPTY,
+        BoardPiece.PLAYER_1,
+        BoardPiece.EMPTY,
+        BoardPiece.EMPTY,
+        BoardPiece.EMPTY,
+      ],
+      [
+        BoardPiece.EMPTY,
+        BoardPiece.EMPTY,
+        BoardPiece.EMPTY,
+        BoardPiece.PLAYER_1,
+        BoardPiece.EMPTY,
+        BoardPiece.PLAYER_1,
+        BoardPiece.EMPTY,
+      ],
+      [
+        BoardPiece.EMPTY,
+        BoardPiece.EMPTY,
+        BoardPiece.EMPTY,
+        BoardPiece.PLAYER_2,
+        BoardPiece.PLAYER_1,
+        BoardPiece.PLAYER_2,
+        BoardPiece.PLAYER_1,
+      ],
+      [
+        BoardPiece.EMPTY,
+        BoardPiece.EMPTY,
+        BoardPiece.EMPTY,
+        BoardPiece.PLAYER_1,
+        BoardPiece.PLAYER_2,
+        BoardPiece.PLAYER_2,
+        BoardPiece.PLAYER_2,
+      ],
+      [
+        BoardPiece.EMPTY,
+        BoardPiece.EMPTY,
+        BoardPiece.EMPTY,
+        BoardPiece.PLAYER_1,
+        BoardPiece.PLAYER_2,
+        BoardPiece.PLAYER_2,
+        BoardPiece.PLAYER_1,
+      ],
+    ]
+
+    board.debug()
+    expect(board.map).toMatchSnapshot()
+    game.currentPlayerId = 1
+    game.start()
+    board.debug()
+    console.log()
+    await game.afterMovePromise
+
+    expect(board.map).toMatchSnapshot()
+    board.debug()
+  })
+})
diff --git a/core/src/player/player-ai.ts b/core/src/player/player-ai.ts
index 3899d09..0bd9038 100644
--- a/core/src/player/player-ai.ts
+++ b/core/src/player/player-ai.ts
@@ -100,11 +100,6 @@ export class PlayerAi extends Player {
   ): number {
     const isWon = winnerBoardPiece === this.boardPiece
     const isLost = winnerBoardPiece === this.enemyBoardPiece
-
-    // value is slightly higher than BIG_NEGATIVE_NUMBER & lower than BIG_POSITIVE_NUMBER
-    // so that minState(...) and maxState(...) could "catch"" this value and AI take this move
-    // This is just my hypothesis, I haven't tested without it yet.
-    // My point is that this AI implementation is basically a heuristic function :P
     if (isWon) {
       returnValue = BIG_POSITIVE_NUMBER - 100
     } else if (isLost) {
@@ -169,16 +164,17 @@ export class PlayerAi extends Player {
         }
 
         // alpha-beta pruning
-        if (value > beta) {
-          return {
-            value: value,
-            move: choose(moveQueue),
-          }
-        }
+        // if (value > beta) {
+        //   return {
+        //     value: value,
+        //     move: choose(moveQueue),
+        //   }
+        // }
         alpha = Math.max(alpha, value)
       }
     }
 
+    console.log('[maxState] depth', depth, value, moveQueue)
     return {
       value: value,
       move: choose(moveQueue),
@@ -211,15 +207,17 @@ export class PlayerAi extends Player {
         }
 
         // alpha-beta pruning
-        if (value < alpha) {
-          return {
-            value: value,
-            move: choose(moveQueue),
-          }
-        }
+        // if (value < alpha) {
+        //   return {
+        //     value: value,
+        //     move: choose(moveQueue),
+        //   }
+        // }
         beta = Math.min(beta, value)
       }
     }
+
+    console.log('[minState] depth', depth, value, moveQueue)
     return {
       value: value,
       move: choose(moveQueue),
diff --git a/core/src/player/player.ts b/core/src/player/player.ts
index 956bdb9..9344e05 100644
--- a/core/src/player/player.ts
+++ b/core/src/player/player.ts
@@ -2,6 +2,7 @@ import { BoardBase, BoardPiece } from '../board'
 
 export abstract class Player {
   boardPiece: BoardPiece
+  /** @return {number} column number (0-index) */
   abstract getAction(board: BoardBase): Promise<number>
   constructor(boardPiece: BoardPiece) {
     this.boardPiece = boardPiece
diff --git a/core/src/utils.ts b/core/src/utils.ts
index ad7ee78..ecf54fb 100644
--- a/core/src/utils.ts
+++ b/core/src/utils.ts
@@ -37,12 +37,12 @@ export function getRandomColumnNumber(): number {
   return Math.floor(Math.random() * BoardBase.COLUMNS)
 }
 
-export function choose(choice: Array<any>): any {
+export function choose<T>(choice: Array<T>): T {
   return choice[Math.floor(Math.random() * choice.length)]
 }
 
-export function clone(array: Array<Array<any>>): Array<Array<any>> {
-  const arr: Array<Array<any>> = []
+export function clone<T>(array: Array<Array<T>>): Array<Array<T>> {
+  const arr: Array<Array<T>> = []
 
   for (let i: number = 0; i < array.length; i++) arr[i] = array[i].slice()
 
@@ -57,7 +57,7 @@ export function getMockPlayerAction(
   success: boolean
   map: Array<Array<number>>
 } {
-  const clonedMap: Array<Array<any>> = clone(map)
+  const clonedMap: Array<Array<number>> = clone(map)
 
   if (
     clonedMap[0][column] !== BoardPiece.EMPTY ||