您的位置:首页 > 其它

JNI学习之步步深入四--皇后的祝福

2015-07-27 15:00 190 查看
上篇中简单介绍了,java中的类型和C中的类型的映射的,本篇将以一个无聊的实例来看看JNI中数组的使用。

皇后的祝福,思路很简单,就是利用我们耳熟能详的把皇后问题结合JNI来实现一点点小小的乐趣,在快乐中学习JNI。。。。

1、用C语言实现八皇后的算法,我们知道八皇后有92种解,每种解是一个数据,对应这当前这组解中八个皇后的位置。

2、在java中通过JNI调用c中的方法,获取八皇后的解。

3、在java端完成一些随机性的提示信息。

本篇的源码大家可以到eoe去下载:
http://www.eoeandroid.com/thread-75221-1-1.html
下面请看代码:

1、首先,在java端定义一个接口Queen.java,只有一个方法,简单的很:

[java] view
plaincopy

public class Queen {

public native int[][] getResult();

}

2、利用javah生成c语言的头文件,此处略过。

3、在C中实现逻辑:

[cpp] view
plaincopy

#include <stdlib.h>

#include <stdio.h>

#include <math.h>

#include <org_liner_queen_Queen.h>

/*

* 求八皇后的解

*/

void queen(int results[][8])

{

int queens[8];

int k=0;

int currIndex = 0;

queens[k]=-1;

while(k>=0)

{

queens[k]=queens[k]+1;

while(queens[k]<8 && !place(k, queens))

{

queens[k]=queens[k]+1;

}

if(queens[k]<8)

{

if(k == 7)

{

int i;

for(i=0; i<8; i++)

{

results[currIndex][i] = queens[i];

}

currIndex++;

}else

{

k++;

queens[k]=-1;

}

}

else

{

k--;

}

}

return;

}

int place(int k, int* queens)

{

int i;

for(i=0; i<k; i++)

{

if(queens[i] == queens[k] || abs(queens[i]-queens[k])==abs(i-k))

{

return 0;

}

}

return 1;

}

//java端生成的方法

JNIEXPORT jobjectArray JNICALL Java_org_liner_queen_Queen_getResult

(JNIEnv *env, jobject thiz)

{

int i=0;

jobjectArray result;

int results[92][8];

queen(results);//获取92种解

jclass cls = (*env)->FindClass(env,"[I"); //寻找java中int[]类型

if(cls == NULL)

{

return NULL;

}

//二维数组其实就是一个一维对象数组,每个元素就是一个数组对象

//调用该接口方法实例化一个对象数组,大小92

result = (*env)->NewObjectArray(env, 92, cls, NULL);

if(result == NULL)

{

return NULL;

}

//将92种解对应的每一维的数组,赋值到result

for(i=0; i<92; i++)

{

jint temp[8];

int j;

jintArray iarr = (*env)->NewIntArray(env,8); //实例化一个一维的int类型的数组,大小为8

if(iarr == NULL)

{

return NULL;

}

for(j=0; j<8;j++)

{

temp[j]=results[i][j];

}

(*env)->SetIntArrayRegion(env, iarr, 0, 8, temp); //给数组赋值

(*env)->SetObjectArrayElement(env, result, i, iarr);//给对象数组赋值,单个元素

(*env)->DeleteLocalRef(env, iarr); //释放刚刚实例化的数组

}

return result;

}

4、在java端的处理:

[java] view
plaincopy

package org.liner.queen;

import org.liner.queen.Tips.Tip;

import android.app.Activity;

import android.content.ContentResolver;

import android.content.ContentValues;

import android.content.Context;

import android.database.Cursor;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import android.view.ViewGroup;

import android.widget.AdapterView;

import android.widget.BaseAdapter;

import android.widget.Button;

import android.widget.GridView;

import android.widget.ImageView;

import android.widget.Toast;

