您的位置:首页 > 移动开发 > Android开发

一切从五子棋开始

2016-06-12 18:31 429 查看
题引:作为一个迫不及待想掌握一门养家糊口技能的大二新人,被一位前辈建议学习Java开发Android,他还说会写五子棋就能找到工作。

写五子棋的要点有两点:棋局展示、胜负判定。

一、棋局展示

忽略交互效果,仅以实现基本功能为目标,展示的方法可通过文本或图片实现。

使用文本展示可通过“o”表示白子,“x”表示黑子,“-”表示空位来进行最简单的展示。用TextView控件及其setText(CharSequence)方法即可实现棋子的更替。

使用图片展示可使交互更直观。最先想到的方法是在底部设置一张棋盘背景,落子后将对应位置的ImageView的显示图片更改为落子贴图。苦于没找到合适的棋盘背景,最后使用三张落子贴图分别代表白子、黑子、无子,在落子后将棋格贴图更改为对应落子贴图即可。



接下来就是如何显示这些贴图了,通过以下代码即可将ImageView控件的图片内容设置为资源文件内的图片。

mImageView.setImageResource(R.drawable.mImage);


光显示贴图还远远不够,我们需要将ImageView按棋盘进行定位布局。考虑到棋盘大小的易变性,控件的创建和定位都通过Java代码动态进行。

/**
* 初始化布局
* @param count 棋盘行列数
* @return 棋格控件数组
*/
private ImageView[][] initView(int count) {
RelativeLayout container=new RelativeLayout(this);
setContentView(container);
ImageView[][] views=new ImageView[count][count];
int pWidth=getResources().getDisplayMetrics().widthPixels,pHeight=getResources().getDisplayMetrics().heightPixels; //获取屏幕宽高
int length=pWidth>pHeight?pHeight/count:pWidth/count; //计算棋格宽高
int left=pWidth>pHeight?(pWidth-pHeight)/2:0; //局中显示水平偏移
int top=pWidth>pHeight?0:(pHeight-pWidth)/2; //局中显示垂直偏移
for(int x=0;x<count;x++) {
for(int y=0;y<count;y++) {
ImageView iv=new ImageView(this);
RelativeLayout.LayoutParams lp=new RelativeLayout.LayoutParams(length, length);
lp.setMargins(left+x*length, top+y*length, 0, 0);
iv.setLayoutParams(lp);
container.addView(iv);
views[x][y]=iv;
}
}
return views;
}


最后是添加交互事件,可以通过View的setOnClickListener(OnClickListener)方法实现点击事件。

这里需要注意的是,由于多个控件设置点击事件,我们需要在处理点击时识别所点击对象。标识点击对象的方法有很多种:

1、关键字final。

2、用回调view遍历比对控件数组。

3、通过view的setTag(Object)方法标记控件,使用回调view的getTag()方法获取唯一标识。

4、继承OnClickListener类,提供两个int型数据进行初始化的构造器。添加新抽象方法onClick(int,int),原抽象方法onClick(View)通过构造传入的int数据调用新抽象方法。

以下代码通过关键字final实现标识。

private ImageView[][] mViews;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mViews=initView(15);
for(int x=0;x<mViews.length;x++) {
for(int y=0;y<mViews[0].length;y++) {
final int finalX=x;
final int finalY=y;
mViews[x][y].setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
handleClick(finalX, finalY);
}
});
}
}

}
private void handleClick(int x, int y) {
//这里处理点击逻辑
}


二、胜负判定
正在进行的棋局只会因下一次落子导致结束,因此胜负判定在每次落子后根据落子位置进行判定即可。

判定思路为由落子位置向四个方向延伸,任意方向连通总量大于五子则落子方获胜。需要注意的是五子棋还存在和棋的可能性,在获胜判定后需统计落子总量,若棋盘已满则产生和局。以下代码为落点胜负判定。

private int[][] mArgs; //棋盘数据数组
private int pieceCount; //棋盘已落子量
private int chessSize; //棋盘行列数

/**
* 胜负判定
* @param x 落子横坐标
* @param y 落子纵坐标
* @return
*/
private int win(int x, int y) {
if(getItemCount(x,y,0,1)+getItemCount(x,y,0,-1)+1>=5) return 1; //落子方获胜
if(getItemCount(x,y,1,0)+getItemCount(x,y,-1,0)+1>=5) return 1; //落子方获胜
if(getItemCount(x,y,1,1)+getItemCount(x,y,-1,-1)+1>=5) return 1; //落子方获胜
if(getItemCount(x,y,1,-1)+getItemCount(x,y,-1,1)+1>=5) return 1; //落子方获胜
if(pieceCount>=chessSize*chessSize) return -1; //平局
return 0; //未分胜负
}
/**
* 连通量统计
* @param x 落子横坐标
* @param y 落子纵坐标
* @param i 延伸方向
* @param j 延伸方向
* @return
*/
private int getItemCount(int x, int y, int i, int j) {
int itemCount=0;
int mType=mArgs[x][y];
int readX=x+i;
int readY=y+j;
while(true) {
if(readX<0||readX>=chessSize||readY<0||readY>=chessSize) break;
if(mType==mArgs[readX][readY]) {
itemCount++;
readX+=i;
readY+=j;
}
else break;
}
return itemCount; //返回该方向累计同色棋数
}


最后再搭配上棋盘的复位功能,一个Android的简单五子棋程序就完成了。(当然现在还存在一个严重的交互问题,在小屏手机上触控容易点错位置,后来我的解决方案是添加了棋盘的双指缩放和单指挪动,这里就不进行详细描述了)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 五子棋