第四章 棋类: 华容道 三子棋AI算法
手机棋牌开发的优点和缺点
与其他手机端游戏相比较,手机棋牌开发演化的手游竞技,与休闲性合二为一,游艺兼备、手游玩家随着公共WIFI的普及,参与门槛越来越低。加上手机棋牌的规则学习与线下的玩法相似,具有广泛的用户基层认知度和接受度;完成一局的时长在3分钟内,与各种类型的手游相比,时短带劲,与手机的移动性、高效性更配哦。
手机棋牌开发符合移动游戏规律,手游发展后劲大,各大手游类型中,棋牌玩家以忠诚度高、留存率与充值率的喜闻乐见而出名,加上中国当之无愧的棋牌类“国民游戏”、“零门槛”特点。个中秘诀,盈利动态值得一窥究竟。
本章节从android智能手机的华容道、三子棋,魔方来简要述说开发棋类游戏的过程。
4.1华容道开发
“华容道”游戏名称来源于我国古典四大名著之一的《三国演义》。华容道”以其变化多端,百玩不厌的特点与“魔方”、“独立钻石棋”一起被国外智力专家并称为智力游戏界的“三个不可思议”。它与七巧板,九连环等中国传统益智玩具并称“中国的难题”。国外亦有类似的游戏,称作尖峰时刻(Rush Hour)或叫巧挪妙移。
4.1.1下法与结构
华容道”有一个带二十个小方格的棋盘,代表华容道。棋盘下方有一个两方格边长的出口,是供曹操逃走的。棋盘上共摆有十个大小不一样的棋子,它们分别代表曹操、张飞、赵云、马超、黄忠和关羽,还有四个卒。棋盘上仅有两个小方格空着,玩法就是通过这两个空格移动棋子,用最少的步数把曹操移出华容道。
4.1.2华容道棋盘与人物绘制
华容道”有一个带二十个小方格的棋盘,用两个数组表示十个人物及空格XY坐标。rx[]={140,140,50,230,50,230,50,230,110,170,110,170},ry[]={90,180,90,90,210,210,300,300,240,240,300,300};表示每个棋的中间坐标。
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 全屏显示窗口
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
//强制横屏
//setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//竖屏
// 显示自定义的游戏View
mAnimView = new MyView(this);
setContentView(mAnimView);
}
public class MyView extends SurfaceView implements Callback,Runnable ,SensorEventListener{
public static final int TIME_IN_FRAME = 30;
Paint mPaint = null;
Paint mTextPaint = null;
SurfaceHolder mSurfaceHolder = null;
boolean mRunning = false;
Canvas mCanvas = null;
boolean mIsRunning = false;
int mScreenWidth = 0, p;
int mScreenHeight = 0;
int i=0,k=0 ,k2=0,k1=0,h0=12;
//cc, gy, c1,c2 ,c3,c4, b1,b2, b3, b4
float h=88,y, maxy=0,maxx=0,maxy0=0,maxx0=0,rx[]={140,140,50,230,50,230,50,230,110,170,110,170},ry[]={90,180,90,90,210,210,300,300,240,240,300,300};
定义布局及用两个数组rx[],ry[]表示十个人物及两个空格XY坐标
public MyView(Context context) {
super(context);
this.setFocusable(true);
this.setFocusableInTouchMode(true);
mMediaPlayer01 = new MediaPlayer();
mMediaPlayer02 = new MediaPlayer();
mSurfaceHolder = this.getHolder();
mSurfaceHolder.addCallback(this);
mCanvas = new Canvas();
mPaint = new Paint();
mPaint.setColor(Color.WHITE);
mbitmapBall = BitmapFactory.decodeResource(this.getResources(), R.drawable.cc);
mbitmapzy = BitmapFactory.decodeResource(this.getResources(), R.drawable.zy);
mbitmapzf = BitmapFactory.decodeResource(this.getResources(), R.drawable.zf);
mbitmapBg = BitmapFactory.decodeResource(this.getResources(), R.drawable.back);
mbitmapgy=BitmapFactory.decodeResource(this.getResources(), R.drawable.gy);
mbitmapmc = BitmapFactory.decodeResource(this.getResources(), R.drawable.mc);
mbitmaphz = BitmapFactory.decodeResource(this.getResources(), R.drawable.hz);
mbitmapb1 = BitmapFactory.decodeResource(this.getResources(), R.drawable.b1);
mbitmapb2 = BitmapFactory.decodeResource(this.getResources(), R.drawable.b2);
mbitmapb3 = BitmapFactory.decodeResource(this.getResources(), R.drawable.b3);
mbitmapb4 = BitmapFactory.decodeResource(this.getResources(), R.drawable.b4);
mbitmapb4 = BitmapFactory.decodeResource(this.getResources(), R.drawable.zg);
4.1.3人物移动算法
.人物移动设计,检测按了哪个人物,及滑动方向,根据棋子的XY面大小移动。
public boolean onTouchEvent(MotionEvent event)
{
// event.getAction() ==
// MotionEvent.ACTION_POINTER_1_DOWN
// MotionEvent.ACTION_POINTER_2_DOWN
p = event.getPointerCount();
//float x = event.getX(p-1);
maxy=0;
for (i=0;i
y = event.getX(i);
// if (maxy
maxy=y;
maxx=event.getY(i);
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
for (i=0;i<10;i++){
if (Math.abs( maxx-ry[i])+ Math.abs( maxy-rx[i] )
{ h0=i;h=Math.abs( maxx-ry[i])+ Math.abs( maxy-rx[i]) ; }
}
//按下时触发
}
4.1.4.碰撞判断,检测步骤2 XY面大小移动的目的地是否为空格的坐标。
case MotionEvent.ACTION_UP: {
h = 38;
if (maxx - ry[h0] > 30) {
if ((ry[h0] + 60 == ry[11]) && (rx[h0] == rx[11]) && h0 > 5) {
ry[11] = ry[h0];
ry[h0] = ry[h0] + 60;
} else if ((ry[h0] + 60 == ry[10]) && (rx[h0] == rx[10])
&& h0 > 5) {
ry[10] = ry[h0];
ry[h0] = ry[h0] + 60;
}
// gy,cc
else if (((ry[h0] + 60 == ry[10])
&& (rx[h0] - 30 == rx[10])
&& (ry[h0] + 60 == ry[11]) && (rx[h0] + 30 == rx[11]))
|| ((ry[h0] + 60 == ry[11])
&& (rx[h0] - 30 == rx[11])
&& (ry[h0] + 60 == ry[10]) && (rx[h0] + 30 == rx[10]))
&& h0 == 1) {
ry[10] = ry[10] - 60;
ry[11] = ry[11] - 60;
;
ry[h0] = ry[h0] + 60;
} else if (((ry[h0] + 90 == ry[10])
&& (rx[h0] - 30 == rx[10])
&& (ry[h0] + 90 == ry[11]) && (rx[h0] + 30 == rx[11]))
|| ((ry[h0] + 90 == ry[11])
&& (rx[h0] - 30 == rx[11])
&& (ry[h0] + 90 == ry[10]) && (rx[h0] + 30 == rx[10]))
&& h0 == 0) {
ry[10] = ry[10] - 120;
ry[11] = ry[11] - 120;
;
ry[h0] = ry[h0] + 60;
}
4.1.5.记录新坐标,用于下步判断。
for (int i = 0; i <= 11; i++) {
rxf[f][i] = rx[i];
ryf[f][i] = ry[i];
}
4.1.6.回放功能,按记录的数据定时画出每个步骤。
if (maxy > 200 & maxx > 380 & maxx < 450) {
f1 = f;
f = 0;f2 = 0;
maxx = 1450;
ff = 1;
}
if (ff == 1) {
// for (int j = 0; j
for (int i = 0; i <= 11; i++) {
rx[i] = rxf[f][i];
ry[i] = ryf[f][i];
}
f2++;
if (f2 <= f1) {
f++;
// f2 = 0;
}
if (f2 == f1) {
ff = 0;
f1 = 0;
}
}
4.1.7华容道游戏玩法技巧
:我在移动板块时,先想办法让“关羽”向下移动,只有这样,“曹操”才有向下移动的可能。评价:你真是一个做事认真的孩子,有着较强的推理能力。:我也是这样做的,我还数了一下,“关羽”移动了五步,“曹操”才走了一步。引导:是的,你非常细心!等到曹操迈出第一步时,你知道所有板块总共移动了多少步吗?最少要26步)