public class MainActivity extends Activity {

static{

System.loadLibrary("org_liner_queen_Queen");

}

public static final int MAX_RESULT_INDEX = 92;//92种解

public static final int COLUMN_NUM = 8;

private GridView chessboard;

private Button btnPre,btnNext;

private int currResultIndex = 0;

private int theQueenIndex;

//棋盘

private Integer picIds[] = {

R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,

R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,

R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,

R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,

R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,

R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,

R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,

R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black

};

//全部解2*8+7=23

private int[][] results;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

//btnFirst = (Button)this.findViewById(R.id.btn_first);

btnPre = (Button)this.findViewById(R.id.btn_pre);

btnNext = (Button)this.findViewById(R.id.btn_next);

//btnLast = (Button)this.findViewById(R.id.btn_last);

_initData();

_init();

}

private void _showGrid(){

chessboard = (GridView)this.findViewById(R.id.chessboard);

chessboard.setAdapter(new GridAdapter(this));

chessboard.setOnItemClickListener(new AdapterView.OnItemClickListener() {

@Override

public void onItemClick(AdapterView<?> parent, View v, int position,

long id) {

// 单击事件,判断当前单击的是否是皇后所在的位置,如果是,则判断当前皇后是否

//是给出祝福的皇后,如果是,则随机选择一个祝福语;否则,则选择一个提示语

//对于非皇后的位置,如果用户点击,则

_tip(position);

}

});

}

private int getRandom(int maxValue){

return (int)(Math.random()*maxValue);

}

private int getTheQueenIndex(){

Log.v("Result:::", results.length+"");

int col = this.getRandom(COLUMN_NUM);

return col*COLUMN_NUM + results[currResultIndex][col];//将二维的转换成一维对应的位置

}

private void _tip(int position){

int type;

if(picIds[position] == R.drawable.bqueen || picIds[position]==R.drawable.wqueen){

if(position == theQueenIndex){

//是送祝福的皇后

type=2;

}else{

//不是送祝福的皇后

type = 1;

}

}else{

//不是皇后

type = 0;

}

String[] projection = new String[]{

Tip._ID,

Tip.CONTENT,

Tip.TYPE

};

String selection = Tip.TYPE+"=?";

String[] selectionArgs = new String[]{

type+""

};

Cursor cursor = this.getContentResolver().query(Tip.CONTENT_URI, projection, selection, selectionArgs, null);

//在所有的数据中随机抽取一条

if(cursor.moveToFirst()){

int rand = this.getRandom(cursor.getCount());

cursor.moveToPosition(rand);

String tip = cursor.getString(cursor.getColumnIndexOrThrow(Tip.CONTENT));

Toast.makeText(this, tip, Toast.LENGTH_LONG).show();

}

cursor.close();

}

private void _initData(){

TipDBHelper db = new TipDBHelper(this);

db.onUpgrade(db.getWritableDatabase(), TipDBHelper.VERSION, TipDBHelper.VERSION+1);

ContentValues values = new ContentValues();

String[] tip0 = new String[]{

"不要乱点哦!",

"真无聊!",

"呵呵,你真的好搞笑哦!",

"不要这么无聊哦!",

"点皇后,你点我干什么!",

"嘿嘿,好痒哦!",

"你真的笨的可以哦,点皇后嘛!",

"再乱点,小心我揍你哦!"

};

String[] tip1 = new String[]{

"皇后现在不在,去洗澡了!",

"皇后正在休息,稍后再来哦!",

"皇后正在看电视,她最讨厌别人打扰了,小心砍你头哦!",

"皇后去游御花园了,你可以去那找她!",

"皇帝来了,他们正在...",

"皇后正在洗澡,一会再来哦!",

"皇后去太后那里请安了!",

"皇后正在化妆,别打扰!"

};

String[] tip2 = new String[]{

"恭喜!皇后祝您身体健康,事事如意!",

"恭喜!皇后祝您梦想成真!",

"恭喜!皇后约你夜半三更后花园见!",

"恭喜!皇后说今天你买彩票可以中五百万!",

"恭喜!皇后说要给你一百万两银子!",

"恭喜!皇后偷偷地说:她喜欢你..."

};

String[][] tips = new String[][]{

tip0,tip1,tip2

};

for(int i=0; i<tips.length; i++){

for(int j=0; j<tips[i].length; j++){

values.put(Tip.CONTENT, tips[i][j]);

values.put(Tip.TYPE, i);

this.getContentResolver().insert(Tip.CONTENT_URI, values);

}

}

}

