0

我正在尝试在 android 中开发一个游戏来解决这个问题。在这个阶段,我已经硬编码了 4x4 数组值。

它有一个活动和 2 个 java 助手类。问题是,当我在控制台模式下运行 java 帮助程序类时,它完美地解决了这个问题。但是,当我集成到 android 环境中时,它会抛出一个错误“不幸的是,Wordgame 已停止”并停止。

活动代码如下:

package org.example.sudoku;

import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class GameActivity extends Activity {

    public final static char matrix[][] = 
        { 
                {'s', 'h', 'g', 'n'},
                {'u', 'e', 'o', 'o'},
                {'s', 'l', 'o', 'h'},
                {'k', 'l', 'd', 'p'}
        };


    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);

        ListView list = (ListView) findViewById(R.id.list);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1);


        Solver solver = null;
        try {
            solver = new Solver();
        } catch (IOException e) {
            e.printStackTrace();
        }

        HashSet<String> words;
        words = solver.findWords(matrix, true); // The programs throws error in this line

        //DO SOMETHING WITH THE VALUE OF "words"
    }

}

Solver.java 类如下:

package org.example.sudoku;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;

public class Solver {
    private boolean q_is_qu_flag;
    private Trie st_machine;
    private HashSet<String> words_;

    public Solver() throws IOException {
        q_is_qu_flag = true;
        st_machine = new Trie();
        words_ = new HashSet<String>();

        // insert dictionary words
        FileInputStream fis = new FileInputStream("wordlist.txt");
        BufferedReader br = new BufferedReader(new InputStreamReader(fis, "UTF-8"));
        String word;
        while ((word = br.readLine()) != null) {
            st_machine.insert(word);
        }

        br.close();
    }

private void check(char matrix[][], boolean path[][], int i, int j) {
    if (i < 0 || i >= matrix.length || j < 0 || j >= matrix[0].length)
        return;

    // check if it's gonna form a cycle
    if (path[i][j] == true)
        return;

    if (!st_machine.transition_forward(matrix[i][j]))
                        return;

                // special case 'q' becomes 'qu'
                // additional transition forward
                if (matrix[i][j] == 'q' && q_is_qu_flag) {
                        if (!st_machine.transition_forward('u'))
                                return;
                }

                // update path
                path[i][j] = true;

                if (st_machine.isWord())
                        words_.add(st_machine.path());

                check(matrix, path, i-1, j-1);
                check(matrix, path,   i, j-1);
                check(matrix, path, i+1, j-1);
                check(matrix, path, i-1,   j);
                check(matrix, path, i+1,   j);
                check(matrix, path, i-1, j+1);
                check(matrix, path,   i, j+1);
                check(matrix, path, i+1, j+1);

                st_machine.transition_backward();

                // pop 'q' after popping 'u'
                if (matrix[i][j] == 'q' && q_is_qu_flag)
                        st_machine.transition_backward();

                // pop off path
                path[i][j] = false;
        }

        // Returns dictionary words found in the 2d array
        // 'q' is treated as 'qu' by default
        // call the overloaded method if you want 'q' to be treated as is
        public HashSet<String> findWords(char matrix[][]) {
                // path is used to determine cycles
                boolean path[][] = new boolean[matrix.length][matrix[0].length];
                for (int i = 0; i < matrix.length; i++) {
                        for (int j = 0; j < matrix[0].length; j++) {
                                check(matrix, path, i, j);
                        }
                }
                return words_;
        }

        // First param: 2D array of characters
        // Second param: Boolean value. If true, 'q' is treated as 'qu' else 'q' is treated as is.
        // Returns dictionary words found in the 2d array
        public HashSet<String> findWords(char matrix[][], boolean qIsQu) {
                q_is_qu_flag = qIsQu;
                return findWords(matrix);
        }
}

Trie.java 类如下:

package org.example.sudoku;

import java.util.Stack;

public class Trie {

        private class State {
                boolean isWord;
                State alphabet[];

                private State() {
                        isWord = false;
                        alphabet = new State[26]; 
                }
        }

        private State start_;
        private Stack<State> state_stack;
        private Stack<Character> path_;

