Skip to content

Instantly share code, notes, and snippets.

@johnoyegbite
Created January 1, 2021 19:52
Show Gist options
  • Save johnoyegbite/b40dba3abb0f6875712908eae2b1aedf to your computer and use it in GitHub Desktop.
Save johnoyegbite/b40dba3abb0f6875712908eae2b1aedf to your computer and use it in GitHub Desktop.
N by N Find Winner on a Tic Tac Toe Game
import java.util.*;
import java.lang.Math;
class Solution {
public int countOnesIn(String str) {
int count = 0;
for(int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if(c == '1') {
count += 1;
}
}
return count;
}
public Boolean didPlayerWin(ArrayList<int[]> moves, int boardDim) {
/** Say boardDim is 3.
[0,0] [0,1] [0,2]
[1,0] [1,1] [1,2]
[2,0] [2,1] [2,2]
Ap are the combinations of A moves that won.
Ap B Ap B A B Ap
[[1,2],[2,1],[1,0],[0,0],[0,1],[2,0],[1,1]]
[B] [A] [ ]
[A] [A] [A]
[B] [B] [ ]
*/
int[] moveStart = moves.get(0);
// Check if all moves are on the same row.
Boolean onSameRow = true;
// Check if all moves are on the same column
Boolean onSameCol = true;
// Check if all moves are on the leading diagonal
Boolean onLeadingDiagonal = true;
// Check if all moves are on the opposite leading diagonal
Boolean onOppLeadingDiagonal = true;
for(int i = 0; i < moves.size(); i++) {
int[] curr = moves.get(i);
if(curr[0] != moveStart[0]){
onSameRow = false;
}
if(curr[1] != moveStart[1]){
onSameCol = false;
}
if(curr[0] != curr[1]){
onLeadingDiagonal = false;
}
if(curr[0] + curr[1] != boardDim - 1){
onOppLeadingDiagonal = false;
}
}
if(onSameRow || onSameCol || onLeadingDiagonal || onOppLeadingDiagonal){
return true;
}
return false;
}
public ArrayList<int[]> winMoves(ArrayList<int[]> playerMoves, int boardDim) {
// Check all possible boardDim combinations in playerMoves.
int totalMoves = playerMoves.size();
int power = (int) Math.pow(2, totalMoves); // size of all possible subsets
for(int n = 1; n < power; n++) {
String binString = Integer.toBinaryString(n);
// I only want only the subset whose length is equal to boardDim
if(countOnesIn(binString) == boardDim) {
// using the knowledge of binary conversion to the advantage here
// if s = "abcd" => power = 2^len(s) = 16
// say n = 2; 2 == 0010 base 2.
// hence pick the item at index 3
// say n = 7; 7 == 0111 base 2.
// hence pick only the last 3 items
ArrayList<int[]> moves = new ArrayList<int[]>();
int idx = totalMoves - 1; // index to pick the item from
int num = n;
while(num > 0){
int rem = num % 2;
if(rem == 1){
moves.add(playerMoves.get(idx));
}
idx -= 1;
num /= 2;
}
if(didPlayerWin(moves, boardDim)) {
return moves;
}
}
}
return new ArrayList<int[]>();
}
public String tictactoe(int[][] moves) {
// Minimum number of play (or minimum length of moves) to have a win
// 5 (2 x 3 - 1) = A B A B A = 3 X 3 (for a 3 by 3 board)
// 7 (2 x 4 - 1) = A B A B A B A = 4 X 4 (for a 4 by 4 board)
// 9 (2 x 5 - 1) = A B A B A B A B A = 5 X 5 (for a 5 by 5 board)
// 11 (2 x 6 - 1) = A B A B A B A B A B A = 6 X 6 (for a 6 by 6 board)
// ... = ...
int boardDim = 3; // Dimension of the board
int minLenToGetAWin = 2 * boardDim - 1;
if(moves.length < minLenToGetAWin){
return "Pending";
}
ArrayList<int[]> playerAMoves = new ArrayList<int[]>();
ArrayList<int[]> playerBMoves = new ArrayList<int[]>();
// Get all the moves for player A and B
for(int i = 0; i < moves.length; i++) {
if(i % 2 == 0) { // moves for player A
playerAMoves.add(moves[i]);
}else{ // moves for player B
playerBMoves.add(moves[i]);
}
}
// Check if player A wins (from all possible "boardDim" combinations)
ArrayList<int[]> playerA = winMoves(playerAMoves, boardDim);
if(playerA.size() > 0) {
return "A";
}
// Check if player B wins (from all possible "boardDim" combinations)
ArrayList<int[]> playerB = winMoves(playerBMoves, boardDim);
if(playerB.size() > 0) {
return "B";
}
// If we can't find a winner and
// 1. both players hasn't exhausted all moves then it is Pending.
// 2. both players hasn exhausted all moves then it is a Draw.
return moves.length != boardDim * boardDim ? "Pending" : "Draw";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment