人机博弈之(六)------代码实现(2)走法产生器

原创 2007年09月23日 16:12:00
package movegenerator;

//走法产生器



import constdata.ConstData;
import chessmovedata.ChessMoveData;

//一个走法的结构


public class MoveGenerator
{
    
public ChessMoveData moveList[][] =new ChessMoveData[10][100];
    
protected int moveCount ;//记录moveList中走法的数量
    public MoveGenerator()
    
{        
        
for(int i = 0; i < 10; i++)
            
for(int j = 0; j < 100; j++)
                moveList[i][j] 
= new ChessMoveData();
    }

    
    
//判断局面position上,从from到to的走法是否合法
    
//合法返回true,否则返回alse
    public boolean isValidMove(byte position[][], int fromX, int fromY, int toX, int toY)
    
{
        
int i;
        
byte moveChessID, targetID;

        
//目的与起点相同
        if(fromX == toX && fromY == toY) return false;

        moveChessID 
= position[fromY][fromX];
        targetID 
= position[toY][toX];

        
if(ConstData.isSameSide((byte)moveChessID, (byte)targetID)) return false;

        
switch(moveChessID)
        
{    //红将
            case ConstData.B_KING:
                
if(targetID == ConstData.R_KING)
                
{
                    
if(fromX != toX)
                    
{
                        
return false;
                    }

                    
for(i = fromY+1; i < toY; ++i)
                        
if(ConstData.NOCHESS != position[i][fromX]) return false;
                }

                
else
                
{
                    
if(toY > 2 || toX < 3 || toX > 5return false;//九宫之外
                    if((Math.abs(fromX-toX)+Math.abs(fromY-toY)) > 1 ) return false;
                }

                
break;

            
case ConstData.B_BISHOP ://黑士
                
//出了九宫之外
                if(toY > 2 || toX > 5 || toX < 3return false;
                
//士走斜线
                if(Math.abs(fromX - toX) != 1 || Math.abs(fromY - toY) != 1return false;
                
break;
            
case ConstData.R_BISHOP ://红士
                
//出了九宫之外
                if(toY < 7 || toX < 3 || toX > 5return false;
                
//士走斜线
                if(Math.abs(fromX - toX) != 1 || Math.abs(fromY - toY) != 1return false;
                
break;
                
            
case ConstData.B_ELEPHANT ://黑象
                if(toY > 4return false;//象不能过河
                if(Math.abs(fromX - toX) != 2 || Math.abs(fromY - toY) != 2return false;
                
if(position[(fromY + toY)/2][(fromX + toX)/2!= ConstData.NOCHESS) return false;
                
break;
                
            
case ConstData.R_ELEPHANT ://红象
                if(toY < 5return false ;//象不能过河
                if(Math.abs(fromX - toX) != 2 || Math.abs(fromY - toY) != 2return false ;
                
if(position[(fromY + toY)/2][(fromX + toX)/2!= ConstData.NOCHESS ) return false;
                
break;
                
            
case ConstData.B_PAWN ://黑兵
                if(toY < fromY) return false//兵不能倒退
                if(fromY < 5 && toY == fromY) return false//没有过河只能往前走
                if(toY - fromY + Math.abs(fromX - toX) > 1 ) return false;
                
break;
            
            
case ConstData.R_PAWN ://红兵
                if(toY > fromY) return false;//兵不能倒退
                if(fromY > 4 && toY == fromY) return false ;
                
if(fromY - toY + Math.abs(fromX - toX) > 1return false;//兵只能走一步
                break;
                
            
case ConstData.R_KING ://红将
                if(targetID == ConstData.B_KING)
                
{
                    
if(fromX != toX) return false;
                    
for(i = fromY - 1; i > toY ; --i )
                        
if(position[i][fromX] != ConstData.NOCHESS) return false;
                }

                
else 
                
{
                    
if(toX < 3 || toX > 5 || toY < 7)return false;
                    
if(Math.abs(toX - fromX) + Math.abs(toY - fromY) > 1return false;
                }

                
break;
                
            
case ConstData.R_CAR : //
            case ConstData.B_CAR :
                
if(toX != fromX && fromY != toY) return false;//车走直线
                
                
if(fromX == toX)
                
{    //没有棋挡着
                    for(i = Math.min(fromY, toY)+1; i < Math.max(fromY, toY); ++i)
                        
if(position[i][fromX] != ConstData.NOCHESS)
                            
return false;
                }

                
else 
                
{//没有棋挡着
                    for(i = Math.min(fromX, toX)+1; i < Math.max(fromX, toX); ++i)
                        
if(position[fromY][i] != ConstData.NOCHESS)
                            
return false;
                }

                
break;
                
            
case ConstData.R_CANON :
            
case ConstData.B_CANON :
                
if(toX != fromX && fromY != toY) return false;//炮走直线
                
                
if(toX == fromX)
                
{
                    
if(targetID == ConstData.NOCHESS)//炮不是吃子
                    {
                        
//不吃子,要没有棋挡着
                        for(i = Math.min(fromY, toY)+1; i < Math.max(fromY, toY); ++i)
                            
if(position[i][fromX] != ConstData.NOCHESS)
                                
return false;
                    }

                    
else 
                    
{
                        
int count = 0;
                        
//吃子,中间必须要有一个棋子
                        for(i = Math.min(fromY, toY)+1; i < Math.max(fromY, toY); ++i)
                            
if(position[i][fromX] != ConstData.NOCHESS) count++;
                        
if(1 != count) return false;
                    }

                }

                
else
                
{
                    
if(targetID == ConstData.NOCHESS)
                    
{    //不吃子,要没有棋挡着
                        for(i = Math.min(fromX, toX)+1; i < Math.max(fromX, toX); ++i)
                            
if(position[fromY][i] != ConstData.NOCHESS)
                                
return false;
                    }

                    
else
                    
{
                        
int count = 0;
//                        吃子,中间必须要有一个棋子
                        for(i = Math.min(fromX, toX)+1; i < Math.max(fromX, toX); ++i)
                            
if(position[fromY][i] != ConstData.NOCHESS) count++;
                        
if(1 != count) return false;
                    }

                }

                
break;
                
            
case ConstData.R_HORSE :
            
case ConstData.B_HORSE :
                
//马走日
                if(Math.abs(toX - fromX) + Math.abs(toY - fromY) != 3 ||
                   toX 
== fromX || toY == fromY)
                    
return false;
                
if(Math.abs(toX - fromX) == 2)
                
{
                    
//有绊脚的棋在
                    if(position[fromY][(toX + fromX)/2!= ConstData.NOCHESS) return false;
                }

                
else
                
{
                    
//有绊脚的棋在
                    if(position[(toY + fromY)/2][fromX] != ConstData.NOCHESS) return false;
                }

                
break;            
            
        }

        
return true;
    }

    
    
//产生给定棋盘上的所有合法的走法
    
//side 指明产生哪一方的走法,true为红方,false为黑方
    
    
public int createPossibleMove(byte position[][], int nPlay, boolean side)
    
{
        
int i, j;
        
byte chessID;
        moveCount 
= 0;
        
//System.out.println("createPossibleMove1");
        for(j = 0; j < 9++j)
            
for(i  = 0; i < 10++i)
            
{
                
if(ConstData.NOCHESS != position[i][j])
                
{
                    chessID 
= position[i][j];
                    
if(!side && ConstData.isRed(chessID))
                        
continue// 如果是黑方走法,跳过红棋
                    if(side && ConstData.isBlack(chessID))
                        
continue//如果是红方走法,跳过黑棋
                    
                    
switch(chessID)
                    
{
                    
case ConstData.R_KING :
                    
case ConstData.B_KING :
                        genKingMove(position, i, j, nPlay );
                        
break;
                        
                    
case ConstData.R_CAR :
                    
case ConstData.B_CAR :
                        genCarMove(position, i, j, nPlay );
                        
break;
                        
                    
case ConstData.R_HORSE :
                    
case ConstData.B_HORSE :
                        genHorseMove(position, i, j, nPlay );
                        
break;
                        
                    
case ConstData.R_BISHOP :
                        genRBishopMove(position, i, j, nPlay );
                        
break;
                        
                    
case ConstData.B_BISHOP :
                        genBBishopMove(position, i, j, nPlay );
                        
break;
                        
                    
case ConstData.R_ELEPHANT :
                    
case ConstData.B_ELEPHANT :
                        genElephantMove(position, i, j, nPlay );
                        
break;
                        
                    
case ConstData.R_CANON :
                    
case ConstData.B_CANON :
                        genCanonMove(position, i, j, nPlay );
                        
break;
                        
                    
case ConstData.R_PAWN :
                        genRPawnMove(position, i, j, nPlay );
                        
break;
                        
                    
case ConstData.B_PAWN :
                        genBPawnMove(position, i, j, nPlay );
                        
break;
                    
default:
                        
break;
                    }

                }

            }

        
return moveCount;
    }

    
//在moveList中插入一个合法的走法
    protected int addMove(int fromX, int fromY, int toX, int toY, int nPlay)
    
{
        
if(moveCount >=80)return moveCount;
        moveList[nPlay][moveCount].from.x 
= fromX;
        moveList[nPlay][moveCount].from.y 
= fromY;
        moveList[nPlay][moveCount].to.x 
= toX;
        moveList[nPlay][moveCount].to.y 
= toY;
        moveCount
++;
        
return moveCount;
    }

//产生王的走法
    protected void genKingMove(byte position[][], int i, int j, int nPlay)
    
{
        
int x, y;
        
for(y = 0; y < 3 ; ++y)
            
for(x = 3; x < 6++x)
            
{
                
if(isValidMove(position, j, i, x, y))
                    addMove(j, i, x, y, nPlay);
            }

        
        
for(y = 7; y < 10++y)
            
for(x = 3; x < 6++x)
                
if(isValidMove(position, j, i, x, y))
                    addMove(j, i, x, y, nPlay);
        
    }

//产生红士的走法
    protected void genRBishopMove(byte position[][], int i, int j, int nPlay)
    
{
        
int x, y;
        
for(y = 7; y < 10++y)
            
for(x = 3; x < 6++x)
                
if(isValidMove(position, j, i, x, y))
                    addMove(j, i, x, y, nPlay);
    }

//产生黑士的走法
    protected void genBBishopMove(byte position[][], int i, int j, int nPlay)
    
{
        
int x, y;
        
for(y = 0; y < 3++y)
            
for(x = 3; x < 6++x)
                
if(isValidMove(position, j, i, x, y))
                    addMove(j, i, x, y, nPlay);
    }

//产生象的走法
    protected void genElephantMove(byte position[][], int i, int j, int nPlay)
    
{
        
int x, y;
        x 
= j + 2;
        y 
= i + 2;
        
if(x < 9 && y < 10 && isValidMove(position, j, i, x, y))
            addMove(j, i, x, y, nPlay);
        
        x 
= j + 2;
        y 
= i - 2;
        
if(x < 9 && y >= 0 && isValidMove(position, j, i, x, y))
            addMove(j, i, x, y, nPlay);
        
        x 
= j - 2;
        y 
= i + 2;
        
if(x >= 0 && y < 10 && isValidMove(position, j, i, x, y))
            addMove(j, i, x, y, nPlay);
        
        x 
= j - 2;
        y 
= i - 2;
        
if(x >= 0 && y >= 0 && isValidMove(position, j, i, x, y))
            addMove(j, i, x, y, nPlay);
    }

//产生马的走法
    protected void genHorseMove(byte position[][], int i, int j, int nPlay)
    
{
        
int x, y;
        x 
= j + 2;
        y 
= i + 1;
        
if(x < 9 && y < 10 && isValidMove(position, j, i, x, y))
            addMove(j, i, x, y, nPlay);
        
        x 
= j + 2;
        y 
= i - 1;
        
if(x < 9 && y >= 0 && isValidMove(position, j, i, x, y))
            addMove(j, i, x, y, nPlay);
        
        x 
= j + 1;
        y 
= i + 2;
        
if(x < 9 && y < 10 && isValidMove(position, j, i, x, y))
            addMove(j, i, x, y, nPlay);
        
        x 
= j + 1;
        y 
= i - 2;
        
if(x < 9 && y >= 0 && isValidMove(position, j, i, x, y))
            addMove(j, i, x, y, nPlay);
        
        x 
= j - 1;
        y 
= i + 2;
        
if(x >= 0 && y < 10 && isValidMove(position, j, i, x, y))
            addMove(j, i, x, y, nPlay);
        
        x 
= j - 1;
        y 
= i - 2;
        
if(x >= 0 && y >= 0 && isValidMove(position, j, i, x, y))
            addMove(j, i, x, y, nPlay);
        
        x 
= j - 2;
        y 
= i + 1;
        
if(x >= 0 && y < 10 && isValidMove(position, j, i, x, y))
            addMove(j, i, x, y, nPlay);
        
        x 
= j - 2;
        y 
= i - 1;
        
if(x >= 0 && y >= 0 && isValidMove(position, j, i, x, y))
            addMove(j, i, x, y, nPlay);
        
    }

//产生车的走法
    protected void genCarMove(byte position[][], int i, int j, int nPlay)
    
{
        
int x, y;
        
byte chessID;
        chessID 
= position[i][j];
        
        x 
= j + 1;
        y 
= i;
        
while(x < 9)
        
{
            
if(ConstData.NOCHESS == position[y][x])
                addMove(j, i, x, y, nPlay);
            
else
            
{
                
//吃子
                 if(!ConstData.isSameSide(chessID, position[y][x]))
                     addMove(j, i, x, y, nPlay);
                 
break;
            }

            
++x;
        }

        
        x 
= j - 1;
        y 
= i;
        
while(x >= 0)
        
{
            
if(ConstData.NOCHESS == position[y][x])
                addMove(j, i, x, y, nPlay);
            
else
            
{//吃子
                if(!ConstData.isSameSide(chessID, position[y][x]))
                    addMove(j, i, x, y, nPlay);
                
break;
            }

            
--x;
        }

        
        x 
= j;
        y 
= i + 1;
        
while(y < 10)
        
{
            
if(ConstData.NOCHESS == position[y][x])
                addMove(j, i, x, y, nPlay);
            
else
            
{//吃子
                if(!ConstData.isSameSide(chessID, position[y][x]))
                    addMove(j, i, x, y, nPlay);
                
break;
            }

            
++y;
        }

        
        x 
= j;
        y 
= i - 1;
        
while(y >= 0)
        
{
            
if(ConstData.NOCHESS == position[y][x])
                addMove(j, i, x, y, nPlay);
            
else
            
{//吃子
                if(!ConstData.isSameSide(chessID, position[y][x]))
                    addMove(j, i, x, y, nPlay);
                
break;
            }

            
--y;
        }

    }

//产生红兵的走法
    protected void genRPawnMove(byte position[][], int i, int j, int nPlay)
    
{
        
int x, y;
        
byte chessID;
        chessID 
= position[i][j];
        y 
= i - 1;
        x 
= j;
        
if(y >= 0 && !ConstData.isSameSide(chessID, position[y][x]))
            addMove(j,i, x, y, nPlay);
        
//过河
        if(i < 5)
        
{
            y 
= i;
            x 
= j + 1;
            
if(x < 9 && !ConstData.isSameSide(chessID, position[y][x]))
                addMove(j, i, x, y, nPlay);
            x 
= j - 1;
            
if(x >= 0 && !ConstData.isSameSide(chessID, position[y][x]))
                addMove(j, i, x, y, nPlay);
        }

    }

//产生黑兵的走法
    protected void genBPawnMove(byte position[][], int i, int j, int nPlay)
    
{
        
int x, y;
        
byte chessID = position[i][j];
        x 
= j;
        y 
= i + 1;
        
if(y < 10 && !ConstData.isSameSide(chessID, position[y][x]))
            addMove(j, i, x, y, nPlay);
        
//过河了
        if(i > 4)
        
{
            y 
= i;
            x 
= j + 1;
            
if(x < 9 && !ConstData.isSameSide(chessID, position[y][x]))
                addMove(j, i, x, y, nPlay);
            x 
= j - 1;
            
if(x >= 0 && !ConstData.isSameSide(chessID, position[y][x]))
                addMove(j, i, x, y, nPlay);
        }

    }

//炮的走法
    protected void genCanonMove(byte position[][], int i, int j, int nPlay)
    
{
        
int x, y;
        
byte chessID;
        
boolean flag;
        chessID 
= position[i][j];
        
        x 
= j;
        y 
= i + 1;
        flag 
= false;
        
while(y < 10)
        
{
            
if(ConstData.NOCHESS == position[y][x])
            
{
                
if(!flag)
                    addMove(j, i, x, y, nPlay);
            }

            
else
            
{
                
if(!flag)
                    flag 
= true;
                
else
                
{//吃子
                    if(!ConstData.isSameSide(chessID, position[y][x]))
                        addMove(j, i, x, y, nPlay);
                    
break;
                }

                
            }

            y
++;
        }

        x 
= j;
        y 
= i - 1;
        flag 
= false;
        
while(y >= 0)
        
{
            
if(ConstData.NOCHESS == position[y][x])
            
{
                
if(!flag)
                    addMove(j, i, x, y, nPlay);
            }

            
else
            
{
                
if(!flag)flag = true;
                
else
                
{
                    
if(!ConstData.isSameSide(chessID, position[y][x]))
                        addMove(j, i, x, y, nPlay);
                    
break;
                }

            }

            
            
--y;
        }

        
        y 
= i ;
        x 
= j + 1;
        flag 
= false;
        
while(x < 9)
        
{
            
if(ConstData.NOCHESS == position[y][x])
            
{
                
if(!flag)
                    addMove(j, i, x, y, nPlay);
            }

            
else
            
{
                
if(!flag)flag = true;
                
else
                
{
                    
if(!ConstData.isSameSide(chessID, position[y][x]))
                        addMove(j, i, x, y, nPlay);
                    
break;
                }

            }

            
            x
++;
        }

        
        y 
= i;
        x 
= j - 1;
        flag 
= false;
        
while(x >= 0)
        
{
            
if(ConstData.NOCHESS == position[y][x])
            
{
                
if(!flag)
                    addMove(j, i, x, y, nPlay);
            }

            
else
            
{
                
if(!flag)flag = true;
                
else
                
{
                    
if(!ConstData.isSameSide(chessID, position[y][x]))
                        addMove(j, i, x, y, nPlay);
                    
break;
                }

            }

            x
--;
        }

        
    }


}

 

较高人工智能的人机博弈程序实现(多个算法结合)含C++源码

较高人工智能的人机博弈程序实现(多个算法结合)含C++源码  本文由恋花蝶最初发表于http://blog.csdn.net/lanphaday 上,您可以转载、引用、打印和分发等,但必须保留本...
  • GarfieldEr007
  • GarfieldEr007
  • 2016年03月06日 19:02
  • 1675

人机版五子棋两种算法概述

人机版五子棋是很有挑战性的。至今好像没有保证可以取胜的算法,但已经有不少写的很专业的五子棋程序了。我在编写五子棋的过程中参考了不少资料,发现人机五子棋大致有两种策略。在这儿总结一下,与大家共享。先说两...
  • u011587401
  • u011587401
  • 2016年03月13日 14:46
  • 2563

基于人工神经网络的五子棋博弈(Details)

基于ANN的Gobang AI 关键词:五子棋博弈;人工神经网络;强化学习;博弈树搜索;α-β剪枝...
  • rm_wang
  • rm_wang
  • 2016年07月24日 10:21
  • 2971

人机博弈-吃子棋游戏(三)走法生成

人机博弈-吃子棋游戏(三)走法生成,介绍吃子棋的走法生成算法
  • zjq2008wd
  • zjq2008wd
  • 2014年10月17日 13:41
  • 893

#牛客#代码实现:字符串的匹配、字符串的交错组成、纸牌博弈、表达式组合

第一题:字符串与含有通用字符.*的字符串匹配问题 /*Problem:字符串匹配问题 给定字符串str,其中绝对不含有字符’.’和’*’。再给定字符串exp,其中可以含有’.’或’*’,’*’字符不能...
  • chenwan1120
  • chenwan1120
  • 2015年09月03日 17:13
  • 325

合并word文件宏代码产生器

  • 2012年09月21日 09:52
  • 25KB
  • 下载

89C51的简单实例,详细有说明,适合入门,通过PROTUES的仿真1.闪烁灯2.模拟开关灯3.多路开关状态指示4. 广告灯的左移右移5.广告灯(利用取表方式)6.报警产生器7. I-O并行口直接驱动LED显示8.按键识别方法之9.一键多功能按键识别技术10. 00-99计数器

  • 2008年09月03日 22:40
  • 789KB
  • 下载

弹出式窗口代码产生器

  • 2013年05月01日 14:32
  • 8KB
  • 下载

C51单片机实例30(1. 闪烁灯 2. 模拟开关灯 广告灯 报警产生器等)

  • 2009年12月20日 15:34
  • 2.14MB
  • 下载

使用json-lib实现的JSON产生器(Java版本)

今天使用了一些JSON的jar包,感觉非常非常便利。开始我是在Action中使用字符串来拼接出JSON。 首先,需要jar包为:commons-beanutils-1.7.0.jar,com...
  • shaofeng41
  • shaofeng41
  • 2011年11月09日 20:17
  • 619
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:人机博弈之(六)------代码实现(2)走法产生器
举报原因:
原因补充:

(最多只允许输入30个字)