        public Trie() {
                start_ = new State();
                state_stack = new Stack<State>();
                state_stack.push(start_);
                path_ = new Stack<Character>();
        }

        private int charToInt(char c) {
                return (int)Character.toUpperCase(c) - 65;
        }

        public void insert(State state, String word, int str_index) {
                if (str_index == word.length()) {
                        state.isWord = true;
                        return;
                }
                int index = charToInt(word.charAt(str_index));
                if (index < 0 || index > 25)
                        return;
                if (state.alphabet[index] == null)
                        state.alphabet[index] = new State(); 
                insert(state.alphabet[index], word, str_index+1);
        }

        public void insert(String word) {
                word = word.toUpperCase();
                this.insert(start_, word, 0);
        }

        public boolean transition_forward(char c) {
                int transition_input = charToInt(c);
                State curr_state = state_stack.peek();
                if (curr_state.alphabet[transition_input] == null)
                        return false;
                state_stack.push(curr_state.alphabet[transition_input]);
                path_.push(c);
                return true;
        }

        public boolean transition_backward() {
                if (state_stack.size() > 1) {
                        state_stack.pop();
                        path_.pop();
                        return true;
                }
                return false;
        }

        public boolean isWord() {
                return state_stack.peek().isWord;
        }

        public String path() {
                char path[] = new char[path_.size()];
                for (int i=0; i < path_.size(); i++)
                        path[i] = path_.get(i).charValue();
                return new String(path);
        }
}

AndroidManifest.xml 文件如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.example.sudoku"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="org.example.sudoku.GameActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>        
    </application>

</manifest>

logcat 输出如下:

