中级农民
- 积分
- 118
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2015-3-4
- 最后登录
- 1970-1-1
|
16.4
Problem:
Design an algorithm to figure out if someone has won a game of tic-tac-toe.
Analysis:
This problem could be 4 scenarios: 1)we use this method multiple times: we can store all possible boards and winner as int value using base-3 and boolean key-value set in hash table to look up. 2)we use this method one time: we can either check all 8 lines of winning scenario which is not scalable, or 3) look up all rows/columns/diagonals. 4)we use this method on N*N board: we can expand 3*3 board second method with iterator or directions passed to check.
Code:
enum Piece {Empty,Red,Blue};
1)multiple times:
public int boardToInt(Piece[][] board){
int res=0;
for(int row=0;row<board.length;row++){
for(int col=0;col<board[0].length;col++){
int p=board[row][col]==Piece.Empty?0:(board[row][col]==Piece.Red?1:2);
res=res*3+p;
}
}
return res;
}
2)one time with last move:
public Piece isWinner(Piece[][] board,int row,int col){
Piece p=board[row][col];
if(p==Piece.Empty){return Piece.Empty;}
//if column/row is wining
if(colWin(col,board)||rowWin(row,board)){return p;}
//if diagonal is winning
if(col==row&&diaWin(p,board,1)){return p;}
if(col==board[0].length-1&&diaWin(p,board,-1)){return p;}
return Piece.Empty;
}
public boolean diaWin(Piece p,Piece[][] board,int direction){
int row=0,col=direction==1?0:board[0].length-1;
while(row<board.length){
if(board[row][col]!=board[p.row][p.col]){return false;}
col+=direction;
row++;
}
return true;
}
public boolean colWin(int col,Piece[][] board){
for(int row=1;row<board.length;row++){
if(board[row][col]!=board[0][col]){return false;}
}
return true;
}
public boolean rowWin(int row,Piece[][] board){
for(int col=1;col<board[0].length;col++){
if(board[row][col]!=board[row][0]){return false;}
}
return true;
}
3)one time without last move look up all rows/columns/diagonals
4)for N*N board
public Piece isWinner(Piece[][] board){
int len=board.length;
List<Direction> directions=new ArrayList<>();
setUpDirections(len,directions);
for(Direction direction:directions){
Piece winner=check(board,direction);
if(winner!=Piece.Empty){return winner;}
}
}
public Piece check(Piece[][] board,Direction direction){
Piece p=board[0][0];
for(int row=direction.row,col=direction.col;row<board.length&&col<board[0].length&&row>=0&&col>=0;row+=direction.rowInc,col+=direction.colInc){
if(board[row][col]!=p){return Piece.Empty;}
}
return p;
}
public void setUpDirections(int len,List<Direction> directions){
//set up checker for rows and columns
for(int i=0;i<len;i++){
directions.add(new Direction(i,0,0,1));
directions.add(new Direction(0,i,1,0));
}
//set up checker for diagonals
directions.add(new Direction(0,0,1,1));
directions.add(new Direction(0,len-1,1,-1));
}
public class Direction{
int row,col,rowInc,colInc;
public Direction(int row,int col,int rowInc,int colInc){
this.row=row;
this.col=col;
this.rowInc=rowInc;
this.colInc=colInc;
}
}
|
|