rename, add hdpi icons, cleanup some warnings
authorgitknilch <gitknilch@cwde.de>
Sun, 24 Feb 2013 19:54:27 +0000 (20:54 +0100)
committergitknilch <gitknilch@cwde.de>
Sun, 24 Feb 2013 19:54:27 +0000 (20:54 +0100)
29 files changed:
.classpath
AndroidManifest.xml
artwork/logo.png [deleted file]
artwork/screenshots/device-2013-01-16-011637.png [deleted file]
artwork/screenshots/device-2013-01-16-011744.png [deleted file]
artwork/screenshots/device-2013-01-16-011805.png [deleted file]
artwork/screenshots/device-2013-01-16-011832.png [deleted file]
lint.xml [new file with mode: 0644]
proguard.cfg
project.properties
res/drawable-hdpi/tileset.png [new file with mode: 0644]
res/layout/options.xml
res/values/strings.xml
src/de/cwde/shisensho/Board.java [new file with mode: 0644]
src/de/cwde/shisensho/Line.java [new file with mode: 0644]
src/de/cwde/shisensho/Move.java [new file with mode: 0644]
src/de/cwde/shisensho/Point.java [new file with mode: 0644]
src/de/cwde/shisensho/ShisenSho.java [new file with mode: 0644]
src/de/cwde/shisensho/ShisenShoActivity.java [new file with mode: 0644]
src/de/cwde/shisensho/ShisenShoOptionsActivity.java [new file with mode: 0644]
src/de/cwde/shisensho/ShisenShoView.java [new file with mode: 0644]
src/org/proofofconcept/shisensho/Board.java [deleted file]
src/org/proofofconcept/shisensho/Line.java [deleted file]
src/org/proofofconcept/shisensho/Move.java [deleted file]
src/org/proofofconcept/shisensho/Point.java [deleted file]
src/org/proofofconcept/shisensho/ShisenSho.java [deleted file]
src/org/proofofconcept/shisensho/ShisenShoActivity.java [deleted file]
src/org/proofofconcept/shisensho/ShisenShoOptionsActivity.java [deleted file]
src/org/proofofconcept/shisensho/ShisenShoView.java [deleted file]

index 6c635c01d50ff53eac279f3c78174168e37a7517..835b375c7fe8e03c9a6bfbf066d06c4cf2d336d4 100644 (file)
@@ -2,6 +2,7 @@
 <classpath>
        <classpathentry kind="src" path="src"/>
        <classpathentry kind="src" path="gen"/>
-       <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+       <classpathentry kind="lib" path="/bigstorage/adt-bundle-linux-x86/sdk/platforms/android-17/android.jar"/>
+       <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
        <classpathentry kind="output" path="bin/classes"/>
 </classpath>
index 6de4e1e4141e1076cb6ebf42426f64f27c31186e..a517c8177a55fda23d8f830c273084c62a6a1cac 100644 (file)
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-      package="org.proofofconcept.shisensho"
+      package="de.cwde.shisensho"
       android:versionCode="1"
-      android:versionName="1.0">
-    <uses-sdk android:minSdkVersion="4"></uses-sdk>
+      android:versionName="0.1">
+    <uses-sdk android:minSdkVersion="5" android:targetSdkVersion="10"></uses-sdk>
 
 
        <application android:icon="@drawable/icon" android:label="@string/app_name"
-               android:name=".ShisenSho">
+               android:name=".ShisenSho" android:allowBackup="true">
                <activity android:name=".ShisenShoActivity"
                        android:screenOrientation="landscape">
                        <intent-filter>
@@ -19,7 +19,7 @@
                    android:name=".ShisenShoOptionsActivity"
                        android:screenOrientation="landscape">
                        <intent-filter>
-                               <action android:name="org.proofofconcept.shisensho.SETTINGS"/>
+                               <action android:name="de.cwde.shisensho.SETTINGS"/>
                                <category android:name="android.intent.category.DEFAULT"></category>
                        </intent-filter>
                </activity>
diff --git a/artwork/logo.png b/artwork/logo.png
deleted file mode 100644 (file)
index b5d6a6d..0000000
Binary files a/artwork/logo.png and /dev/null differ
diff --git a/artwork/screenshots/device-2013-01-16-011637.png b/artwork/screenshots/device-2013-01-16-011637.png
deleted file mode 100644 (file)
index 75205c2..0000000
Binary files a/artwork/screenshots/device-2013-01-16-011637.png and /dev/null differ
diff --git a/artwork/screenshots/device-2013-01-16-011744.png b/artwork/screenshots/device-2013-01-16-011744.png
deleted file mode 100644 (file)
index 7fe59be..0000000
Binary files a/artwork/screenshots/device-2013-01-16-011744.png and /dev/null differ
diff --git a/artwork/screenshots/device-2013-01-16-011805.png b/artwork/screenshots/device-2013-01-16-011805.png
deleted file mode 100644 (file)
index ea4a108..0000000
Binary files a/artwork/screenshots/device-2013-01-16-011805.png and /dev/null differ
diff --git a/artwork/screenshots/device-2013-01-16-011832.png b/artwork/screenshots/device-2013-01-16-011832.png
deleted file mode 100644 (file)
index 689939d..0000000
Binary files a/artwork/screenshots/device-2013-01-16-011832.png and /dev/null differ
diff --git a/lint.xml b/lint.xml
new file mode 100644 (file)
index 0000000..ee0eead
--- /dev/null
+++ b/lint.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lint>
+</lint>
\ No newline at end of file
index 12dd0392c055019367e1fede8ad2c2d6e4cbb62c..4dc32b10298dd18b543839383b0693568e392939 100644 (file)
 -keep public class * extends android.preference.Preference
 -keep public class com.android.vending.licensing.ILicensingService
 
