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

上篇中简单介绍了,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 plain copy
  1. public class Queen {  
  2.       
  3.     public native int[][] getResult();  
  4. }  

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

 

3、在C中实现逻辑:

[cpp]  view plain copy
  1. #include <stdlib.h>  
  2. #include <stdio.h>  
  3. #include <math.h>  
  4. #include <org_liner_queen_Queen.h>   
  5. /* 
  6. * 求八皇后的解 
  7. */  
  8. void queen(int results[][8])  
  9. {  
  10.      int queens[8];   
  11.      int k=0;  
  12.      int currIndex = 0;  
  13.      queens[k]=-1;  
  14.        
  15.      while(k>=0)  
  16.      {  
  17.          queens[k]=queens[k]+1;  
  18.          while(queens[k]<8 && !place(k, queens))  
  19.          {  
  20.                 
  21.               queens[k]=queens[k]+1;  
  22.          }  
  23.            
  24.          if(queens[k]<8)  
  25.          {  
  26.                                 
  27.               if(k == 7)  
  28.               {  
  29.                    int i;  
  30.                    for(i=0; i<8; i++)  
  31.                    {  
  32.                         results[currIndex][i] = queens[i];   
  33.                    }  
  34.                    currIndex++;   
  35.               }else  
  36.               {  
  37.                   k++;  
  38.                   queens[k]=-1;                      
  39.               }                
  40.                 
  41.          }  
  42.          else  
  43.          {  
  44.               k--;  
  45.          }                 
  46.      }   
  47.      return;        
  48. }  
  49.         
  50. int place(int k, int* queens)  
  51. {  
  52.    int i;  
  53.    for(i=0; i<k; i++)  
  54.    {  
  55.        if(queens[i] == queens[k] || abs(queens[i]-queens[k])==abs(i-k))  
  56.        {  
  57.            return 0;   
  58.        }  
  59.    }  
  60.      
  61.    return 1;  
  62. }  
  63. //java端生成的方法  
  64. JNIEXPORT jobjectArray JNICALL Java_org_liner_queen_Queen_getResult  
  65.   (JNIEnv *env, jobject thiz)  
  66. {  
  67.      int i=0;  
  68.      jobjectArray result;  
  69.      int results[92][8];  
  70.        
  71.      queen(results);//获取92种解  
  72.        
  73.      jclass cls = (*env)->FindClass(env,"[I"); //寻找java中int[]类型  
  74.        
  75.      if(cls == NULL)  
  76.      {  
  77.          return NULL;  
  78.      }  
  79.        
  80.      //二维数组其实就是一个一维对象数组,每个元素就是一个数组对象  
  81.      //调用该接口方法实例化一个对象数组,大小92  
  82.      result = (*env)->NewObjectArray(env, 92, cls, NULL);  
  83.        
  84.      if(result == NULL)  
  85.      {  
  86.          return NULL;  
  87.      }  
  88.      //将92种解对应的每一维的数组,赋值到result  
  89.      for(i=0; i<92; i++)  
  90.      {  
  91.           jint temp[8];  
  92.           int j;  
  93.           jintArray iarr = (*env)->NewIntArray(env,8); //实例化一个一维的int类型的数组,大小为8  
  94.           if(iarr == NULL)  
  95.           {  
  96.                return NULL;   
  97.           }  
  98.           for(j=0; j<8;j++)  
  99.           {  
  100.               temp[j]=results[i][j];  
  101.           }  
  102.           (*env)->SetIntArrayRegion(env, iarr, 0, 8, temp); //给数组赋值  
  103.           (*env)->SetObjectArrayElement(env, result, i, iarr);//给对象数组赋值,单个元素  
  104.           (*env)->DeleteLocalRef(env, iarr); //释放刚刚实例化的数组  
  105.             
  106.      }  
  107.        
  108.      return result;      
  109. }  

 

4、在java端的处理:

[java]  view plain copy
  1. package org.liner.queen;  
  2. import org.liner.queen.Tips.Tip;  
  3. import android.app.Activity;  
  4. import android.content.ContentResolver;  
  5. import android.content.ContentValues;  
  6. import android.content.Context;  
  7. import android.database.Cursor;  
  8. import android.os.Bundle;  
  9. import android.util.Log;  
  10. import android.view.View;  
  11. import android.view.ViewGroup;  
  12. import android.widget.AdapterView;  
  13. import android.widget.BaseAdapter;  
  14. import android.widget.Button;  
  15. import android.widget.GridView;  
  16. import android.widget.ImageView;  
  17. import android.widget.Toast;  
  18. public class MainActivity extends Activity {  
  19.       
  20.     static{  
  21.         System.loadLibrary("org_liner_queen_Queen");  
  22.     }     
  23.       
  24.     public static final int MAX_RESULT_INDEX = 92;//92种解  
  25.     public static final int COLUMN_NUM = 8;  
  26.       
  27.     private GridView chessboard;  
  28.       
  29.     private Button btnPre,btnNext;  
  30.       
  31.     private int currResultIndex = 0;  
  32.       
  33.     private int theQueenIndex;  
  34.       
  35.     //棋盘  
  36.     private Integer picIds[] = {  
  37.             R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,  
  38.             R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,  
  39.             R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,  
  40.             R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,  
  41.             R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,  
  42.             R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,  
  43.             R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,  
  44.             R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black           
  45.     };  
  46.       
  47.     //全部解2*8+7=23  
  48.     private int[][] results;  
  49.       
  50.     @Override  
  51.     public void onCreate(Bundle savedInstanceState) {  
  52.         super.onCreate(savedInstanceState);  
  53.         setContentView(R.layout.main);  
  54.           
  55.         //btnFirst = (Button)this.findViewById(R.id.btn_first);  
  56.         btnPre = (Button)this.findViewById(R.id.btn_pre);  
  57.         btnNext = (Button)this.findViewById(R.id.btn_next);  
  58.         //btnLast = (Button)this.findViewById(R.id.btn_last);  
  59.         _initData();  
  60.           
  61.         _init();  
  62.     }  
  63.       
  64.     private void _showGrid(){  
  65.         chessboard = (GridView)this.findViewById(R.id.chessboard);  
  66.         chessboard.setAdapter(new GridAdapter(this));  
  67.           
  68.         chessboard.setOnItemClickListener(new AdapterView.OnItemClickListener() {  
  69.             @Override  
  70.             public void onItemClick(AdapterView<?> parent, View v, int position,  
  71.                     long id) {  
  72.                 // 单击事件,判断当前单击的是否是皇后所在的位置,如果是,则判断当前皇后是否  
  73.                 //是给出祝福的皇后,如果是,则随机选择一个祝福语;否则,则选择一个提示语  
  74.                 //对于非皇后的位置,如果用户点击,则  
  75.                 _tip(position);  
  76.             }  
  77.               
  78.         });       
  79.     }  
  80.       
  81.       
  82.       
  83.     private int getRandom(int maxValue){  
  84.           
  85.         return (int)(Math.random()*maxValue);  
  86.     }  
  87.       
  88.     private int getTheQueenIndex(){  
  89.         Log.v("Result:::", results.length+"");  
  90.         int col = this.getRandom(COLUMN_NUM);  
  91.         return col*COLUMN_NUM + results[currResultIndex][col];//将二维的转换成一维对应的位置  
  92.     }  
  93.       
  94.     private void _tip(int position){  
  95.         int type;  
  96.           
  97.         if(picIds[position] == R.drawable.bqueen || picIds[position]==R.drawable.wqueen){  
  98.             if(position == theQueenIndex){  
  99.                 //是送祝福的皇后  
  100.                 type=2;  
  101.             }else{  
  102.                 //不是送祝福的皇后  
  103.                 type = 1;  
  104.             }  
  105.               
  106.         }else{  
  107.             //不是皇后  
  108.             type = 0;  
  109.         }  
  110.           
  111.         String[] projection = new String[]{  
  112.                 Tip._ID,  
  113.                 Tip.CONTENT,  
  114.                 Tip.TYPE  
  115.         };  
  116.         String selection = Tip.TYPE+"=?";  
  117.         String[] selectionArgs = new String[]{  
  118.                 type+""  
  119.         };  
  120.         Cursor cursor = this.getContentResolver().query(Tip.CONTENT_URI, projection, selection, selectionArgs, null);  
  121.         //在所有的数据中随机抽取一条  
  122.         if(cursor.moveToFirst()){  
  123.             int rand = this.getRandom(cursor.getCount());  
  124.             cursor.moveToPosition(rand);  
  125.             String tip = cursor.getString(cursor.getColumnIndexOrThrow(Tip.CONTENT));  
  126.             Toast.makeText(this, tip, Toast.LENGTH_LONG).show();  
  127.         }  
  128.         cursor.close();  
  129.     }  
  130.       
  131.     private void _initData(){  
  132.           
  133.         TipDBHelper db = new TipDBHelper(this);  
  134.           
  135.         db.onUpgrade(db.getWritableDatabase(), TipDBHelper.VERSION, TipDBHelper.VERSION+1);    
  136.           
  137.           
  138.           
  139.         ContentValues values = new ContentValues();  
  140.           
  141.         String[] tip0 = new String[]{  
  142.                 "不要乱点哦!",  
  143.                 "真无聊!",  
  144.                 "呵呵,你真的好搞笑哦!",  
  145.                 "不要这么无聊哦!",  
  146.                 "点皇后,你点我干什么!",  
  147.                 "嘿嘿,好痒哦!",  
  148.                 "你真的笨的可以哦,点皇后嘛!",  
  149.                 "再乱点,小心我揍你哦!"  
  150.         };  
  151.           
  152.         String[] tip1 = new String[]{  
  153.                 "皇后现在不在,去洗澡了!",  
  154.                 "皇后正在休息,稍后再来哦!",  
  155.                 "皇后正在看电视,她最讨厌别人打扰了,小心砍你头哦!",  
  156.                 "皇后去游御花园了,你可以去那找她!",  
  157.                 "皇帝来了,他们正在...",  
  158.                 "皇后正在洗澡,一会再来哦!",  
  159.                 "皇后去太后那里请安了!",  
  160.                 "皇后正在化妆,别打扰!"  
  161.         };  
  162.           
  163.         String[] tip2 = new String[]{  
  164.                 "恭喜!皇后祝您身体健康,事事如意!",  
  165.                 "恭喜!皇后祝您梦想成真!",  
  166.                 "恭喜!皇后约你夜半三更后花园见!",  
  167.                 "恭喜!皇后说今天你买彩票可以中五百万!",  
  168.                 "恭喜!皇后说要给你一百万两银子!",  
  169.                 "恭喜!皇后偷偷地说:她喜欢你..."  
  170.         };  
  171.           
  172.         String[][] tips = new String[][]{  
  173.                 tip0,tip1,tip2  
  174.         };  
  175.           
  176.         for(int i=0; i<tips.length; i++){  
  177.             for(int j=0; j<tips[i].length; j++){  
  178.                 values.put(Tip.CONTENT, tips[i][j]);  
  179.                 values.put(Tip.TYPE, i);  
  180.                 this.getContentResolver().insert(Tip.CONTENT_URI, values);                
  181.             }  
  182.           
  183.         }   
  184.     }  
  185.       
  186.     //初始化方法,  
  187.     private void _init(){  
  188.         currResultIndex=0;  
  189.           
  190.         Queen queen = new Queen();  
  191.         results = queen.getResult(); //调用JNI,获取八皇后问题的解,初始化results数组  
  192.         _placeQueens();  
  193.         //_showGrid();  
  194.     }  
  195.       
  196.     private void _placeQueens(){  
  197.           
  198.         theQueenIndex = this.getTheQueenIndex();//随机取得送祝福的皇后  
  199.           
  200.         int[] currResult = results[currResultIndex];  
  201.         for(int i=0; i<currResult.length; i++){  
  202.             int rIndex = i*COLUMN_NUM+currResult[i]; //计算当前皇后在棋盘中的位置  
  203.               
  204.             if((rIndex/COLUMN_NUM)%2==0){  
  205.                 //黑白  
  206.                 if((rIndex%COLUMN_NUM)%2 == 0){  
  207.                     //当前是黑色  
  208.                     picIds[rIndex] = R.drawable.bqueen;  
  209.                 }else{  
  210.                     picIds[rIndex] = R.drawable.wqueen;  
  211.                 }  
  212.             }else{  
  213.                 //白黑  
  214.                 if((rIndex%COLUMN_NUM)%2 == 0){  
  215.                     //当前是白色  
  216.                     picIds[rIndex] = R.drawable.wqueen;  
  217.                 }else{  
  218.                     picIds[rIndex] = R.drawable.bqueen;  
  219.                 }                 
  220.             }  
  221.               
  222.               
  223.         }  
  224.         //chessboard.removeAllViews();  
  225.         _showGrid();  
  226.     }  
  227.       
  228.     private void _removeQueens(int index){  
  229.         int[] currResult = results[index];  
  230.         for(int i=0; i<currResult.length; i++){  
  231.             int rIndex = i*COLUMN_NUM+currResult[i]; //计算当前皇后在棋盘中的位置  
  232.               
  233.             if((rIndex/COLUMN_NUM)%2==0){  
  234.                 //黑白  
  235.                 if((rIndex%COLUMN_NUM)%2 == 0){  
  236.                     //当前是黑色  
  237.                     picIds[rIndex] = R.drawable.black;  
  238.                 }else{  
  239.                     picIds[rIndex] = R.drawable.white;  
  240.                 }  
  241.             }else{  
  242.                 //白黑  
  243.                 if((rIndex%COLUMN_NUM)%2 == 0){  
  244.                     //当前是白色  
  245.                     picIds[rIndex] = R.drawable.white;  
  246.                 }else{  
  247.                     picIds[rIndex] = R.drawable.black;  
  248.                 }                 
  249.             }  
  250.               
  251.               
  252.         }  
  253.         //chessboard.removeAllViews();  
  254.         //_showGrid();        
  255.     }  
  256.       
  257.     private void _first(){  
  258.         _removeQueens(currResultIndex);  
  259.           
  260.         this.currResultIndex = 0;  
  261.         _placeQueens();  
  262.           
  263.         btnPre.setEnabled(false);  
  264.         btnNext.setEnabled(true);  
  265.           
  266.     }  
  267.       
  268.     private void _pre(){  
  269.           
  270.         _removeQueens(currResultIndex);  
  271.           
  272.         this.currResultIndex--;  
  273.           
  274.         if(currResultIndex ==0){  
  275.             btnPre.setEnabled(false);  
  276.         }  
  277.           
  278.         btnNext.setEnabled(true);  
  279.         _placeQueens();  
  280.     }  
  281.       
  282.     private void _next(){  
  283.         _removeQueens(currResultIndex);  
  284.           
  285.         this.currResultIndex++;  
  286.           
  287.         if(currResultIndex == MAX_RESULT_INDEX-1){  
  288.             btnNext.setEnabled(false);  
  289.         }  
  290.           
  291.         btnPre.setEnabled(true);  
  292.         _placeQueens();  
  293.     }  
  294.       
  295.     private void _last(){  
  296.         _removeQueens(currResultIndex);  
  297.         this.currResultIndex=MAX_RESULT_INDEX-1;  
  298.         btnNext.setEnabled(false);  
  299.         btnPre.setEnabled(true);  
  300.           
  301.         _placeQueens();  
  302.     }  
  303.       
  304.       
  305.       
  306.     public void onClic(View v){  
  307.         int id = v.getId();  
  308.         switch(id){  
  309.         case R.id.btn_first:  
  310.             _first();  
  311.             break;  
  312.         case R.id.btn_pre:  
  313.             _pre();  
  314.             break;  
  315.               
  316.         case R.id.btn_next:  
  317.             _next();  
  318.             break;  
  319.         case R.id.btn_last:  
  320.             _last();  
  321.             break;  
  322.         }  
  323.     }  
  324.       
  325.     /** 
  326.      * GridView中每一个View需要是一个ImageView 
  327.      * @author chenjie 
  328.      * 
  329.      */  
  330.     public class GridAdapter extends BaseAdapter{  
  331.           
  332.         private Context context;  
  333.           
  334.         public GridAdapter(Context context){  
  335.             this.context = context;  
  336.         }  
  337.         @Override  
  338.         public int getCount() {  
  339.             // TODO Auto-generated method stub  
  340.             return picIds.length;  
  341.         }  
  342.         @Override  
  343.         public Object getItem(int position) {  
  344.             // TODO Auto-generated method stub  
  345.             return picIds[position];  
  346.         }  
  347.         @Override  
  348.         public long getItemId(int position) {  
  349.             // TODO Auto-generated method stub  
  350.             return position;  
  351.         }  
  352.         @Override  
  353.         public View getView(int position, View convertView, ViewGroup parent) {  
  354.             ImageView imageView;  
  355.             if(convertView == null){  
  356.                 imageView = new ImageView(context);  
  357.                 imageView.setLayoutParams(new GridView.LayoutParams(4040));  
  358.                 imageView.setAdjustViewBounds(false);  
  359.                 imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);  
  360.                 imageView.setPadding(2222);  
  361.             }else{  
  362.                 imageView = (ImageView)convertView;  
  363.             }  
  364.               
  365.             imageView.setImageResource(picIds[position]);  
  366.               
  367.             return imageView;  
  368.         }  
  369.           
  370.     }  
  371. }  

 

5、效果预览:

jj ll


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值