11-14 02:09:54.511: D/gralloc_goldfish(1088): Emulator without GPU emulation detected.
11-14 02:11:57.461: I/Choreographer(1088): Skipped 33 frames!  The application may be doing too much work on its main thread.
11-14 02:11:57.941: D/dalvikvm(1088): GC_FOR_ALLOC freed 67K, 7% free 2818K/3004K, paused 70ms, total 85ms
11-14 02:11:57.961: I/dalvikvm-heap(1088): Grow heap (frag case) to 3.471MB for 635812-byte allocation
11-14 02:11:58.081: D/dalvikvm(1088): GC_FOR_ALLOC freed 7K, 6% free 3432K/3628K, paused 112ms, total 112ms
11-14 02:11:58.251: W/System.err(1088): java.io.FileNotFoundException: /wordlist.txt: open failed: ENOENT (No such file or directory)
11-14 02:11:58.251: W/System.err(1088):     at libcore.io.IoBridge.open(IoBridge.java:409)
11-14 02:11:58.251: W/System.err(1088):     at java.io.FileInputStream.<init>(FileInputStream.java:78)
11-14 02:11:58.251: W/System.err(1088):     at java.io.FileInputStream.<init>(FileInputStream.java:105)
11-14 02:11:58.281: W/System.err(1088):     at org.example.sudoku.Solver.<init>(Solver.java:20)
11-14 02:11:58.281: W/System.err(1088):     at org.example.sudoku.GameActivity.onCreate(GameActivity.java:36)
11-14 02:11:58.281: W/System.err(1088):     at android.app.Activity.performCreate(Activity.java:5133)
11-14 02:11:58.301: W/System.err(1088):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
11-14 02:11:58.301: W/System.err(1088):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
11-14 02:11:58.301: W/System.err(1088):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
11-14 02:11:58.321: W/System.err(1088):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
11-14 02:11:58.331: W/System.err(1088):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
11-14 02:11:58.331: W/System.err(1088):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-14 02:11:58.341: W/System.err(1088):     at android.os.Looper.loop(Looper.java:137)
11-14 02:11:58.341: W/System.err(1088):     at android.app.ActivityThread.main(ActivityThread.java:5103)
11-14 02:11:58.351: W/System.err(1088):     at java.lang.reflect.Method.invokeNative(Native Method)
11-14 02:11:58.351: W/System.err(1088):     at java.lang.reflect.Method.invoke(Method.java:525)
11-14 02:11:58.351: W/System.err(1088):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
11-14 02:11:58.361: W/System.err(1088):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-14 02:11:58.371: W/System.err(1088):     at dalvik.system.NativeStart.main(Native Method)
11-14 02:11:58.381: W/System.err(1088): Caused by: libcore.io.ErrnoException: open failed: ENOENT (No such file or directory)
11-14 02:11:58.411: W/System.err(1088):     at libcore.io.Posix.open(Native Method)
11-14 02:11:58.421: W/System.err(1088):     at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
11-14 02:11:58.432: W/System.err(1088):     at libcore.io.IoBridge.open(IoBridge.java:393)
11-14 02:11:58.432: W/System.err(1088):     ... 18 more
11-14 02:11:58.451: D/AndroidRuntime(1088): Shutting down VM
11-14 02:11:58.451: W/dalvikvm(1088): threadid=1: thread exiting with uncaught exception (group=0x414c4700)
11-14 02:11:58.521: E/AndroidRuntime(1088): FATAL EXCEPTION: main
11-14 02:11:58.521: E/AndroidRuntime(1088): java.lang.RuntimeException: Unable to start activity ComponentInfo{org.example.sudoku/org.example.sudoku.GameActivity}: java.lang.NullPointerException
11-14 02:11:58.521: E/AndroidRuntime(1088):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
11-14 02:11:58.521: E/AndroidRuntime(1088):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
11-14 02:11:58.521: E/AndroidRuntime(1088):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
11-14 02:11:58.521: E/AndroidRuntime(1088):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
11-14 02:11:58.521: E/AndroidRuntime(1088):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-14 02:11:58.521: E/AndroidRuntime(1088):     at android.os.Looper.loop(Looper.java:137)
11-14 02:11:58.521: E/AndroidRuntime(1088):     at android.app.ActivityThread.main(ActivityThread.java:5103)
11-14 02:11:58.521: E/AndroidRuntime(1088):     at java.lang.reflect.Method.invokeNative(Native Method)
11-14 02:11:58.521: E/AndroidRuntime(1088):     at java.lang.reflect.Method.invoke(Method.java:525)
11-14 02:11:58.521: E/AndroidRuntime(1088):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
11-14 02:11:58.521: E/AndroidRuntime(1088):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-14 02:11:58.521: E/AndroidRuntime(1088):     at dalvik.system.NativeStart.main(Native Method)
11-14 02:11:58.521: E/AndroidRuntime(1088): Caused by: java.lang.NullPointerException
11-14 02:11:58.521: E/AndroidRuntime(1088):     at org.example.sudoku.GameActivity.onCreate(GameActivity.java:42)
11-14 02:11:58.521: E/AndroidRuntime(1088):     at android.app.Activity.performCreate(Activity.java:5133)
11-14 02:11:58.521: E/AndroidRuntime(1088):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
11-14 02:11:58.521: E/AndroidRuntime(1088):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
11-14 02:11:58.521: E/AndroidRuntime(1088):     ... 11 more
11-14 02:16:58.691: I/Process(1088): Sending signal. PID: 1088 SIG: 9

在上述情况下,我会恳请专家建议我解决上述错误的方法。

4

3 回答 3

1

您无法像在 PC 上的 JVM 中那样在 Android 中打开文件。您应该将文件放到your_project/res/raw目录中,然后您可以通过 R.raw.your_file 访问它。

您打开文件的代码如下所示:

BufferedReader instream = new BufferedReader(new InputStreamReader(
                context.getResources().openRawResource(R.raw.your_file)));
于 2013-11-14T07:51:51.050 回答
0

首先,忽略异常是不好的。在您的代码中,如果Solver()抛出异常,您将打印异常并继续,就好像它没有发生一样。

您可以使用:

    try {
        solver = new Solver();
        HashSet<String> words;
        words = solver.findWords(matrix, true); 
    } catch (IOException e) {
        e.printStackTrace();
    }

真正的问题是它无法在预期的位置找到文件。

于 2013-11-14T07:51:27.707 回答
0

应用程序无法从您提到的位置获取文件 wordlist.txt。尝试从存储文件的位置获取文件。

于 2013-11-14T07:49:03.463 回答