ボーグルを解決するアンドロイドでゲームを開発しようとしています。この段階で、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
上記の状況では、専門家に上記のエラーの解決策を提案してもらいたいと思います。