//初始化方法,

private void _init(){

currResultIndex=0;

Queen queen = new Queen();

results = queen.getResult(); //调用JNI,获取八皇后问题的解,初始化results数组

_placeQueens();

//_showGrid();

}

private void _placeQueens(){

theQueenIndex = this.getTheQueenIndex();//随机取得送祝福的皇后

int[] currResult = results[currResultIndex];

for(int i=0; i<currResult.length; i++){

int rIndex = i*COLUMN_NUM+currResult[i]; //计算当前皇后在棋盘中的位置

if((rIndex/COLUMN_NUM)%2==0){

//黑白

if((rIndex%COLUMN_NUM)%2 == 0){

//当前是黑色

picIds[rIndex] = R.drawable.bqueen;

}else{

picIds[rIndex] = R.drawable.wqueen;

}

}else{

//白黑

if((rIndex%COLUMN_NUM)%2 == 0){

//当前是白色

picIds[rIndex] = R.drawable.wqueen;

}else{

picIds[rIndex] = R.drawable.bqueen;

}

}

}

//chessboard.removeAllViews();

_showGrid();

}

private void _removeQueens(int index){

int[] currResult = results[index];

for(int i=0; i<currResult.length; i++){

int rIndex = i*COLUMN_NUM+currResult[i]; //计算当前皇后在棋盘中的位置

if((rIndex/COLUMN_NUM)%2==0){

//黑白

if((rIndex%COLUMN_NUM)%2 == 0){

//当前是黑色

picIds[rIndex] = R.drawable.black;

}else{

picIds[rIndex] = R.drawable.white;

}

}else{

//白黑

if((rIndex%COLUMN_NUM)%2 == 0){

//当前是白色

picIds[rIndex] = R.drawable.white;

}else{

picIds[rIndex] = R.drawable.black;

}

}

}

//chessboard.removeAllViews();

//_showGrid();

}

private void _first(){

_removeQueens(currResultIndex);

this.currResultIndex = 0;

_placeQueens();

btnPre.setEnabled(false);

btnNext.setEnabled(true);

}

private void _pre(){

_removeQueens(currResultIndex);

this.currResultIndex--;

if(currResultIndex ==0){

btnPre.setEnabled(false);

}

btnNext.setEnabled(true);

_placeQueens();

}

private void _next(){

_removeQueens(currResultIndex);

this.currResultIndex++;

if(currResultIndex == MAX_RESULT_INDEX-1){

btnNext.setEnabled(false);

}

btnPre.setEnabled(true);

_placeQueens();

}

private void _last(){

_removeQueens(currResultIndex);

this.currResultIndex=MAX_RESULT_INDEX-1;

btnNext.setEnabled(false);

btnPre.setEnabled(true);

_placeQueens();

}

public void onClic(View v){

int id = v.getId();

switch(id){

case R.id.btn_first:

_first();

break;

case R.id.btn_pre:

_pre();

break;

case R.id.btn_next:

_next();

break;

case R.id.btn_last:

_last();

break;

}

}

/**

* GridView中每一个View需要是一个ImageView

* @author chenjie

*

*/

public class GridAdapter extends BaseAdapter{

private Context context;

public GridAdapter(Context context){

this.context = context;

}

@Override

public int getCount() {

// TODO Auto-generated method stub

return picIds.length;

}

@Override

public Object getItem(int position) {

// TODO Auto-generated method stub

return picIds[position];

}

@Override

public long getItemId(int position) {

// TODO Auto-generated method stub

return position;

}

@Override

public View getView(int position, View convertView, ViewGroup parent) {

ImageView imageView;

if(convertView == null){

imageView = new ImageView(context);

imageView.setLayoutParams(new GridView.LayoutParams(40, 40));

imageView.setAdjustViewBounds(false);

imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);

imageView.setPadding(2, 2, 2, 2);

}else{

imageView = (ImageView)convertView;

}

imageView.setImageResource(picIds[position]);

return imageView;

}

}

}

5、效果预览:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: