diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..a4f1e40
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..633e601
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+/bin/
+/proguard/
+/gen/
+/libs/
diff --git a/.project b/.project
new file mode 100644
index 0000000..de86dba
--- /dev/null
+++ b/.project
@@ -0,0 +1,33 @@
+
+
+ FindNumber
+
+
+
+
+
+ com.android.ide.eclipse.adt.ResourceManagerBuilder
+
+
+
+
+ com.android.ide.eclipse.adt.PreCompilerBuilder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ com.android.ide.eclipse.adt.ApkBuilder
+
+
+
+
+
+ com.android.ide.eclipse.adt.AndroidNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
new file mode 100644
index 0000000..09cb0d3
--- /dev/null
+++ b/AndroidManifest.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..ccde8bb
--- /dev/null
+++ b/README.md
@@ -0,0 +1,34 @@
+
+----
+
+![FindNumber Logo](/bw/findnumber/raw/master/f/art/logo.png)
+
+![Screen 1](/bw/findnumber/raw/master/f/art/screen1.png)
+![Screen 2](/bw/findnumber/raw/master/f/art/screen2.png)
+
+![Screen 3](/bw/findnumber/raw/master/f/art/screen3.png)
+
+----
+
+# FindNumber
+
+Game for expand attention.
+
+A similar table is a set of tests for mental health screening and training pilots and cosmonauts.
+The table shows the numbers that are different in size and in form. From the future-pilot requires
+in fast pace to call the numbers in order. The less time you spend to searching for all the numbers,
+the higher your observancy.
+
+----
+
+## Download binary
+
+![Download APK QR-code](/bw/findnumber/raw/master/f/art/find-number-qr.png)
+
+[Download APK](https://icystar.com/downloads/com.icystar.dicegenerator.apk)
+
+[Relative link to APK in the repo](/bw/findnumber/raw/master/f/release/com.icystar.findnumber.apk)
+
+----
+
+content of this repo is a public domain
diff --git a/art/banner.png b/art/banner.png
new file mode 100644
index 0000000..feee470
Binary files /dev/null and b/art/banner.png differ
diff --git a/art/banner.psd b/art/banner.psd
new file mode 100644
index 0000000..ae03980
Binary files /dev/null and b/art/banner.psd differ
diff --git a/art/dialogs_hdpi.psd b/art/dialogs_hdpi.psd
new file mode 100644
index 0000000..de64ab2
Binary files /dev/null and b/art/dialogs_hdpi.psd differ
diff --git a/art/dialogs_ldpi.psd b/art/dialogs_ldpi.psd
new file mode 100644
index 0000000..5e0d4f0
Binary files /dev/null and b/art/dialogs_ldpi.psd differ
diff --git a/art/dialogs_mdpi.psd b/art/dialogs_mdpi.psd
new file mode 100644
index 0000000..d4595f8
Binary files /dev/null and b/art/dialogs_mdpi.psd differ
diff --git a/art/dialogs_xhdpi.psd b/art/dialogs_xhdpi.psd
new file mode 100644
index 0000000..bd5a497
Binary files /dev/null and b/art/dialogs_xhdpi.psd differ
diff --git a/art/find-number-qr.png b/art/find-number-qr.png
new file mode 100644
index 0000000..61d32d3
Binary files /dev/null and b/art/find-number-qr.png differ
diff --git a/art/icons.psd b/art/icons.psd
new file mode 100644
index 0000000..6b43719
Binary files /dev/null and b/art/icons.psd differ
diff --git a/art/icons/continue.png b/art/icons/continue.png
new file mode 100644
index 0000000..87ada1e
Binary files /dev/null and b/art/icons/continue.png differ
diff --git a/art/icons/double.png b/art/icons/double.png
new file mode 100644
index 0000000..f5aad45
Binary files /dev/null and b/art/icons/double.png differ
diff --git a/art/icons/exit.png b/art/icons/exit.png
new file mode 100644
index 0000000..1bb5fe2
Binary files /dev/null and b/art/icons/exit.png differ
diff --git a/art/icons/help.png b/art/icons/help.png
new file mode 100644
index 0000000..1fe7604
Binary files /dev/null and b/art/icons/help.png differ
diff --git a/art/icons/lock.png b/art/icons/lock.png
new file mode 100644
index 0000000..3bf69a4
Binary files /dev/null and b/art/icons/lock.png differ
diff --git a/art/icons/n100.png b/art/icons/n100.png
new file mode 100644
index 0000000..e4e670e
Binary files /dev/null and b/art/icons/n100.png differ
diff --git a/art/icons/n25.png b/art/icons/n25.png
new file mode 100644
index 0000000..fe328f3
Binary files /dev/null and b/art/icons/n25.png differ
diff --git a/art/icons/n50.png b/art/icons/n50.png
new file mode 100644
index 0000000..5118fb2
Binary files /dev/null and b/art/icons/n50.png differ
diff --git a/art/icons/new.png b/art/icons/new.png
new file mode 100644
index 0000000..eb21c36
Binary files /dev/null and b/art/icons/new.png differ
diff --git a/art/icons/scoreboard.png b/art/icons/scoreboard.png
new file mode 100644
index 0000000..cf95403
Binary files /dev/null and b/art/icons/scoreboard.png differ
diff --git a/art/icons/single.png b/art/icons/single.png
new file mode 100644
index 0000000..5aca110
Binary files /dev/null and b/art/icons/single.png differ
diff --git a/art/icons/sound_off.png b/art/icons/sound_off.png
new file mode 100644
index 0000000..2ea7c1b
Binary files /dev/null and b/art/icons/sound_off.png differ
diff --git a/art/icons/sound_on.png b/art/icons/sound_on.png
new file mode 100644
index 0000000..52375a0
Binary files /dev/null and b/art/icons/sound_on.png differ
diff --git a/art/logo-256x256.png b/art/logo-256x256.png
new file mode 100644
index 0000000..0512b92
Binary files /dev/null and b/art/logo-256x256.png differ
diff --git a/art/logo-large.png b/art/logo-large.png
new file mode 100644
index 0000000..dde1712
Binary files /dev/null and b/art/logo-large.png differ
diff --git a/art/logo-transparent.png b/art/logo-transparent.png
new file mode 100644
index 0000000..1390191
Binary files /dev/null and b/art/logo-transparent.png differ
diff --git a/art/logo.png b/art/logo.png
new file mode 100644
index 0000000..3b021f6
Binary files /dev/null and b/art/logo.png differ
diff --git a/art/logo.psd b/art/logo.psd
new file mode 100644
index 0000000..9e38303
Binary files /dev/null and b/art/logo.psd differ
diff --git a/art/screen1.png b/art/screen1.png
new file mode 100644
index 0000000..a7ffa4f
Binary files /dev/null and b/art/screen1.png differ
diff --git a/art/screen2.png b/art/screen2.png
new file mode 100644
index 0000000..0034532
Binary files /dev/null and b/art/screen2.png differ
diff --git a/art/screen3.png b/art/screen3.png
new file mode 100644
index 0000000..72983a5
Binary files /dev/null and b/art/screen3.png differ
diff --git a/art/screens.psd b/art/screens.psd
new file mode 100644
index 0000000..77b4503
Binary files /dev/null and b/art/screens.psd differ
diff --git a/art/sounds/13957_33634-lq.ogg b/art/sounds/13957_33634-lq.ogg
new file mode 100644
index 0000000..dff7c87
Binary files /dev/null and b/art/sounds/13957_33634-lq.ogg differ
diff --git a/art/sounds/13958_33634-lq.ogg b/art/sounds/13958_33634-lq.ogg
new file mode 100644
index 0000000..525f1af
Binary files /dev/null and b/art/sounds/13958_33634-lq.ogg differ
diff --git a/art/sounds/13959_33634-lq.ogg b/art/sounds/13959_33634-lq.ogg
new file mode 100644
index 0000000..8b89b94
Binary files /dev/null and b/art/sounds/13959_33634-lq.ogg differ
diff --git a/art/sounds/17772_5190-lq.ogg b/art/sounds/17772_5190-lq.ogg
new file mode 100644
index 0000000..fcff05f
Binary files /dev/null and b/art/sounds/17772_5190-lq.ogg differ
diff --git a/art/sounds/19089_82369-lq.ogg b/art/sounds/19089_82369-lq.ogg
new file mode 100644
index 0000000..475fee9
Binary files /dev/null and b/art/sounds/19089_82369-lq.ogg differ
diff --git a/art/sounds/20796_45941-lq.ogg b/art/sounds/20796_45941-lq.ogg
new file mode 100644
index 0000000..fafb2ad
Binary files /dev/null and b/art/sounds/20796_45941-lq.ogg differ
diff --git a/art/sounds/21352_36084-lq.ogg b/art/sounds/21352_36084-lq.ogg
new file mode 100644
index 0000000..99b6627
Binary files /dev/null and b/art/sounds/21352_36084-lq.ogg differ
diff --git a/art/sounds/21363_36084-lq.ogg b/art/sounds/21363_36084-lq.ogg
new file mode 100644
index 0000000..1b70f39
Binary files /dev/null and b/art/sounds/21363_36084-lq.ogg differ
diff --git a/art/sounds/21375_36084-lq.ogg b/art/sounds/21375_36084-lq.ogg
new file mode 100644
index 0000000..7e5fa9f
Binary files /dev/null and b/art/sounds/21375_36084-lq.ogg differ
diff --git a/art/sounds/21389_36084-lq.ogg b/art/sounds/21389_36084-lq.ogg
new file mode 100644
index 0000000..308650f
Binary files /dev/null and b/art/sounds/21389_36084-lq.ogg differ
diff --git a/art/sounds/21695_103578-lq.ogg b/art/sounds/21695_103578-lq.ogg
new file mode 100644
index 0000000..489e2c6
Binary files /dev/null and b/art/sounds/21695_103578-lq.ogg differ
diff --git a/art/sounds/2554_4330-lq.ogg b/art/sounds/2554_4330-lq.ogg
new file mode 100644
index 0000000..7f377cf
Binary files /dev/null and b/art/sounds/2554_4330-lq.ogg differ
diff --git a/art/sounds/35631_18799-lq.ogg b/art/sounds/35631_18799-lq.ogg
new file mode 100644
index 0000000..ef78c20
Binary files /dev/null and b/art/sounds/35631_18799-lq.ogg differ
diff --git a/art/sounds/35978_205819-lq.ogg b/art/sounds/35978_205819-lq.ogg
new file mode 100644
index 0000000..2d529ba
Binary files /dev/null and b/art/sounds/35978_205819-lq.ogg differ
diff --git a/art/sounds/407_196-lq.ogg b/art/sounds/407_196-lq.ogg
new file mode 100644
index 0000000..9427b08
Binary files /dev/null and b/art/sounds/407_196-lq.ogg differ
diff --git a/art/sounds/41990_29541-lq.ogg b/art/sounds/41990_29541-lq.ogg
new file mode 100644
index 0000000..75d6d8c
Binary files /dev/null and b/art/sounds/41990_29541-lq.ogg differ
diff --git a/art/sounds/54405_497386-lq.ogg b/art/sounds/54405_497386-lq.ogg
new file mode 100644
index 0000000..140d964
Binary files /dev/null and b/art/sounds/54405_497386-lq.ogg differ
diff --git a/art/sounds/706_207-lq.ogg b/art/sounds/706_207-lq.ogg
new file mode 100644
index 0000000..99d6bfe
Binary files /dev/null and b/art/sounds/706_207-lq.ogg differ
diff --git a/art/sounds/778_207-lq (1).ogg b/art/sounds/778_207-lq (1).ogg
new file mode 100644
index 0000000..6efae17
Binary files /dev/null and b/art/sounds/778_207-lq (1).ogg differ
diff --git a/art/sounds/778_207-lq.ogg b/art/sounds/778_207-lq.ogg
new file mode 100644
index 0000000..6efae17
Binary files /dev/null and b/art/sounds/778_207-lq.ogg differ
diff --git a/art/sounds/779_207-lq.ogg b/art/sounds/779_207-lq.ogg
new file mode 100644
index 0000000..c8e099d
Binary files /dev/null and b/art/sounds/779_207-lq.ogg differ
diff --git a/art/sounds/9447_23262-lq.ogg b/art/sounds/9447_23262-lq.ogg
new file mode 100644
index 0000000..34afefd
Binary files /dev/null and b/art/sounds/9447_23262-lq.ogg differ
diff --git a/art/sounds/sound_palyer1_clicked.ogg b/art/sounds/sound_palyer1_clicked.ogg
new file mode 100644
index 0000000..f4b6788
Binary files /dev/null and b/art/sounds/sound_palyer1_clicked.ogg differ
diff --git a/art/sounds/sound_player2_clicked.ogg b/art/sounds/sound_player2_clicked.ogg
new file mode 100644
index 0000000..8e4fa3d
Binary files /dev/null and b/art/sounds/sound_player2_clicked.ogg differ
diff --git a/art/title.png b/art/title.png
new file mode 100644
index 0000000..877c858
Binary files /dev/null and b/art/title.png differ
diff --git a/art/title.psd b/art/title.psd
new file mode 100644
index 0000000..1ec0b80
Binary files /dev/null and b/art/title.psd differ
diff --git a/ic_launcher-web.png b/ic_launcher-web.png
new file mode 100644
index 0000000..dde1712
Binary files /dev/null and b/ic_launcher-web.png differ
diff --git a/proguard-project.txt b/proguard-project.txt
new file mode 100644
index 0000000..f2fe155
--- /dev/null
+++ b/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/project.properties b/project.properties
new file mode 100644
index 0000000..2cab5fb
--- /dev/null
+++ b/project.properties
@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-4
diff --git a/release/com.icystar.findnumber.apk b/release/com.icystar.findnumber.apk
new file mode 100644
index 0000000..b0e4e55
Binary files /dev/null and b/release/com.icystar.findnumber.apk differ
diff --git a/res/anim/fade_in.xml b/res/anim/fade_in.xml
new file mode 100644
index 0000000..b4afc12
--- /dev/null
+++ b/res/anim/fade_in.xml
@@ -0,0 +1,5 @@
+
+
\ No newline at end of file
diff --git a/res/anim/fade_out.xml b/res/anim/fade_out.xml
new file mode 100644
index 0000000..9d874ed
--- /dev/null
+++ b/res/anim/fade_out.xml
@@ -0,0 +1,5 @@
+
+
\ No newline at end of file
diff --git a/res/drawable-hdpi-v5/ic_tab_n100_selected.png b/res/drawable-hdpi-v5/ic_tab_n100_selected.png
new file mode 100644
index 0000000..c988d2e
Binary files /dev/null and b/res/drawable-hdpi-v5/ic_tab_n100_selected.png differ
diff --git a/res/drawable-hdpi-v5/ic_tab_n100_unselected.png b/res/drawable-hdpi-v5/ic_tab_n100_unselected.png
new file mode 100644
index 0000000..ad4e13c
Binary files /dev/null and b/res/drawable-hdpi-v5/ic_tab_n100_unselected.png differ
diff --git a/res/drawable-hdpi-v5/ic_tab_n25_selected.png b/res/drawable-hdpi-v5/ic_tab_n25_selected.png
new file mode 100644
index 0000000..f3ef9cd
Binary files /dev/null and b/res/drawable-hdpi-v5/ic_tab_n25_selected.png differ
diff --git a/res/drawable-hdpi-v5/ic_tab_n25_unselected.png b/res/drawable-hdpi-v5/ic_tab_n25_unselected.png
new file mode 100644
index 0000000..c6ba9d7
Binary files /dev/null and b/res/drawable-hdpi-v5/ic_tab_n25_unselected.png differ
diff --git a/res/drawable-hdpi-v5/ic_tab_n50_selected.png b/res/drawable-hdpi-v5/ic_tab_n50_selected.png
new file mode 100644
index 0000000..4084567
Binary files /dev/null and b/res/drawable-hdpi-v5/ic_tab_n50_selected.png differ
diff --git a/res/drawable-hdpi-v5/ic_tab_n50_unselected.png b/res/drawable-hdpi-v5/ic_tab_n50_unselected.png
new file mode 100644
index 0000000..5779d34
Binary files /dev/null and b/res/drawable-hdpi-v5/ic_tab_n50_unselected.png differ
diff --git a/res/drawable-hdpi/ic_action_search.png b/res/drawable-hdpi/ic_action_search.png
new file mode 100644
index 0000000..67de12d
Binary files /dev/null and b/res/drawable-hdpi/ic_action_search.png differ
diff --git a/res/drawable-hdpi/ic_button_continue.png b/res/drawable-hdpi/ic_button_continue.png
new file mode 100644
index 0000000..91d154f
Binary files /dev/null and b/res/drawable-hdpi/ic_button_continue.png differ
diff --git a/res/drawable-hdpi/ic_button_double.png b/res/drawable-hdpi/ic_button_double.png
new file mode 100644
index 0000000..b9c84de
Binary files /dev/null and b/res/drawable-hdpi/ic_button_double.png differ
diff --git a/res/drawable-hdpi/ic_button_exit.png b/res/drawable-hdpi/ic_button_exit.png
new file mode 100644
index 0000000..5dafce8
Binary files /dev/null and b/res/drawable-hdpi/ic_button_exit.png differ
diff --git a/res/drawable-hdpi/ic_button_help.png b/res/drawable-hdpi/ic_button_help.png
new file mode 100644
index 0000000..cb80f2c
Binary files /dev/null and b/res/drawable-hdpi/ic_button_help.png differ
diff --git a/res/drawable-hdpi/ic_button_lock.png b/res/drawable-hdpi/ic_button_lock.png
new file mode 100644
index 0000000..4130f96
Binary files /dev/null and b/res/drawable-hdpi/ic_button_lock.png differ
diff --git a/res/drawable-hdpi/ic_button_new.png b/res/drawable-hdpi/ic_button_new.png
new file mode 100644
index 0000000..fa5425b
Binary files /dev/null and b/res/drawable-hdpi/ic_button_new.png differ
diff --git a/res/drawable-hdpi/ic_button_scoreboard.png b/res/drawable-hdpi/ic_button_scoreboard.png
new file mode 100644
index 0000000..32601d1
Binary files /dev/null and b/res/drawable-hdpi/ic_button_scoreboard.png differ
diff --git a/res/drawable-hdpi/ic_button_single.png b/res/drawable-hdpi/ic_button_single.png
new file mode 100644
index 0000000..e94e955
Binary files /dev/null and b/res/drawable-hdpi/ic_button_single.png differ
diff --git a/res/drawable-hdpi/ic_button_sound_off.png b/res/drawable-hdpi/ic_button_sound_off.png
new file mode 100644
index 0000000..db23757
Binary files /dev/null and b/res/drawable-hdpi/ic_button_sound_off.png differ
diff --git a/res/drawable-hdpi/ic_button_sound_on.png b/res/drawable-hdpi/ic_button_sound_on.png
new file mode 100644
index 0000000..be75c57
Binary files /dev/null and b/res/drawable-hdpi/ic_button_sound_on.png differ
diff --git a/res/drawable-hdpi/ic_dialog_alert.png b/res/drawable-hdpi/ic_dialog_alert.png
new file mode 100644
index 0000000..7f905ba
Binary files /dev/null and b/res/drawable-hdpi/ic_dialog_alert.png differ
diff --git a/res/drawable-hdpi/ic_dialog_info.png b/res/drawable-hdpi/ic_dialog_info.png
new file mode 100644
index 0000000..efee1ef
Binary files /dev/null and b/res/drawable-hdpi/ic_dialog_info.png differ
diff --git a/res/drawable-hdpi/ic_dialog_new.png b/res/drawable-hdpi/ic_dialog_new.png
new file mode 100644
index 0000000..40e9452
Binary files /dev/null and b/res/drawable-hdpi/ic_dialog_new.png differ
diff --git a/res/drawable-hdpi/ic_dialog_win.png b/res/drawable-hdpi/ic_dialog_win.png
new file mode 100644
index 0000000..59d9c82
Binary files /dev/null and b/res/drawable-hdpi/ic_dialog_win.png differ
diff --git a/res/drawable-hdpi/ic_launcher.png b/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..a6037cc
Binary files /dev/null and b/res/drawable-hdpi/ic_launcher.png differ
diff --git a/res/drawable-hdpi/ic_tab_n100_selected.png b/res/drawable-hdpi/ic_tab_n100_selected.png
new file mode 100644
index 0000000..f716fc4
Binary files /dev/null and b/res/drawable-hdpi/ic_tab_n100_selected.png differ
diff --git a/res/drawable-hdpi/ic_tab_n100_unselected.png b/res/drawable-hdpi/ic_tab_n100_unselected.png
new file mode 100644
index 0000000..dc2e4b8
Binary files /dev/null and b/res/drawable-hdpi/ic_tab_n100_unselected.png differ
diff --git a/res/drawable-hdpi/ic_tab_n25_selected.png b/res/drawable-hdpi/ic_tab_n25_selected.png
new file mode 100644
index 0000000..058b756
Binary files /dev/null and b/res/drawable-hdpi/ic_tab_n25_selected.png differ
diff --git a/res/drawable-hdpi/ic_tab_n25_unselected.png b/res/drawable-hdpi/ic_tab_n25_unselected.png
new file mode 100644
index 0000000..29abd77
Binary files /dev/null and b/res/drawable-hdpi/ic_tab_n25_unselected.png differ
diff --git a/res/drawable-hdpi/ic_tab_n50_selected.png b/res/drawable-hdpi/ic_tab_n50_selected.png
new file mode 100644
index 0000000..6c8f875
Binary files /dev/null and b/res/drawable-hdpi/ic_tab_n50_selected.png differ
diff --git a/res/drawable-hdpi/ic_tab_n50_unselected.png b/res/drawable-hdpi/ic_tab_n50_unselected.png
new file mode 100644
index 0000000..fd2ffcc
Binary files /dev/null and b/res/drawable-hdpi/ic_tab_n50_unselected.png differ
diff --git a/res/drawable-hdpi/title.png b/res/drawable-hdpi/title.png
new file mode 100644
index 0000000..e1d61a2
Binary files /dev/null and b/res/drawable-hdpi/title.png differ
diff --git a/res/drawable-ldpi-v5/ic_tab_n100_selected.png b/res/drawable-ldpi-v5/ic_tab_n100_selected.png
new file mode 100644
index 0000000..df5c62a
Binary files /dev/null and b/res/drawable-ldpi-v5/ic_tab_n100_selected.png differ
diff --git a/res/drawable-ldpi-v5/ic_tab_n100_unselected.png b/res/drawable-ldpi-v5/ic_tab_n100_unselected.png
new file mode 100644
index 0000000..6799ccc
Binary files /dev/null and b/res/drawable-ldpi-v5/ic_tab_n100_unselected.png differ
diff --git a/res/drawable-ldpi-v5/ic_tab_n25_selected.png b/res/drawable-ldpi-v5/ic_tab_n25_selected.png
new file mode 100644
index 0000000..f2c25c7
Binary files /dev/null and b/res/drawable-ldpi-v5/ic_tab_n25_selected.png differ
diff --git a/res/drawable-ldpi-v5/ic_tab_n25_unselected.png b/res/drawable-ldpi-v5/ic_tab_n25_unselected.png
new file mode 100644
index 0000000..d3c5887
Binary files /dev/null and b/res/drawable-ldpi-v5/ic_tab_n25_unselected.png differ
diff --git a/res/drawable-ldpi-v5/ic_tab_n50_selected.png b/res/drawable-ldpi-v5/ic_tab_n50_selected.png
new file mode 100644
index 0000000..32d0527
Binary files /dev/null and b/res/drawable-ldpi-v5/ic_tab_n50_selected.png differ
diff --git a/res/drawable-ldpi-v5/ic_tab_n50_unselected.png b/res/drawable-ldpi-v5/ic_tab_n50_unselected.png
new file mode 100644
index 0000000..9507ab4
Binary files /dev/null and b/res/drawable-ldpi-v5/ic_tab_n50_unselected.png differ
diff --git a/res/drawable-ldpi/ic_button_continue.png b/res/drawable-ldpi/ic_button_continue.png
new file mode 100644
index 0000000..84688a9
Binary files /dev/null and b/res/drawable-ldpi/ic_button_continue.png differ
diff --git a/res/drawable-ldpi/ic_button_double.png b/res/drawable-ldpi/ic_button_double.png
new file mode 100644
index 0000000..22cec05
Binary files /dev/null and b/res/drawable-ldpi/ic_button_double.png differ
diff --git a/res/drawable-ldpi/ic_button_exit.png b/res/drawable-ldpi/ic_button_exit.png
new file mode 100644
index 0000000..472027e
Binary files /dev/null and b/res/drawable-ldpi/ic_button_exit.png differ
diff --git a/res/drawable-ldpi/ic_button_help.png b/res/drawable-ldpi/ic_button_help.png
new file mode 100644
index 0000000..2c8fc6a
Binary files /dev/null and b/res/drawable-ldpi/ic_button_help.png differ
diff --git a/res/drawable-ldpi/ic_button_lock.png b/res/drawable-ldpi/ic_button_lock.png
new file mode 100644
index 0000000..7d2b379
Binary files /dev/null and b/res/drawable-ldpi/ic_button_lock.png differ
diff --git a/res/drawable-ldpi/ic_button_new.png b/res/drawable-ldpi/ic_button_new.png
new file mode 100644
index 0000000..7c4a5ab
Binary files /dev/null and b/res/drawable-ldpi/ic_button_new.png differ
diff --git a/res/drawable-ldpi/ic_button_scoreboard.png b/res/drawable-ldpi/ic_button_scoreboard.png
new file mode 100644
index 0000000..e7251cd
Binary files /dev/null and b/res/drawable-ldpi/ic_button_scoreboard.png differ
diff --git a/res/drawable-ldpi/ic_button_single.png b/res/drawable-ldpi/ic_button_single.png
new file mode 100644
index 0000000..f168323
Binary files /dev/null and b/res/drawable-ldpi/ic_button_single.png differ
diff --git a/res/drawable-ldpi/ic_button_sound_off.png b/res/drawable-ldpi/ic_button_sound_off.png
new file mode 100644
index 0000000..40e3d44
Binary files /dev/null and b/res/drawable-ldpi/ic_button_sound_off.png differ
diff --git a/res/drawable-ldpi/ic_button_sound_on.png b/res/drawable-ldpi/ic_button_sound_on.png
new file mode 100644
index 0000000..7be4428
Binary files /dev/null and b/res/drawable-ldpi/ic_button_sound_on.png differ
diff --git a/res/drawable-ldpi/ic_dialog_alert.png b/res/drawable-ldpi/ic_dialog_alert.png
new file mode 100644
index 0000000..6c3c624
Binary files /dev/null and b/res/drawable-ldpi/ic_dialog_alert.png differ
diff --git a/res/drawable-ldpi/ic_dialog_info.png b/res/drawable-ldpi/ic_dialog_info.png
new file mode 100644
index 0000000..a1dcc5a
Binary files /dev/null and b/res/drawable-ldpi/ic_dialog_info.png differ
diff --git a/res/drawable-ldpi/ic_dialog_new.png b/res/drawable-ldpi/ic_dialog_new.png
new file mode 100644
index 0000000..571fe5b
Binary files /dev/null and b/res/drawable-ldpi/ic_dialog_new.png differ
diff --git a/res/drawable-ldpi/ic_dialog_win.png b/res/drawable-ldpi/ic_dialog_win.png
new file mode 100644
index 0000000..82aafea
Binary files /dev/null and b/res/drawable-ldpi/ic_dialog_win.png differ
diff --git a/res/drawable-ldpi/ic_launcher.png b/res/drawable-ldpi/ic_launcher.png
new file mode 100644
index 0000000..0645a32
Binary files /dev/null and b/res/drawable-ldpi/ic_launcher.png differ
diff --git a/res/drawable-ldpi/ic_tab_n100_selected.png b/res/drawable-ldpi/ic_tab_n100_selected.png
new file mode 100644
index 0000000..4b5c385
Binary files /dev/null and b/res/drawable-ldpi/ic_tab_n100_selected.png differ
diff --git a/res/drawable-ldpi/ic_tab_n100_unselected.png b/res/drawable-ldpi/ic_tab_n100_unselected.png
new file mode 100644
index 0000000..c75ea35
Binary files /dev/null and b/res/drawable-ldpi/ic_tab_n100_unselected.png differ
diff --git a/res/drawable-ldpi/ic_tab_n25_selected.png b/res/drawable-ldpi/ic_tab_n25_selected.png
new file mode 100644
index 0000000..64b6a82
Binary files /dev/null and b/res/drawable-ldpi/ic_tab_n25_selected.png differ
diff --git a/res/drawable-ldpi/ic_tab_n25_unselected.png b/res/drawable-ldpi/ic_tab_n25_unselected.png
new file mode 100644
index 0000000..cdb4223
Binary files /dev/null and b/res/drawable-ldpi/ic_tab_n25_unselected.png differ
diff --git a/res/drawable-ldpi/ic_tab_n50_selected.png b/res/drawable-ldpi/ic_tab_n50_selected.png
new file mode 100644
index 0000000..d53484e
Binary files /dev/null and b/res/drawable-ldpi/ic_tab_n50_selected.png differ
diff --git a/res/drawable-ldpi/ic_tab_n50_unselected.png b/res/drawable-ldpi/ic_tab_n50_unselected.png
new file mode 100644
index 0000000..9ecb910
Binary files /dev/null and b/res/drawable-ldpi/ic_tab_n50_unselected.png differ
diff --git a/res/drawable-ldpi/title.png b/res/drawable-ldpi/title.png
new file mode 100644
index 0000000..884c056
Binary files /dev/null and b/res/drawable-ldpi/title.png differ
diff --git a/res/drawable-mdpi-v5/ic_tab_n100_selected.png b/res/drawable-mdpi-v5/ic_tab_n100_selected.png
new file mode 100644
index 0000000..9f951e3
Binary files /dev/null and b/res/drawable-mdpi-v5/ic_tab_n100_selected.png differ
diff --git a/res/drawable-mdpi-v5/ic_tab_n100_unselected.png b/res/drawable-mdpi-v5/ic_tab_n100_unselected.png
new file mode 100644
index 0000000..268fdd9
Binary files /dev/null and b/res/drawable-mdpi-v5/ic_tab_n100_unselected.png differ
diff --git a/res/drawable-mdpi-v5/ic_tab_n25_selected.png b/res/drawable-mdpi-v5/ic_tab_n25_selected.png
new file mode 100644
index 0000000..b4eb98a
Binary files /dev/null and b/res/drawable-mdpi-v5/ic_tab_n25_selected.png differ
diff --git a/res/drawable-mdpi-v5/ic_tab_n25_unselected.png b/res/drawable-mdpi-v5/ic_tab_n25_unselected.png
new file mode 100644
index 0000000..21feecb
Binary files /dev/null and b/res/drawable-mdpi-v5/ic_tab_n25_unselected.png differ
diff --git a/res/drawable-mdpi-v5/ic_tab_n50_selected.png b/res/drawable-mdpi-v5/ic_tab_n50_selected.png
new file mode 100644
index 0000000..efb447c
Binary files /dev/null and b/res/drawable-mdpi-v5/ic_tab_n50_selected.png differ
diff --git a/res/drawable-mdpi-v5/ic_tab_n50_unselected.png b/res/drawable-mdpi-v5/ic_tab_n50_unselected.png
new file mode 100644
index 0000000..39d7589
Binary files /dev/null and b/res/drawable-mdpi-v5/ic_tab_n50_unselected.png differ
diff --git a/res/drawable-mdpi/ic_action_search.png b/res/drawable-mdpi/ic_action_search.png
new file mode 100644
index 0000000..134d549
Binary files /dev/null and b/res/drawable-mdpi/ic_action_search.png differ
diff --git a/res/drawable-mdpi/ic_button_continue.png b/res/drawable-mdpi/ic_button_continue.png
new file mode 100644
index 0000000..29cf632
Binary files /dev/null and b/res/drawable-mdpi/ic_button_continue.png differ
diff --git a/res/drawable-mdpi/ic_button_double.png b/res/drawable-mdpi/ic_button_double.png
new file mode 100644
index 0000000..93cce76
Binary files /dev/null and b/res/drawable-mdpi/ic_button_double.png differ
diff --git a/res/drawable-mdpi/ic_button_exit.png b/res/drawable-mdpi/ic_button_exit.png
new file mode 100644
index 0000000..b908415
Binary files /dev/null and b/res/drawable-mdpi/ic_button_exit.png differ
diff --git a/res/drawable-mdpi/ic_button_help.png b/res/drawable-mdpi/ic_button_help.png
new file mode 100644
index 0000000..2a66a14
Binary files /dev/null and b/res/drawable-mdpi/ic_button_help.png differ
diff --git a/res/drawable-mdpi/ic_button_lock.png b/res/drawable-mdpi/ic_button_lock.png
new file mode 100644
index 0000000..49be15d
Binary files /dev/null and b/res/drawable-mdpi/ic_button_lock.png differ
diff --git a/res/drawable-mdpi/ic_button_new.png b/res/drawable-mdpi/ic_button_new.png
new file mode 100644
index 0000000..b5bd817
Binary files /dev/null and b/res/drawable-mdpi/ic_button_new.png differ
diff --git a/res/drawable-mdpi/ic_button_scoreboard.png b/res/drawable-mdpi/ic_button_scoreboard.png
new file mode 100644
index 0000000..4453291
Binary files /dev/null and b/res/drawable-mdpi/ic_button_scoreboard.png differ
diff --git a/res/drawable-mdpi/ic_button_single.png b/res/drawable-mdpi/ic_button_single.png
new file mode 100644
index 0000000..f882b44
Binary files /dev/null and b/res/drawable-mdpi/ic_button_single.png differ
diff --git a/res/drawable-mdpi/ic_button_sound_off.png b/res/drawable-mdpi/ic_button_sound_off.png
new file mode 100644
index 0000000..5b23d34
Binary files /dev/null and b/res/drawable-mdpi/ic_button_sound_off.png differ
diff --git a/res/drawable-mdpi/ic_button_sound_on.png b/res/drawable-mdpi/ic_button_sound_on.png
new file mode 100644
index 0000000..91ae12a
Binary files /dev/null and b/res/drawable-mdpi/ic_button_sound_on.png differ
diff --git a/res/drawable-mdpi/ic_dialog_alert.png b/res/drawable-mdpi/ic_dialog_alert.png
new file mode 100644
index 0000000..ef498ef
Binary files /dev/null and b/res/drawable-mdpi/ic_dialog_alert.png differ
diff --git a/res/drawable-mdpi/ic_dialog_info.png b/res/drawable-mdpi/ic_dialog_info.png
new file mode 100644
index 0000000..e8b0229
Binary files /dev/null and b/res/drawable-mdpi/ic_dialog_info.png differ
diff --git a/res/drawable-mdpi/ic_dialog_new.png b/res/drawable-mdpi/ic_dialog_new.png
new file mode 100644
index 0000000..1cbc400
Binary files /dev/null and b/res/drawable-mdpi/ic_dialog_new.png differ
diff --git a/res/drawable-mdpi/ic_dialog_win.png b/res/drawable-mdpi/ic_dialog_win.png
new file mode 100644
index 0000000..e7a8c04
Binary files /dev/null and b/res/drawable-mdpi/ic_dialog_win.png differ
diff --git a/res/drawable-mdpi/ic_launcher.png b/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..20e6ba8
Binary files /dev/null and b/res/drawable-mdpi/ic_launcher.png differ
diff --git a/res/drawable-mdpi/ic_tab_n100_selected.png b/res/drawable-mdpi/ic_tab_n100_selected.png
new file mode 100644
index 0000000..11ad714
Binary files /dev/null and b/res/drawable-mdpi/ic_tab_n100_selected.png differ
diff --git a/res/drawable-mdpi/ic_tab_n100_unselected.png b/res/drawable-mdpi/ic_tab_n100_unselected.png
new file mode 100644
index 0000000..2e971ff
Binary files /dev/null and b/res/drawable-mdpi/ic_tab_n100_unselected.png differ
diff --git a/res/drawable-mdpi/ic_tab_n25_selected.png b/res/drawable-mdpi/ic_tab_n25_selected.png
new file mode 100644
index 0000000..02eabec
Binary files /dev/null and b/res/drawable-mdpi/ic_tab_n25_selected.png differ
diff --git a/res/drawable-mdpi/ic_tab_n25_unselected.png b/res/drawable-mdpi/ic_tab_n25_unselected.png
new file mode 100644
index 0000000..3703f83
Binary files /dev/null and b/res/drawable-mdpi/ic_tab_n25_unselected.png differ
diff --git a/res/drawable-mdpi/ic_tab_n50_selected.png b/res/drawable-mdpi/ic_tab_n50_selected.png
new file mode 100644
index 0000000..2dfc514
Binary files /dev/null and b/res/drawable-mdpi/ic_tab_n50_selected.png differ
diff --git a/res/drawable-mdpi/ic_tab_n50_unselected.png b/res/drawable-mdpi/ic_tab_n50_unselected.png
new file mode 100644
index 0000000..0f39da4
Binary files /dev/null and b/res/drawable-mdpi/ic_tab_n50_unselected.png differ
diff --git a/res/drawable-mdpi/title.png b/res/drawable-mdpi/title.png
new file mode 100644
index 0000000..57d0175
Binary files /dev/null and b/res/drawable-mdpi/title.png differ
diff --git a/res/drawable-xhdpi-v5/ic_tab_n100_selected.png b/res/drawable-xhdpi-v5/ic_tab_n100_selected.png
new file mode 100644
index 0000000..03c588d
Binary files /dev/null and b/res/drawable-xhdpi-v5/ic_tab_n100_selected.png differ
diff --git a/res/drawable-xhdpi-v5/ic_tab_n100_unselected.png b/res/drawable-xhdpi-v5/ic_tab_n100_unselected.png
new file mode 100644
index 0000000..b0e9578
Binary files /dev/null and b/res/drawable-xhdpi-v5/ic_tab_n100_unselected.png differ
diff --git a/res/drawable-xhdpi-v5/ic_tab_n25_selected.png b/res/drawable-xhdpi-v5/ic_tab_n25_selected.png
new file mode 100644
index 0000000..5e0e308
Binary files /dev/null and b/res/drawable-xhdpi-v5/ic_tab_n25_selected.png differ
diff --git a/res/drawable-xhdpi-v5/ic_tab_n25_unselected.png b/res/drawable-xhdpi-v5/ic_tab_n25_unselected.png
new file mode 100644
index 0000000..a70b78c
Binary files /dev/null and b/res/drawable-xhdpi-v5/ic_tab_n25_unselected.png differ
diff --git a/res/drawable-xhdpi-v5/ic_tab_n50_selected.png b/res/drawable-xhdpi-v5/ic_tab_n50_selected.png
new file mode 100644
index 0000000..43d5179
Binary files /dev/null and b/res/drawable-xhdpi-v5/ic_tab_n50_selected.png differ
diff --git a/res/drawable-xhdpi-v5/ic_tab_n50_unselected.png b/res/drawable-xhdpi-v5/ic_tab_n50_unselected.png
new file mode 100644
index 0000000..9faf6d6
Binary files /dev/null and b/res/drawable-xhdpi-v5/ic_tab_n50_unselected.png differ
diff --git a/res/drawable-xhdpi/ic_action_search.png b/res/drawable-xhdpi/ic_action_search.png
new file mode 100644
index 0000000..d699c6b
Binary files /dev/null and b/res/drawable-xhdpi/ic_action_search.png differ
diff --git a/res/drawable-xhdpi/ic_button_continue.png b/res/drawable-xhdpi/ic_button_continue.png
new file mode 100644
index 0000000..569ff50
Binary files /dev/null and b/res/drawable-xhdpi/ic_button_continue.png differ
diff --git a/res/drawable-xhdpi/ic_button_double.png b/res/drawable-xhdpi/ic_button_double.png
new file mode 100644
index 0000000..a9a8378
Binary files /dev/null and b/res/drawable-xhdpi/ic_button_double.png differ
diff --git a/res/drawable-xhdpi/ic_button_exit.png b/res/drawable-xhdpi/ic_button_exit.png
new file mode 100644
index 0000000..0a343c4
Binary files /dev/null and b/res/drawable-xhdpi/ic_button_exit.png differ
diff --git a/res/drawable-xhdpi/ic_button_help.png b/res/drawable-xhdpi/ic_button_help.png
new file mode 100644
index 0000000..05f6975
Binary files /dev/null and b/res/drawable-xhdpi/ic_button_help.png differ
diff --git a/res/drawable-xhdpi/ic_button_lock.png b/res/drawable-xhdpi/ic_button_lock.png
new file mode 100644
index 0000000..fa14491
Binary files /dev/null and b/res/drawable-xhdpi/ic_button_lock.png differ
diff --git a/res/drawable-xhdpi/ic_button_new.png b/res/drawable-xhdpi/ic_button_new.png
new file mode 100644
index 0000000..eb84646
Binary files /dev/null and b/res/drawable-xhdpi/ic_button_new.png differ
diff --git a/res/drawable-xhdpi/ic_button_scoreboard.png b/res/drawable-xhdpi/ic_button_scoreboard.png
new file mode 100644
index 0000000..a5eb507
Binary files /dev/null and b/res/drawable-xhdpi/ic_button_scoreboard.png differ
diff --git a/res/drawable-xhdpi/ic_button_single.png b/res/drawable-xhdpi/ic_button_single.png
new file mode 100644
index 0000000..0f10b4a
Binary files /dev/null and b/res/drawable-xhdpi/ic_button_single.png differ
diff --git a/res/drawable-xhdpi/ic_button_sound_off.png b/res/drawable-xhdpi/ic_button_sound_off.png
new file mode 100644
index 0000000..98f34b0
Binary files /dev/null and b/res/drawable-xhdpi/ic_button_sound_off.png differ
diff --git a/res/drawable-xhdpi/ic_button_sound_on.png b/res/drawable-xhdpi/ic_button_sound_on.png
new file mode 100644
index 0000000..82bf0a3
Binary files /dev/null and b/res/drawable-xhdpi/ic_button_sound_on.png differ
diff --git a/res/drawable-xhdpi/ic_dialog_alert.png b/res/drawable-xhdpi/ic_dialog_alert.png
new file mode 100644
index 0000000..2834f35
Binary files /dev/null and b/res/drawable-xhdpi/ic_dialog_alert.png differ
diff --git a/res/drawable-xhdpi/ic_dialog_info.png b/res/drawable-xhdpi/ic_dialog_info.png
new file mode 100644
index 0000000..478dcc1
Binary files /dev/null and b/res/drawable-xhdpi/ic_dialog_info.png differ
diff --git a/res/drawable-xhdpi/ic_dialog_new.png b/res/drawable-xhdpi/ic_dialog_new.png
new file mode 100644
index 0000000..5d8770f
Binary files /dev/null and b/res/drawable-xhdpi/ic_dialog_new.png differ
diff --git a/res/drawable-xhdpi/ic_dialog_win.png b/res/drawable-xhdpi/ic_dialog_win.png
new file mode 100644
index 0000000..ae6e518
Binary files /dev/null and b/res/drawable-xhdpi/ic_dialog_win.png differ
diff --git a/res/drawable-xhdpi/ic_launcher.png b/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..f9e48f1
Binary files /dev/null and b/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/res/drawable-xhdpi/ic_tab_n100_selected.png b/res/drawable-xhdpi/ic_tab_n100_selected.png
new file mode 100644
index 0000000..81d0d6b
Binary files /dev/null and b/res/drawable-xhdpi/ic_tab_n100_selected.png differ
diff --git a/res/drawable-xhdpi/ic_tab_n100_unselected.png b/res/drawable-xhdpi/ic_tab_n100_unselected.png
new file mode 100644
index 0000000..d3599dd
Binary files /dev/null and b/res/drawable-xhdpi/ic_tab_n100_unselected.png differ
diff --git a/res/drawable-xhdpi/ic_tab_n25_selected.png b/res/drawable-xhdpi/ic_tab_n25_selected.png
new file mode 100644
index 0000000..d00149f
Binary files /dev/null and b/res/drawable-xhdpi/ic_tab_n25_selected.png differ
diff --git a/res/drawable-xhdpi/ic_tab_n25_unselected.png b/res/drawable-xhdpi/ic_tab_n25_unselected.png
new file mode 100644
index 0000000..03d3475
Binary files /dev/null and b/res/drawable-xhdpi/ic_tab_n25_unselected.png differ
diff --git a/res/drawable-xhdpi/ic_tab_n50_selected.png b/res/drawable-xhdpi/ic_tab_n50_selected.png
new file mode 100644
index 0000000..348cb21
Binary files /dev/null and b/res/drawable-xhdpi/ic_tab_n50_selected.png differ
diff --git a/res/drawable-xhdpi/ic_tab_n50_unselected.png b/res/drawable-xhdpi/ic_tab_n50_unselected.png
new file mode 100644
index 0000000..819fb53
Binary files /dev/null and b/res/drawable-xhdpi/ic_tab_n50_unselected.png differ
diff --git a/res/drawable-xhdpi/title.png b/res/drawable-xhdpi/title.png
new file mode 100644
index 0000000..71edd5d
Binary files /dev/null and b/res/drawable-xhdpi/title.png differ
diff --git a/res/drawable/ic_tab_n100.xml b/res/drawable/ic_tab_n100.xml
new file mode 100644
index 0000000..ce8bd8f
--- /dev/null
+++ b/res/drawable/ic_tab_n100.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/ic_tab_n25.xml b/res/drawable/ic_tab_n25.xml
new file mode 100644
index 0000000..108ac53
--- /dev/null
+++ b/res/drawable/ic_tab_n25.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/ic_tab_n50.xml b/res/drawable/ic_tab_n50.xml
new file mode 100644
index 0000000..a1a7c34
--- /dev/null
+++ b/res/drawable/ic_tab_n50.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/activity_double.xml b/res/layout/activity_double.xml
new file mode 100644
index 0000000..829e7aa
--- /dev/null
+++ b/res/layout/activity_double.xml
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/activity_main.xml b/res/layout/activity_main.xml
new file mode 100644
index 0000000..4356bc0
--- /dev/null
+++ b/res/layout/activity_main.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/activity_new_game.xml b/res/layout/activity_new_game.xml
new file mode 100644
index 0000000..aee179f
--- /dev/null
+++ b/res/layout/activity_new_game.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/activity_scoreboard.xml b/res/layout/activity_scoreboard.xml
new file mode 100644
index 0000000..eef6850
--- /dev/null
+++ b/res/layout/activity_scoreboard.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/activity_single.xml b/res/layout/activity_single.xml
new file mode 100644
index 0000000..2691e49
--- /dev/null
+++ b/res/layout/activity_single.xml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/activity_splash.xml b/res/layout/activity_splash.xml
new file mode 100644
index 0000000..9879194
--- /dev/null
+++ b/res/layout/activity_splash.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/raw/sound_lock.ogg b/res/raw/sound_lock.ogg
new file mode 100644
index 0000000..fafb2ad
Binary files /dev/null and b/res/raw/sound_lock.ogg differ
diff --git a/res/raw/sound_player1_clicked.ogg b/res/raw/sound_player1_clicked.ogg
new file mode 100644
index 0000000..75d6d8c
Binary files /dev/null and b/res/raw/sound_player1_clicked.ogg differ
diff --git a/res/raw/sound_player2_clicked.ogg b/res/raw/sound_player2_clicked.ogg
new file mode 100644
index 0000000..2d529ba
Binary files /dev/null and b/res/raw/sound_player2_clicked.ogg differ
diff --git a/res/raw/sound_test.ogg b/res/raw/sound_test.ogg
new file mode 100644
index 0000000..75d6d8c
Binary files /dev/null and b/res/raw/sound_test.ogg differ
diff --git a/res/raw/sound_win.ogg b/res/raw/sound_win.ogg
new file mode 100644
index 0000000..ef78c20
Binary files /dev/null and b/res/raw/sound_win.ogg differ
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
new file mode 100644
index 0000000..b71fa5d
--- /dev/null
+++ b/res/values-ru/strings.xml
@@ -0,0 +1,45 @@
+
+
+ Найди число
+ Найди число
+ Новая игра
+ Рекорды
+ Продолжить
+ Новая игра
+ Один игрок
+ Два игрока
+ Рекорды
+ Как играть
+ Выход
+ Звук включен
+ Звук отключен
+ Количество чисел
+ %1$d
+ Победитель! (%2$d/%3$d)
+ Проигравший (%2$d/%3$d)
+ Да
+ Нет
+ OK
+ OK
+ Внимание
+ Созранённая игра будет потеряна. Начать новую игру?
+ Как играть
+ Нажимайте числа в порядке возрастания. Чем меньше времени Вы затратите, тем выше Ваша наблюдательность.
+ Игра окончена
+ Вы победили!
+ Вы победили!
+ Вы попали в таблицу рекордов!\nМесто: %2$d\n%3$d чисел за %4$d сек.\nВаше имя:
+ Игра окончена!
+ %1$s победил!
+ Игра окончена!
+ %1$s победил и попал в таблицу рекордов!\nМесто: %2$d\n%3$d чисел за %4$d сек.
+ Игрок
+ Игрок1
+ Игрок2
+ №
+ Игрок
+ Сек/числа
+ Скорость
+ Нажимайте только правильные числа.\nИгра продолжится через 5 секунд.
+
+
\ No newline at end of file
diff --git a/res/values-small/dimens.xml b/res/values-small/dimens.xml
new file mode 100644
index 0000000..5492cb7
--- /dev/null
+++ b/res/values-small/dimens.xml
@@ -0,0 +1,4 @@
+
+
+ 3sp
+
\ No newline at end of file
diff --git a/res/values-xlarge/dimens.xml b/res/values-xlarge/dimens.xml
new file mode 100644
index 0000000..a3fa816
--- /dev/null
+++ b/res/values-xlarge/dimens.xml
@@ -0,0 +1,7 @@
+
+
+ 10sp
+ 500sp
+ 120sp
+ 20sp
+
diff --git a/res/values-xlarge/strings.xml b/res/values-xlarge/strings.xml
new file mode 100644
index 0000000..9c0825f
--- /dev/null
+++ b/res/values-xlarge/strings.xml
@@ -0,0 +1,5 @@
+
+
+ xlarge
+
+
\ No newline at end of file
diff --git a/res/values-xlarge/styles.xml b/res/values-xlarge/styles.xml
new file mode 100644
index 0000000..5f07a98
--- /dev/null
+++ b/res/values-xlarge/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
new file mode 100644
index 0000000..4aef028
--- /dev/null
+++ b/res/values/colors.xml
@@ -0,0 +1,5 @@
+
+
+ #ddd
+
+
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
new file mode 100644
index 0000000..3c0333e
--- /dev/null
+++ b/res/values/dimens.xml
@@ -0,0 +1,7 @@
+
+
+ 5sp
+ 250sp
+ 60sp
+ 10sp
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
new file mode 100644
index 0000000..d10d7ee
--- /dev/null
+++ b/res/values/strings.xml
@@ -0,0 +1,52 @@
+
+
+ Find the Number
+ Find the Number
+ New game
+ Scoreboard
+ "Continue"
+ New game
+ One player
+ Two players
+ Scoreboard
+ How to play
+ Exit
+ Sound is on
+ Sound is off
+ Numbers count
+ "25"
+ "50"
+ "100"
+ %1$d
+ Win! (%2$d/%3$d)
+ Lose (%2$d/%3$d)
+ Yes
+ No
+ OK
+ Submit
+ Game already started
+ Do you wish to cancel previous game and start a new game?
+ How to play
+ Tap the numbers in ascending order. The less time you spend, the higher your observancy.
+ Well done!
+ All numbers have been found
+ Congratulations!
+ You hit the score board!\nRank: %2$d\n%3$d numbers in %4$d seconds
+ Game finished!
+ %1$s win
+ Game finished!
+ %1$s win and hit the score board!\nRank: %2$d\n%3$d numbers in %4$d seconds
+ 1
+ 00:00
+ Player
+ Player1
+ Player2
+ #
+ Player
+ Secs/Nums
+ Speed
+ Try to tap only valid numbers.\nThis message will closed after 5 seconds.
+ icystar.com
+ normal
+
+
\ No newline at end of file
diff --git a/res/values/styles.xml b/res/values/styles.xml
new file mode 100644
index 0000000..1df7335
--- /dev/null
+++ b/res/values/styles.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/com/icystar/findnumber/DoubleActivity.java b/src/com/icystar/findnumber/DoubleActivity.java
new file mode 100644
index 0000000..b5ba14f
--- /dev/null
+++ b/src/com/icystar/findnumber/DoubleActivity.java
@@ -0,0 +1,157 @@
+package com.icystar.findnumber;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnCancelListener;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.InputType;
+import android.widget.EditText;
+import android.widget.TextView;
+
+public class DoubleActivity extends Activity implements Game.Listener {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ SoundPlayer.initSounds(getApplication());
+ setContentView(R.layout.activity_double);
+ }
+
+ @Override
+ protected void onResume() {
+ Game.games[0].setListener(this);
+ Game.games[0].setNumberTextView( (TextView)findViewById(R.id.TextView1) );
+ Game.games[0].setTimeTextView( (TextView)findViewById(R.id.TextView2) );
+ Game.games[0].setPlayerNameTextView( (TextView)findViewById(R.id.TextView4) );
+ Game.games[0].setNumbersView( (NumbersView)findViewById(R.id.NumbersView1) );
+ Game.games[0].setLockView( findViewById(R.id.frameLock) );
+
+ Game.games[1].setListener(this);
+ Game.games[1].setNumberTextView( (TextView)findViewById(R.id.TextView3) );
+ Game.games[1].setTimeTextView(null);
+ Game.games[1].setPlayerNameTextView( (TextView)findViewById(R.id.TextView5) );
+ Game.games[1].setNumbersView( (NumbersView)findViewById(R.id.NumbersView2) );
+ Game.games[1].setLockView(null);
+
+ ((NumbersView)findViewById(R.id.NumbersView1)).setGameIndex(0);
+ ((NumbersView)findViewById(R.id.NumbersView2)).setGameIndex(1);
+
+ for(Game g : Game.games) g.setPaused(false);
+
+ super.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ for(Game g : Game.games) g.setPaused(true);
+
+ Game.saveState(getApplication());
+
+ ((NumbersView)findViewById(R.id.NumbersView1)).setGameIndex(-1);
+ ((NumbersView)findViewById(R.id.NumbersView2)).setGameIndex(-1);
+
+ Game.games[0].setListener(null);
+ Game.games[0].setNumberTextView(null);
+ Game.games[0].setTimeTextView(null);
+ Game.games[0].setPlayerNameTextView(null);
+ Game.games[0].setNumbersView(null);
+ Game.games[0].setLockView(null);
+
+ Game.games[1].setListener(null);
+ Game.games[1].setNumberTextView(null);
+ Game.games[1].setTimeTextView(null);
+ Game.games[1].setPlayerNameTextView(null);
+ Game.games[1].setNumbersView(null);
+ Game.games[1].setLockView(null);
+
+ super.onPause();
+ }
+
+ @Override
+ public void onWin(Game game, float time) {
+ for(Game g : Game.games) if (game != g) g.lose();
+
+ SoundPlayer.playSound(R.raw.sound_win);
+
+ final int count = game.getCount();
+ final int secs = Math.round(time);
+ final int gameIndex = game == Game.games[0] ? 0 : 1;
+ final int rank = ScoreboardActivity.isRecord(count, secs);
+ final Activity activity = this;
+ final String defaultPlayerName = getString(gameIndex == 0 ? R.string.defaultPlayer1Name : R.string.defaultPlayer2Name);
+
+ if (rank > 0) {
+ String name = Game.getPlayerName(gameIndex + 1);
+ if (name.length() == 0) name = defaultPlayerName;
+ ScoreboardActivity.addNewRecord(count, secs, name);
+ Game.saveState(getApplication());
+
+ final EditText edit = new EditText(this);
+ edit.setInputType(InputType.TYPE_TEXT_VARIATION_PERSON_NAME);
+ edit.setText(name);
+
+ final Intent intent = new Intent(activity, ScoreboardActivity.class);
+ intent.putExtra("count", count);
+ intent.putExtra("rank", rank);
+
+ new AlertDialog.Builder(this)
+ .setTitle(R.string.dialogDoubleRecordTitle)
+ .setIcon(R.drawable.ic_dialog_win)
+ .setMessage(getString(R.string.dialogDoubleRecordMessage, defaultPlayerName, rank, count, secs))
+ .setView(edit)
+ .setPositiveButton(R.string.dialogSubmit, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ String name = edit.getText().toString();
+ ScoreboardActivity.updateRecord(count, secs, name);
+ Game.setPlayerName(gameIndex + 1, name);
+ Game.saveState(getApplication());
+ startActivity(intent);
+ activity.finish();
+ }
+ })
+ .setOnCancelListener(new OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ String name = edit.getText().toString();
+ ScoreboardActivity.updateRecord(count, secs, name);
+ Game.setPlayerName(gameIndex + 1, name);
+ Game.saveState(getApplication());
+ startActivity(intent);
+ activity.finish();
+ }
+ })
+ .show();
+ } else {
+ new AlertDialog.Builder(this)
+ .setTitle(R.string.dialogDoubleWinTitle)
+ .setIcon(R.drawable.ic_dialog_win)
+ .setMessage(getString(R.string.dialogDoubleWinMessage, defaultPlayerName))
+ .setPositiveButton(R.string.dialogOk, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) { activity.finish(); }
+ })
+ .setOnCancelListener(new OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) { activity.finish(); }
+ })
+ .show();
+ }
+ }
+
+ @Override
+ public void onTouchNumber(Game game, int touchedNumber, int maxNumber, boolean win) {
+ if (!win) {
+ if (game == Game.games[0]) SoundPlayer.playSound(R.raw.sound_player1_clicked);
+ if (game == Game.games[1]) SoundPlayer.playSound(R.raw.sound_player2_clicked);
+ }
+ }
+
+ @Override
+ public void onLock(Game game) {
+ SoundPlayer.playSound(R.raw.sound_lock);
+ }
+}
diff --git a/src/com/icystar/findnumber/Game.java b/src/com/icystar/findnumber/Game.java
new file mode 100644
index 0000000..87c4302
--- /dev/null
+++ b/src/com/icystar/findnumber/Game.java
@@ -0,0 +1,653 @@
+package com.icystar.findnumber;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.Typeface;
+import android.text.TextPaint;
+import android.util.FloatMath;
+import android.view.View;
+import android.widget.TextView;
+
+public class Game {
+ public static Game[] games = new Game[] { new Game(), new Game() };
+
+ public static class Number {
+ public int number;
+ public String text;
+ public int digits;
+ public int sizeIndex;
+ public float size;
+ public float scaleX;
+ public int fontIndex;
+ Typeface font;
+ public Rect rect = new Rect();
+ public Point position = new Point();
+
+ public void save(FileOutputStream fos) throws IOException {
+ Serializer.writeInt(fos, number);
+ Serializer.writeFloat(fos, size);
+ Serializer.writeFloat(fos, scaleX);
+ Serializer.writeInt(fos, fontIndex);
+ Serializer.writeInt(fos, rect.left);
+ Serializer.writeInt(fos, rect.right);
+ Serializer.writeInt(fos, rect.top);
+ Serializer.writeInt(fos, rect.bottom);
+ Serializer.writeInt(fos, position.x);
+ Serializer.writeInt(fos, position.y);
+ }
+
+ public void load(FileInputStream fis) throws IOException {
+ number = Serializer.readInt(fis);
+ size = Serializer.readFloat(fis);
+ scaleX = Serializer.readFloat(fis);
+ fontIndex = Serializer.readInt(fis);
+ rect.left = Serializer.readInt(fis);
+ rect.right = Serializer.readInt(fis);
+ rect.top = Serializer.readInt(fis);
+ rect.bottom = Serializer.readInt(fis);
+ position.x = Serializer.readInt(fis);
+ position.y = Serializer.readInt(fis);
+
+ text = Integer.toString(number);
+ digits = text.length();
+ sizeIndex = 0;
+ font = fonts[fontIndex];
+ }
+ }
+
+ public interface Listener {
+ public void onLock(Game game);
+ public void onWin(Game game, float time);
+ public void onTouchNumber(Game game, int touchedNumber, int maxNumber, boolean win);
+ }
+
+ private static final String filename = "game.sav";
+ private static final int sizesCount = 100;
+ private static final int generationTrials = 100;
+ private static final int fontTrials = 100;
+ private static final int positionTrials = 100;
+ public static final Typeface[] fonts = new Typeface[] {
+ Typeface.create(Typeface.SERIF, Typeface.NORMAL),
+ Typeface.create(Typeface.SERIF, Typeface.BOLD),
+ Typeface.create(Typeface.SERIF, Typeface.ITALIC),
+ Typeface.create(Typeface.SERIF, Typeface.BOLD_ITALIC),
+ Typeface.create(Typeface.SANS_SERIF, Typeface.NORMAL),
+ Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD),
+ Typeface.create(Typeface.SANS_SERIF, Typeface.ITALIC),
+ Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD_ITALIC)
+ };
+
+ private static Object staticHandle = new Object();
+ private static boolean stateLoaded = false;
+ private static String[] playerNames;
+
+ private int width = 0;
+ private int height = 0;
+ private float minSize;
+ private float maxSize;
+ private int initialMaxSizeIndex;
+ private int maxDigits;
+ private Rect[][][] sizes;
+
+ private TextPaint paint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
+ private TextView numberTextView;
+ private TextView timeTextView;
+ private TextView playerNameTextView;
+ private NumbersView numbersView;
+ private View lockView;
+ private Listener listener;
+
+ private Timer timer;
+ private Object handle = new Object();
+ private int waitToGenerate = 0;
+
+ private List invalidTouches = new ArrayList();
+
+ // serialization data
+ private Number[] numbers = new Number[0];
+ private int currentNumberIndex = -1;
+ private int currentNumber = 0;
+ private float time = 0;
+ private float lockTime = 0;
+ private boolean paused = true;
+ private boolean playing = false;
+ private boolean isWin = false;
+ private boolean isLose = false;
+
+ public void save(FileOutputStream fos) throws IOException {
+ synchronized (handle) {
+ Serializer.writeInt(fos, currentNumberIndex);
+ Serializer.writeInt(fos, Math.round(time));
+ Serializer.writeInt(fos, Math.round(lockTime));
+ Serializer.writeInt(fos, paused ? 1 : 0);
+ Serializer.writeInt(fos, playing ? 1 : 0);
+ Serializer.writeInt(fos, numbers.length);
+ for(Number number : numbers)
+ number.save(fos);
+ }
+ }
+
+ public void load(FileInputStream fis) throws IOException {
+ synchronized (handle) {
+ currentNumberIndex = Serializer.readInt(fis);
+ time = Serializer.readInt(fis);
+ lockTime = Serializer.readInt(fis);
+ paused = Serializer.readInt(fis) != 0;
+ playing = Serializer.readInt(fis) != 0;
+ numbers = new Number[Serializer.readInt(fis)];
+ for(int i = 0; i < numbers.length; i++) {
+ numbers[i] = new Number();
+ numbers[i].load(fis);
+ }
+ currentNumber = currentNumberIndex >= 0 && currentNumberIndex < numbers.length
+ ? numbers[currentNumberIndex].number : 0;
+ }
+ }
+
+
+ Game() {
+ timer = new Timer();
+ timer.schedule(new TimerTask() {
+ @Override
+ public void run() { onTime(1); }
+ }, 1000, 1000);
+ }
+
+ private float internalCalcSize(int index) {
+ return minSize + (maxSize - minSize)*(float)index/(float)(sizesCount-1);
+ }
+
+ private void internalCalcSizes(int count) {
+ maxSize = Math.min(width, height)/2f;
+ minSize = count < 50 ? maxSize/5f : maxSize/10f;
+ initialMaxSizeIndex = sizesCount/2;
+ if (count > 25) initialMaxSizeIndex = sizesCount/4;
+ if (count > 50) initialMaxSizeIndex = sizesCount/6;
+ if (initialMaxSizeIndex < 1) initialMaxSizeIndex = 1;
+
+ String template = "MMMMMMMMMMMMMMMMMMMMMMMMMMMMM";
+ sizes = new Rect[fonts.length][sizesCount][maxDigits + 1];
+ paint.setTextScaleX(1f);
+ for(int fontIndex = 0; fontIndex < fonts.length; fontIndex++) {
+ paint.setTypeface(fonts[fontIndex]);
+ for(int sizeIndex = 0; sizeIndex < sizesCount; sizeIndex++) {
+ paint.setTextSize(internalCalcSize(sizeIndex));
+ for(int digits = 0; digits <= maxDigits; digits++) {
+ sizes[fontIndex][sizeIndex][digits] = new Rect();
+ paint.getTextBounds(template, 0, digits, sizes[fontIndex][sizeIndex][digits]);
+ }
+ }
+ }
+ }
+
+ private boolean internalCheckRect(Rect rect, int count, int exclude) {
+ if (rect.left < 0 || rect.top < 0 || rect.right > width || rect.bottom > height)
+ return false;
+ for(int i = 0; i < count; i++)
+ if (Rect.intersects(rect, numbers[i].rect))
+ return false;
+ return true;
+ }
+
+ private void internalGenerate(int count) {
+ waitToGenerate = 0;
+ time = 0;
+ lockTime = 0;
+ playing = false;
+ isWin = false;
+ isLose = false;
+ if (timer != null) timer.cancel();
+ timer = null;
+
+ maxDigits = count < 10 ? 1 : (count < 100 ? 2 : (count < 1000 ? 3 : 4));
+ internalCalcSizes(count);
+
+ numbers = new Number[count];
+ Random random = new Random();
+
+ // fill digits
+ int[] remainingNumbers = new int[count];
+ for(int i = 0; i < count; i++) remainingNumbers[i] = i+1;
+ for(int i = 0; i < count; i++) {
+ int j = random.nextInt(count - i);
+ numbers[i] = new Number();
+ numbers[i].number = remainingNumbers[j];
+ numbers[i].text = Integer.toString(numbers[i].number);
+ numbers[i].digits = numbers[i].text.length();
+ for(int k = j+1; k < count-i; k++) remainingNumbers[k-1] = remainingNumbers[k];
+ }
+
+ // generate numbers
+ boolean success = false;
+ for(int generationTry = 0; !success && generationTry < generationTrials; generationTry++) {
+ for(int i = 0; i < count; i++) {
+ success = false;
+ Number number = numbers[i];
+ for(int fontTry = 0; !success && fontTry < fontTrials && fontTry < initialMaxSizeIndex; fontTry++) {
+ number.fontIndex = random.nextInt(fonts.length);
+ number.sizeIndex = random.nextInt(initialMaxSizeIndex - fontTry);
+ number.font = fonts[number.fontIndex];
+ number.size = internalCalcSize(number.sizeIndex);
+ number.scaleX = 1f; //random.nextFloat()*1.5f + 0.5f;
+ Rect r = sizes[number.fontIndex][number.sizeIndex][number.digits];
+ int w = Math.round((r.right - r.left)*number.scaleX);
+ int h = r.bottom - r.top;
+ if (w < width && h < height) {
+ for(int positionTry = 0; !success && positionTry < positionTrials; positionTry++) {
+ int x = random.nextInt(width - w);
+ int y = random.nextInt(height - h);
+ number.rect.set(x, y, x+w, y+h);
+ number.position.set(number.rect.left - r.left, number.rect.top - r.top);
+ if (internalCheckRect(number.rect, i, -1))
+ success = true;
+ }
+ }
+ }
+ if (!success) break;
+ }
+ }
+
+ if (success) {
+ // enlarge numbers
+ boolean enlarged = false;
+ Rect[] rects = new Rect[] { new Rect(), new Rect(), new Rect(), new Rect() };
+ while (enlarged) {
+ enlarged = true;
+ for(int i = 0; i < count; i++) {
+ Number number = numbers[i];
+ if (number.sizeIndex < sizesCount) {
+ Rect r = sizes[number.fontIndex][number.sizeIndex+1][number.digits];
+ int w = Math.round((r.right - r.left)*number.scaleX);
+ int h = r.bottom - r.top;
+ int validCount = 0;
+ for(int j = 0; j < 3; j++) {
+ int x = j % 2 == 0 ? number.rect.left : number.rect.right - w;
+ int y = j / 2 == 0 ? number.rect.top : number.rect.bottom - h;
+ rects[validCount].set(x, y, x+w, y+h);
+ if (internalCheckRect(rects[validCount], count, i)) validCount++;
+ }
+ if (validCount > 0) {
+ number.sizeIndex++;
+ number.size = internalCalcSize(number.sizeIndex);
+ number.rect.set(rects[random.nextInt(validCount)]);
+ number.position.set(number.rect.left - r.left, number.rect.top - r.top);
+ enlarged = true;
+ }
+ }
+ }
+ }
+ } else {
+ numbers = new Number[0];
+ }
+
+ time = 0;
+ lockTime = 0;
+ playing = true;
+ internalSetCurrentNumber(1);
+ internalUpdateViews();
+ timer = new Timer();
+ timer.schedule(new TimerTask() {
+ @Override
+ public void run() { onTime(1); }
+ }, 1000, 1000);
+ }
+
+ private static boolean checkDistance(int x0, int y0, int x1, int y1, int distSqr)
+ { return (x1-x0)*(x1-x0) + (y1-y0)*(y1-y0) < distSqr; }
+
+ private boolean internalCheckTouch(int x, int y) {
+ Number number = null;
+ try { number = numbers[currentNumberIndex]; } catch (Exception e) { }
+ if (number != null) {
+ int radius = Math.min(width, height)/20;
+ int radiusSqr = radius*radius;
+ Rect rect = number.rect;
+
+ if (new Rect(rect.left - radius, rect.top, rect.right + 2*radius, rect.bottom ).contains(x, y)
+ || new Rect(rect.left, rect.top - radius, rect.right, rect.bottom + 2*radius ).contains(x, y)
+ || checkDistance(x, y, rect.left, rect.top, radiusSqr)
+ || checkDistance(x, y, rect.right, rect.top, radiusSqr)
+ || checkDistance(x, y, rect.left, rect.bottom, radiusSqr)
+ || checkDistance(x, y, rect.right, rect.bottom, radiusSqr)
+ ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void internalSetCurrentNumber(int value) {
+ currentNumberIndex = -1;
+ currentNumber = 0;
+ for(int i = 0; i < numbers.length; i++)
+ if (numbers[i].number == value)
+ { currentNumberIndex = i; currentNumber = value; break; }
+ internalUpdateNumberTextView();
+ }
+
+ private void internalUpdateNumberTextView() {
+ if (numberTextView != null) {
+ int numbersCount = numbers.length;
+ int numbersFound = isWin ? numbersCount : currentNumber - 1;
+ int id = R.string.currentNumber;
+ if (isLose) id = R.string.currentNumberLose;
+ if (isWin) { id = R.string.currentNumberWin; numbersFound = numbersCount; }
+
+ final TextView textView = numberTextView;
+ final String text = textView.getContext().getString(id, currentNumber, numbersFound, numbersCount);
+ textView.post(new Runnable() { @Override public void run() { textView.setText(text); } });
+ }
+ }
+
+ private void internalUpdateTimeTextView() {
+ if (timeTextView != null) {
+ int min = (int)FloatMath.floor(time/60);
+ int sec = (int)FloatMath.floor(time - min*60);
+ String minStr = Integer.toString(min);
+ String secStr = Integer.toString(sec);
+ while (minStr.length() < 2) minStr = "0" + minStr;
+ while (secStr.length() < 2) secStr = "0" + secStr;
+
+ final TextView textView = timeTextView;
+ final String text = minStr + ":" + secStr;
+ textView.post(new Runnable() { @Override public void run() { textView.setText(text); } });
+ }
+ }
+
+ private void internalUpdatePlayerNameTextView() {
+ if (playerNameTextView != null) {
+ final TextView textView = playerNameTextView;
+ final int visibility = playing ? View.VISIBLE : View.GONE;
+ textView.post(new Runnable() { @Override public void run() { textView.setVisibility(visibility); } });
+ }
+ }
+
+ private void internalUpdateNumbersView() {
+ if (numbersView != null) {
+ final NumbersView view = numbersView;
+ view.post(new Runnable() { @Override public void run() { view.invalidate(); } });
+ }
+ }
+
+ private void internalUpdateLockView() {
+ if (lockView != null) {
+ final View view = lockView;
+ final int visibility = lockTime <= 0 ? View.GONE : View.VISIBLE;
+ view.post(new Runnable() { @Override public void run() {
+ if (view.getVisibility() != visibility) view.setVisibility(visibility);
+ if (visibility == View.VISIBLE) view.invalidate();
+ } });
+ }
+ }
+
+ private void internalUpdateViews() {
+ internalUpdateNumberTextView();
+ internalUpdateTimeTextView();
+ internalUpdatePlayerNameTextView();
+ internalUpdateNumbersView();
+ internalUpdateLockView();
+ }
+
+
+
+ public void start(int count) {
+ synchronized (handle) {
+ if (width > 0 && height > 0)
+ internalGenerate(count);
+ else
+ waitToGenerate = count;
+ }
+ }
+
+ public void stop() {
+ synchronized (handle) {
+ playing = false;
+ isWin = false;
+ isLose = false;
+ numbers = new Number[0];
+ internalUpdateNumberTextView();
+ internalUpdatePlayerNameTextView();
+ }
+ }
+
+ public void lose() {
+ synchronized (handle) {
+ playing = false;
+ isWin = false;
+ isLose = true;
+ internalUpdateNumberTextView();
+ internalUpdatePlayerNameTextView();
+ }
+ }
+
+ public void win() {
+ synchronized (handle) {
+ playing = false;
+ isWin = true;
+ isLose = false;
+ internalUpdateNumberTextView();
+ internalUpdatePlayerNameTextView();
+ }
+ }
+
+ public static void lock() {
+ for(Game game : games) {
+ synchronized (game.handle) {
+ game.lockTime = 5;
+ game.internalUpdateLockView();
+ }
+ if (game.listener != null) game.listener.onLock(game);
+ }
+ }
+
+ public boolean getPlaying()
+ { synchronized (handle) { return playing; } }
+ public boolean getPaused()
+ { synchronized (handle) { return paused; } }
+ public void setPaused(boolean value)
+ { synchronized (handle) { paused = value; } }
+ public int getCount()
+ { synchronized (handle) { return numbers.length; } }
+
+ public int getCurrentNumber() {
+ synchronized (handle) {
+ try { return numbers[currentNumberIndex].number; } catch (Exception e) { }
+ return 0;
+ }
+ }
+
+ public void onLayout(int width, int height) {
+ synchronized (handle) {
+ this.width = width;
+ this.height = height;
+ if (width > 0 && height > 0 && waitToGenerate > 0)
+ internalGenerate(waitToGenerate);
+ }
+ }
+
+ public void onTouch(int x, int y) {
+ boolean touch = false;
+ int touchedNumber = 0;
+ int maxNumber = 0;
+
+ boolean win = false;
+ float winTime = 0;
+
+ synchronized (handle) {
+ if (playing && !paused && lockTime <= 0) {
+ if (internalCheckTouch(x, y)) {
+ touch = true;
+ touchedNumber = currentNumber;
+ maxNumber = numbers.length;
+ if (currentNumber < numbers.length) {
+ internalSetCurrentNumber(currentNumber + 1);
+ } else {
+ this.win();
+ win = true;
+ winTime = time;
+ }
+ invalidTouches.clear();
+ } else {
+ invalidTouches.add(new Point(x, y));
+ if (invalidTouches.size() > 1) {
+ int maxDist = Math.min(width, height)/4;
+ int places = 1;
+ Point min = new Point(width, height);
+ Point max = new Point(0, 0);
+ for(Point p : invalidTouches) {
+ min.x = Math.min(min.x, p.x);
+ min.y = Math.min(min.y, p.y);
+ max.x = Math.max(max.x, p.x);
+ max.y = Math.max(max.y, p.y);
+ if (max.x - min.x > maxDist || max.y - min.y > maxDist) {
+ places++;
+ min.set(p.x, p.y);
+ max.set(p.x, p.y);
+ }
+ }
+ if (places > 3) {
+ lock();
+ invalidTouches.clear();
+ }
+ }
+ }
+ }
+ }
+
+ if (touch && listener != null) listener.onTouchNumber(this, touchedNumber, maxNumber, win);
+ if (win && listener != null) listener.onWin(this, winTime);
+ }
+
+ public void onTime(float time) {
+ synchronized (handle) {
+ if (playing && !paused) {
+ this.time += time;
+ lockTime -= time;
+ if (lockTime <= 0) lockTime = 0;
+ internalUpdateTimeTextView();
+ internalUpdateLockView();
+ if (Math.round(this.time) % 3 == 0 && invalidTouches.size() > 0)
+ invalidTouches.remove(0);
+ }
+ }
+ }
+
+ public void draw(Canvas canvas) {
+ synchronized (handle) {
+ for(int i = 0; i < numbers.length; i++) {
+ Number number = numbers[i];
+ paint.setTypeface(number.font);
+ paint.setTextSize(number.size);
+ paint.setTextScaleX(number.scaleX);
+ canvas.drawText(number.text, number.position.x, number.position.y, paint);
+ }
+ }
+ }
+
+ public void setListener(Listener value)
+ { synchronized (handle) { listener = value; } }
+ public void setNumberTextView(TextView value)
+ { synchronized (handle) { numberTextView = value; internalUpdateNumberTextView(); } }
+ public void setTimeTextView(TextView value)
+ { synchronized (handle) { timeTextView = value; internalUpdateTimeTextView(); } }
+ public void setPlayerNameTextView(TextView value)
+ { synchronized (handle) { playerNameTextView = value; internalUpdatePlayerNameTextView(); } }
+ public void setNumbersView(NumbersView value)
+ { synchronized (handle) { numbersView = value; internalUpdateNumbersView(); } }
+ public void setLockView(View value)
+ { synchronized (handle) { lockView = value; internalUpdateLockView(); } }
+
+ private static void save(Context context) {
+ try {
+ FileOutputStream fos = context.openFileOutput(filename, Context.MODE_PRIVATE);
+ for(Game game : games) game.save(fos);
+ Serializer.writeInt(fos, playerNames.length);
+ if (playerNames == null) playerNames = new String[0];
+ for(String name : playerNames)
+ Serializer.writeString(fos, name);
+ ScoreboardActivity.save(fos);
+ Serializer.writeInt(fos, SoundPlayer.getEnabled() ? 1 : 0);
+ } catch (Exception e) { }
+ }
+
+ private static void load(Context context) {
+ for(Game game : games) game.stop();
+
+ try {
+ FileInputStream fis = context.openFileInput(filename);
+ for(Game game : games) game.load(fis);
+ playerNames = new String[Serializer.readInt(fis)];
+ for(int i = 0; i < playerNames.length; i++)
+ playerNames[i] = Serializer.readString(fis);
+ ScoreboardActivity.load(fis);
+ SoundPlayer.setEnabled(Serializer.readInt(fis) != 0);
+ } catch (Exception e) {
+ for(Game game : games) game.stop();
+ //e.printStackTrace();
+ }
+ if (playerNames == null) playerNames = new String[0];
+ }
+
+ public static void saveState(Context context) {
+ synchronized (staticHandle) {
+ save(context);
+ }
+ }
+
+ public static void loadState(Context context) {
+ synchronized (staticHandle) {
+ if (!stateLoaded) {
+ stateLoaded = true;
+ load(context);
+ }
+ }
+ }
+
+ public static int getMode() {
+ boolean g0 = games[0].getCount() > 0;
+ boolean g1 = games[1].getCount() > 0;
+ if (g0 && g1) return 2;
+ if (g0 && !g1) return 1;
+ return 0;
+ }
+
+ public static boolean getAnyPlaying() {
+ switch (getMode()) {
+ case 1:
+ return games[0].getPlaying();
+ case 2:
+ return games[0].getPlaying() || games[1].getPlaying();
+ }
+ return false;
+ }
+
+ public static String getPlayerName(int index) {
+ synchronized (staticHandle) {
+ try { return playerNames[index] == null ? "" : playerNames[index]; } catch (Exception e) { }
+ return "";
+ }
+ }
+
+ public static void setPlayerName(int index, String name) {
+ synchronized (staticHandle) {
+ if (name != null && name.length() > 0) {
+ try {
+ playerNames = Serializer.enlargeArrayIfNeed(String.class, playerNames, index+1);
+ playerNames[index] = name;
+ } catch (Exception e) { }
+ }
+ }
+ }
+}
diff --git a/src/com/icystar/findnumber/MainActivity.java b/src/com/icystar/findnumber/MainActivity.java
new file mode 100644
index 0000000..938944e
--- /dev/null
+++ b/src/com/icystar/findnumber/MainActivity.java
@@ -0,0 +1,96 @@
+package com.icystar.findnumber;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+
+public class MainActivity extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ SoundPlayer.initSounds(getApplication());
+ setContentView(R.layout.activity_main);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ Game.loadState(getApplication());
+ findViewById(R.id.buttonContinue).setVisibility(Game.getAnyPlaying() ? View.VISIBLE : View.GONE);
+ ((Button)findViewById(R.id.buttonSound)).setCompoundDrawablesWithIntrinsicBounds(
+ SoundPlayer.getEnabled() ? R.drawable.ic_button_sound_on : R.drawable.ic_button_sound_off,
+ 0, 0, 0 );
+ ((Button)findViewById(R.id.buttonSound)).setText(
+ SoundPlayer.getEnabled() ? R.string.soundEnabled : R.string.soundDisabled );
+ }
+
+ @Override
+ protected void onPause() {
+ Game.saveState(getApplication());
+ super.onPause();
+ }
+
+ public void onButton(View view) {
+ switch (view.getId()) {
+ case R.id.buttonContinue:
+ switch (Game.getMode()) {
+ case 1:
+ startActivity(new Intent(this, SingleActivity.class));
+ break;
+ case 2:
+ startActivity(new Intent(this, DoubleActivity.class));
+ break;
+ }
+ break;
+ case R.id.buttonNewGame:
+ if (Game.getAnyPlaying()) {
+ final MainActivity context = this;
+ new AlertDialog.Builder(this)
+ .setTitle(R.string.dialogGameAlreadyStartedTitle)
+ .setIcon(R.drawable.ic_dialog_alert)
+ .setMessage(R.string.dialogGameAlreadyStartedMessage)
+ .setPositiveButton(R.string.dialogYes, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ startActivity(new Intent(context, NewGameActivity.class));
+ }
+ })
+ .setNegativeButton(R.string.dialogNo, null)
+ .show();
+ } else {
+ startActivity(new Intent(this, NewGameActivity.class));
+ }
+ break;
+ case R.id.buttonSound:
+ SoundPlayer.setEnabled( !SoundPlayer.getEnabled() );
+ ((Button)findViewById(R.id.buttonSound)).setCompoundDrawablesWithIntrinsicBounds(
+ SoundPlayer.getEnabled() ? R.drawable.ic_button_sound_on : R.drawable.ic_button_sound_off,
+ 0, 0, 0 );
+ ((Button)findViewById(R.id.buttonSound)).setText(
+ SoundPlayer.getEnabled() ? R.string.soundEnabled : R.string.soundDisabled );
+ SoundPlayer.playSound(R.raw.sound_test);
+ Game.saveState(getApplication());
+ break;
+ case R.id.buttonScoreboard:
+ startActivity(new Intent(this, ScoreboardActivity.class));
+ break;
+ case R.id.buttonHelp:
+ new AlertDialog.Builder(this)
+ .setTitle(R.string.dialogHelpTitle)
+ .setIcon(R.drawable.ic_dialog_info)
+ .setMessage(R.string.dialogHelpMessage)
+ .setPositiveButton(R.string.dialogOk, null)
+ .show();
+ break;
+ case R.id.buttonExit:
+ finish();
+ break;
+ }
+ }
+}
diff --git a/src/com/icystar/findnumber/NewGameActivity.java b/src/com/icystar/findnumber/NewGameActivity.java
new file mode 100644
index 0000000..e90abc8
--- /dev/null
+++ b/src/com/icystar/findnumber/NewGameActivity.java
@@ -0,0 +1,72 @@
+package com.icystar.findnumber;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.Window;
+import android.widget.RadioGroup;
+
+public class NewGameActivity extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Window w = getWindow();
+ w.requestFeature(Window.FEATURE_LEFT_ICON);
+
+ setContentView(R.layout.activity_new_game);
+
+ w.setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, R.drawable.ic_dialog_new);
+
+ int id = 0;
+ switch(Game.games[0].getCount()) {
+ case 25:
+ id = R.id.radio25;
+ break;
+ case 50:
+ id = R.id.radio50;
+ break;
+ case 100:
+ id = R.id.radio100;
+ break;
+ }
+ if (id != 0)
+ ((RadioGroup)findViewById(R.id.radioGroupNumbersCount)).check(id);
+ }
+
+ public void onButton(View view) {
+ int count;
+
+ switch (((RadioGroup)findViewById(R.id.radioGroupNumbersCount)).getCheckedRadioButtonId()) {
+ case R.id.radio25:
+ count = 25;
+ break;
+ case R.id.radio50:
+ count = 50;
+ break;
+ case R.id.radio100:
+ count = 100;
+ break;
+ default:
+ return;
+ }
+
+ switch (view.getId()) {
+ case R.id.buttonSingle:
+ Game.games[0].start(count);
+ Game.games[1].stop();
+ startActivity(new Intent(this, SingleActivity.class));
+ finish();
+ break;
+ case R.id.buttonDouble:
+ Game.games[0].start(count);
+ Game.games[1].start(count);
+ startActivity(new Intent(this, DoubleActivity.class));
+ finish();
+ break;
+ }
+ }
+
+}
diff --git a/src/com/icystar/findnumber/NumbersView.java b/src/com/icystar/findnumber/NumbersView.java
new file mode 100644
index 0000000..326e3e7
--- /dev/null
+++ b/src/com/icystar/findnumber/NumbersView.java
@@ -0,0 +1,67 @@
+package com.icystar.findnumber;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+
+public class NumbersView extends View {
+ private int gameIndex = -1;
+
+ public NumbersView(Context context) {
+ this(context, null);
+ initialize();
+ }
+
+ public NumbersView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ initialize();
+ }
+
+ public NumbersView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ initialize();
+ }
+
+ public void initialize() {
+ setKeepScreenOn(true);
+ }
+
+ public int getGameIndex(int value)
+ { return gameIndex; }
+
+ public void setGameIndex(int value) {
+ if (getGame() != null) getGame().onLayout(0, 0);
+ gameIndex = value;
+ if (getGame() != null) getGame().onLayout(getMeasuredWidth(), getMeasuredHeight());
+ }
+
+ public Game getGame()
+ { return gameIndex >= 0 ? Game.games[gameIndex] : null; }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ Game game = getGame();
+ if (game != null) game.draw(canvas);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ Game game = getGame();
+ if (game != null) game.onLayout(getMeasuredWidth(), getMeasuredHeight());
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ Game game = getGame();
+ if (game != null) game.onTouch(Math.round(event.getX()), Math.round(event.getY()));
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/src/com/icystar/findnumber/ScoreboardActivity.java b/src/com/icystar/findnumber/ScoreboardActivity.java
new file mode 100644
index 0000000..f9a70aa
--- /dev/null
+++ b/src/com/icystar/findnumber/ScoreboardActivity.java
@@ -0,0 +1,282 @@
+package com.icystar.findnumber;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import android.app.Activity;
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.widget.TabHost;
+import android.widget.TableLayout;
+import android.widget.TableRow;
+import android.widget.TableRow.LayoutParams;
+import android.widget.TextView;
+
+public class ScoreboardActivity extends Activity {
+ public static final int maxScoresCount = 10;
+ public static final int[] counts = { 25, 50, 100 };
+
+ public static class Score {
+ boolean exists = false;
+ String name = "";
+ int count = 0;
+ int time = 0;
+ float secondsPerNumber = 0;
+
+ public void save(FileOutputStream fos) throws IOException {
+ Serializer.writeInt(fos, exists ? 1 : 0);
+ Serializer.writeString(fos, name);
+ Serializer.writeInt(fos, count);
+ Serializer.writeInt(fos, time);
+ }
+
+ public void load(FileInputStream fis) throws IOException {
+ exists = Serializer.readInt(fis) != 0;
+ name = Serializer.readString(fis);
+ count = Serializer.readInt(fis);
+ time = Serializer.readInt(fis);
+ secondsPerNumber = count > 0 ? (float)time/(float)count : time;
+ }
+ }
+
+ private static Object staticHandle = new Object();
+ private static Score[][] scores;
+
+ private static void fixScores() {
+ scores = Serializer.resizeArrayIfNeed(Score[].class, scores, counts.length);
+ for(int i = 0; i < scores.length; i++) {
+ scores[i] = Serializer.resizeArrayIfNeed(Score.class, scores[i], maxScoresCount);
+ for(int j = 0; j < scores[i].length; j++)
+ if (scores[i][j] == null) scores[i][j] = new Score();
+ }
+ }
+
+ public static void save(FileOutputStream fos) throws IOException {
+ synchronized (staticHandle) {
+ fixScores();
+ Serializer.writeInt(fos, scores.length);
+ for(Score[] ss : scores) {
+ Serializer.writeInt(fos, ss.length);
+ for(Score score : ss) score.save(fos);
+ }
+ }
+ }
+
+ public static void load(FileInputStream fis) throws IOException {
+ synchronized (staticHandle) {
+ Score[][] ss = null;
+ try {
+ ss = new Score[Serializer.readInt(fis)][0];
+ for(int i = 0; i < ss.length; i++) {
+ ss[i] = new Score[Serializer.readInt(fis)];
+ for(int j = 0; j < ss[i].length; j++) {
+ ss[i][j] = new Score();
+ ss[i][j].load(fis);
+ }
+ }
+ } finally {
+ scores = ss;
+ fixScores();
+ }
+ }
+ }
+
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_scoreboard);
+
+ TabHost tabs = (TabHost)findViewById(android.R.id.tabhost);
+
+ tabs.setup();
+
+ TabHost.TabSpec spec;
+ boolean xlarge = getString(R.string.screenSize).compareTo("xlarge") == 0;
+
+ spec = tabs.newTabSpec("tap25");
+ spec.setContent(R.id.tab25);
+ spec.setIndicator(getString(R.string.radio25), xlarge ? null : getResources().getDrawable(R.drawable.ic_tab_n25));
+ tabs.addTab(spec);
+
+ spec = tabs.newTabSpec("tag50");
+ spec.setContent(R.id.tab50);
+ spec.setIndicator(getString(R.string.radio50), xlarge ? null : getResources().getDrawable(R.drawable.ic_tab_n50));
+ tabs.addTab(spec);
+
+ spec = tabs.newTabSpec("tab100");
+ spec.setContent(R.id.tab100);
+ spec.setIndicator(getString(R.string.radio100), xlarge ? null : getResources().getDrawable(R.drawable.ic_tab_n100));
+ tabs.addTab(spec);
+
+ tabs.setCurrentTab( getCountMode(Game.games[0].getCount(), 0) );
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ synchronized (staticHandle) {
+ int count = getIntent().getIntExtra("count", 0);
+ int rank = getIntent().getIntExtra("rank", 0);
+
+ fixScores();
+ final int[] ids = new int[] { R.id.tab25, R.id.tab50, R.id.tab100 };
+ for(int i = 0; i < scores.length; i++) {
+ TableLayout table = (TableLayout)findViewById(ids[i]);
+ table.removeAllViews();
+
+ // first row - column titles
+ TableRow row = new TableRow(this);
+ TextView text;
+
+ int margin = getResources().getDimensionPixelSize(R.dimen.margin);
+ TableRow.LayoutParams layoutRank = new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0f);
+ layoutRank.setMargins(margin, 0, margin, 0);
+ TableRow.LayoutParams layoutName = new TableRow.LayoutParams(0, LayoutParams.WRAP_CONTENT, 1f);
+ layoutName.setMargins(margin, 0, margin, 0);
+ TableRow.LayoutParams layoutTimeCount = new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0f);
+ layoutTimeCount.setMargins(margin, 0, margin, 0);
+ TableRow.LayoutParams layoutSecondsPerNumber = new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0f);
+ layoutSecondsPerNumber.setMargins(margin, 0, margin, 0);
+
+ text = new TextView(this);
+ text.setText(R.string.scoreRank);
+ text.setTypeface(Typeface.DEFAULT_BOLD);
+ text.setTextSize(text.getTextSize()/2f);
+ text.setSingleLine();
+ text.setGravity(Gravity.RIGHT);
+ row.addView(text);
+ text.setLayoutParams(layoutRank);
+
+ text = new TextView(this);
+ text.setText(R.string.scoreName);
+ text.setTypeface(Typeface.DEFAULT_BOLD);
+ text.setTextSize(text.getTextSize()/2f);
+ text.setSingleLine();
+ text.setGravity(Gravity.LEFT);
+ row.addView(text);
+ text.setLayoutParams(layoutName);
+
+ text = new TextView(this);
+ text.setText(R.string.scoreTimeCount);
+ text.setTypeface(Typeface.DEFAULT_BOLD);
+ text.setTextSize(text.getTextSize()/2f);
+ text.setSingleLine();
+ text.setGravity(Gravity.RIGHT);
+ row.addView(text);
+ text.setLayoutParams(layoutTimeCount);
+
+ text = new TextView(this);
+ text.setText(R.string.scoreSecondsPerNumber);
+ text.setTypeface(Typeface.DEFAULT_BOLD);
+ text.setTextSize(text.getTextSize()/2f);
+ text.setSingleLine();
+ text.setGravity(Gravity.RIGHT);
+ row.addView(text);
+ text.setLayoutParams(layoutSecondsPerNumber);
+
+ table.addView(row);
+
+ // rows
+ for(int j = 0; j < scores[i].length; j++) {
+ row = new TableRow(this);
+ boolean blank = !scores[i][j].exists;
+ String dummy = " -- ";
+
+ if (counts[i] == count && j+1 == rank)
+ row.setBackgroundColor(getResources().getColor(R.color.statusbar_color));
+
+ text = new TextView(this);
+ text.setText(String.format("%d. ", j+1));
+ text.setSingleLine();
+ text.setGravity(Gravity.RIGHT);
+ row.addView(text);
+ text.setLayoutParams(layoutRank);
+
+ text = new TextView(this);
+ text.setText(blank ? dummy : scores[i][j].name);
+ text.setSingleLine();
+ text.setGravity(Gravity.LEFT);
+ row.addView(text);
+ text.setLayoutParams(layoutName);
+
+ text = new TextView(this);
+ text.setText(blank ? dummy : String.format("%d/%d", scores[i][j].time, scores[i][j].count));
+ text.setSingleLine();
+ text.setGravity(Gravity.RIGHT);
+ row.addView(text);
+ text.setLayoutParams(layoutTimeCount);
+
+ text = new TextView(this);
+ text.setText(blank ? dummy : String.format("%.3f", scores[i][j].secondsPerNumber));
+ text.setSingleLine();
+ text.setGravity(Gravity.RIGHT);
+ row.addView(text);
+ text.setLayoutParams(layoutSecondsPerNumber);
+
+ table.addView(row);
+ }
+ }
+ }
+ }
+
+ private static int getCountMode(int count, int def) {
+ for(int i = 0; i < counts.length; i++)
+ if (counts[i] == count)
+ return i;
+ return def;
+ }
+
+ public static int isRecord(int count, int time) {
+ synchronized (staticHandle) {
+ fixScores();
+ int countMode = getCountMode(count, -1);
+ if (countMode >= 0)
+ for(int i = 0; i < scores[countMode].length; i++)
+ if (!scores[countMode][i].exists || time < scores[countMode][i].time)
+ return i+1;
+ }
+ return 0;
+ }
+
+ public static void addNewRecord(int count, int time, String name) {
+ int countMode = getCountMode(count, -1);
+ if (name != null && countMode >= 0 && isRecord(count, time) > 0) {
+ synchronized (staticHandle) {
+ fixScores();
+
+ Score score = new Score();
+ score.exists = true;
+ score.name = name;
+ score.count = counts[countMode];
+ score.time = time;
+ score.secondsPerNumber = score.count > 0 ? (float)score.time/(float)score.count : 0;
+
+ for(int i = 0; i < scores[countMode].length; i++) {
+ if (!scores[countMode][i].exists || score.time < scores[countMode][i].time) {
+ for(int j = scores[countMode].length-1; j > i ; j--)
+ scores[countMode][j] = scores[countMode][j-1];
+ scores[countMode][i] = score;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ public static void updateRecord(int count, int time, String name) {
+ int countMode = getCountMode(count, -1);
+ if (name != null && countMode >= 0) {
+ synchronized (staticHandle) {
+ fixScores();
+ for(int i = scores[countMode].length - 1; i >= 0 ; i--)
+ if (scores[countMode][i].exists && scores[countMode][i].time == time)
+ { scores[countMode][i].name = name; break; }
+ }
+ }
+ }
+
+}
diff --git a/src/com/icystar/findnumber/Serializer.java b/src/com/icystar/findnumber/Serializer.java
new file mode 100644
index 0000000..11084f5
--- /dev/null
+++ b/src/com/icystar/findnumber/Serializer.java
@@ -0,0 +1,74 @@
+package com.icystar.findnumber;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.reflect.Array;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+public class Serializer {
+ public static void writeInt(FileOutputStream fos, int value) throws IOException {
+ fos.write( ByteBuffer.allocate((Integer.SIZE+7)/8).putInt(value).array() );
+ }
+
+ public static int readInt(FileInputStream fis) throws IOException {
+ byte[] b = new byte[(Integer.SIZE+7)/8];
+ Arrays.fill(b, (byte)0);
+ fis.read(b);
+ return ByteBuffer.wrap(b).getInt();
+ }
+
+ public static void writeFloat(FileOutputStream fos, float value) throws IOException {
+ fos.write( ByteBuffer.allocate((Float.SIZE+7)/8).putFloat(value).array() );
+ }
+
+ public static float readFloat(FileInputStream fis) throws IOException {
+ byte[] b = new byte[(Float.SIZE+7)/8];
+ Arrays.fill(b, (byte)0);
+ fis.read(b);
+ return ByteBuffer.wrap(b).getFloat();
+ }
+
+ public static void writeString(FileOutputStream fos, String value) throws IOException {
+ byte[] b = value.getBytes();
+ writeInt(fos, b.length);
+ fos.write(b);
+ }
+
+ public static String readString(FileInputStream fis) throws IOException {
+ byte[] b = new byte[readInt(fis)];
+ fis.read(b);
+ return new String(b);
+ }
+
+ public static T[] resizeArray(Class typeClass, T[] array, int size) {
+ @SuppressWarnings("unchecked")
+ T[] resized = (T[])Array.newInstance(typeClass, Math.max(0, size));
+ if (array != null)
+ for(int i = 0; i < array.length && i < resized.length; i++)
+ resized[i] = array[i];
+ return resized;
+ }
+
+ public static T[] resizeArrayIfNeed(Class typeClass, T[] array, int size) {
+ if (array != null && array.length == Math.max(0, size)) return array;
+ return resizeArray(typeClass, array, Math.max(0, size));
+ }
+
+ public static T[] enlargeArray(Class typeClass, T[] array, int size) {
+ return resizeArray(typeClass, array, Math.max(size, array == null ? 0 : array.length));
+ }
+
+ public static T[] reduceArray(Class typeClass, T[] array, int size) {
+ return resizeArray(typeClass, array, Math.min(size, array == null ? 0 : array.length));
+ }
+
+ public static T[] enlargeArrayIfNeed(Class typeClass, T[] array, int size) {
+ return resizeArrayIfNeed(typeClass, array, Math.max(size, array == null ? 0 : array.length));
+ }
+
+ public static T[] reduceArrayIfNeed(Class typeClass, T[] array, int size) {
+ return resizeArrayIfNeed(typeClass, array, Math.min(size, array == null ? 0 : array.length));
+ }
+}
diff --git a/src/com/icystar/findnumber/SingleActivity.java b/src/com/icystar/findnumber/SingleActivity.java
new file mode 100644
index 0000000..ef86063
--- /dev/null
+++ b/src/com/icystar/findnumber/SingleActivity.java
@@ -0,0 +1,146 @@
+package com.icystar.findnumber;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnCancelListener;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.InputType;
+import android.widget.EditText;
+import android.widget.TextView;
+
+public class SingleActivity extends Activity implements Game.Listener {
+ private static Object staticHandle;
+ private static String previousName;
+
+ public static void save(FileOutputStream fos) throws IOException {
+ synchronized (staticHandle) {
+ Serializer.writeString(fos, previousName);
+ }
+ }
+
+ public static void load(FileInputStream fis) throws IOException
+ { synchronized (staticHandle) { previousName = Serializer.readString(fis); } }
+
+ public static String getPreviousName()
+ { synchronized (staticHandle) { return previousName; } }
+
+
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ SoundPlayer.initSounds(getApplication());
+ setContentView(R.layout.activity_single);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ Game.games[0].setListener(this);
+ Game.games[0].setNumberTextView( (TextView)findViewById(R.id.TextView1) );
+ Game.games[0].setTimeTextView( (TextView)findViewById(R.id.TextView2) );
+ Game.games[0].setNumbersView( (NumbersView)findViewById(R.id.NumbersView1) );
+ Game.games[0].setLockView( findViewById(R.id.frameLock) );
+ ((NumbersView)findViewById(R.id.NumbersView1)).setGameIndex(0);
+ Game.games[0].setPaused(false);
+ }
+
+ @Override
+ protected void onPause() {
+ Game.games[0].setPaused(true);
+ Game.saveState(getApplication());
+ ((NumbersView)findViewById(R.id.NumbersView1)).setGameIndex(-1);
+ Game.games[0].setListener(null);
+ Game.games[0].setNumberTextView(null);
+ Game.games[0].setTimeTextView(null);
+ Game.games[0].setNumbersView(null);
+ Game.games[0].setLockView(null);
+ super.onPause();
+ }
+
+ @Override
+ public void onWin(Game game, float time) {
+ SoundPlayer.playSound(R.raw.sound_win);
+
+ final int count = game.getCount();
+ final int secs = Math.round(time);
+ final int rank = ScoreboardActivity.isRecord(count, secs);
+ final Activity activity = this;
+ final String defaultPlayerName = getString(R.string.defaultPlayerName);
+
+ if (rank > 0) {
+ String name = Game.getPlayerName(0);
+ if (name.length() == 0) name = defaultPlayerName;
+ ScoreboardActivity.addNewRecord(count, secs, name);
+ Game.saveState(getApplication());
+
+ final EditText edit = new EditText(this);
+ edit.setInputType(InputType.TYPE_TEXT_VARIATION_PERSON_NAME);
+ edit.setText(name);
+
+ final Intent intent = new Intent(activity, ScoreboardActivity.class);
+ intent.putExtra("count", count);
+ intent.putExtra("rank", rank);
+
+ new AlertDialog.Builder(this)
+ .setTitle(R.string.dialogRecordTitle)
+ .setIcon(R.drawable.ic_dialog_win)
+ .setMessage(getString(R.string.dialogRecordMessage, defaultPlayerName, rank, count, secs))
+ .setView(edit)
+ .setPositiveButton(R.string.dialogSubmit, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ String name = edit.getText().toString();
+ ScoreboardActivity.updateRecord(count, secs, name);
+ Game.setPlayerName(0, name);
+ Game.saveState(getApplication());
+ startActivity(intent);
+ activity.finish();
+ }
+ })
+ .setOnCancelListener(new OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ String name = edit.getText().toString();
+ ScoreboardActivity.updateRecord(count, secs, name);
+ Game.setPlayerName(0, name);
+ Game.saveState(getApplication());
+ startActivity(intent);
+ activity.finish();
+ }
+ })
+ .show();
+ } else {
+ new AlertDialog.Builder(this)
+ .setTitle(R.string.dialogWinTitle)
+ .setIcon(R.drawable.ic_dialog_win)
+ .setMessage(getString(R.string.dialogWinMessage, defaultPlayerName))
+ .setPositiveButton(R.string.dialogOk, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) { activity.finish(); }
+ })
+ .setOnCancelListener(new OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) { activity.finish(); }
+ })
+ .show();
+ }
+ }
+
+ @Override
+ public void onTouchNumber(Game game, int touchedNumber, int maxNumber, boolean win) {
+ if (!win) SoundPlayer.playSound(R.raw.sound_player1_clicked);
+ }
+
+ @Override
+ public void onLock(Game game) {
+ SoundPlayer.playSound(R.raw.sound_lock);
+ }
+}
diff --git a/src/com/icystar/findnumber/SoundPlayer.java b/src/com/icystar/findnumber/SoundPlayer.java
new file mode 100644
index 0000000..5dff28d
--- /dev/null
+++ b/src/com/icystar/findnumber/SoundPlayer.java
@@ -0,0 +1,39 @@
+package com.icystar.findnumber;
+
+import android.content.Context;
+import android.media.AudioManager;
+import android.media.SoundPool;
+import android.util.SparseArray;
+
+public class SoundPlayer {
+ private static Object handle = new Object();
+ private static boolean enabled = true;
+ private static SoundPool pool;
+ private static SparseArray map;
+
+ public static void initSounds(Context context) {
+ synchronized (handle) {
+ if (pool == null || map == null) {
+ pool = new SoundPool(2, AudioManager.STREAM_MUSIC, 0);
+ map = new SparseArray(5);
+ map.put( R.raw.sound_player1_clicked, pool.load(context, R.raw.sound_player1_clicked, 1) );
+ map.put( R.raw.sound_player2_clicked, pool.load(context, R.raw.sound_player2_clicked, 1) );
+ map.put( R.raw.sound_lock, pool.load(context, R.raw.sound_lock, 1) );
+ map.put( R.raw.sound_win, pool.load(context, R.raw.sound_win, 1) );
+ map.put( R.raw.sound_test, pool.load(context, R.raw.sound_test, 1) );
+ }
+ }
+ }
+
+ public static void playSound(int id) {
+ synchronized (handle) {
+ if (enabled && pool != null && map != null && map.indexOfKey(id) >= 0)
+ pool.play(map.get(id), 1, 1, 1, 0, 1f);
+ }
+ }
+
+ public static boolean getEnabled()
+ { synchronized (handle) { return enabled; } }
+ public static void setEnabled(boolean value)
+ { synchronized (handle) { enabled = value; } }
+}
diff --git a/src/com/icystar/findnumber/SplashActivity.java b/src/com/icystar/findnumber/SplashActivity.java
new file mode 100644
index 0000000..5607cec
--- /dev/null
+++ b/src/com/icystar/findnumber/SplashActivity.java
@@ -0,0 +1,29 @@
+package com.icystar.findnumber;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.widget.ViewAnimator;
+
+public class SplashActivity extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_splash);
+
+ final ViewAnimator animator = (ViewAnimator)findViewById(R.id.ViewAnimator1);
+ animator.showNext();
+
+ (new Handler()).postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ SplashActivity.this.startActivity(new Intent(SplashActivity.this, MainActivity.class));
+ finish();
+ }
+
+ }, 2000);
+ }
+
+}