大道五目Flash英文版(Renju Problems)程序分析之禁手判断
现在界面已经完成了,
刚刚完成了禁手算法,把代码共享出来:
Code
private function IsForbidden(x:int, y:int, board:Array):int {
var index:int = x*15+y;
// set this position(x,y) to black.
board[index] = CellType.BLACK;
// 1st check whether there is overline.
var array:Array =this.GetAnalyseArray(x,y,board);
if(this.IsOverline(array)) {
board[index] = CellType.EMPTY;
return ResultType.OVERLINE;
}
// use recursion to check whether there is double-4 or double-3.
// the check methord is count the open 3 and open 4's count,
// if one of them larger than 1 so is a forbidden.
var count3:int = 0;
var count4:int = 0;
var i, j:int = 0;
for(i=0; i<4; i++) {
// calculate open 4's count.
for(j=3; j<7; j++) {
// patten: ?0x000?
if(array[i][j]==CellType.BLACK&&this.IsEmpty(i,j+1,array)&&
array[i][j+2]==CellType.BLACK&&array[i][j+3]==CellType.BLACK&&
array[i][j+4]==CellType.BLACK&&
this.IsNotBlack(i,j-1,array)&&this.IsNotBlack(i,j+5,array)) {
count4++;
continue;
}
// patten: ?00x00?
if(array[i][j]==CellType.BLACK&&array[i][j+1]==CellType.BLACK&&
this.IsEmpty(i,j+2,array)&&array[i][j+3]==CellType.BLACK&&
array[i][j+4]==CellType.BLACK&&
this.IsNotBlack(i,j-1,array)&&this.IsNotBlack(i,j+5,array)) {
count4++;
continue;
}
// patten: ?000x0?
if(array[i][j]==CellType.BLACK&&array[i][j+1]==CellType.BLACK &&
array[i][j+2]==CellType.BLACK&&this.IsEmpty(i,j+3,array) &&
array[i][j+4]==CellType.BLACK&&
this.IsNotBlack(i,j-1,array)&&this.IsNotBlack(i,j+5,array)) {
count4++;
continue;
}
// patten: ??0000??
// not like above three, this check index is the above index plus 1.
// in other words, the check index is 4 to 8 and above index is 3 to 7.
if(array[i][j+1]==CellType.BLACK&&array[i][j+2]==CellType.BLACK&&
array[i][j+3]==CellType.BLACK&&array[i][j+4]==CellType.BLACK) {
if(this.IsEmpty(i,j,array)&&this.IsNotBlack(i,j-1,array)&&this.IsNotBlack(i,j+5,array)) {
count4++;
continue;
}
if(this.IsEmpty(i,j+5,array)&&this.IsNotBlack(i,j+4,array)&&this.IsNotBlack(i,j,array)) {
count4++;
continue;
}
}
}
var tmpIndex:int;
// calculate open 3's count
for(j=4; j<7; j++) {
// patten: ??0x00??
if(array[i][j]==CellType.BLACK&&this.IsEmpty(i,j+1,array)&&
array[i][j+2]==CellType.BLACK&&array[i][j+3]==CellType.BLACK&&
this.IsEmpty(i,j-1,array)&&this.IsEmpty(i,j+4,array)&&
(this.IsNotBlack(i,j-2,array)||this.IsNotBlack(i,j+5,array))) {
tmpIndex = this.IndexConverter(i,j+1,x,y);
if(this.IsForbidden(Math.floor(tmpIndex/15),tmpIndex%15,board)==ResultType.NOTHING){
count3++;
}
continue;
}
// patten: ??00x0??
if(array[i][j]==CellType.BLACK&&array[i][j+1]==CellType.BLACK&&
this.IsEmpty(i,j+2,array)&&array[i][j+3]==CellType.BLACK&&
this.IsEmpty(i,j-1,array)&&this.IsEmpty(i,j+4,array)&&
(this.IsNotBlack(i,j-2,array)||this.IsNotBlack(i,j+5,array))) {
tmpIndex = this.IndexConverter(i,j+2,x,y);
if(this.IsForbidden(Math.floor(tmpIndex/15),tmpIndex%15,board)==ResultType.NOTHING) {
count3++;
}
continue;
}
// patten: ??000??
if(array[i][j]==CellType.BLACK&&array[i][j+1]==CellType.BLACK&&array[i][j+2]==CellType.BLACK) {
if(this.IsEmpty(i,j-2,array)&&this.IsEmpty(i,j-1,array)&&
this.IsEmpty(i,j+3,array)&&this.IsNotBlack(i,j-3,array)) {
tmpIndex = this.IndexConverter(i,j-1,x,y);
if(this.IsForbidden(Math.floor(tmpIndex/15),tmpIndex%15,board)==ResultType.NOTHING) {
count3++;
continue;
}
}
if(this.IsEmpty(i,j-1,array)&&this.IsEmpty(i,j+3,array)&&
this.IsEmpty(i,j+4,array)&&this.IsNotBlack(i,j+5,array)) {
tmpIndex = this.IndexConverter(i,j+3,x,y);
if(this.IsForbidden(Math.floor(tmpIndex/15),tmpIndex%15,board)==ResultType.NOTHING) {
count3++;
continue;
}
}
}
}
}
// reset the position to empty and return result.
board[index] = CellType.EMPTY;
if(count3>1) {
return ResultType.DOUBLE_THREE;
}
if(count4>1) {
return ResultType.DOUBLE_FOUR;
}
return ResultType.NOTHING;
}
private function IsForbidden(x:int, y:int, board:Array):int {
var index:int = x*15+y;
// set this position(x,y) to black.
board[index] = CellType.BLACK;
// 1st check whether there is overline.
var array:Array =this.GetAnalyseArray(x,y,board);
if(this.IsOverline(array)) {
board[index] = CellType.EMPTY;
return ResultType.OVERLINE;
}
// use recursion to check whether there is double-4 or double-3.
// the check methord is count the open 3 and open 4's count,
// if one of them larger than 1 so is a forbidden.
var count3:int = 0;
var count4:int = 0;
var i, j:int = 0;
for(i=0; i<4; i++) {
// calculate open 4's count.
for(j=3; j<7; j++) {
// patten: ?0x000?
if(array[i][j]==CellType.BLACK&&this.IsEmpty(i,j+1,array)&&
array[i][j+2]==CellType.BLACK&&array[i][j+3]==CellType.BLACK&&
array[i][j+4]==CellType.BLACK&&
this.IsNotBlack(i,j-1,array)&&this.IsNotBlack(i,j+5,array)) {
count4++;
continue;
}
// patten: ?00x00?
if(array[i][j]==CellType.BLACK&&array[i][j+1]==CellType.BLACK&&
this.IsEmpty(i,j+2,array)&&array[i][j+3]==CellType.BLACK&&
array[i][j+4]==CellType.BLACK&&
this.IsNotBlack(i,j-1,array)&&this.IsNotBlack(i,j+5,array)) {
count4++;
continue;
}
// patten: ?000x0?
if(array[i][j]==CellType.BLACK&&array[i][j+1]==CellType.BLACK &&
array[i][j+2]==CellType.BLACK&&this.IsEmpty(i,j+3,array) &&
array[i][j+4]==CellType.BLACK&&
this.IsNotBlack(i,j-1,array)&&this.IsNotBlack(i,j+5,array)) {
count4++;
continue;
}
// patten: ??0000??
// not like above three, this check index is the above index plus 1.
// in other words, the check index is 4 to 8 and above index is 3 to 7.
if(array[i][j+1]==CellType.BLACK&&array[i][j+2]==CellType.BLACK&&
array[i][j+3]==CellType.BLACK&&array[i][j+4]==CellType.BLACK) {
if(this.IsEmpty(i,j,array)&&this.IsNotBlack(i,j-1,array)&&this.IsNotBlack(i,j+5,array)) {
count4++;
continue;
}
if(this.IsEmpty(i,j+5,array)&&this.IsNotBlack(i,j+4,array)&&this.IsNotBlack(i,j,array)) {
count4++;
continue;
}
}
}
var tmpIndex:int;
// calculate open 3's count
for(j=4; j<7; j++) {
// patten: ??0x00??
if(array[i][j]==CellType.BLACK&&this.IsEmpty(i,j+1,array)&&
array[i][j+2]==CellType.BLACK&&array[i][j+3]==CellType.BLACK&&
this.IsEmpty(i,j-1,array)&&this.IsEmpty(i,j+4,array)&&
(this.IsNotBlack(i,j-2,array)||this.IsNotBlack(i,j+5,array))) {
tmpIndex = this.IndexConverter(i,j+1,x,y);
if(this.IsForbidden(Math.floor(tmpIndex/15),tmpIndex%15,board)==ResultType.NOTHING){
count3++;
}
continue;
}
// patten: ??00x0??
if(array[i][j]==CellType.BLACK&&array[i][j+1]==CellType.BLACK&&
this.IsEmpty(i,j+2,array)&&array[i][j+3]==CellType.BLACK&&
this.IsEmpty(i,j-1,array)&&this.IsEmpty(i,j+4,array)&&
(this.IsNotBlack(i,j-2,array)||this.IsNotBlack(i,j+5,array))) {
tmpIndex = this.IndexConverter(i,j+2,x,y);
if(this.IsForbidden(Math.floor(tmpIndex/15),tmpIndex%15,board)==ResultType.NOTHING) {
count3++;
}
continue;
}
// patten: ??000??
if(array[i][j]==CellType.BLACK&&array[i][j+1]==CellType.BLACK&&array[i][j+2]==CellType.BLACK) {
if(this.IsEmpty(i,j-2,array)&&this.IsEmpty(i,j-1,array)&&
this.IsEmpty(i,j+3,array)&&this.IsNotBlack(i,j-3,array)) {
tmpIndex = this.IndexConverter(i,j-1,x,y);
if(this.IsForbidden(Math.floor(tmpIndex/15),tmpIndex%15,board)==ResultType.NOTHING) {
count3++;
continue;
}
}
if(this.IsEmpty(i,j-1,array)&&this.IsEmpty(i,j+3,array)&&
this.IsEmpty(i,j+4,array)&&this.IsNotBlack(i,j+5,array)) {
tmpIndex = this.IndexConverter(i,j+3,x,y);
if(this.IsForbidden(Math.floor(tmpIndex/15),tmpIndex%15,board)==ResultType.NOTHING) {
count3++;
continue;
}
}
}
}
}
// reset the position to empty and return result.
board[index] = CellType.EMPTY;
if(count3>1) {
return ResultType.DOUBLE_THREE;
}
if(count4>1) {
return ResultType.DOUBLE_FOUR;
}
return ResultType.NOTHING;
}
就是通过一个递归判断是否当前下子为禁手。
测试后发现可以判断复杂的禁手,如:
posted on 2008-11-04 14:10 Boringlamb 阅读(550) 评论(0) 编辑 收藏 举报