--keepclasseswithmembernames class * {
+-keepclasseswithmembers class * {
     native <methods>;
 }
 
--keepclasseswithmembernames class * {
+-keepclasseswithmembers class * {
     public <init>(android.content.Context, android.util.AttributeSet);
 }
 
--keepclasseswithmembernames class * {
+-keepclasseswithmembers class * {
     public <init>(android.content.Context, android.util.AttributeSet, int);
 }
 
index b7c2081d560fdc20da7de29311a09e6cfa7defb8..a3ee5ab64f5e1901414e83e26717725e035b2aae 100644 (file)
@@ -11,4 +11,4 @@
 #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
 
 # Project target.
-target=android-10
+target=android-17
diff --git a/res/drawable-hdpi/tileset.png b/res/drawable-hdpi/tileset.png
new file mode 100644 (file)
index 0000000..a001c5f
Binary files /dev/null and b/res/drawable-hdpi/tileset.png differ
index 493b173e8d53f7ab8cabad84a489fc4b02aa3591..1c1352f989faa75b18c3aacc4e8059704089f4e9 100644 (file)
        <TableRow android:id="@+id/tableRow4" android:layout_height="wrap_content"
                android:layout_width="fill_parent">
                <TextView android:paddingLeft="5dip" android:layout_width="wrap_content"
-                       android:textSize="8pt" android:layout_height="wrap_content" android:id="@+id/gravityLabel" android:text="@string/gravity_label" android:layout_marginTop="12px"></TextView>
-               <ToggleButton android:id="@+id/gravity" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="ToggleButton" android:layout_marginTop="3px" android:layout_marginBottom="3px"></ToggleButton>
+                       android:textSize="8pt" android:layout_height="wrap_content" android:id="@+id/gravityLabel" android:text="@string/gravity_label" android:layout_marginTop="12dp"></TextView>
+               <ToggleButton android:id="@+id/gravity" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="3dp" android:layout_marginBottom="3dp"></ToggleButton>
        </TableRow>
        <TableRow android:id="@+id/tableRow5" android:layout_height="wrap_content"
                android:layout_width="fill_parent">
                <TextView android:paddingLeft="5dip" android:layout_width="wrap_content"
-                       android:textSize="8pt" android:layout_height="wrap_content" android:id="@+id/timeCounterLabel" android:text="@string/time_counter_label" android:layout_marginTop="12px"></TextView>
-               <ToggleButton android:id="@+id/timeCounter" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="ToggleButton" android:layout_marginTop="3px" android:layout_marginBottom="3px"></ToggleButton>
+                       android:textSize="8pt" android:layout_height="wrap_content" android:id="@+id/timeCounterLabel" android:text="@string/time_counter_label" android:layout_marginTop="12dp"></TextView>
+               <ToggleButton android:id="@+id/timeCounter" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="3dp" android:layout_marginBottom="3dp"></ToggleButton>
        </TableRow>
 </TableLayout>
index 4011bc8888da2dc5dc460c52b264114a114a0ba9..4b0535b40c421045910570bec436f3ed8c5e9ffe 100644 (file)
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
-    <string name="hello">Hello World, ShisenSho!</string>
     <string name="app_name">ShisenSho</string>
     <string name="clean">Clean</string>
     <string name="hint">Hint</string>
@@ -8,12 +7,13 @@
     <string name="options">Options</string>
     <string name="about">About</string>
     <string name="aboutText">\n
-(C) 2013 contact.proofofconcept@gmail.com\n
+&#169; 2013 knilch. Originally:\n
+&#169; 2013 contact.proofofconcept@gmail.com\n
 Images taken from kshisen (Shisen Sho 1.5.1), from the package kdegames\n
-(C) 1997 Mario Weilguni\n
+&#169; 1997 Mario Weilguni\n
 Distributed under GPL v2:\n
 http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt\n
-Get the source code: http://db.tt/Imh8zH4M  
+Get the source code: TODO
     </string>
     <string name="size">Size</string>
     <string name="difficulty">Difficulty</string>
diff --git a/src/de/cwde/shisensho/Board.java b/src/de/cwde/shisensho/Board.java
new file mode 100644 (file)
index 0000000..140b855
--- /dev/null
@@ -0,0 +1,389 @@
+package de.cwde.shisensho;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+public class Board {
+       private static String charpieces = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+       public int difficulty=1; // 1=Hard ... N=Easy                                                        
+       public boolean gravity=true;                                                                            
+       public int [] boardSize;                                                                            
+       public char[][] board;                                                                              
+       public LinkedList<Move> history;                                                                          
+
+       // ----------------------                                                                            
+       // Public methods                                                                                    
+       // ----------------------                                                                            
+
+       public Board() {                                                                         
+       }                                                                                         
+
+       // The board always has a 1-square width free rectangle that has                                     
+       // to be taken into account when specifying the size                                                 
+       public void initialize(int sizeI, int sizeJ) {                                                     
+               boardSize = new int[2];                                                                           
+               boardSize[0]=sizeI;                                                                              
+               boardSize[1]=sizeJ;                                                                              
+               board = new char[boardSize[0]][boardSize[1]];                                                    
+               for (int i=0;i<boardSize[0];i++)                                                                  
+                       for (int j=0;j<boardSize[1];j++)                                                                
+                               board[i][j]=0;                                                                                  
+               history=new LinkedList<Move>();                                                                       
+       }                                                                                                    
+
+       public static String pieceToString(char piece) {                                                  
+               return charpieces.substring(piece,1);                                                              
+       }                                                                                                    
+
+       public static char StringToPiece(String piece) {                                                  
+               char upiece;                                                                                      
+               long charpiecesLen=charpieces.length();                                                             
+               for(upiece=0;(upiece<charpiecesLen && charpieces.substring(upiece,1)!=piece);upiece++);           
+               if (upiece<charpiecesLen) return upiece;                                                          
+               else return 0;                                                                                     
+       }                                                                                                    
+
+       public String toString() {                                                                          
+               String result="  ";                                                                                
+               for (int j=0;j<boardSize[1];j++) {                                                                
+                       if (j>0) result+=" ";                                                                          
+                       result+=""+(j%10);                                                                     
+               }                                                                                                  
+               result+="\n  "+StringRepeat("--",boardSize[1]);                                                  
+               for (int i=0;i<boardSize[0];i++) {                                                                
+                       result+="\n"+(i%10)+"|";                                                                    
+                       for (int j=0;j<boardSize[1];j++) {                                                              
+                               if (j>0) result+=" ";      
+                               result+=charpieces.substring(board[i][j],board[i][j]+1);
+                       }                                                                                                
+                       result+=" |\n";                                                                                  
+                       if (i<boardSize[0]-1)                                                                           
+                               result+=" |"+StringRepeat("  ",boardSize[1])+"|";                                            
+               }                                                                                                  
+               result+="  "+StringRepeat("--",boardSize[1])+"\n";                                               
+               return result;                                                                                     
+       }                                                                                                    
+
+       public void buildRandomBoard(int sizeI, int sizeJ, int difficulty, boolean gravity) {
+               initialize(sizeI,sizeJ);                                                                
+               this.difficulty=difficulty;                                                                    
+               this.gravity=gravity;                                                                          
+
+               int numDifferentPieces=((boardSize[0]-2)*(boardSize[1]-2)/((difficulty+1)*2))+1;  
+               for (int n=0;n<((difficulty+1)*2);n++) {                                                  
+                       for (int k=0;k<numDifferentPieces;k++) {                                               
+                               int i,j;                                                                                
+                               do {                                                                                    
+                                       j=(myrand() % (boardSize[1]-2))+1;                                               
+                                       i=findFreeRow(j);                                                                 
+                               } while (i<1); 
+                               // ShisenSho.log("numDifferentPieces="+numDifferentPieces+", n="+n+", k="+(int)k+", i="+i+", j="+j);
+                               // ShisenSho.log(toString());
+                               board[i][j]=(char)k;
+                       }                                                                                         
+               }                                                                                           
+       }                                                                                             
+
+       /*                                                                                            
+         ALGORITHM TO COMPUTE CONNECTION PATH BETWEEN PIECES A (IA,JA) AND B (IB,JB)                   
+
+         - Delete A and B from the board (consider them as blank spaces)                               
+         - Calculate the set H of possible horizontal lines in the board (lines through blank spaces)  
+         - Calculate the set V of possible vertical lines in the board                                 
+         - Find HA, VA, HB, VB in the sets                                                             
+         - If HA=HB, result is a straight horizontal line A-B                                          
+         - If VA=VB, result is a straight vertical line A-B                                            
+         - If HA cuts VB, the result is an L line A-(IA,JB)-B                                          
+         - If VA cuts HB, the result is an L line A-(IB,JA)-B                                          
+         - If exists an V line that cuts HA and HB, the result is a Z line A-(IA,JV)-(IB-JV)-B         
+         - If exists an H line that cuts VA and VB, the result is a Z line A-(IV,JA)-(IV,JB)-B         
+
+         The following data types are defined:                                                         
+
+         - Board                                                                                       
+         - Point(int i, int j)                                                                         
+         - Line(Point a, Point b)                                                                      
+         - LineSet(Line l1, ..., Line lN)                                                              
+
+         The following operations are defined                                                          
+
+         - LineSet getHorizontalLines(Board board, Point a, Point b) // a and b needed to consider them as blank
+         - LineSet getVerticalLines(Board board, Point a, Point b)                                              
+         - boolean lineIsHorizontal(Line l)                                                                     
+         - boolean lineIsVertical(Line l)                                                                       
+         - boolean lineContainsPoint(Line l, Point p)                                                           
+         - boolean lineEqualsLine(Line l1, Line l2)                                                             
+         - boolean lineCutsLine(Line l1, Line l2)                                                               
+        */                                                                                                     
+       public List<Point> getPath(Point a, Point b) {                                                       
+               List<Point> result=new ArrayList<Point>();                                                                
+
+               if (getPiece(a)!=getPiece(b)) return result;                                                         
+
+               List<Line> h=getHorizontalLines(a,b);                                                              
+               List<Line> v=getVerticalLines(a,b);                                                                
+               Line ha=null, va=null, hb=null, vb=null;                                                             
+
+               for (Line l : h) {                                                                              
+                       if (l.contains(a)) ha=l;                                                                           
+                       if (l.contains(b)) hb=l;                                                                           
+                       if (ha!=null && hb!=null) break;                                                                   
+               }                                                                                                    
+
+               for (Line l : v) {                                                                              
+                       if (l.contains(a)) va=l;                                                                           
+                       if (l.contains(b)) vb=l;                                                                           
+                       if (va!=null && vb!=null) break;                                                                   
+               }                                                                                                    
+
+               // stdout.printf("va=%s, ha=%s, vb=%s, hb=%s\n",va.toString(),ha.toString(),vb.toString(),hb.toString());
+
+               if ((ha==null && va==null) || (hb==null && vb==null))                                                        
+                       return result;                                                                                               
+
+               if (ha.equals(hb) || va.equals(vb)) {                                                                        
+                       result.add(a);                                                                                          
+                       result.add(b);                                                                                          
+                       return result;                                                                                             
+               }                                                                                                            
+
+               Point ab;                                                                                                    
+
+               ab=ha.cuts(vb);                                                                                              
+               // stdout.printf("(ha cuts vb) ab=%s\n",ab.toString());                                                     
+
+               if (ab!=null) {                                                                                              
+                       result.add(a);                                                                                          
+                       result.add(ab);                                                                                         
+                       result.add(b);                                                                                          
+                       return result;                                                                                             
+               }                                                                                                            
+
+               ab=va.cuts(hb);                                                                                              
+               // stdout.printf("(va cuts hb) ab=%s\n",ab.toString());                                                     
+
+               if (ab!=null) {
+                       result.add(a);
+                       result.add(ab);
+                       result.add(b); 
+                       return result;    
+               }                   
+
+               for (Line l : v) {
+                       Point al=l.cuts(ha); 
+                       Point bl=l.cuts(hb); 
+
+                       // stdout.printf("(%s cuts ha) al=%s\n",l.toString(),al.toString());
+                       // stdout.printf("(%s cuts hb) bl=%s\n",l.toString(),bl.toString());
+
+                       if (al!=null && bl!=null) {                                           
+                               result.add(a);                                                   
+                               result.add(al);                                                  
+                               result.add(bl);                                                  
+                               result.add(b);                                                   
+                               return result;                                                      
+                       }                                                                     
+               }                                                                       
+
+               for (Line l : h) {                                                 
+                       Point al=l.cuts(va);                                                  
+                       Point bl=l.cuts(vb);                                                  
+
+                       // stdout.printf("(%s cuts va) al=%s\n",l.toString(),al.toString());
+                       // stdout.printf("(%s cuts vb) bl=%s\n",l.toString(),bl.toString());
+
+                       if (al!=null && bl!=null) {
+                               result.add(a);        
+                               result.add(al);       
+                               result.add(bl);       
+                               result.add(b);        
+                               return result;           
+                       }                          
+               }                            
+
+               return result;                 
+       }                              
+
+       public char getPiece(Point p) {
+               return board[p.i][p.j];         
+       }                                
+
+       public void setPiece(Point p, char piece) {
+               board[p.i][p.j]=piece;                      
+       }                                            
+
+       public String getStrPiece(Point p) {       
+               char piece=board[p.i][p.j];                
+               return charpieces.substring(piece,1);      
+       }                                            
+
+       public void setStrPiece(Point p, String piece) {
+               char upiece;                                   
+               long charpiecesLen=charpieces.length();          
+               for(upiece=0;(upiece<charpiecesLen && charpieces.substring(upiece,1)!=piece);upiece++);
+               if (upiece<charpiecesLen) board[p.i][p.j]=upiece;                                       
+       }                                                                                         
+
+       public void play(Point a0, Point b0) {                                                    
+               // It's important to sink the upper piece first                                         
+               Point a=(a0.i<b0.i)?a0:b0;                                                              
+               Point b=(a0.i<b0.i)?b0:a0;                                                              
+               Move m=new Move(a,b,getPiece(a));                                                      
+               history.add(0,m);                                                                   
+               setPiece(a,(char)0);                                                                         
+               processGravity(a);                                                                     
+               setPiece(b,(char)0);                                                                         
+               processGravity(b);                                                                     
+       }                                                                                         
+
+       public boolean getCanUndo() {                                                              
+               return !history.isEmpty();                                                             
+       }                                                                                         
+
+       public void undo() {                                                                      
+               if (!getCanUndo()) return;                                                            
+               Move m=history.remove(0);                                                              
+               undoGravity(m.b);                                                                      
+               setPiece(m.b,m.piece);                                                                 
+               undoGravity(m.a);                                                                      
+               setPiece(m.a,m.piece);                                                                 
+       }                                                                                         
+
+       public List<Line> getPairs(int maxResults) {                                            
+               List<Line> result=new ArrayList<Line>();                                                     
+               List<Integer> pieces=new ArrayList<Integer>();                                                       
+               List<List<Point>> piecePoints=new ArrayList<List<Point>>();                                               
+               for (int i=0;i<boardSize[0];i++)                                                       
+                       for (int j=0;j<boardSize[1];j++) {                                                   
+                               int piece=(int)board[i][j];                                                          
+                               if (piece==0) continue;                                                             
+                               int key=pieces.indexOf(piece);                                                        
+                               Point p=new Point(i,j);                                                            
+                               if (key==-1) {                                                                      
+                                       List<Point> points0=new ArrayList<Point>();                                            
+                                       points0.add(p);                                                               
+                                       pieces.add(piece);                                                             
+                                       piecePoints.add(points0);
+
+                                       key=pieces.indexOf(piece);                                                          
+                                       piecePoints.get(key);                              
+                               } else {                                                                            
+                                       List<Point> points1=piecePoints.get(key);                              
+                                       points1.add(p);                                                                
+                               }                                                                                   
+                       }                                                                                     
+
+               int nresults=0;                                                                         
+               for (List<Point> points : piecePoints) {                                     
+                       int n=(int)points.size();                                                           
+                       for (int i=0;i<n;i++) {                                                               
+                               Point a=points.get(i);                                                    
+                               for (int j=i+1;j<n;j++) {                                                           
+                                       Point b=points.get(j);                                                  
+                                       List<Point> path=getPath(a.copy(),b.copy());                                     
+                                       if (path!=null && path.size()>0) {                                              
+                                               result.add(new Line(a,b));                                                   
+                                               if (nresults++==maxResults) break;                                             
+                                       }                                                                                 
+                               }                                                                                   
+                               if (nresults==maxResults) break;                                                   
+                       }                                                                                     
+                       if (nresults==maxResults) break;                                                     
+               }                                                                                       
+               return result;                                                                          
+       }                                                                                         
+
+       public int getNumPieces() {                                                               
+               int result=0;                                                                           
+               for (int j=0;j<boardSize[1];j++) {                                                     
+                       for (int i=0;i<boardSize[0];i++) {                                                   
+                               if (board[i][j]!=0) result++;                                                        
+                       }                                                                                     
+               }                                                                                       
+               return result;                                                                          
+       }                                                                                         
+
+       // ----------------------                                                                 
+       // Private methods                                                                        
+       // ----------------------                                                                 
+
+       /* RAND_MAX assumed to be 32767 */                                                        
+       private int myrand() {                                                                    
+               return (int)Math.floor(Math.random()*32768);
+       }                                                                                         
+
+       private String StringRepeat(String s, int n) {                                           
+               String result="";                                                                       
+               for (int i=0;i<n;i++)                                                                   
+                       result+=s;                                                                            
+               return result;                                                                          
+       }                                                                                         
+
+       private int findFreeRow(int j) {                                                        
+               for (int i=1;i<boardSize[0]-1;i++) {                                                   
+                       if (board[i][j]!=0) return (i-1);                                                      
+               }                                                                                       
+               return (boardSize[0]-1-1);                                                             
+       }                                                                                         
+
+       private List<Line> getHorizontalLines(Point excludeA, Point excludeB) {               
+               List<Line> result=new ArrayList<Line>();                                                     
+               for (int i=0;i<boardSize[0];i++) {                                                     
+                       int j0=-1;                                                                            
+                       boolean empty;                                                                           
+                       for (int j=0;j<boardSize[1];j++) {                                                   
+                               empty=(board[i][j]==0 || (i==excludeA.i && j==excludeA.j)                          
+                                               || (i==excludeB.i && j==excludeB.j));                                           
+                               if (j0==-1 && empty) {                                                              
+                                       j0=j;                                                                             
+                               } else if (j0!=-1 && !empty) {                                                      
+                                       result.add(new Line(new Point(i,j0), new Point(i,j-1)));                       
+                                       j0=-1;                                                                            
+                               }                                                                                   
+                       }                                                                                     
+                       if (j0!=-1) result.add(new Line(new Point(i,j0), new Point(i,boardSize[1]-1)));   
+               }                                                                                       
+
+               // stdout.printf("\ngetHorizontalLines( %s, %s ): ",excludeA.toString(),excludeB.toString());
+               // for (Line line : result) stdout.printf("%s ",line.toString());                            
+               // stdout.printf("\n");                                                                            
+
+               return result;                                                                                     
+       }                                                                                                    
+
+       private List<Line> getVerticalLines(Point excludeA, Point excludeB) {
+               List<Line> result=new ArrayList<Line>();
+               for (int j=0;j<boardSize[1];j++) {
+                       int i0=-1;
+                       boolean empty;
+                       for (int i=0;i<boardSize[0];i++) {
+                               empty=(board[i][j]==0 || (i==excludeA.i && j==excludeA.j)
+                                               || (i==excludeB.i && j==excludeB.j));
+                               if (i0==-1 && empty) {
+                                       i0=i;
+                               } else if (i0!=-1 && !empty) {
+                                       result.add(new Line(new Point(i0,j), new Point(i-1,j)));
+                                       i0=-1;
+                               }
+                       }
+                       if (i0!=-1) result.add(new Line(new Point(i0,j), new Point(boardSize[0]-1,j)));
+               }
+
+               // stdout.printf("\ngetVerticalLines( %s, %s ): ",excludeA.toString(),excludeB.toString());
+               // for (Line line : result) stdout.printf("%s ",line.toString());
+               // stdout.printf("\n");
+
+               return result;
+       }
+
+       private void processGravity(Point p) {
+               if (gravity) for (int i=p.i;i>0;i--) board[i][p.j]=board[i-1][p.j];
+       }
+
+       private void undoGravity(Point p) {
+               if (gravity) for (int i=0;i<p.i;i++) board[i][p.j]=board[i+1][p.j];
+       }
+
+}
diff --git a/src/de/cwde/shisensho/Line.java b/src/de/cwde/shisensho/Line.java
new file mode 100644 (file)
index 0000000..0e1a915
--- /dev/null
@@ -0,0 +1,54 @@
+package de.cwde.shisensho;
+
+public class Line {
+       public Line(Point a, Point b) {
+               this.a=a;                    
+               this.b=b;                    
+       }                              
+
+       public boolean equals(Line l) {   
+               return (a.equals(l.a) && b.equals(l.b));
+       }                                         
+
+       public boolean isHorizontal() {             
+               return (a.i==b.i);                      
+       }                                         
+
+       public boolean isVertical() {               
+               return (a.j==b.j);                      
+       }                                         
+
+       public boolean contains(Point p) {
+               return (p.i==a.i && p.i==b.i && p.j>=getMin().j && p.j<=getMax().j)
+               || (p.j==a.j && p.j==b.j && p.i>=getMin().i && p.i<=getMax().i);
+       }
+
+       public Point cuts(Line l) {
+               if (isHorizontal() && l.isVertical()
+                               && getMin().j<=l.a.j && getMax().j>=l.a.j
+                               && l.getMin().i<=a.i && l.getMax().i>=a.i ) {
+                       return new Point(a.i,l.a.j);
+               } else if (isVertical() && l.isHorizontal()
+                               && getMin().i<=l.a.i && getMax().i>=l.a.i
+                               && l.getMin().j<=a.j && l.getMax().j>=a.j ) {
+                       return new Point(l.a.i,a.j);
+               } else return null;
+       }
+
+       public Point getMin() {
+               if (a.i<b.i || a.j<b.j) return a;
+               else return b;
+       }
+
+       public Point getMax() {
+               if (a.i>b.i || a.j>b.j) return a;
+               else return b;
+       }
+
+       public String toString() {
+               return a+"-"+b;
+       }
+
+       public Point a;
+       public Point b;
+}
diff --git a/src/de/cwde/shisensho/Move.java b/src/de/cwde/shisensho/Move.java
new file mode 100644 (file)
index 0000000..28bf071
--- /dev/null
@@ -0,0 +1,17 @@
+package de.cwde.shisensho;
+
+public class Move {
+       public Move(Point a, Point b, char piece) {
+               this.a=a;
+               this.b=b;
+               this.piece=piece;
+       }
+
+       public String toString() {
+               return a+"-"+b+"("+Board.pieceToString(piece)+")";
+       }
+
+       public Point a;
+       public Point b;
+       public char piece;
+}
diff --git a/src/de/cwde/shisensho/Point.java b/src/de/cwde/shisensho/Point.java
new file mode 100644 (file)
index 0000000..73879cd
--- /dev/null
@@ -0,0 +1,30 @@
+package de.cwde.shisensho;
+
+class Point {
+       public Point(int i, int j) {
+               this.i=i;
+               this.j=j;
+       }
+
+       public boolean equals(Point p) {
+               return (i==p.i && j==p.j);
+       }
+
+       public String toString() {
+               return "("+i+","+j+")";
+       }
+
+       public static Point fromString(String s) {
+               String[] ij=s.split(",",2);
+               int i=Integer.parseInt(ij[0]);
+               int j=Integer.parseInt(ij[1]);
+               return new Point(i,j);
+       }
+
+       public int i;
+       public int j;
+
+       public Point copy() {
+               return new Point(this.i,this.j);
+       }
+}
diff --git a/src/de/cwde/shisensho/ShisenSho.java b/src/de/cwde/shisensho/ShisenSho.java
new file mode 100644 (file)
index 0000000..8fe7d30
--- /dev/null
@@ -0,0 +1,117 @@
+package de.cwde.shisensho;
+
+import android.app.Application;
+import android.os.Bundle;
+import android.util.Log;
+
+public class ShisenSho extends Application {   
+       private static ShisenSho instance = null; 
+       private ShisenShoView view = null;
+       public ShisenShoActivity activity = null;
+       
+       public Board board;
+       public int[] boardSize=new int[2];
+       public int difficulty=1; // 1=Hard, 2=Easy
+       public int size=3; // 1=Small, 2=Medium, 3=Big
+       public boolean gravity=true;
+       public boolean timeCounter=true;
+
+       public static void log(String msg) {
+               Log.w("ShisenSho", msg);
+       }
+
+       public void newPlay() {
+               board = new Board();
+               board.buildRandomBoard(boardSize[0],boardSize[1],difficulty,gravity);
+       }
+
+       public void setSize(int s) {
+               switch (s) {
+               case 1:
+                       size=1;
+                       boardSize[0]=6+2;
+                       boardSize[1]=8+2;
+                       break;
+               case 2:
+                       size=2;
+                       boardSize[0]=6+2;
+                       boardSize[1]=12+2;
+                       break;
+               case 3:
+               default:
+                       size=3;
+                       boardSize[0]=6+2;
+                       boardSize[1]=16+2;
+                       break;
+               }
+       }
+
+       public void sleep(int deciSeconds) {
+               try {
+                       Thread.sleep(deciSeconds*100);
+               } catch (InterruptedException e) { }
+       }
+
+       public ShisenSho() {
+               instance = this;
+               setSize(size);
+       }
+       
+       public static synchronized ShisenSho app() {
+               return instance;
+       }
+       
+       public ShisenShoView getView() {
+               if (view == null) view = new ShisenShoView(this);
+               return view;
+       }
+               
+       /** Called when the activity is first created. */
+    @Override
+    public void onCreate() {
+        super.onCreate();
+    }
+    
+       public Bundle getOptions() {
+               Bundle options = new Bundle();
+               options.putInt("size", size);
+               options.putInt("difficulty", difficulty);
+               options.putBoolean("gravity", gravity);
+               options.putBoolean("timeCounter", timeCounter);
+               return options;
+       }
+
+       public void setOptions(Bundle options) {
+               int size = options.getInt("size");
+               int difficulty = options.getInt("difficulty");
+               boolean gravity = options.getBoolean("gravity");
+               boolean timeCounter = options.getBoolean("timeCounter");
+
+               boolean needsReset = false;
+               
+               if (size != this.size) {
+                       setSize(size);
+                       needsReset = true;
+               }
+               
+               if (difficulty != this.difficulty) {
+                       this.difficulty = difficulty;
+                       needsReset = true;
+               }
+
+               if (gravity != this.gravity) {
+                       this.gravity = gravity;
+                       needsReset = true;
+               }
+               
+               if (timeCounter != this.timeCounter) {
+                       this.timeCounter = timeCounter;
+                       view.onTimeCounterActivate();
+               }
+
+               if (needsReset) {
+                       view.reset();
+               }
+       }
+
+}
diff --git a/src/de/cwde/shisensho/ShisenShoActivity.java b/src/de/cwde/shisensho/ShisenShoActivity.java
new file mode 100644 (file)
index 0000000..b87979f
--- /dev/null
@@ -0,0 +1,120 @@
+package de.cwde.shisensho;
+
+import de.cwde.shisensho.R;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Bundle;
+import android.text.SpannableString;
+import android.text.util.Linkify;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.TextView;
+
+public class ShisenShoActivity extends Activity {
+       private ShisenShoView view;
+
+       /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+        //getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
+        //             WindowManager.LayoutParams.FLAG_FULLSCREEN);
+
+        view = ShisenSho.app().getView();
+        ShisenSho.app().activity = this;
+        setContentView(view);
+    }
+
+       @Override
+       protected void onDestroy() {
+               ViewGroup vg = (ViewGroup)(view.getParent());
+               vg.removeView(view);
+        ShisenSho.app().activity = null;
+               super.onDestroy();
+       }
+
+       @Override
+       protected void onPause() {
+               if (view!=null) {
+                       view.pauseTime();
+               }
+               super.onPause();
+       }
+
+       @Override
+       protected void onResume() {
+               super.onResume();
+               if (view!=null) {
+                       view.resumeTime();
+               }
+       }
+
+       @Override
+       public boolean onCreateOptionsMenu(Menu menu) {
+           MenuInflater inflater = getMenuInflater();
+           inflater.inflate(R.menu.menu, menu);
+           return true;
+       }
+
+       @Override
+       public boolean onOptionsItemSelected(MenuItem item) {
+           // Handle item selection
+           switch (item.getItemId()) {
+           case R.id.hint:
+           case R.id.undo:
+           case R.id.clean:
+               return view.onOptionsItemSelected(item);
+           case R.id.options:
+               startActivityForResult(new Intent("de.cwde.shisensho.SETTINGS", null), 0);
+               return true;
+           case R.id.about:
+               onAboutActivate();
+               return true;
+           default:
+               return super.onOptionsItemSelected(item);
+           }
+       }
+
+       private void onAboutActivate() {
+        // Try to load the a package matching the name of our own package
+        PackageInfo pInfo;
+               try {
+                       pInfo = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_META_DATA);
+               String aboutTitle = String.format("About %s", getString(R.string.app_name));
+               String versionString = String.format("Version: %s", pInfo.versionName);
+               String aboutText = getString(R.string.aboutText);
+
+               // Set up the TextView
+               final TextView message = new TextView(this);
+               // We'll use a spannablestring to be able to make links clickable
+               final SpannableString s = new SpannableString(aboutText);
+
+               // Set some padding
+               message.setPadding(5, 5, 5, 5);
+               // Set up the final string
+               message.setText(versionString + "\n" + s);
+               // Now linkify the text
+               Linkify.addLinks(message, Linkify.ALL);
+
+               new AlertDialog.Builder(this)
+                       .setTitle(aboutTitle)
+                       .setCancelable(true)
+                       .setIcon(R.drawable.icon)
+                       .setPositiveButton(getString(android.R.string.ok), null)
+                       .setView(message).create()
+                       .show();
+               } catch (NameNotFoundException e) {
+                       e.printStackTrace();
+               }
+       }
+}
diff --git a/src/de/cwde/shisensho/ShisenShoOptionsActivity.java b/src/de/cwde/shisensho/ShisenShoOptionsActivity.java
new file mode 100644 (file)
index 0000000..9d3ecbb
--- /dev/null
@@ -0,0 +1,101 @@
+package de.cwde.shisensho;
+
+import java.io.Serializable;
+
+import de.cwde.shisensho.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.Window;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.CompoundButton;
+import android.widget.Spinner;
+import android.widget.ToggleButton;
+
+public class ShisenShoOptionsActivity extends Activity {
+
+       Bundle state;
+       ShisenSho app;
+
+       private void appToState (boolean merge) {
+               String[] fields = { "size", "difficulty", "gravity", "timeCounter" };
+               Bundle options = app.getOptions();
+               if (state == null) state = new Bundle();
+               for (int i=0; i<fields.length; i++) {
+                       if (!merge || !state.containsKey(fields[i])) {
+                               state.putSerializable(fields[i], (Serializable)(options.get(fields[i])));
+                       }
+               }
+       }
+
+       /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+        setContentView(R.layout.options);
+
+        app = ShisenSho.app();
+        state = savedInstanceState;
+        appToState(true);
+
+        Spinner s;
+        ToggleButton tb;
+        ArrayAdapter adapter;
+
+        s = (Spinner) findViewById(R.id.size);
+        adapter = ArrayAdapter.createFromResource(
+                this, R.array.sizes, android.R.layout.simple_spinner_item);
+        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        s.setAdapter(adapter);
+        s.setSelection(state.getInt("size")-1);
+        s.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+                       public void onItemSelected(AdapterView<?> arg0, View arg1,
+                                       int pos, long arg3) {
+                               state.putInt("size", pos+1);
+                       }
+
+                       public void onNothingSelected(AdapterView<?> arg0) { }
+        });
+
+        s = (Spinner) findViewById(R.id.difficulty);
+        adapter = ArrayAdapter.createFromResource(
+                this, R.array.difficulties, android.R.layout.simple_spinner_item);
+        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        s.setAdapter(adapter);
+        s.setSelection(2-state.getInt("difficulty"));
+        s.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+                       public void onItemSelected(AdapterView<?> arg0, View arg1,
+                                       int pos, long arg3) {
+                               state.putInt("difficulty", 2-pos);
+                       }
+
+                       public void onNothingSelected(AdapterView<?> arg0) { }
+        });
+
+        tb = (ToggleButton) findViewById(R.id.gravity);
+        tb.setChecked(state.getBoolean("gravity"));
+        tb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+                       public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
+                               state.putBoolean("gravity", arg1);
+                       }
+        });
+
+        tb = (ToggleButton) findViewById(R.id.timeCounter);
+        tb.setChecked(state.getBoolean("timeCounter"));
+        tb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+                       public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
+                               state.putBoolean("timeCounter", arg1);
+                       }
+        });
+    }
+
+       @Override
+       public void onBackPressed() {
+               app.setOptions(state);
+               super.onBackPressed();
+       }
+
+}
diff --git a/src/de/cwde/shisensho/ShisenShoView.java b/src/de/cwde/shisensho/ShisenShoView.java
new file mode 100644 (file)
index 0000000..cb1a57c
--- /dev/null
@@ -0,0 +1,662 @@
+package de.cwde.shisensho;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import de.cwde.shisensho.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Paint.Align;
+import android.graphics.Paint.Cap;
+import android.graphics.Paint.Join;
+import android.graphics.Paint.Style;
+import android.graphics.Rect;
+import android.graphics.Typeface;
+import android.os.Handler;
+import android.os.Message;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+class ShisenShoView extends SurfaceView implements SurfaceHolder.Callback {
+
+       private enum StatePlay { UNINITIALIZED, IDLE, SELECTED1, SELECTED2, GAMEOVER };
+       private enum StatePaint { BOARD, SELECTED1, SELECTED2, MATCHED, WIN, LOSE, HINT, TIME };
+
+       private int screenWidth;
+       private int screenHeight;
+       private int tilesetRows;
+       private int tilesetCols;
+       private int tileHeight;
+       private int tileWidth;
+       private Bitmap bg;
+       private Bitmap tile[];
+       private int[] selection1=new int[2];
+       private int[] selection2=new int[2];
+       private List<Point> path=null;
+       private List<Line> pairs=null;
+       private long startTime;
+       private long playTime;
+       private long baseTime;
+       private Timer timer;
+       private static Handler timerHandler;
+
+       private boolean timerRegistered=false;
+       private ShisenSho app;
+       private StatePlay cstate;
+       private StatePaint pstate;
+       private Canvas canvas = null;
+       private SurfaceHolder surfaceHolder = null;
+       public ShisenShoView(ShisenSho shishenSho) {
+               super((Context)shishenSho);
+               this.app = shishenSho;
+               cstate = StatePlay.UNINITIALIZED;
+               surfaceHolder = getHolder();
+               surfaceHolder.addCallback(this);
+       }
+
+       private void paint(StatePaint pstate) {
+               this.pstate=pstate;
+               repaint();
+       }
+
+       private void control(StatePlay cstate) {
+               this.cstate=cstate;
+       }
+
+       private void loadTileset() {
+               BitmapFactory.Options ops = new BitmapFactory.Options();
+               ops.inScaled = false;
+               Bitmap tileset = BitmapFactory.decodeResource(getResources(), R.drawable.tileset, ops);
+               tileset.setDensity(Bitmap.DENSITY_NONE);
+
+               // The tile set has 4 rows x 9 columns
+               tilesetRows = 4;
+               tilesetCols = 9;
+               tileWidth = tileset.getWidth()/tilesetCols;
+               tileHeight = tileset.getHeight()/tilesetRows;
+               tile = new Bitmap[tilesetRows*tilesetCols];
+               int k=0;
+               for (int i=0; i<tilesetRows; i++) {
+                       for (int j=0; j<tilesetCols; j++) {
+                               tile[k] = Bitmap.createBitmap(tileset, j*tileWidth, i*tileHeight, tileWidth, tileHeight, null, false);
+                               tile[k].setDensity(Bitmap.DENSITY_NONE);
+                               k++;
+                       }
+               }
+               tileWidth = tile[0].getWidth();
+               tileHeight = tile[0].getHeight();
+       }
+
+       private void loadBackground() {
+               BitmapFactory.Options ops = new BitmapFactory.Options();
+               ops.inScaled = false;
+               bg = BitmapFactory.decodeResource(getResources(), R.drawable.kshisen_bgnd, ops);
+               bg.setDensity(Bitmap.DENSITY_NONE);
+       }
+
+       private void registerTimer() {
+               if (timer!=null) return; // Already registered
+               timerHandler = new Handler() {
+                       public void handleMessage(Message msg) {
+                               onUpdateTime();
+                       }
+               };
+               timer=new Timer();
+       timer.scheduleAtFixedRate(new TimerTask() {
+               public void run() {
+                       timerHandler.sendEmptyMessage(Activity.RESULT_OK);
+               }
+       }, 0, 1000);
+               timerRegistered=true;
+       }
+
+       private void unregisterTimer() {
+               if (timer==null) return; // Already unregistered
+               timer.cancel();
+       timer = null;
+               timerHandler = null;
+               timerRegistered=false;
+       }
+
+       public void pauseTime() {
+               updateTime();
+               baseTime = playTime;
+               startTime = System.currentTimeMillis();
+
+       }
+
+       public void resumeTime() {
+               startTime = System.currentTimeMillis();
+               updateTime();
+       }
+
+       private void updateTime() {
+               if (cstate!=StatePlay.GAMEOVER) {
+                       playTime = (System.currentTimeMillis()-startTime)/1000+baseTime;
+               }
+       }
+
+       private void initializeGame() {
+               loadBackground();
+               loadTileset();
+               screenWidth=getWidth();
+               screenHeight=getHeight();
+               //undo.sensitive=false;
+               pstate=StatePaint.BOARD;
+               app.newPlay();
+               control(StatePlay.IDLE);
+               startTime=System.currentTimeMillis();
+               playTime=0;
+               baseTime=0;
+               if (app.timeCounter && !timerRegistered) {
+                       registerTimer();
+               }
+               pairs=app.board.getPairs(1);
+       }
+
+       public boolean onOptionsItemSelected(MenuItem item) {
+           // Handle item selection
+           switch (item.getItemId()) {
+           case R.id.hint:
+               this.postDelayed(new Runnable() { public void run() { onHintActivate(); } }, 100);
+               return true;
+           case R.id.undo:
+               this.postDelayed(new Runnable() { public void run() { onUndoActivate(); } }, 100);
+               return true;
+           case R.id.clean:
+               this.postDelayed(new Runnable() { public void run() { reset(); } }, 100);
+               return true;
+           case R.id.options:
+               return true;
+           case R.id.about:
+               return true;
+           default:
+               return false;
+           }
+       }
+
+       public void reset() {
+               control(StatePlay.UNINITIALIZED);
+               paint(StatePaint.BOARD);
+       }
+
+       private void onHintActivate() {
+               if (cstate!=StatePlay.GAMEOVER) {
+                       pairs=app.board.getPairs(1);
+                       paint(StatePaint.HINT);
+                       app.sleep(10);
+                       paint(StatePaint.BOARD);
+                       control(StatePlay.IDLE);
+               }
+       }
+
+       private void onUndoActivate() {
+               if (app.board.getCanUndo()) {
+                       if (cstate==StatePlay.GAMEOVER && app.timeCounter && !timerRegistered) {
+                               // Reprogram the time update that had been
+                               // deactivated with the game over status
+                               registerTimer();
+                       }
+                       app.board.undo();
+                       paint(StatePaint.BOARD);
+                       //undo.sensitive=app.board.getCanUndo();
+                       control(StatePlay.IDLE);
+               }
+       }
+
+       public void onTimeCounterActivate() {
+               if (app.timeCounter && cstate!=StatePlay.GAMEOVER && !timerRegistered) {
+                       // Reprogram the time update that had been
+                       // deactivated with the time_counter=false
+                       registerTimer();
+               }
+       }
+
+       private void onUpdateTime() {
+               paint(pstate);
+           if (!(app.timeCounter && cstate!=StatePlay.GAMEOVER)) {
+               unregisterTimer();
+           }
+       }
+
+       public void drawMessage(Canvas canvas, int x, int y, boolean centered, String message, String color, float textSize)  {
+               Paint paint = new Paint();
+               paint.setColor(Color.parseColor(color));
+               paint.setLinearText(true);
+               paint.setAntiAlias(true);
+               paint.setTextAlign(centered?Align.CENTER:Align.LEFT);
+               paint.setTypeface(Typeface.SANS_SERIF);
+               paint.setFakeBoldText(true);
+               paint.setTextSize(textSize);
+               canvas.drawText(message, x, y, paint);
+       }
+
+       public void repaint() {
+               if (surfaceHolder == null) return;
+               try {
+                       if (canvas == null) canvas = surfaceHolder.lockCanvas(null);
+                       if (canvas == null) return;
+                       if (cstate==StatePlay.UNINITIALIZED) initializeGame();
+                       synchronized (surfaceHolder) {
+                               doDraw(canvas);
+                       }
+               } finally {
+                       if (canvas != null) {
+                               surfaceHolder.unlockCanvasAndPost(canvas);
+                               canvas = null;
+                       }
+               }
+       }
+
+       protected void doDraw(Canvas canvas) {
+               try {
+                       // Double buffering
+                       // Bitmap buffer = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
+                       //Canvas cbuffer = new Canvas(buffer);
+                       Canvas cbuffer = canvas;
+                       if (canvas == null) return;
+
+                       //super.onDraw(canvas);
+
+                       // Board upper left corner on screen
+                       int x0=0;
+                       int y0=0;
+
+                       if (app!=null && app.board!=null) {
+                               x0=(screenWidth-app.board.boardSize[1]*tileWidth)/2;
+                               y0=(screenHeight-app.board.boardSize[0]*tileHeight)/2;
+                       }
+
+                       int red = Color.parseColor("#FF0000");
+                       int orange = Color.parseColor("#F0C000");
+                       Paint paint = new Paint();
+                       paint.setFlags(Paint.ANTI_ALIAS_FLAG);
+
+                       // Background & board painting
+                       switch (pstate) {
+                       case BOARD:
+                       case SELECTED1:
+                       case SELECTED2:
+                       case MATCHED:
+                       case WIN:
+                       case LOSE:
+                       case HINT:
+                       case TIME:
+                               // Background painting
+                               int bgWidth = bg.getWidth();
+                               int bgHeight = bg.getHeight();
+                               for (int i=0; i<screenHeight/bgHeight+1; i++) {
+                                       for (int j=0; j<screenWidth/bgWidth+1; j++) {
+                                               cbuffer.drawBitmap(bg, j*bgWidth, i*bgHeight, paint);
+                                       }
+                               }
+
+                               // Board painting
+                               // Max visible size: 7x17
+                               if (app!=null && app.board!=null) {
+                                       for (int i=0;i<app.board.boardSize[0];i++) {
+                                               for (int j=0;j<app.board.boardSize[1];j++) {
+                                                       // Tiles are 56px height, 40px width each
+                                                       char piece=app.board.board[i][j];
+                                                       if (piece!=0) {
+                                                               cbuffer.drawBitmap(tile[piece], x0+j*tileWidth, y0+i*tileHeight, paint);
+                                                       }
+                                               }
+                                       }
+                               }
+                               break;
+                       }
+
+                       // Red rectangle for selection 1
+                       switch (pstate) {
+                       case SELECTED1:
+                       case SELECTED2:
+                       case MATCHED:
+                               paint.setColor(red);
+                               paint.setStyle(Style.STROKE);
+                               paint.setStrokeCap(Cap.ROUND);
+                               paint.setStrokeJoin(Join.ROUND);
+                               paint.setStrokeWidth(3);
+                               cbuffer.drawRect(new Rect(
+                                               x0+selection1[1]*tileWidth-2,
+                                               y0+selection1[0]*tileHeight-2,
+                                               x0+selection1[1]*tileWidth-2+tileWidth+2*2,
+                                               y0+selection1[0]*tileHeight-2+tileHeight+2*2),
+                                               paint);
+                               break;
+                       }
+
+                       // Red rectangle for selection 2
+                       switch (pstate) {
+                       case SELECTED2:
+                       case MATCHED:
+                               paint.setColor(red);
+                               paint.setStyle(Style.STROKE);
+                               paint.setStrokeCap(Cap.ROUND);
+                               paint.setStrokeJoin(Join.ROUND);
+                               paint.setStrokeWidth(3);
+                               cbuffer.drawRect(new Rect(
+                                               x0+selection2[1]*tileWidth-2,
+                                               y0+selection2[0]*tileHeight-2,
+                                               x0+selection2[1]*tileWidth-2+tileWidth+2*2,
+                                               y0+selection2[0]*tileHeight-2+tileHeight+2*2),
+                                               paint);
+                               break;
+                       }
+
+                       // Matching path
+                       switch (pstate) {
+                       case MATCHED:
+                               paint.setColor(red);
+                               paint.setStyle(Style.STROKE);
+                               paint.setStrokeCap(Cap.ROUND);
+                               paint.setStrokeJoin(Join.ROUND);
+                               paint.setStrokeWidth(3);
+
+                               if (path!=null) {
+                                       Point p0=null;
+                                       for (Point p1 : path) {
+                                               if (p0!=null) {
+                                                       cbuffer.drawLine(
+                                                                       x0+p0.j*tileWidth-2+(tileWidth/2),
+                                                                       y0+p0.i*tileHeight-2+(tileHeight/2),
+                                                                       x0+p1.j*tileWidth-2+(tileWidth/2),
+                                                                       y0+p1.i*tileHeight-2+(tileHeight/2),
+                                                                       paint);
+                                               }
+                                               p0=p1;
+                                       }
+                               }
+                               break;
+                       }
+
+                       // Orange hint rectangles
+                       switch (pstate) {
+                       case HINT:
+                               if (pairs!=null && pairs.size()>0) {
+                                       Line pair=pairs.get(0);
+                                       Point a=pair.a;
+                                       Point b=pair.b;
+                                       path=app.board.getPath(a,b);
+                                       paint.setColor(orange);
+                                       paint.setStyle(Style.STROKE);
+                                       paint.setStrokeCap(Cap.ROUND);
+                                       paint.setStrokeJoin(Join.ROUND);
+                                       paint.setStrokeWidth(3);
+
+                                       cbuffer.drawRect(new Rect(
+                                                       x0+a.j*tileWidth-2,
+                                                       y0+a.i*tileHeight-2,
+                                                       x0+a.j*tileWidth-2+tileWidth+2*2,
+                                                       y0+a.i*tileHeight-2+tileHeight+2*2),
+                                                       paint);
+
+                                       if (path!=null) {
+                                               Point p0=null;
+                                               for (Point p1 : path) {
+                                                       if (p0!=null) {
+                                                               cbuffer.drawLine(
+                                                                               x0+p0.j*tileWidth-2+(tileWidth/2),
+                                                                               y0+p0.i*tileHeight-2+(tileHeight/2),
+                                                                               x0+p1.j*tileWidth-2+(tileWidth/2),
+                                                                               y0+p1.i*tileHeight-2+(tileHeight/2),
+                                                                               paint);
+                                                       }
+                                                       p0=p1;
+                                               }
+                                               path=null;
+                                       }
+
+                                       cbuffer.drawRect(new Rect(
+                                                       x0+b.j*tileWidth-2,
+                                                       y0+b.i*tileHeight-2,
+                                                       x0+b.j*tileWidth-2+tileWidth+2*2,
+                                                       y0+b.i*tileHeight-2+tileHeight+2*2),
+                                                       paint);
+                               }
+                               break;
+                       }
+
+                       // Win & loose notifications
+                       switch (pstate) {
+                       case WIN:
+                               drawMessage(cbuffer, screenWidth/2,screenHeight/2,true,"You Win!", "#FFFFFF", 100);
+                               break;
+                       case LOSE:
+                               drawMessage(cbuffer, screenWidth/2,screenHeight/2,true,"Game Over", "#FFFFFF", 100);
+                               break;
+                       }
+
+                       if (app.timeCounter) switch (pstate) {
+                       case BOARD:
+                       case SELECTED1:
+                       case SELECTED2:
+                       case MATCHED:
+                       case WIN:
+                       case LOSE:
+                       case HINT:
+                       case TIME:
+                               updateTime();
+                               int hours=(int)(playTime/(60*60));
+                               int minutes=(int)((playTime/60)%60);
+                               int seconds=(int)(playTime%60);
+                               String time=String.format(Locale.US, "%01d:%02d:%02d", hours, minutes, seconds);
+
+                               int timePosX=screenWidth-120;
+                               int timePosY=screenHeight-10;
+
+                               drawMessage(cbuffer, timePosX+1,timePosY+1,false,time,"#000000",30);
+                               drawMessage(cbuffer, timePosX,timePosY,false,time,"#FFFFFF",30);
+                               break;
+                       }
+
+                       // Debug messages
+                       /*
+                       debugMessage="StatePlay: "+cstate+"\n"+"StatePaint: "+pstate;
+                       if (debugMessage!=null && debugMessage.length()>0) {
+                               int l = 20;
+                               String lines[] = debugMessage.split("\n");
+                               for (int i=0; i<lines.length; i++) {
+                                       drawMessage(cbuffer,1,l,false,lines[i],"#FFFF00",30);
+                                       l+=30;
+                               }
+                       }
+                       */
+
+                       // Double buffer dumping
+                       // canvas.drawBitmap(buffer, 0, 0, null);
+
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+
+       }
+
+       @Override
+       public boolean onTouchEvent(MotionEvent event) {
+               if (event.getAction()==MotionEvent.ACTION_DOWN) {
+                       onClick(Math.round(event.getX()),Math.round(event.getY()));
+               }
+               return super.onTouchEvent(event);
+       }
+
+       private void onClick(int x, int y) {
+               try {
+                       int i=(y-(screenHeight-app.board.boardSize[0]*tileHeight)/2)/tileHeight;
+                       int j=(x-(screenWidth-app.board.boardSize[1]*tileWidth)/2)/tileWidth;
+
+                       switch (cstate) {
+                       case IDLE:
+                               if (i>=0 &&
+                                               i<app.board.boardSize[0] &&
+                                               j>=0 && j<app.board.boardSize[1] &&
+                                               app.board.board[i][j]!=0) {
+                                       selection1[0]=i;
+                                       selection1[1]=j;
+                                       paint(StatePaint.SELECTED1);
+                                       control(StatePlay.SELECTED1);
+                               }
+                               break;
+                       case SELECTED1:
+                               if (i>=0 && i<app.board.boardSize[0] &&
+                                               j>=0 && j<app.board.boardSize[1] &&
+                                               app.board.board[i][j]!=0) {
+                                       if (i==selection1[0] && j==selection1[1]) {
+                                               paint(StatePaint.BOARD);
+                                               control(StatePlay.IDLE);
+                                       } else {
+                                               selection2[0]=i;
+                                               selection2[1]=j;
+                                               paint(StatePaint.SELECTED2);
+
+                                               Point a=new Point(selection1[0],selection1[1]);
+                                               Point b=new Point(selection2[0],selection2[1]);
+                                               path=app.board.getPath(a,b);
+                                               paint(StatePaint.MATCHED);
+                                               app.sleep(2);
+                                               paint(StatePaint.BOARD);
+                                               if (path.size()>0) {
+                                                       app.board.play(a,b);
+                                               }
+                                               path=null;
+                                               paint(StatePaint.BOARD);
+
+                                               pairs=app.board.getPairs(1);
+                                               if (pairs.size()==0) {
+                                                       if (app.board.getNumPieces()==0) {
+                                                               paint(StatePaint.WIN);
+                                                       } else {
+                                                               paint(StatePaint.LOSE);
+                                                       }
+                                                       control(StatePlay.GAMEOVER);
+                                               } else {
+                                                       control(StatePlay.IDLE);
+                                               }
+                                               //undo.sensitive=app.board.getCanUndo();
+                                       }
+                               }
+                               break;
+                       case GAMEOVER:
+                               reset();
+                               paint(StatePaint.BOARD);
+                               break;
+                       }
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       public void surfaceChanged(SurfaceHolder holder, int format, int width,
+                       int height) {
+               surfaceHolder = holder;
+               if (cstate!=StatePlay.GAMEOVER && app.timeCounter && !timerRegistered) {
+                       registerTimer();
+               }
+               repaint();
+       }
+
+       public void surfaceCreated(SurfaceHolder holder) {
+               surfaceHolder = holder;
+               repaint();
+       }
+
+       public void surfaceDestroyed(SurfaceHolder holder) {
+               surfaceHolder = null;
+               if (timerRegistered) {
+                       unregisterTimer();
+               }
+       }
+
+       /*
+       @Override
+       protected void onDraw(Canvas canvas) {
+               super.onDraw(canvas);
+
+               if (!initialized) initialize();
+
+               long currTime = System.currentTimeMillis();
+
+               a = (float)(currTime - startTime) / (float)duration;
+               if (a > (float)1.0) a = (float)1.0;
+
+               x = Math.round(nextx*a + prevx*(1-a));
+               y = Math.round(nexty*a + prevy*(1-a));
+
+               if (a == (float)1.0) computeNextTarget();
+
+               int bgWidth = bg.getWidth();
+               int bgHeight = bg.getHeight();
+               for (int i=0; i<height/bgHeight+1; i++) {
+                       for (int j=0; j<width/bgWidth+1; j++) {
+                               canvas.drawBitmap(bg, j*bgWidth, i*bgHeight, paint);
+                       }
+               }
+
+               canvas.drawBitmap(tile[randomtile], x, y, paint);
+
+               repaint();
+       }
+
+       @Override
+       public boolean onTouchEvent(MotionEvent event) {
+               if (event.getActionMasked()==MotionEvent.ACTION_DOWN) {
+                       //computeNextTarget();
+                       //nextx=Math.round(event.getX());
+                       //nexty=Math.round(event.getY());
+               }
+               return super.onTouchEvent(event);
+       }
+
+       private void initialize() {
+               width = getWidth();
+               height = getHeight();
+
+               bg = BitmapFactory.decodeResource(getResources(), R.drawable.kshisen_bgnd);
+               Bitmap tileset = BitmapFactory.decodeResource(getResources(), R.drawable.tileset);
+
+               // The tile set has 4 rows x 9 columns
+               tsrows = 4;
+               tscols = 9;
+               twidth = tileset.getWidth()/tscols;
+               theight = tileset.getHeight()/tsrows;
+               tile = new Bitmap[tsrows*tscols];
+               int k=0;
+               for (int i=0; i<tsrows; i++) {
+                       for (int j=0; j<tscols; j++) {
+                               tile[k] = Bitmap.createBitmap(tileset, j*twidth, i*theight, twidth, theight, null, false);
+                               k++;
+                       }
+               }
+
+               x = width/2;
+               y = height/2;
+
+               computeNextTarget();
+
+               initialized = true;
+       }
+
+       private void computeNextTarget() {
+               startTime = System.currentTimeMillis();
+               prevx = x;
+               prevy = y;
+               nextx = (int) Math.floor(Math.random() * width);
+               nexty = (int) Math.floor(Math.random() * height);
+               randomtile = (int) Math.floor(Math.random() * tile.length);
+
+               paint = new Paint();
+               paint.setColor(Color.parseColor("#006666"));
+               paint.setFlags(Paint.ANTI_ALIAS_FLAG);
+       }
+*/
+}
\ No newline at end of file
diff --git a/src/org/proofofconcept/shisensho/Board.java b/src/org/proofofconcept/shisensho/Board.java
deleted file mode 100644 (file)
index 436d187..0000000
+++ /dev/null
@@ -1,391 +0,0 @@
-package org.proofofconcept.shisensho;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-public class Board {
-       private static String charpieces = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
-
-       public int difficulty=1; // 1=Hard ... N=Easy                                                        
-       public boolean gravity=true;                                                                            
-       public int [] boardSize;                                                                            
-       public char[][] board;                                                                              
-       public LinkedList<Move> history;                                                                          
-
-       // ----------------------                                                                            
-       // Public methods                                                                                    
-       // ----------------------                                                                            
-
-       public Board() {                                                                         
-       }                                                                                         
-
-       // The board always has a 1-square width free rectangle that has                                     
-       // to be taken into account when specifying the size                                                 
-       public void initialize(int sizeI, int sizeJ) {                                                     
-               boardSize = new int[2];                                                                           
-               boardSize[0]=sizeI;                                                                              
-               boardSize[1]=sizeJ;                                                                              
-               board = new char[boardSize[0]][boardSize[1]];                                                    
-               for (int i=0;i<boardSize[0];i++)                                                                  
-                       for (int j=0;j<boardSize[1];j++)                                                                
-                               board[i][j]=0;                                                                                  
-               history=new LinkedList<Move>();                                                                       
-       }                                                                                                    
-
-       public static String pieceToString(char piece) {                                                  
-               return charpieces.substring(piece,1);                                                              
-       }                                                                                                    
-
-       public static char StringToPiece(String piece) {                                                  
-               char upiece;                                                                                      
-               long charpiecesLen=charpieces.length();                                                             
-               for(upiece=0;(upiece<charpiecesLen && charpieces.substring(upiece,1)!=piece);upiece++);           
-               if (upiece<charpiecesLen) return upiece;                                                          
-               else return 0;                                                                                     
-       }                                                                                                    
-
-       public String toString() {                                                                          
-               String result="  ";                                                                                
-               for (int j=0;j<boardSize[1];j++) {                                                                
-                       if (j>0) result+=" ";                                                                          
-                       result+=""+(j%10);                                                                     
-               }                                                                                                  
-               result+="\n  "+StringRepeat("--",boardSize[1]);                                                  
-               for (int i=0;i<boardSize[0];i++) {                                                                
-                       result+="\n"+(i%10)+"|";                                                                    
-                       for (int j=0;j<boardSize[1];j++) {                                                              
-                               if (j>0) result+=" ";      
-                               result+=charpieces.substring(board[i][j],board[i][j]+1);
-                       }                                                                                                
-                       result+=" |\n";                                                                                  
-                       if (i<boardSize[0]-1)                                                                           
-                               result+=" |"+StringRepeat("  ",boardSize[1])+"|";                                            
-               }                                                                                                  
-               result+="  "+StringRepeat("--",boardSize[1])+"\n";                                               
-               return result;                                                                                     
-       }                                                                                                    
-
-       public void buildRandomBoard(int sizeI, int sizeJ, int difficulty, boolean gravity) {
-               initialize(sizeI,sizeJ);                                                                
-               this.difficulty=difficulty;                                                                    
-               this.gravity=gravity;                                                                          
-
-               int numDifferentPieces=((boardSize[0]-2)*(boardSize[1]-2)/((difficulty+1)*2))+1;  
-               for (int n=0;n<((difficulty+1)*2);n++) {                                                  
-                       for (int k=0;k<numDifferentPieces;k++) {                                               
-                               int i,j;                                                                                
-                               do {                                                                                    
-                                       j=(myrand() % (boardSize[1]-2))+1;                                               
-                                       i=findFreeRow(j);                                                                 
-                               } while (i<1); 
-                               // ShisenSho.log("numDifferentPieces="+numDifferentPieces+", n="+n+", k="+(int)k+", i="+i+", j="+j);
-                               // ShisenSho.log(toString());
-                               board[i][j]=(char)k;
-                       }                                                                                         
-               }                                                                                           
-       }                                                                                             
-
-       /*                                                                                            
-         ALGORITHM TO COMPUTE CONNECTION PATH BETWEEN PIECES A (IA,JA) AND B (IB,JB)                   
-
-         - Delete A and B from the board (consider them as blank spaces)                               
-         - Calculate the set H of possible horizontal lines in the board (lines through blank spaces)  
-         - Calculate the set V of possible vertical lines in the board                                 
-         - Find HA, VA, HB, VB in the sets                                                             
-         - If HA=HB, result is a straight horizontal line A-B                                          
-         - If VA=VB, result is a straight vertical line A-B                                            
-         - If HA cuts VB, the result is an L line A-(IA,JB)-B                                          
-         - If VA cuts HB, the result is an L line A-(IB,JA)-B                                          
-         - If exists an V line that cuts HA and HB, the result is a Z line A-(IA,JV)-(IB-JV)-B         
-         - If exists an H line that cuts VA and VB, the result is a Z line A-(IV,JA)-(IV,JB)-B         
-
-         The following data types are defined:                                                         
-
-         - Board                                                                                       
-         - Point(int i, int j)                                                                         
-         - Line(Point a, Point b)                                                                      
-         - LineSet(Line l1, ..., Line lN)                                                              
-
-         The following operations are defined                                                          
-
-         - LineSet getHorizontalLines(Board board, Point a, Point b) // a and b needed to consider them as blank
-         - LineSet getVerticalLines(Board board, Point a, Point b)                                              
-         - boolean lineIsHorizontal(Line l)                                                                     
-         - boolean lineIsVertical(Line l)                                                                       
-         - boolean lineContainsPoint(Line l, Point p)                                                           
-         - boolean lineEqualsLine(Line l1, Line l2)                                                             
-         - boolean lineCutsLine(Line l1, Line l2)                                                               
-        */                                                                                                     
-       public List<Point> getPath(Point a, Point b) {                                                       
-               List<Point> result=new ArrayList<Point>();                                                                
-
-               if (getPiece(a)!=getPiece(b)) return result;                                                         
-
-               List<Line> h=getHorizontalLines(a,b);                                                              
-               List<Line> v=getVerticalLines(a,b);                                                                
-               Line ha=null, va=null, hb=null, vb=null;                                                             
-
-               for (Line l : h) {                                                                              
-                       if (l.contains(a)) ha=l;                                                                           
-                       if (l.contains(b)) hb=l;                                                                           
-                       if (ha!=null && hb!=null) break;                                                                   
-               }                                                                                                    
-
-               for (Line l : v) {                                                                              
-                       if (l.contains(a)) va=l;                                                                           
-                       if (l.contains(b)) vb=l;                                                                           
-                       if (va!=null && vb!=null) break;                                                                   
-               }                                                                                                    
-
-               // stdout.printf("va=%s, ha=%s, vb=%s, hb=%s\n",va.toString(),ha.toString(),vb.toString(),hb.toString());
-
-               if ((ha==null && va==null) || (hb==null && vb==null))                                                        
-                       return result;                                                                                               
-
-               if (ha.equals(hb) || va.equals(vb)) {                                                                        
-                       result.add(a);                                                                                          
-                       result.add(b);                                                                                          
-                       return result;                                                                                             
-               }                                                                                                            
-
-               Point ab;                                                                                                    
-
-               ab=ha.cuts(vb);                                                                                              
-               // stdout.printf("(ha cuts vb) ab=%s\n",ab.toString());                                                     
-
-               if (ab!=null) {                                                                                              
-                       result.add(a);                                                                                          
-                       result.add(ab);                                                                                         
-                       result.add(b);                                                                                          
-                       return result;                                                                                             
-               }                                                                                                            
-
-               ab=va.cuts(hb);                                                                                              
-               // stdout.printf("(va cuts hb) ab=%s\n",ab.toString());                                                     
-
-               if (ab!=null) {
-                       result.add(a);
-                       result.add(ab);
-                       result.add(b); 
-                       return result;    
-               }                   
-
-               for (Line l : v) {
-                       Point al=l.cuts(ha); 
-                       Point bl=l.cuts(hb); 
-
-                       // stdout.printf("(%s cuts ha) al=%s\n",l.toString(),al.toString());
-                       // stdout.printf("(%s cuts hb) bl=%s\n",l.toString(),bl.toString());
-
-                       if (al!=null && bl!=null) {                                           
-                               result.add(a);                                                   
-                               result.add(al);                                                  
-                               result.add(bl);                                                  
-                               result.add(b);                                                   
-                               return result;                                                      
-                       }                                                                     
-               }                                                                       
-
-               for (Line l : h) {                                                 
-                       Point al=l.cuts(va);                                                  
-                       Point bl=l.cuts(vb);                                                  
-
-                       // stdout.printf("(%s cuts va) al=%s\n",l.toString(),al.toString());
-                       // stdout.printf("(%s cuts vb) bl=%s\n",l.toString(),bl.toString());
-
-                       if (al!=null && bl!=null) {
-                               result.add(a);        
-                               result.add(al);       
-                               result.add(bl);       
-                               result.add(b);        
-                               return result;           
-                       }                          
-               }                            
-
-               return result;                 
-       }                              
-
-       public char getPiece(Point p) {
-               return board[p.i][p.j];         
-       }                                
-
-       public void setPiece(Point p, char piece) {
-               board[p.i][p.j]=piece;                      
-       }                                            
-
-       public String getStrPiece(Point p) {       
-               char piece=board[p.i][p.j];                
-               return charpieces.substring(piece,1);      
-       }                                            
-
-       public void setStrPiece(Point p, String piece) {
-               char upiece;                                   
-               long charpiecesLen=charpieces.length();          
-               for(upiece=0;(upiece<charpiecesLen && charpieces.substring(upiece,1)!=piece);upiece++);
-               if (upiece<charpiecesLen) board[p.i][p.j]=upiece;                                       
-       }                                                                                         
-
-       public void play(Point a0, Point b0) {                                                    
-               // It's important to sink the upper piece first                                         
-               Point a=(a0.i<b0.i)?a0:b0;                                                              
-               Point b=(a0.i<b0.i)?b0:a0;                                                              
-               Move m=new Move(a,b,getPiece(a));                                                      
-               history.add(0,m);                                                                   
-               setPiece(a,(char)0);                                                                         
-               processGravity(a);                                                                     
-               setPiece(b,(char)0);                                                                         
-               processGravity(b);                                                                     
-       }                                                                                         
-
-       public boolean getCanUndo() {                                                              
-               return !history.isEmpty();                                                             
-       }                                                                                         
-
-       public void undo() {                                                                      
-               if (!getCanUndo()) return;                                                            
-               Move m=history.remove(0);                                                              
-               undoGravity(m.b);                                                                      
-               setPiece(m.b,m.piece);                                                                 
-               undoGravity(m.a);                                                                      
-               setPiece(m.a,m.piece);                                                                 
-       }                                                                                         
-
-       public List<Line> getPairs(int maxResults) {                                            
-               List<Line> result=new ArrayList<Line>();                                                     
-               List<Integer> pieces=new ArrayList<Integer>();                                                       
-               List<List<Point>> piecePoints=new ArrayList<List<Point>>();                                               
-               for (int i=0;i<boardSize[0];i++)                                                       
-                       for (int j=0;j<boardSize[1];j++) {                                                   
-                               int piece=(int)board[i][j];                                                          
-                               if (piece==0) continue;                                                             
-                               int key=pieces.indexOf(piece);                                                        
-                               Point p=new Point(i,j);                                                            
-                               if (key==-1) {                                                                      
-                                       List<Point> points0=new ArrayList<Point>();                                            
-                                       points0.add(p);                                                               
-                                       pieces.add(piece);                                                             
-                                       piecePoints.add(points0);
-
-                                       key=pieces.indexOf(piece);                                                          
-                                       piecePoints.get(key);                              
-                               } else {                                                                            
-                                       List<Point> points1=piecePoints.get(key);                              
-                                       points1.add(p);                                                                
-                               }                                                                                   
-                       }                                                                                     
-
-               int nresults=0;                                                                         
-               int k=0;                                                                                
-               for (List<Point> points : piecePoints) {                                     
-                       int n=(int)points.size();                                                           
-                       for (int i=0;i<n;i++) {                                                               
-                               Point a=points.get(i);                                                    
-                               for (int j=i+1;j<n;j++) {                                                           
-                                       Point b=points.get(j);                                                  
-                                       List<Point> path=getPath(a.copy(),b.copy());                                     
-                                       if (path!=null && path.size()>0) {                                              
-                                               result.add(new Line(a,b));                                                   
-                                               if (nresults++==maxResults) break;                                             
-                                       }                                                                                 
-                               }                                                                                   
-                               if (nresults==maxResults) break;                                                   
-                       }                                                                                     
-                       k++;                                                                                  
-                       if (nresults==maxResults) break;                                                     
-               }                                                                                       
-               return result;                                                                          
-       }                                                                                         
-
-       public int getNumPieces() {                                                               
-               int result=0;                                                                           
-               for (int j=0;j<boardSize[1];j++) {                                                     
-                       for (int i=0;i<boardSize[0];i++) {                                                   
-                               if (board[i][j]!=0) result++;                                                        
-                       }                                                                                     
-               }                                                                                       
-               return result;                                                                          
-       }                                                                                         
-
-       // ----------------------                                                                 
-       // Private methods                                                                        
-       // ----------------------                                                                 
-
-       /* RAND_MAX assumed to be 32767 */                                                        
-       private int myrand() {                                                                    
-               return (int)Math.floor(Math.random()*32768);
-       }                                                                                         
-
-       private String StringRepeat(String s, int n) {                                           
-               String result="";                                                                       
-               for (int i=0;i<n;i++)                                                                   
-                       result+=s;                                                                            
-               return result;                                                                          
-       }                                                                                         
-
-       private int findFreeRow(int j) {                                                        
-               for (int i=1;i<boardSize[0]-1;i++) {                                                   
-                       if (board[i][j]!=0) return (i-1);                                                      
-               }                                                                                       
-               return (boardSize[0]-1-1);                                                             
-       }                                                                                         
-
-       private List<Line> getHorizontalLines(Point excludeA, Point excludeB) {               
-               List<Line> result=new ArrayList<Line>();                                                     
-               for (int i=0;i<boardSize[0];i++) {                                                     
-                       int j0=-1;                                                                            
-                       boolean empty;                                                                           
-                       for (int j=0;j<boardSize[1];j++) {                                                   
-                               empty=(board[i][j]==0 || (i==excludeA.i && j==excludeA.j)                          
-                                               || (i==excludeB.i && j==excludeB.j));                                           
-                               if (j0==-1 && empty) {                                                              
-                                       j0=j;                                                                             
-                               } else if (j0!=-1 && !empty) {                                                      
-                                       result.add(new Line(new Point(i,j0), new Point(i,j-1)));                       
-                                       j0=-1;                                                                            
-                               }                                                                                   
-                       }                                                                                     
-                       if (j0!=-1) result.add(new Line(new Point(i,j0), new Point(i,boardSize[1]-1)));   
-               }                                                                                       
-
-               // stdout.printf("\ngetHorizontalLines( %s, %s ): ",excludeA.toString(),excludeB.toString());
-               // for (Line line : result) stdout.printf("%s ",line.toString());                            
-               // stdout.printf("\n");                                                                            
-
-               return result;                                                                                     
-       }                                                                                                    
-
-       private List<Line> getVerticalLines(Point excludeA, Point excludeB) {
-               List<Line> result=new ArrayList<Line>();
-               for (int j=0;j<boardSize[1];j++) {
-                       int i0=-1;
-                       boolean empty;
-                       for (int i=0;i<boardSize[0];i++) {
-                               empty=(board[i][j]==0 || (i==excludeA.i && j==excludeA.j)
-                                               || (i==excludeB.i && j==excludeB.j));
-                               if (i0==-1 && empty) {
-                                       i0=i;
-                               } else if (i0!=-1 && !empty) {
-                                       result.add(new Line(new Point(i0,j), new Point(i-1,j)));
-                                       i0=-1;
-                               }
-                       }
-                       if (i0!=-1) result.add(new Line(new Point(i0,j), new Point(boardSize[0]-1,j)));
-               }
-
-               // stdout.printf("\ngetVerticalLines( %s, %s ): ",excludeA.toString(),excludeB.toString());
-               // for (Line line : result) stdout.printf("%s ",line.toString());
-               // stdout.printf("\n");
-
-               return result;
-       }
-
-       private void processGravity(Point p) {
-               if (gravity) for (int i=p.i;i>0;i--) board[i][p.j]=board[i-1][p.j];
-       }
-
-       private void undoGravity(Point p) {
-               if (gravity) for (int i=0;i<p.i;i++) board[i][p.j]=board[i+1][p.j];
-       }
-
-}
diff --git a/src/org/proofofconcept/shisensho/Line.java b/src/org/proofofconcept/shisensho/Line.java
deleted file mode 100644 (file)
index b85aaf1..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-package org.proofofconcept.shisensho;
-
-public class Line {
-       public Line(Point a, Point b) {
-               this.a=a;                    
-               this.b=b;                    
-       }                              
-
-       public boolean equals(Line l) {   
-               return (a.equals(l.a) && b.equals(l.b));
-       }                                         
-
-       public boolean isHorizontal() {             
-               return (a.i==b.i);                      
-       }                                         
-
-       public boolean isVertical() {               
-               return (a.j==b.j);                      
-       }                                         
-
-       public boolean contains(Point p) {
-               return (p.i==a.i && p.i==b.i && p.j>=getMin().j && p.j<=getMax().j)
-               || (p.j==a.j && p.j==b.j && p.i>=getMin().i && p.i<=getMax().i);
-       }
-
-       public Point cuts(Line l) {
-               if (isHorizontal() && l.isVertical()
-                               && getMin().j<=l.a.j && getMax().j>=l.a.j
-                               && l.getMin().i<=a.i && l.getMax().i>=a.i ) {
-                       return new Point(a.i,l.a.j);
-               } else if (isVertical() && l.isHorizontal()
-                               && getMin().i<=l.a.i && getMax().i>=l.a.i
-                               && l.getMin().j<=a.j && l.getMax().j>=a.j ) {
-                       return new Point(l.a.i,a.j);
-               } else return null;
-       }
-
-       public Point getMin() {
-               if (a.i<b.i || a.j<b.j) return a;
-               else return b;
-       }
-
-       public Point getMax() {
-               if (a.i>b.i || a.j>b.j) return a;
-               else return b;
-       }
-
-       public String toString() {
-               return a+"-"+b;
-       }
-
-       public Point a;
-       public Point b;
-}
diff --git a/src/org/proofofconcept/shisensho/Move.java b/src/org/proofofconcept/shisensho/Move.java
deleted file mode 100644 (file)
index 1b51289..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.proofofconcept.shisensho;
-
-public class Move {
-       public Move(Point a, Point b, char piece) {
-               this.a=a;
-               this.b=b;
-               this.piece=piece;
-       }
-
-       public String toString() {
-               return a+"-"+b+"("+Board.pieceToString(piece)+")";
-       }
-
-       public Point a;
-       public Point b;
-       public char piece;
-}
diff --git a/src/org/proofofconcept/shisensho/Point.java b/src/org/proofofconcept/shisensho/Point.java
deleted file mode 100644 (file)
index 7771ef5..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.proofofconcept.shisensho;
-
-class Point {
-       public Point(int i, int j) {
-               this.i=i;
-               this.j=j;
-       }
-
-       public boolean equals(Point p) {
-               return (i==p.i && j==p.j);
-       }
-
-       public String toString() {
-               return "("+i+","+j+")";
-       }
-
-       public static Point fromString(String s) {
-               String[] ij=s.split(",",2);
-               int i=Integer.parseInt(ij[0]);
-               int j=Integer.parseInt(ij[1]);
-               return new Point(i,j);
-       }
-
-       public int i;
-       public int j;
-
-       public Point copy() {
-               return new Point(this.i,this.j);
-       }
-}
diff --git a/src/org/proofofconcept/shisensho/ShisenSho.java b/src/org/proofofconcept/shisensho/ShisenSho.java
deleted file mode 100644 (file)
index a7d29b4..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-package org.proofofconcept.shisensho;
-
-import java.util.Observable;
-import java.util.Observer;
-
-import android.app.Application;
-import android.os.Bundle;
-import android.util.Log;
-
-public class ShisenSho extends Application {   
-       private static ShisenSho instance = null; 
-       private ShisenShoView view = null;
-       public ShisenShoActivity activity = null;
-       
-       public Board board;
-       public int[] boardSize=new int[2];
-       public int difficulty=1; // 1=Hard, 2=Easy
-       public int size=3; // 1=Small, 2=Medium, 3=Big
-       public boolean gravity=true;
-       public boolean timeCounter=true;
-
-       public static void log(String msg) {
-               Log.w("ShisenSho", msg);
-       }
-
-       public void newPlay() {
-               board = new Board();
-               board.buildRandomBoard(boardSize[0],boardSize[1],difficulty,gravity);
-       }
-
-       public void setSize(int s) {
-               switch (s) {
-               case 1:
-                       size=1;
-                       boardSize[0]=6+2;
-                       boardSize[1]=8+2;
-                       break;
-               case 2:
-                       size=2;
-                       boardSize[0]=6+2;
-                       boardSize[1]=12+2;
-                       break;
-               case 3:
-               default:
-                       size=3;
-                       boardSize[0]=6+2;
-                       boardSize[1]=16+2;
-                       break;
-               }
-       }
-
-       public void sleep(int deciSeconds) {
-               try {
-                       Thread.sleep(deciSeconds*100);
-               } catch (InterruptedException e) { }
-       }
-
-       public ShisenSho() {
-               instance = this;
-               setSize(size);
-       }
-       
-       public static synchronized ShisenSho app() {
-               return instance;
-       }
-       
-       public ShisenShoView getView() {
-               if (view == null) view = new ShisenShoView(this);
-               return view;
-       }
-               
-       /** Called when the activity is first created. */
-    @Override
-    public void onCreate() {
-        super.onCreate();
-    }
-    
-       public Bundle getOptions() {
-               Bundle options = new Bundle();
-               options.putInt("size", size);
-               options.putInt("difficulty", difficulty);
-               options.putBoolean("gravity", gravity);
-               options.putBoolean("timeCounter", timeCounter);
-               return options;
-       }
-
-       public void setOptions(Bundle options) {
-               int size = options.getInt("size");
-               int difficulty = options.getInt("difficulty");
-               boolean gravity = options.getBoolean("gravity");
-               boolean timeCounter = options.getBoolean("timeCounter");
-
-               boolean needsReset = false;
-               
-               if (size != this.size) {
-                       setSize(size);
-                       needsReset = true;
-               }
-               
-               if (difficulty != this.difficulty) {
-                       this.difficulty = difficulty;
-                       needsReset = true;
-               }
-
-               if (gravity != this.gravity) {
-                       this.gravity = gravity;
-                       needsReset = true;
-               }
-               
-               if (timeCounter != this.timeCounter) {
-                       this.timeCounter = timeCounter;
-                       view.onTimeCounterActivate();
-               }
-
-               if (needsReset) {
-                       view.reset();
-               }
-       }
-
-}
diff --git a/src/org/proofofconcept/shisensho/ShisenShoActivity.java b/src/org/proofofconcept/shisensho/ShisenShoActivity.java
deleted file mode 100644 (file)
index 5036eb8..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-package org.proofofconcept.shisensho;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.Intent;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.os.Bundle;
-import android.text.SpannableString;
-import android.text.util.Linkify;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.widget.TextView;
-
-public class ShisenShoActivity extends Activity {
-       private ShisenShoView view;
-
-       /** Called when the activity is first created. */
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        requestWindowFeature(Window.FEATURE_NO_TITLE);
-        //getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
-        //             WindowManager.LayoutParams.FLAG_FULLSCREEN);
-
-        view = ShisenSho.app().getView();
-        ShisenSho.app().activity = this;
-        setContentView(view);
-    }
-
-       @Override
-       protected void onDestroy() {
-               ViewGroup vg = (ViewGroup)(view.getParent());
-               vg.removeView(view);
-        ShisenSho.app().activity = null;
-               super.onDestroy();
-       }
-
-       @Override
-       protected void onPause() {
-               if (view!=null) {
-                       view.pauseTime();
-               }
-               super.onPause();
-       }
-
-       @Override
-       protected void onResume() {
-               super.onResume();
-               if (view!=null) {
-                       view.resumeTime();
-               }
-       }
-
-       @Override
-       public boolean onCreateOptionsMenu(Menu menu) {
-           MenuInflater inflater = getMenuInflater();
-           inflater.inflate(R.menu.menu, menu);
-           return true;
-       }
-
-       @Override
-       public boolean onOptionsItemSelected(MenuItem item) {
-           // Handle item selection
-           switch (item.getItemId()) {
-           case R.id.hint:
-           case R.id.undo:
-           case R.id.clean:
-               return view.onOptionsItemSelected(item);
-           case R.id.options:
-               startActivityForResult(new Intent("org.proofofconcept.shisensho.SETTINGS", null), 0);
-               return true;
-           case R.id.about:
-               onAboutActivate();
-               return true;
-           default:
-               return super.onOptionsItemSelected(item);
-           }
-       }
-
-       private void onAboutActivate() {
-        // Try to load the a package matching the name of our own package
-        PackageInfo pInfo;
-               try {
-                       pInfo = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_META_DATA);
-               String aboutTitle = String.format("About %s", getString(R.string.app_name));
-               String versionString = String.format("Version: %s", pInfo.versionName);
-               String aboutText = getString(R.string.aboutText);
-
-               // Set up the TextView
-               final TextView message = new TextView(this);
-               // We'll use a spannablestring to be able to make links clickable
-               final SpannableString s = new SpannableString(aboutText);
-
-               // Set some padding
-               message.setPadding(5, 5, 5, 5);
-               // Set up the final string
-               message.setText(versionString + "\n" + s);
-               // Now linkify the text
-               Linkify.addLinks(message, Linkify.ALL);
-
-               new AlertDialog.Builder(this)
-                       .setTitle(aboutTitle)
-                       .setCancelable(true)
-                       .setIcon(R.drawable.icon)
-                       .setPositiveButton(getString(android.R.string.ok), null)
-                       .setView(message).create()
-                       .show();
-               } catch (NameNotFoundException e) {
-                       e.printStackTrace();
-               }
-       }
-}
diff --git a/src/org/proofofconcept/shisensho/ShisenShoOptionsActivity.java b/src/org/proofofconcept/shisensho/ShisenShoOptionsActivity.java
deleted file mode 100644 (file)
index 87631bd..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-package org.proofofconcept.shisensho;
-
-import java.io.Serializable;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.View;
-import android.view.Window;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.CompoundButton;
-import android.widget.Spinner;
-import android.widget.ToggleButton;
-
-public class ShisenShoOptionsActivity extends Activity {
-
-       Bundle state;
-       ShisenSho app;
-
-       private void appToState (boolean merge) {
-               String[] fields = { "size", "difficulty", "gravity", "timeCounter" };
-               Bundle options = app.getOptions();
-               if (state == null) state = new Bundle();
-               for (int i=0; i<fields.length; i++) {
-                       if (!merge || !state.containsKey(fields[i])) {
-                               state.putSerializable(fields[i], (Serializable)(options.get(fields[i])));
-                       }
-               }
-       }
-
-       /** Called when the activity is first created. */
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        requestWindowFeature(Window.FEATURE_NO_TITLE);
-        setContentView(R.layout.options);
-
-        app = ShisenSho.app();
-        state = savedInstanceState;
-        appToState(true);
-
-        Spinner s;
-        ToggleButton tb;
-        ArrayAdapter adapter;
-
-        s = (Spinner) findViewById(R.id.size);
-        adapter = ArrayAdapter.createFromResource(
-                this, R.array.sizes, android.R.layout.simple_spinner_item);
-        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
-        s.setAdapter(adapter);
-        s.setSelection(state.getInt("size")-1);
-        s.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
-                       public void onItemSelected(AdapterView<?> arg0, View arg1,
-                                       int pos, long arg3) {
-                               state.putInt("size", pos+1);
-                       }
-
-                       public void onNothingSelected(AdapterView<?> arg0) { }
-        });
-
-        s = (Spinner) findViewById(R.id.difficulty);
-        adapter = ArrayAdapter.createFromResource(
-                this, R.array.difficulties, android.R.layout.simple_spinner_item);
-        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
-        s.setAdapter(adapter);
-        s.setSelection(2-state.getInt("difficulty"));
-        s.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
-                       public void onItemSelected(AdapterView<?> arg0, View arg1,
-                                       int pos, long arg3) {
-                               state.putInt("difficulty", 2-pos);
-                       }
-
-                       public void onNothingSelected(AdapterView<?> arg0) { }
-        });
-
-        tb = (ToggleButton) findViewById(R.id.gravity);
-        tb.setChecked(state.getBoolean("gravity"));
-        tb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
-                       public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
-                               state.putBoolean("gravity", arg1);
-                       }
-        });
-
-        tb = (ToggleButton) findViewById(R.id.timeCounter);
-        tb.setChecked(state.getBoolean("timeCounter"));
-        tb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
-                       public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
-                               state.putBoolean("timeCounter", arg1);
-                       }
-        });
-    }
-
-       @Override
-       public void onBackPressed() {
-               app.setOptions(state);
-               super.onBackPressed();
-       }
-
-}
diff --git a/src/org/proofofconcept/shisensho/ShisenShoView.java b/src/org/proofofconcept/shisensho/ShisenShoView.java
deleted file mode 100644 (file)
index 1cc1e07..0000000
+++ /dev/null
@@ -1,661 +0,0 @@
-package org.proofofconcept.shisensho;
-
-import java.util.List;
-import java.util.Timer;
-import java.util.TimerTask;
-
-import android.app.Activity;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Paint.Align;
-import android.graphics.Paint.Cap;
-import android.graphics.Paint.Join;
-import android.graphics.Paint.Style;
-import android.graphics.Rect;
-import android.graphics.Typeface;
-import android.os.Handler;
-import android.os.Message;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-
-class ShisenShoView extends SurfaceView implements SurfaceHolder.Callback {
-
-       private enum StatePlay { UNINITIALIZED, IDLE, SELECTED1, SELECTED2, GAMEOVER };
-       private enum StatePaint { BOARD, SELECTED1, SELECTED2, MATCHED, WIN, LOSE, HINT, TIME };
-
-       private int screenWidth;
-       private int screenHeight;
-       private int tilesetRows;
-       private int tilesetCols;
-       private int tileHeight;
-       private int tileWidth;
-       private Bitmap bg;
-       private Bitmap tile[];
-       private int[] selection1=new int[2];
-       private int[] selection2=new int[2];
-       private List<Point> path=null;
-       private List<Line> pairs=null;
-       private long startTime;
-       private long playTime;
-       private long baseTime;
-       private Timer timer;
-       private Handler timerHandler;
-
-       private boolean timerRegistered=false;
-       private ShisenSho app;
-       private StatePlay cstate;
-       private StatePaint pstate;
-       private Canvas canvas = null;
-       private SurfaceHolder surfaceHolder = null;
-       private String debugMessage = "";
-
-       public ShisenShoView(ShisenSho shishenSho) {
-               super((Context)shishenSho);
-               this.app = shishenSho;
-               cstate = StatePlay.UNINITIALIZED;
-               surfaceHolder = getHolder();
-               surfaceHolder.addCallback(this);
-       }
-
-       private void paint(StatePaint pstate) {
-               this.pstate=pstate;
-               repaint();
-       }
-
-       private void control(StatePlay cstate) {
-               this.cstate=cstate;
-       }
-
-       private void loadTileset() {
-               BitmapFactory.Options ops = new BitmapFactory.Options();
-               ops.inScaled = false;
-               Bitmap tileset = BitmapFactory.decodeResource(getResources(), R.drawable.tileset, ops);
-               tileset.setDensity(Bitmap.DENSITY_NONE);
-
-               // The tile set has 4 rows x 9 columns
-               tilesetRows = 4;
-               tilesetCols = 9;
-               tileWidth = tileset.getWidth()/tilesetCols;
-               tileHeight = tileset.getHeight()/tilesetRows;
-               tile = new Bitmap[tilesetRows*tilesetCols];
-               int k=0;
-               for (int i=0; i<tilesetRows; i++) {
-                       for (int j=0; j<tilesetCols; j++) {
-                               tile[k] = Bitmap.createBitmap(tileset, j*tileWidth, i*tileHeight, tileWidth, tileHeight, null, false);
-                               tile[k].setDensity(Bitmap.DENSITY_NONE);
-                               k++;
-                       }
-               }
-               tileWidth = tile[0].getWidth();
-               tileHeight = tile[0].getHeight();
-       }
-
-       private void loadBackground() {
-               BitmapFactory.Options ops = new BitmapFactory.Options();
-               ops.inScaled = false;
-               bg = BitmapFactory.decodeResource(getResources(), R.drawable.kshisen_bgnd, ops);
-               bg.setDensity(Bitmap.DENSITY_NONE);
-       }
-
-       private void registerTimer() {
-               if (timer!=null) return; // Already registered
-               timerHandler = new Handler() {
-                       public void handleMessage(Message msg) {
-                               onUpdateTime();
-                       }
-               };
-               timer=new Timer();
-       timer.scheduleAtFixedRate(new TimerTask() {
-               public void run() {
-                       timerHandler.sendEmptyMessage(Activity.RESULT_OK);
-               }
-       }, 0, 1000);
-               timerRegistered=true;
-       }
-
-       private void unregisterTimer() {
-               if (timer==null) return; // Already unregistered
-               timer.cancel();
-       timer = null;
-               timerHandler = null;
-               timerRegistered=false;
-       }
-
-       public void pauseTime() {
-               updateTime();
-               baseTime = playTime;
-               startTime = System.currentTimeMillis();
-
-       }
-
-       public void resumeTime() {
-               startTime = System.currentTimeMillis();
-               updateTime();
-       }
-
-       private void updateTime() {
-               if (cstate!=StatePlay.GAMEOVER) {
-                       playTime = (System.currentTimeMillis()-startTime)/1000+baseTime;
-               }
-       }
-
-       private void initializeGame() {
-               loadBackground();
-               loadTileset();
-               screenWidth=getWidth();
-               screenHeight=getHeight();
-               //undo.sensitive=false;
-               pstate=StatePaint.BOARD;
-               app.newPlay();
-               control(StatePlay.IDLE);
-               startTime=System.currentTimeMillis();
-               playTime=0;
-               baseTime=0;
-               if (app.timeCounter && !timerRegistered) {
-                       registerTimer();
-               }
-               pairs=app.board.getPairs(1);
-       }
-
-       public boolean onOptionsItemSelected(MenuItem item) {
-           // Handle item selection
-           switch (item.getItemId()) {
-           case R.id.hint:
-               this.postDelayed(new Runnable() { public void run() { onHintActivate(); } }, 100);
-               return true;
-           case R.id.undo:
-               this.postDelayed(new Runnable() { public void run() { onUndoActivate(); } }, 100);
-               return true;
-           case R.id.clean:
-               this.postDelayed(new Runnable() { public void run() { reset(); } }, 100);
-               return true;
-           case R.id.options:
-               return true;
-           case R.id.about:
-               return true;
-           default:
-               return false;
-           }
-       }
-
-       public void reset() {
-               control(StatePlay.UNINITIALIZED);
-               paint(StatePaint.BOARD);
-       }
-
-       private void onHintActivate() {
-               if (cstate!=StatePlay.GAMEOVER) {
-                       pairs=app.board.getPairs(1);
-                       paint(StatePaint.HINT);
-                       app.sleep(10);
-                       paint(StatePaint.BOARD);
-                       control(StatePlay.IDLE);
-               }
-       }
-
-       private void onUndoActivate() {
-               if (app.board.getCanUndo()) {
-                       if (cstate==StatePlay.GAMEOVER && app.timeCounter && !timerRegistered) {
-                               // Reprogram the time update that had been
-                               // deactivated with the game over status
-                               registerTimer();
-                       }
-                       app.board.undo();
-                       paint(StatePaint.BOARD);
-                       //undo.sensitive=app.board.getCanUndo();
-                       control(StatePlay.IDLE);
-               }
-       }
-
-       public void onTimeCounterActivate() {
-               if (app.timeCounter && cstate!=StatePlay.GAMEOVER && !timerRegistered) {
-                       // Reprogram the time update that had been
-                       // deactivated with the time_counter=false
-                       registerTimer();
-               }
-       }
-
-       private void onUpdateTime() {
-               paint(pstate);
-           if (!(app.timeCounter && cstate!=StatePlay.GAMEOVER)) {
-               unregisterTimer();
-           }
-       }
-
-       public void drawMessage(Canvas canvas, int x, int y, boolean centered, String message, String color, float textSize)  {
-               Paint paint = new Paint();
-               paint.setColor(Color.parseColor(color));
-               paint.setLinearText(true);
-               paint.setAntiAlias(true);
-               paint.setTextAlign(centered?Align.CENTER:Align.LEFT);
-               paint.setTypeface(Typeface.SANS_SERIF);
-               paint.setFakeBoldText(true);
-               paint.setTextSize(textSize);
-               canvas.drawText(message, x, y, paint);
-       }
-
-       public void repaint() {
-               if (surfaceHolder == null) return;
-               try {
-                       if (canvas == null) canvas = surfaceHolder.lockCanvas(null);
-                       if (canvas == null) return;
-                       if (cstate==StatePlay.UNINITIALIZED) initializeGame();
-                       synchronized (surfaceHolder) {
-                               doDraw(canvas);
-                       }
-               } finally {
-                       if (canvas != null) {
-                               surfaceHolder.unlockCanvasAndPost(canvas);
-                               canvas = null;
-                       }
-               }
-       }
-
-       protected void doDraw(Canvas canvas) {
-               try {
-                       // Double buffering
-                       // Bitmap buffer = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
-                       //Canvas cbuffer = new Canvas(buffer);
-                       Canvas cbuffer = canvas;
-                       if (canvas == null) return;
-
-                       //super.onDraw(canvas);
-
-                       // Board upper left corner on screen
-                       int x0=0;
-                       int y0=0;
-
-                       if (app!=null && app.board!=null) {
-                               x0=(screenWidth-app.board.boardSize[1]*tileWidth)/2;
-                               y0=(screenHeight-app.board.boardSize[0]*tileHeight)/2;
-                       }
-
-                       int red = Color.parseColor("#FF0000");
-                       int orange = Color.parseColor("#F0C000");
-                       Paint paint = new Paint();
-                       paint.setFlags(Paint.ANTI_ALIAS_FLAG);
-
-                       // Background & board painting
-                       switch (pstate) {
-                       case BOARD:
-                       case SELECTED1:
-                       case SELECTED2:
-                       case MATCHED:
-                       case WIN:
-                       case LOSE:
-                       case HINT:
-                       case TIME:
-                               // Background painting
-                               int bgWidth = bg.getWidth();
-                               int bgHeight = bg.getHeight();
-                               for (int i=0; i<screenHeight/bgHeight+1; i++) {
-                                       for (int j=0; j<screenWidth/bgWidth+1; j++) {
-                                               cbuffer.drawBitmap(bg, j*bgWidth, i*bgHeight, paint);
-                                       }
-                               }
-
-                               // Board painting
-                               // Max visible size: 7x17
-                               if (app!=null && app.board!=null) {
-                                       for (int i=0;i<app.board.boardSize[0];i++) {
-                                               for (int j=0;j<app.board.boardSize[1];j++) {
-                                                       // Tiles are 56px height, 40px width each
-                                                       char piece=app.board.board[i][j];
-                                                       if (piece!=0) {
-                                                               cbuffer.drawBitmap(tile[piece], x0+j*tileWidth, y0+i*tileHeight, paint);
-                                                       }
-                                               }
-                                       }
-                               }
-                               break;
-                       }
-
-                       // Red rectangle for selection 1
-                       switch (pstate) {
-                       case SELECTED1:
-                       case SELECTED2:
-                       case MATCHED:
-                               paint.setColor(red);
-                               paint.setStyle(Style.STROKE);
-                               paint.setStrokeCap(Cap.ROUND);
-                               paint.setStrokeJoin(Join.ROUND);
-                               paint.setStrokeWidth(3);
-                               cbuffer.drawRect(new Rect(
-                                               x0+selection1[1]*tileWidth-2,
-                                               y0+selection1[0]*tileHeight-2,
-                                               x0+selection1[1]*tileWidth-2+tileWidth+2*2,
-                                               y0+selection1[0]*tileHeight-2+tileHeight+2*2),
-                                               paint);
-                               break;
-                       }
-
-                       // Red rectangle for selection 2
-                       switch (pstate) {
-                       case SELECTED2:
-                       case MATCHED:
-                               paint.setColor(red);
-                               paint.setStyle(Style.STROKE);
-                               paint.setStrokeCap(Cap.ROUND);
-                               paint.setStrokeJoin(Join.ROUND);
-                               paint.setStrokeWidth(3);
-                               cbuffer.drawRect(new Rect(
-                                               x0+selection2[1]*tileWidth-2,
-                                               y0+selection2[0]*tileHeight-2,
-                                               x0+selection2[1]*tileWidth-2+tileWidth+2*2,
-                                               y0+selection2[0]*tileHeight-2+tileHeight+2*2),
-                                               paint);
-                               break;
-                       }
-
-                       // Matching path
-                       switch (pstate) {
-                       case MATCHED:
-                               paint.setColor(red);
-                               paint.setStyle(Style.STROKE);
-                               paint.setStrokeCap(Cap.ROUND);
-                               paint.setStrokeJoin(Join.ROUND);
-                               paint.setStrokeWidth(3);
-
-                               if (path!=null) {
-                                       Point p0=null;
-                                       for (Point p1 : path) {
-                                               if (p0!=null) {
-                                                       cbuffer.drawLine(
-                                                                       x0+p0.j*tileWidth-2+(tileWidth/2),
-                                                                       y0+p0.i*tileHeight-2+(tileHeight/2),
-                                                                       x0+p1.j*tileWidth-2+(tileWidth/2),
-                                                                       y0+p1.i*tileHeight-2+(tileHeight/2),
-                                                                       paint);
-                                               }
-                                               p0=p1;
-                                       }
-                               }
-                               break;
-                       }
-
-                       // Orange hint rectangles
-                       switch (pstate) {
-                       case HINT:
-                               if (pairs!=null && pairs.size()>0) {
-                                       Line pair=pairs.get(0);
-                                       Point a=pair.a;
-                                       Point b=pair.b;
-                                       path=app.board.getPath(a,b);
-                                       paint.setColor(orange);
-                                       paint.setStyle(Style.STROKE);
-                                       paint.setStrokeCap(Cap.ROUND);
-                                       paint.setStrokeJoin(Join.ROUND);
-                                       paint.setStrokeWidth(3);
-
-                                       cbuffer.drawRect(new Rect(
-                                                       x0+a.j*tileWidth-2,
-                                                       y0+a.i*tileHeight-2,
-                                                       x0+a.j*tileWidth-2+tileWidth+2*2,
-                                                       y0+a.i*tileHeight-2+tileHeight+2*2),
-                                                       paint);
-
-                                       if (path!=null) {
-                                               Point p0=null;
-                                               for (Point p1 : path) {
-                                                       if (p0!=null) {
-                                                               cbuffer.drawLine(
-                                                                               x0+p0.j*tileWidth-2+(tileWidth/2),
-                                                                               y0+p0.i*tileHeight-2+(tileHeight/2),
-                                                                               x0+p1.j*tileWidth-2+(tileWidth/2),
-                                                                               y0+p1.i*tileHeight-2+(tileHeight/2),
-                                                                               paint);
-                                                       }
-                                                       p0=p1;
-                                               }
-                                               path=null;
-                                       }
-
-                                       cbuffer.drawRect(new Rect(
-                                                       x0+b.j*tileWidth-2,
-                                                       y0+b.i*tileHeight-2,
-                                                       x0+b.j*tileWidth-2+tileWidth+2*2,
-                                                       y0+b.i*tileHeight-2+tileHeight+2*2),
-                                                       paint);
-                               }
-                               break;
-                       }
-
-                       // Win & loose notifications
-                       switch (pstate) {
-                       case WIN:
-                               drawMessage(cbuffer, screenWidth/2,screenHeight/2,true,"You Win!", "#FFFFFF", 100);
-                               break;
-                       case LOSE:
-                               drawMessage(cbuffer, screenWidth/2,screenHeight/2,true,"Game Over", "#FFFFFF", 100);
-                               break;
-                       }
-
-                       if (app.timeCounter) switch (pstate) {
-                       case BOARD:
-                       case SELECTED1:
-                       case SELECTED2:
-                       case MATCHED:
-                       case WIN:
-                       case LOSE:
-                       case HINT:
-                       case TIME:
-                               updateTime();
-                               int hours=(int)(playTime/(60*60));
-                               int minutes=(int)((playTime/60)%60);
-                               int seconds=(int)(playTime%60);
-                               String time=String.format("%01d:%02d:%02d", hours, minutes, seconds);
-
-                               int timePosX=screenWidth-120;
-                               int timePosY=screenHeight-10;
-
-                               drawMessage(cbuffer, timePosX+1,timePosY+1,false,time,"#000000",30);
-                               drawMessage(cbuffer, timePosX,timePosY,false,time,"#FFFFFF",30);
-                               break;
-                       }
-
-                       // Debug messages
-                       /*
-                       debugMessage="StatePlay: "+cstate+"\n"+"StatePaint: "+pstate;
-                       if (debugMessage!=null && debugMessage.length()>0) {
-                               int l = 20;
-                               String lines[] = debugMessage.split("\n");
-                               for (int i=0; i<lines.length; i++) {
-                                       drawMessage(cbuffer,1,l,false,lines[i],"#FFFF00",30);
-                                       l+=30;
-                               }
-                       }
-                       */
-
-                       // Double buffer dumping
-                       // canvas.drawBitmap(buffer, 0, 0, null);
-
-               } catch (Exception e) {
-                       e.printStackTrace();
-               }
-
-       }
-
-       @Override
-       public boolean onTouchEvent(MotionEvent event) {
-               if (event.getAction()==MotionEvent.ACTION_DOWN) {
-                       onClick(Math.round(event.getX()),Math.round(event.getY()));
-               }
-               return super.onTouchEvent(event);
-       }
-
-       private void onClick(int x, int y) {
-               try {
-                       int i=(y-(screenHeight-app.board.boardSize[0]*tileHeight)/2)/tileHeight;
-                       int j=(x-(screenWidth-app.board.boardSize[1]*tileWidth)/2)/tileWidth;
-
-                       switch (cstate) {
-                       case IDLE:
-                               if (i>=0 &&
-                                               i<app.board.boardSize[0] &&
-                                               j>=0 && j<app.board.boardSize[1] &&
-                                               app.board.board[i][j]!=0) {
-                                       selection1[0]=i;
-                                       selection1[1]=j;
-                                       paint(StatePaint.SELECTED1);
-                                       control(StatePlay.SELECTED1);
-                               }
-                               break;
-                       case SELECTED1:
-                               if (i>=0 && i<app.board.boardSize[0] &&
-                                               j>=0 && j<app.board.boardSize[1] &&
-                                               app.board.board[i][j]!=0) {
-                                       if (i==selection1[0] && j==selection1[1]) {
-                                               paint(StatePaint.BOARD);
-                                               control(StatePlay.IDLE);
-                                       } else {
-                                               selection2[0]=i;
-                                               selection2[1]=j;
-                                               paint(StatePaint.SELECTED2);
-
-                                               Point a=new Point(selection1[0],selection1[1]);
-                                               Point b=new Point(selection2[0],selection2[1]);
-                                               path=app.board.getPath(a,b);
-                                               paint(StatePaint.MATCHED);
-                                               app.sleep(2);
-                                               paint(StatePaint.BOARD);
-                                               if (path.size()>0) {
-                                                       app.board.play(a,b);
-                                               }
-                                               path=null;
-                                               paint(StatePaint.BOARD);
-
-                                               pairs=app.board.getPairs(1);
-                                               if (pairs.size()==0) {
-                                                       if (app.board.getNumPieces()==0) {
-                                                               paint(StatePaint.WIN);
-                                                       } else {
-                                                               paint(StatePaint.LOSE);
-                                                       }
-                                                       control(StatePlay.GAMEOVER);
-                                               } else {
-                                                       control(StatePlay.IDLE);
-                                               }
-                                               //undo.sensitive=app.board.getCanUndo();
-                                       }
-                               }
-                               break;
-                       case GAMEOVER:
-                               reset();
-                               paint(StatePaint.BOARD);
-                               break;
-                       }
-               } catch (Exception e) {
-                       e.printStackTrace();
-               }
-       }
-
-       public void surfaceChanged(SurfaceHolder holder, int format, int width,
-                       int height) {
-               surfaceHolder = holder;
-               if (cstate!=StatePlay.GAMEOVER && app.timeCounter && !timerRegistered) {
-                       registerTimer();
-               }
-               repaint();
-       }
-
-       public void surfaceCreated(SurfaceHolder holder) {
-               surfaceHolder = holder;
-               repaint();
-       }
-
-       public void surfaceDestroyed(SurfaceHolder holder) {
-               surfaceHolder = null;
-               if (timerRegistered) {
-                       unregisterTimer();
-               }
-       }
-
-       /*
-       @Override
-       protected void onDraw(Canvas canvas) {
-               super.onDraw(canvas);
-
-               if (!initialized) initialize();
-
-               long currTime = System.currentTimeMillis();
-
-               a = (float)(currTime - startTime) / (float)duration;
-               if (a > (float)1.0) a = (float)1.0;
-
-               x = Math.round(nextx*a + prevx*(1-a));
-               y = Math.round(nexty*a + prevy*(1-a));
-
-               if (a == (float)1.0) computeNextTarget();
-
-               int bgWidth = bg.getWidth();
-               int bgHeight = bg.getHeight();
-               for (int i=0; i<height/bgHeight+1; i++) {
-                       for (int j=0; j<width/bgWidth+1; j++) {
-                               canvas.drawBitmap(bg, j*bgWidth, i*bgHeight, paint);
-                       }
-               }
-
-               canvas.drawBitmap(tile[randomtile], x, y, paint);
-
-               repaint();
-       }
-
-       @Override
-       public boolean onTouchEvent(MotionEvent event) {
-               if (event.getActionMasked()==MotionEvent.ACTION_DOWN) {
-                       //computeNextTarget();
-                       //nextx=Math.round(event.getX());
-                       //nexty=Math.round(event.getY());
-               }
-               return super.onTouchEvent(event);
-       }
-
-       private void initialize() {
-               width = getWidth();
-               height = getHeight();
-
-               bg = BitmapFactory.decodeResource(getResources(), R.drawable.kshisen_bgnd);
-               Bitmap tileset = BitmapFactory.decodeResource(getResources(), R.drawable.tileset);
-
-               // The tile set has 4 rows x 9 columns
-               tsrows = 4;
-               tscols = 9;
-               twidth = tileset.getWidth()/tscols;
-               theight = tileset.getHeight()/tsrows;
-               tile = new Bitmap[tsrows*tscols];
-               int k=0;
-               for (int i=0; i<tsrows; i++) {
-                       for (int j=0; j<tscols; j++) {
-                               tile[k] = Bitmap.createBitmap(tileset, j*twidth, i*theight, twidth, theight, null, false);
-                               k++;
-                       }
-               }
-
-               x = width/2;
-               y = height/2;
-
-               computeNextTarget();
-
-               initialized = true;
-       }
-
-       private void computeNextTarget() {
-               startTime = System.currentTimeMillis();
-               prevx = x;
-               prevy = y;
-               nextx = (int) Math.floor(Math.random() * width);
-               nexty = (int) Math.floor(Math.random() * height);
-               randomtile = (int) Math.floor(Math.random() * tile.length);
-
-               paint = new Paint();
-               paint.setColor(Color.parseColor("#006666"));
-               paint.setFlags(Paint.ANTI_ALIAS_FLAG);
-       }
-*/
-}
\ No newline at end of file
Impressum, Datenschutz