├── app
├── .gitignore
├── src
│ └── main
│ │ ├── res
│ │ ├── values
│ │ │ ├── drawables.xml
│ │ │ ├── attrs.xml
│ │ │ ├── dimens.xml
│ │ │ ├── styles.xml
│ │ │ └── colors.xml
│ │ ├── mipmap-hdpi
│ │ │ ├── ic_drawer.png
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_splash.png
│ │ │ ├── icon_drawer.png
│ │ │ ├── splash_icon.png
│ │ │ ├── icon_launcher.png
│ │ │ ├── ic_launcher_adaptive_back.png
│ │ │ └── ic_launcher_adaptive_fore.png
│ │ ├── mipmap-mdpi
│ │ │ ├── ic_drawer.png
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_splash.png
│ │ │ ├── icon_drawer.png
│ │ │ ├── splash_icon.png
│ │ │ ├── icon_launcher.png
│ │ │ ├── ic_launcher_adaptive_back.png
│ │ │ └── ic_launcher_adaptive_fore.png
│ │ ├── mipmap-xhdpi
│ │ │ ├── ic_drawer.png
│ │ │ ├── ic_splash.png
│ │ │ ├── ic_launcher.png
│ │ │ ├── icon_drawer.png
│ │ │ ├── splash_icon.png
│ │ │ ├── icon_launcher.png
│ │ │ ├── ic_launcher_adaptive_back.png
│ │ │ └── ic_launcher_adaptive_fore.png
│ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_drawer.png
│ │ │ ├── ic_splash.png
│ │ │ ├── ic_launcher.png
│ │ │ ├── icon_drawer.png
│ │ │ ├── splash_icon.png
│ │ │ ├── icon_launcher.png
│ │ │ ├── ic_launcher_adaptive_back.png
│ │ │ └── ic_launcher_adaptive_fore.png
│ │ ├── drawable-hdpi
│ │ │ ├── ic_cpu_easy.png
│ │ │ ├── ic_cpu_hard.png
│ │ │ └── ic_info_black_24dp.png
│ │ ├── drawable-mdpi
│ │ │ ├── ic_cpu_easy.png
│ │ │ ├── ic_cpu_hard.png
│ │ │ ├── ic_info_black_24dp.png
│ │ │ ├── ic_people_black_24px.png
│ │ │ └── ic_person_black_24px.png
│ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_drawer.png
│ │ │ ├── ic_splash.png
│ │ │ ├── ic_launcher.png
│ │ │ ├── icon_drawer.png
│ │ │ ├── icon_launcher.png
│ │ │ ├── splash_icon.png
│ │ │ ├── ic_launcher_adaptive_back.png
│ │ │ └── ic_launcher_adaptive_fore.png
│ │ ├── drawable-xhdpi
│ │ │ ├── ic_cpu_easy.png
│ │ │ ├── ic_cpu_hard.png
│ │ │ ├── ic_info_black_24dp.png
│ │ │ ├── ic_trophy_black_48dp.png
│ │ │ ├── ic_trophy_award_black_48dp.png
│ │ │ └── splash_screen.xml
│ │ ├── drawable-xxhdpi
│ │ │ ├── ic_cpu_easy.png
│ │ │ ├── ic_cpu_hard.png
│ │ │ └── ic_info_black_24dp.png
│ │ ├── drawable-xxxhdpi
│ │ │ ├── ic_cpu_easy.png
│ │ │ ├── ic_cpu_hard.png
│ │ │ └── ic_info_black_24dp.png
│ │ ├── drawable
│ │ │ ├── secuso_logo_blau_blau.png
│ │ │ ├── privacyfriendlyappslogo.png
│ │ │ ├── button_normal.xml
│ │ │ ├── button_disabled.xml
│ │ │ ├── button_fullwidth.xml
│ │ │ ├── ic_menu_home.xml
│ │ │ ├── ic_keyboard_arrow_left_black_24dp.xml
│ │ │ ├── ic_keyboard_arrow_right_black_24dp.xml
│ │ │ ├── ic_menu_tutorial.xml
│ │ │ ├── ic_menu_info.xml
│ │ │ ├── ship_front_right.xml
│ │ │ ├── ship_front_down.xml
│ │ │ ├── ship_front_left.xml
│ │ │ ├── ship_front_up.xml
│ │ │ ├── ship_middle_right.xml
│ │ │ ├── ship_middle_down.xml
│ │ │ ├── ship_middle_left.xml
│ │ │ ├── ship_middle_up.xml
│ │ │ ├── ship_back_right.xml
│ │ │ ├── ship_back_up.xml
│ │ │ ├── ship_back_down.xml
│ │ │ ├── ship_back_left.xml
│ │ │ ├── ic_menu_help.xml
│ │ │ ├── arrow_down_black.xml
│ │ │ ├── arrow_left_black.xml
│ │ │ ├── arrow_right_black.xml
│ │ │ ├── arrow_up_black.xml
│ │ │ ├── arrow_rotate_right_black.xml
│ │ │ ├── arrow_rotate_left_black.xml
│ │ │ └── ic_menu_settings.xml
│ │ ├── mipmap-anydpi-v26
│ │ │ └── ic_launcher.xml
│ │ ├── values-v21
│ │ │ └── styles.xml
│ │ ├── values-w820dp
│ │ │ └── dimens.xml
│ │ ├── layout
│ │ │ ├── fragment_size_main.xml
│ │ │ ├── placement_dialog.xml
│ │ │ ├── placement_invalid_dialog.xml
│ │ │ ├── toolbar.xml
│ │ │ ├── placement_switch_player_dialog.xml
│ │ │ ├── help_dialog.xml
│ │ │ ├── game_dialog.xml
│ │ │ ├── fragment_mode_main.xml
│ │ │ ├── tutorial_slide1.xml
│ │ │ ├── nav_header_main.xml
│ │ │ ├── activity_tutorial.xml
│ │ │ ├── activity_main.xml
│ │ │ ├── activity_ship_set.xml
│ │ │ ├── activity_place_ship.xml
│ │ │ ├── activity_help.xml
│ │ │ ├── lose_dialog.xml
│ │ │ ├── tutorial_slide2.xml
│ │ │ ├── activity_game_content.xml
│ │ │ ├── activity_game.xml
│ │ │ ├── content_place_ship.xml
│ │ │ ├── win_dialog.xml
│ │ │ └── activity_about.xml
│ │ ├── layout-land
│ │ │ ├── fragment_size_main.xml
│ │ │ ├── fragment_mode_main.xml
│ │ │ ├── activity_game_content.xml
│ │ │ ├── content_place_ship.xml
│ │ │ ├── win_dialog.xml
│ │ │ ├── content_main.xml
│ │ │ └── activity_about.xml
│ │ ├── menu
│ │ │ └── activity_main_drawer.xml
│ │ ├── xml
│ │ │ └── help.xml
│ │ ├── layout-xlarge
│ │ │ ├── activity_about.xml
│ │ │ └── content_main.xml
│ │ └── layout-xlarge-land
│ │ │ └── activity_about.xml
│ │ ├── java
│ │ └── org
│ │ │ └── secuso
│ │ │ └── privacyfriendlybattleship
│ │ │ ├── game
│ │ │ ├── Direction.kt
│ │ │ ├── GridSize.kt
│ │ │ ├── BattleshipsTimer.kt
│ │ │ ├── GameMode.kt
│ │ │ ├── GameGrid.kt
│ │ │ └── GameCell.kt
│ │ │ ├── ui
│ │ │ ├── SplashActivity.kt
│ │ │ ├── HelpActivity.kt
│ │ │ ├── GameActivityLayoutProvider.kt
│ │ │ ├── AboutActivity.kt
│ │ │ ├── AppCompatPreferenceActivity.kt
│ │ │ └── GameGridAdapter.kt
│ │ │ └── util
│ │ │ └── PrefManager.kt
│ │ └── AndroidManifest.xml
├── lint.xml
├── proguard-rules.pro
└── build.gradle
├── settings.gradle
├── fastlane
└── metadata
│ └── android
│ ├── de-DE
│ ├── title.txt
│ ├── short_description.txt
│ ├── images
│ │ ├── icon.png
│ │ └── phoneScreenshots
│ │ │ ├── 1.png
│ │ │ └── 2.png
│ └── full_description.txt
│ └── en-US
│ ├── title.txt
│ ├── short_description.txt
│ ├── images
│ ├── icon.png
│ └── phoneScreenshots
│ │ ├── 1.png
│ │ └── 2.png
│ └── full_description.txt
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── .gitignore
├── .github
└── workflows
│ ├── changelog.yml
│ ├── ci.yml
│ └── android-test.yml
├── CHANGELOG.md
├── gradlew.bat
└── CONTRIBUTING.md
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/title.txt:
--------------------------------------------------------------------------------
1 | Schiffe versenken (Privacy Friendly)
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/title.txt:
--------------------------------------------------------------------------------
1 | Battleship Game (Privacy Friendly)
--------------------------------------------------------------------------------
/app/src/main/res/values/drawables.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/short_description.txt:
--------------------------------------------------------------------------------
1 | (SECUSO) Play the battleship game on your smartphone without ads or permissions.
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/short_description.txt:
--------------------------------------------------------------------------------
1 | (SECUSO) Spiele "Schiffe versenken" bequem auf dem Smartphone, ohne Werbung oder Berechtigungen.
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | android.enableJetifier=true
2 | android.useAndroidX=true
3 | android.nonTransitiveRClass=false
4 | android.nonFinalResIds=false
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_drawer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-hdpi/ic_drawer.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-hdpi/ic_splash.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/icon_drawer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-hdpi/icon_drawer.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/splash_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-hdpi/splash_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_drawer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-mdpi/ic_drawer.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-mdpi/ic_splash.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/icon_drawer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-mdpi/icon_drawer.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/splash_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-mdpi/splash_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_drawer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xhdpi/ic_drawer.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xhdpi/ic_splash.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_drawer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xxhdpi/ic_drawer.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xxhdpi/ic_splash.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_cpu_easy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/drawable-hdpi/ic_cpu_easy.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_cpu_hard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/drawable-hdpi/ic_cpu_hard.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_cpu_easy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/drawable-mdpi/ic_cpu_easy.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_cpu_hard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/drawable-mdpi/ic_cpu_hard.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/icon_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-hdpi/icon_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/icon_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-mdpi/icon_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_drawer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xhdpi/icon_drawer.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/splash_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xhdpi/splash_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/icon_drawer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xxhdpi/icon_drawer.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/splash_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xxhdpi/splash_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_drawer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_drawer.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_splash.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_cpu_easy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/drawable-xhdpi/ic_cpu_easy.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_cpu_hard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/drawable-xhdpi/ic_cpu_hard.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_cpu_easy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/drawable-xxhdpi/ic_cpu_easy.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_cpu_hard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/drawable-xxhdpi/ic_cpu_hard.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_cpu_easy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/drawable-xxxhdpi/ic_cpu_easy.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_cpu_hard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/drawable-xxxhdpi/ic_cpu_hard.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xhdpi/icon_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/icon_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xxhdpi/icon_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/icon_drawer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xxxhdpi/icon_drawer.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/icon_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xxxhdpi/icon_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/splash_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xxxhdpi/splash_icon.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/fastlane/metadata/android/de-DE/images/icon.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/fastlane/metadata/android/en-US/images/icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/secuso_logo_blau_blau.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/drawable/secuso_logo_blau_blau.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_info_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/drawable-hdpi/ic_info_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_info_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/drawable-mdpi/ic_info_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_info_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/drawable-xhdpi/ic_info_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/privacyfriendlyappslogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/drawable/privacyfriendlyappslogo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_people_black_24px.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/drawable-mdpi/ic_people_black_24px.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_person_black_24px.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/drawable-mdpi/ic_person_black_24px.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_trophy_black_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/drawable-xhdpi/ic_trophy_black_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_info_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/drawable-xxhdpi/ic_info_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_info_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/drawable-xxxhdpi/ic_info_black_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_adaptive_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_adaptive_back.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_adaptive_fore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_adaptive_fore.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_adaptive_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_adaptive_back.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_adaptive_fore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_adaptive_fore.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_adaptive_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_adaptive_back.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_adaptive_fore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_adaptive_fore.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_adaptive_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_adaptive_back.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_adaptive_fore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_adaptive_fore.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_adaptive_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_adaptive_back.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_adaptive_fore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_adaptive_fore.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/images/phoneScreenshots/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/fastlane/metadata/android/de-DE/images/phoneScreenshots/1.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/images/phoneScreenshots/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/fastlane/metadata/android/de-DE/images/phoneScreenshots/2.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_trophy_award_black_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SecUSo/privacy-friendly-battleship/HEAD/app/src/main/res/drawable-xhdpi/ic_trophy_award_black_48dp.png
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/lint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_normal.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_disabled.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_fullwidth.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_home.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_keyboard_arrow_left_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_keyboard_arrow_right_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_tutorial.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/splash_screen.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 | -
7 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_info.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ship_front_right.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ship_front_down.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ship_front_left.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ship_front_up.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ship_middle_right.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ship_middle_down.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ship_middle_left.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ship_middle_up.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ship_back_right.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ship_back_up.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ship_back_down.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ship_back_left.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | /*/build/
3 |
4 | # Crashlytics configuations
5 | com_crashlytics_export_strings.xml
6 |
7 | # Local configuration file (sdk path, etc)
8 | local.properties
9 |
10 | # Gradle generated files
11 | .gradle/
12 |
13 | # Signing files
14 | .signing/
15 |
16 | # User-specific configurations
17 | .idea/*
18 | *.iml
19 |
20 | # OS-specific files
21 | .DS_Store
22 | .DS_Store?
23 | ._*
24 | .Spotlight-V100
25 | .Trashes
26 | ehthumbs.db
27 | Thumbs.db
28 |
29 | # Documents
30 | *.pdf
31 | *.doc
32 | *.docx
33 | *.odt
34 |
35 | build/
36 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_help.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/arrow_down_black.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/arrow_left_black.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/arrow_right_black.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/arrow_up_black.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
--------------------------------------------------------------------------------
/.github/workflows/changelog.yml:
--------------------------------------------------------------------------------
1 | name: Changelog Generation
2 |
3 | on:
4 | release:
5 | types: [published]
6 | workflow_dispatch:
7 |
8 | jobs:
9 | changelog:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v3
13 | with:
14 | submodules: 'recursive'
15 | ref: master
16 | - uses: rhysd/changelog-from-release/action@v3
17 | with:
18 | file: CHANGELOG.md
19 | pull_request: true
20 | github_token: ${{ secrets.GITHUB_TOKEN }}
21 | commit_summary_template: 'update changelog for %s changes'
22 | args: -l 2
23 | header: |
24 | # Changelog
25 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_size_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 160dp
4 |
5 | 16dp
6 | 16dp
7 |
8 | 30dp
9 | 20dp
10 | 120dp
11 | 30dp
12 | 16dp
13 | 40dp
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-land/fragment_size_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/placement_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
11 |
15 |
16 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /home/yonjuni/Android/Sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/placement_invalid_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
11 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/toolbar.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/placement_switch_player_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
11 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/arrow_rotate_right_black.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/arrow_rotate_left_black.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
16 |
17 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/activity_main_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_settings.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/help_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
11 |
15 |
19 |
23 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/game_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
19 |
20 |
25 |
26 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #024265
4 | #024265
5 | #0274B2
6 | #00000000
7 | #ffffff
8 | #0274B2
9 | #8aa5ce
10 | #024265
11 | #A8A8A8
12 | #f6d126
13 | #B71C1C
14 |
15 |
16 | #026499
17 |
18 |
19 | #448bb2
20 |
21 |
22 | - @color/dot_light_screen
23 | - @color/dot_light_screen
24 | - @color/dot_light_screen
25 | - @color/dot_light_screen
26 | - @color/dot_light_screen
27 |
28 |
29 |
30 | - @color/dot_dark_screen
31 | - @color/dot_dark_screen
32 | - @color/dot_dark_screen
33 | - @color/dot_dark_screen
34 | - @color/dot_dark_screen
35 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_mode_main.xml:
--------------------------------------------------------------------------------
1 |
14 |
15 |
23 |
24 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-land/fragment_mode_main.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
24 |
25 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/java/org/secuso/privacyfriendlybattleship/game/Direction.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2017 Alexander Müller, Ali Kalsen
3 |
4 | This file is part of Privacy Friendly Battleships.
5 |
6 | Privacy Friendly Battleships is free software: you can redistribute
7 | it and/or modify it under the terms of the GNU General Public License
8 | as published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | Privacy Friendly Battleships is distributed in the hope that it will
12 | be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13 | of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with Foobar. If not, see http://www.gnu.org/licenses/.
18 | */
19 | package org.secuso.privacyfriendlybattleship.game
20 |
21 | import java.util.Random
22 |
23 | /**
24 | * This file represents the direction, used for ship placement.
25 | *
26 | * @author Alexander Müller, Ali Kalsen
27 | */
28 | enum class Direction {
29 | NORTH, EAST, SOUTH, WEST;
30 |
31 | companion object {
32 | fun getRandomDirection(): Direction {
33 | val ranGen = Random()
34 | val direction = ranGen.nextInt(4)
35 | return when (direction) {
36 | 0 -> NORTH
37 | 1 -> EAST
38 | 2 -> SOUTH
39 | else -> WEST
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/full_description.txt:
--------------------------------------------------------------------------------
1 | With the Privacy Friendly Battleship app, you can play the popular game "Battleship" conveniently on your smartphone. The goal of the game is to sink all of your opponent's ships by taking turns "shooting" at the opponent's board.
2 |
3 | The game offers two game modes:
4 | - Player vs. Computer
5 | - Player vs. Player
6 |
7 | The player can choose between 5x5 and 10x10 board sizes and place their ships freely. The number of ships can be selected before the game. Ships of sizes 2 (submarines), 3 (destroyers), 4 (cruisers), and 5 (battleships) are possible.
8 |
9 | What distinguishes Privacy Friendly Battleship from other similar apps?
10 |
11 | 1. No Permissions
12 | Privacy Friendly Battleship does not require any permissions.
13 | For comparison: The top ten similar apps available in the Google Play Store require an average of 6.1 permissions (as of November 2017). These include access to networks, the internet, and location data.
14 |
15 | 2. No intrusive ads
16 | Many other free apps in the Google Play Store display intrusive ads, which, among other things, can shorten battery life and consume data.
17 |
18 | The app belongs to the group of Privacy Friendly Apps developed by the SECUSO research group at the Karlsruhe Institute of Technology. More information at: https://secuso.org/pfa
19 |
20 | Feel free to contact us via:
21 | Bluesky - @secusoresearch.bsky.social https://bsky.app/profile/secusoresearch.bsky.social
22 | Mastodon - @SECUSO_Research@bawü.social https://xn--baw-joa.social/@SECUSO_Research/
23 | Job opening - https://secuso.aifb.kit.edu/english/Job_Offers.php
--------------------------------------------------------------------------------
/app/src/main/java/org/secuso/privacyfriendlybattleship/ui/SplashActivity.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017, Alexander Müller, Ali Kalsen and affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * SplashActivity.java is part of Privacy Friendly Battleship.
6 | *
7 | * Privacy Friendly Battleship is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Privacy Friendly Battleship is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Privacy Friendly Battleship. If not, see //www.gnu.org/licenses/>.
19 | */
20 | package org.secuso.privacyfriendlybattleship.ui
21 |
22 | import android.content.Intent
23 | import android.os.Bundle
24 | import androidx.appcompat.app.AppCompatActivity
25 |
26 | /**
27 | * This activity is called when the app starts. It displays the logo of the app.
28 | */
29 | class SplashActivity : AppCompatActivity() {
30 | override fun onCreate(savedInstanceState: Bundle?) {
31 | super.onCreate(savedInstanceState)
32 |
33 | val mainIntent = Intent(this@SplashActivity, TutorialActivity::class.java)
34 | this@SplashActivity.startActivity(mainIntent)
35 | this@SplashActivity.finish()
36 | }
37 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/tutorial_slide1.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
22 |
23 |
28 |
29 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/nav_header_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
19 |
20 |
27 |
28 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/full_description.txt:
--------------------------------------------------------------------------------
1 | Mit der App Privacy Friendly Schiffe versenken kann man das beliebte Spiel "Schiffe versenken" bequem auf dem Smartphone spielen. Ziel des Spiels ist es, alle Schiffe des Gegners zu versenken, indem beide Spieler abwechselnd auf das Spielfeld des Gegners "schießen".
2 |
3 | Das Spiel bietet zwei Spielmodi:
4 | - Spieler vs Computer
5 | - Spieler vs Spieler
6 |
7 | Der Spieler kann dabei zwischen den Spielfeldgrößen 5x5 und 10x10 wählen und seine Schiffe frei platzieren. Die Anzahl der Schiffe kann vor dem Spiel selbst gewählt werden. Dabei sind Schiffe der Größen 2 (U-Boote), 3 (Zerstörer), 4 (Kreuzer) und 5 (Schlachtschiffe) möglich.
8 |
9 | Was unterscheidet Privacy Friendly Schiffe Versenken von anderen, ähnlichen Apps?
10 |
11 | 1. Keine Berechtigungen
12 | Privacy Friendly Schiffe versenken verwendet keine Berechtigungen.
13 | Zum Vergleich: Die Top Ten ähnlicher Apps, die im Google Play Store erhältlich sind, benötigt durchschnittlich 6,1 Berechtigungen (Stand: November 2017). Hierzu zählen der Zugriff auf Netzwerke, das Internet oder Standortdaten.
14 |
15 | 2. Keine störende Werbung
16 | Viele andere kostenlose Apps im Google Play Store blenden störende Werbung ein, die unter anderem auch die Akkulaufzeit verkürzt und Datenvolumen verbrauchen kann.
17 |
18 | Die App gehört zur Gruppe der Privacy Friendly Apps, die von der Forschungsgruppe SECUSO am Karlsruher Institut für Technologie entwickelt werden. Mehr Informationen unter: https://secuso.org/pfa
19 |
20 | Kontaktieren Sie uns gerne über:
21 | Bluesky - @secusoresearch.bsky.social https://bsky.app/profile/secusoresearch.bsky.social
22 | Mastodon - @SECUSO_Research@bawü.social https://xn--baw-joa.social/@SECUSO_Research/
23 | Offene Stellen - https://secuso.aifb.kit.edu/83.php
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: Continuous Integration
2 | on: [push, pull_request]
3 |
4 | jobs:
5 | test:
6 | runs-on: ubuntu-latest
7 | steps:
8 | - name: Checkout
9 | uses: actions/checkout@v3
10 | with:
11 | submodules: "recursive"
12 |
13 | - name: Set up JDK environment
14 | uses: actions/setup-java@v3
15 | with:
16 | distribution: "zulu"
17 | java-version: 21
18 |
19 | - name: Make gradlew executable
20 | run: chmod +x ./gradlew
21 |
22 | - name: Setup Gradle
23 | uses: gradle/gradle-build-action@v2
24 |
25 | - name: Run local unit tests
26 | run: bash ./gradlew test --stacktrace
27 |
28 | build:
29 | runs-on: ubuntu-latest
30 | steps:
31 | - name: Checkout
32 | uses: actions/checkout@v3
33 | with:
34 | submodules: "recursive"
35 |
36 | - name: Set up JDK environment
37 | uses: actions/setup-java@v3
38 | with:
39 | distribution: "zulu"
40 | java-version: 21
41 |
42 | - name: Make gradlew executable
43 | run: chmod +x ./gradlew
44 |
45 | - name: Setup Gradle
46 | uses: gradle/gradle-build-action@v2
47 |
48 | - name: Run lint check
49 | run: bash ./gradlew lint
50 |
51 | - name: Upload lint result
52 | uses: actions/upload-artifact@v4
53 | with:
54 | name: lint-results-debug
55 | path: app/build/reports/lint-results-debug.html
56 |
57 | - name: Build the app
58 | run: bash ./gradlew build --stacktrace
59 |
60 | - name: Build debug apk
61 | run: bash ./gradlew assembleDebug
62 |
63 | - name: Upload debug apk
64 | uses: actions/upload-artifact@v4
65 | with:
66 | name: debug-apk
67 | path: app/build/outputs/apk/debug/*.apk
68 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id "com.android.application"
3 | id "kotlin-android"
4 | id "com.google.devtools.ksp"
5 | }
6 |
7 | android {
8 | namespace "org.secuso.privacyfriendlybattleship"
9 |
10 | defaultConfig {
11 | applicationId "org.secuso.privacyfriendlybattleship"
12 | minSdkVersion 17
13 | targetSdkVersion 35
14 | compileSdk 35
15 | versionCode 100
16 | versionName "1.2.6"
17 | vectorDrawables.useSupportLibrary = true
18 |
19 | ksp {
20 | arg("room.schemaLocation", "$projectDir/schemas")
21 | }
22 | }
23 |
24 | applicationVariants.configureEach { variant ->
25 | variant.outputs.configureEach {
26 | def appName = "pfa-battleship"
27 | outputFileName = appName + "-${variant.name}-v${variant.versionName}.apk"
28 | }
29 | }
30 |
31 | buildFeatures {
32 | buildConfig = true
33 | }
34 |
35 | buildTypes {
36 | release {
37 | minifyEnabled false
38 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
39 | }
40 | }
41 |
42 | compileOptions {
43 | sourceCompatibility JavaVersion.VERSION_21
44 | targetCompatibility JavaVersion.VERSION_21
45 | }
46 |
47 | kotlinOptions {
48 | jvmTarget = JavaVersion.VERSION_21.toString()
49 | }
50 |
51 | kotlin {
52 | jvmToolchain(21)
53 | }
54 |
55 | lint {
56 | lintConfig = file("lint.xml")
57 | }
58 | }
59 |
60 | dependencies {
61 | implementation fileTree(dir: 'libs', include: ['*.jar'])
62 | implementation 'androidx.preference:preference-ktx:1.2.1'
63 | testImplementation 'junit:junit:4.13.2'
64 | implementation 'androidx.appcompat:appcompat:1.6.1'
65 | implementation 'com.google.android.material:material:1.11.0'
66 | implementation 'androidx.legacy:legacy-support-v4:1.0.0'
67 | }
68 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_tutorial.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
21 |
22 |
28 |
29 |
38 |
39 |
48 |
49 |
--------------------------------------------------------------------------------
/app/src/main/java/org/secuso/privacyfriendlybattleship/game/GridSize.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2025, Christian Adams. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * GridSize.java is part of Privacy Friendly Battleship.
6 | *
7 | * Privacy Friendly Battleship is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Privacy Friendly Battleship is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Privacy Friendly Battleship. If not, see //www.gnu.org/licenses/>.
19 | */
20 | package org.secuso.privacyfriendlybattleship.game
21 |
22 | /**
23 | * This file represents the sizes for a battleships game.
24 | *
25 | * @author Christian Adams
26 | */
27 | enum class GridSize(val width: Int, val height: Int) {
28 | SIZE_5X5(5, 5),
29 | SIZE_10X10(10, 10);
30 |
31 | companion object {
32 | /** Number of enumeration entries. */
33 | @JvmField
34 | val LENGTH = entries.size
35 |
36 | /**
37 | * Provides the enumeration value that matches the given ordinal number.
38 | *
39 | * @param ordinal The ordinal number of the requested enumeration value.
40 | * @return The requested enumeration value if the given ordinal is valid. Otherwise the
41 | * default value.
42 | */
43 | fun fromOrdinal(ordinal: Int, defaultValue: GridSize): GridSize {
44 | return if (ordinal in 0..//www.gnu.org/licenses/>.
19 | */
20 | package org.secuso.privacyfriendlybattleship.ui
21 |
22 | import android.os.Bundle
23 | import android.preference.PreferenceFragment
24 | import org.secuso.privacyfriendlybattleship.R
25 |
26 | /**
27 | * Created by yonjuni on 17.06.16.
28 | */
29 | class HelpActivity : BaseActivity() {
30 | override fun onCreate(savedInstanceState: Bundle?) {
31 | super.onCreate(savedInstanceState)
32 |
33 | setContentView(R.layout.activity_help)
34 |
35 | //getFragmentManager().beginTransaction().replace(android.R.id.content, new HelpFragment()).commit();
36 | overridePendingTransition(0, 0)
37 | }
38 |
39 | override val navigationDrawerID: Int
40 | get() = R.id.nav_help
41 |
42 | class HelpFragment : PreferenceFragment() {
43 | override fun onCreate(savedInstanceState: Bundle?) {
44 | super.onCreate(savedInstanceState)
45 |
46 | addPreferencesFromResource(R.xml.help)
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
15 |
16 |
17 |
22 |
23 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
39 |
40 |
41 |
42 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_ship_set.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
16 |
17 |
18 |
23 |
24 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
40 |
41 |
42 |
43 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_place_ship.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
22 |
23 |
29 |
30 |
31 |
32 |
33 |
37 |
38 |
39 |
40 |
48 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_help.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
17 |
18 |
19 |
20 |
30 |
34 |
35 |
36 |
37 |
38 |
39 |
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/java/org/secuso/privacyfriendlybattleship/ui/GameActivityLayoutProvider.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017, Alexander Müller, Ali Kalsen and affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * GameActivityLayoutProvider.java is part of Privacy Friendly Battleship.
6 | *
7 | * Privacy Friendly Battleship is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Privacy Friendly Battleship is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Privacy Friendly Battleship. If not, see //www.gnu.org/licenses/>.
19 | */
20 | package org.secuso.privacyfriendlybattleship.ui
21 |
22 | import android.app.Activity
23 | import android.view.View
24 | import org.secuso.privacyfriendlybattleship.R
25 |
26 | /**
27 | * This class computes the size of a grid cell for the big and the small grid view in pixel.
28 | * Created on 01.02.2017.
29 | *
30 | * @author Ali Kalsen
31 | */
32 | class GameActivityLayoutProvider(context: Activity, private val gridSize: Int) {
33 |
34 | private val gridViewBig = context.findViewById(R.id.game_gridview_big)
35 | private val gridViewSmall = context.findViewById(R.id.game_gridview_small)
36 |
37 | val mainGridCellSizeInPixel: Int
38 | get() = getGridCellSizeInPixel(gridViewBig)
39 |
40 | val miniGridCellSizeInPixel: Int
41 | get() = getGridCellSizeInPixel(gridViewSmall)
42 |
43 | private fun getGridCellSizeInPixel(gridView: View): Int {
44 | var result = 0
45 | if (gridView.width > 0) {
46 | result = (gridView.width - gridSize + 1) / gridSize
47 | }
48 | return result
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/org/secuso/privacyfriendlybattleship/game/BattleshipsTimer.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017, Alexander Müller, Ali Kalsen and affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * BattleshipsTimer.java is part of Privacy Friendly Battleship.
6 | *
7 | * Privacy Friendly Battleship is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Privacy Friendly Battleship is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Privacy Friendly Battleship. If not, see //www.gnu.org/licenses/>.
19 | */
20 | package org.secuso.privacyfriendlybattleship.game
21 |
22 | import java.util.Timer
23 | import java.util.TimerTask
24 | import java.util.concurrent.atomic.AtomicBoolean
25 |
26 | /**
27 | * This class creates a timer, which only counts full seconds, if it is running. Created on 27.01.2017.
28 | *
29 | * @author Ali Kalsen
30 | */
31 | class BattleshipsTimer {
32 | private var internalTimer: Timer? = null
33 | private val timerRunning = AtomicBoolean(false)
34 | var time: Int = 0
35 | private set
36 | private val WAIT_TIME = 1000
37 |
38 | private fun init() {
39 | internalTimer = Timer()
40 | internalTimer!!.scheduleAtFixedRate(object : TimerTask() {
41 | override fun run() {
42 | if (timerRunning.get()) {
43 | time++
44 | }
45 | }
46 | }, 0, WAIT_TIME.toLong())
47 | }
48 |
49 | fun stop() {
50 | timerRunning.set(false)
51 | }
52 |
53 | fun start() {
54 | timerRunning.set(true)
55 | if (internalTimer == null) {
56 | init()
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/lose_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
17 |
18 |
25 |
26 |
33 |
34 |
35 |
36 |
40 |
41 |
46 |
47 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/tutorial_slide2.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
22 |
23 |
28 |
29 |
39 |
40 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/java/org/secuso/privacyfriendlybattleship/ui/AboutActivity.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017, Alexander Müller, Ali Kalsen and affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * AboutActivity.java is part of Privacy Friendly Battleship.
6 | *
7 | * Privacy Friendly Battleship is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Privacy Friendly Battleship is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Privacy Friendly Battleship. If not, see //www.gnu.org/licenses/>.
19 | */
20 | package org.secuso.privacyfriendlybattleship.ui
21 |
22 | import android.os.Bundle
23 | import android.text.method.LinkMovementMethod
24 | import android.view.View
25 | import android.widget.TextView
26 | import androidx.appcompat.app.AppCompatActivity
27 | import org.secuso.privacyfriendlybattleship.BuildConfig
28 | import org.secuso.privacyfriendlybattleship.R
29 |
30 | /**
31 | * Created by yonjuni on 15.06.16.
32 | */
33 | class AboutActivity : AppCompatActivity() {
34 | override fun onCreate(savedInstanceState: Bundle?) {
35 | super.onCreate(savedInstanceState)
36 | setContentView(R.layout.activity_about)
37 |
38 | val ab = supportActionBar
39 | ab?.setDisplayHomeAsUpEnabled(true)
40 |
41 | val mainContent = findViewById(R.id.main_content)
42 | if (mainContent != null) {
43 | mainContent.alpha = 0f
44 | mainContent.animate().alpha(1f)
45 | .setDuration(BaseActivity.MAIN_CONTENT_FADEIN_DURATION.toLong())
46 | }
47 |
48 | findViewById(R.id.secusoWebsite).movementMethod =
49 | LinkMovementMethod.getInstance()
50 | findViewById(R.id.githubURL).movementMethod =
51 | LinkMovementMethod.getInstance()
52 | findViewById(R.id.textFieldVersionName).text =
53 | BuildConfig.VERSION_NAME
54 |
55 | overridePendingTransition(0, 0)
56 | }
57 |
58 | //@Override
59 | //protected int getNavigationDrawerID() {
60 | // return R.id.nav_about;
61 | //}
62 | }
63 |
64 |
--------------------------------------------------------------------------------
/app/src/main/java/org/secuso/privacyfriendlybattleship/game/GameMode.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017, Alexander Müller, Ali Kalsen and affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * GameMode.java is part of Privacy Friendly Battleship.
6 | *
7 | * Privacy Friendly Battleship is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Privacy Friendly Battleship is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Privacy Friendly Battleship. If not, see //www.gnu.org/licenses/>.
19 | */
20 | package org.secuso.privacyfriendlybattleship.game
21 |
22 | import androidx.annotation.DrawableRes
23 | import androidx.annotation.StringRes
24 | import org.secuso.privacyfriendlybattleship.R
25 |
26 | /**
27 | * This file represents the mode for a battleships game. It is used to
28 | * define whether the game is played in the two player mode or against the
29 | * AI in one of two difficulty levels.
30 | *
31 | * @author Alexander Müller, Ali Kalsen
32 | */
33 | enum class GameMode(@param:StringRes val stringResID: Int, @param:DrawableRes val imageResID: Int) {
34 | VS_PLAYER(R.string.mode_two_player, R.drawable.ic_people_black_24px),
35 | VS_AI_EASY(R.string.mode_vs_cpu_easy, R.drawable.ic_cpu_easy),
36 | VS_AI_HARD(R.string.mode_vs_cpu_hard, R.drawable.ic_cpu_hard),
37 | CUSTOM(R.string.mode_custom, R.drawable.ic_people_black_24px);
38 |
39 | companion object {
40 | /** Number of enumeration entries. */
41 | @JvmField
42 | val LENGTH = entries.size
43 |
44 | /**
45 | * Provides the enumeration value that matches the given ordinal number.
46 | *
47 | * Note: GameMode ´CUSTOM´ is excluded by this function.
48 | *
49 | * @param ordinal The ordinal number of the requested enumeration value.
50 | * @return The requested enumeration value if the given ordinal is valid. Otherwise the
51 | * default value.
52 | */
53 | fun fromOrdinal(ordinal: Int, defaultValue: GameMode): GameMode {
54 | return if (ordinal in 0..
4 | ## [Battleship (Privacy Friendly) v1.2.3](https://github.com/SecUSo/privacy-friendly-battleship/releases/tag/v1.2.3) - 2025-01-03
5 |
6 | ## What's Changed
7 | * Updates to SDK 34 by [@coderPaddyS](https://github.com/coderPaddyS) in [#30](https://github.com/SecUSo/privacy-friendly-battleship/pull/30)
8 |
9 |
10 | **Full Changelog**: https://github.com/SecUSo/privacy-friendly-battleship/compare/v1.2.2...v1.2.3
11 |
12 | [Changes][v1.2.3]
13 |
14 |
15 |
16 | ## [Battleship (Privacy Friendly) v1.2.2](https://github.com/SecUSo/privacy-friendly-battleship/releases/tag/v1.2.2) - 2024-02-19
17 |
18 | ## What's Changed
19 | * Add ci workflow and code cleanup by [@udenr](https://github.com/udenr) in [#24](https://github.com/SecUSo/privacy-friendly-battleship/pull/24)
20 | * Update dependencies by [@udenr](https://github.com/udenr) in [#25](https://github.com/SecUSo/privacy-friendly-battleship/pull/25)
21 |
22 | ## New Contributors
23 | * [@udenr](https://github.com/udenr) made their first contribution in [#24](https://github.com/SecUSo/privacy-friendly-battleship/pull/24)
24 |
25 | **Full Changelog**: https://github.com/SecUSo/privacy-friendly-battleship/compare/v1.2.1...v1.2.2
26 |
27 | [Changes][v1.2.2]
28 |
29 |
30 |
31 | ## [Privacy Friendly Battleship (v1.2.1)](https://github.com/SecUSo/privacy-friendly-battleship/releases/tag/v1.2.1) - 2023-10-24
32 |
33 | ## What's Changed
34 | * Fixed typo in german translation of ship destory message by [@hanneshofmann](https://github.com/hanneshofmann) in [#17](https://github.com/SecUSo/privacy-friendly-battleship/pull/17)
35 | * Updates to TargetSDK 33. by [@coderPaddyS](https://github.com/coderPaddyS) in [#21](https://github.com/SecUSo/privacy-friendly-battleship/pull/21)
36 |
37 | ## New Contributors
38 | * [@hanneshofmann](https://github.com/hanneshofmann) made their first contribution in [#17](https://github.com/SecUSo/privacy-friendly-battleship/pull/17)
39 | * [@coderPaddyS](https://github.com/coderPaddyS) made their first contribution in [#21](https://github.com/SecUSo/privacy-friendly-battleship/pull/21)
40 |
41 | **Full Changelog**: https://github.com/SecUSo/privacy-friendly-battleship/compare/v1.2...v1.2.1
42 |
43 | [Changes][v1.2.1]
44 |
45 |
46 |
47 | ## [Battleships (Privacy Friendly) (v1.2)](https://github.com/SecUSo/privacy-friendly-battleship/releases/tag/v1.2) - 2018-10-29
48 |
49 | - Initial release
50 |
51 | [Changes][v1.2]
52 |
53 |
54 | [v1.2.3]: https://github.com/SecUSo/privacy-friendly-battleship/compare/v1.2.2...v1.2.3
55 | [v1.2.2]: https://github.com/SecUSo/privacy-friendly-battleship/compare/v1.2.1...v1.2.2
56 | [v1.2.1]: https://github.com/SecUSo/privacy-friendly-battleship/compare/v1.2...v1.2.1
57 | [v1.2]: https://github.com/SecUSo/privacy-friendly-battleship/tree/v1.2
58 |
59 |
60 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_game_content.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
22 |
23 |
36 |
37 |
50 |
51 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-land/activity_game_content.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
22 |
23 |
36 |
37 |
50 |
51 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/app/src/main/java/org/secuso/privacyfriendlybattleship/ui/AppCompatPreferenceActivity.kt:
--------------------------------------------------------------------------------
1 | package org.secuso.privacyfriendlybattleship.ui
2 |
3 | import android.content.res.Configuration
4 | import android.os.Bundle
5 | import android.preference.PreferenceActivity
6 | import android.view.MenuInflater
7 | import android.view.View
8 | import android.view.ViewGroup
9 | import androidx.annotation.LayoutRes
10 | import androidx.appcompat.app.ActionBar
11 | import androidx.appcompat.app.AppCompatDelegate
12 | import androidx.appcompat.widget.Toolbar
13 |
14 | /**
15 | * A [android.preference.PreferenceActivity] which implements and proxies the necessary calls
16 | * to be used with AppCompat.
17 | */
18 | abstract class AppCompatPreferenceActivity : PreferenceActivity() {
19 | private var mDelegate: AppCompatDelegate? = null
20 |
21 | override fun onCreate(savedInstanceState: Bundle?) {
22 | delegate.installViewFactory()
23 | delegate.onCreate(savedInstanceState)
24 | super.onCreate(savedInstanceState)
25 | }
26 |
27 | override fun onPostCreate(savedInstanceState: Bundle?) {
28 | super.onPostCreate(savedInstanceState)
29 | delegate.onPostCreate(savedInstanceState)
30 | }
31 |
32 | val supportActionBar: ActionBar?
33 | get() = delegate.supportActionBar
34 |
35 | fun setSupportActionBar(toolbar: Toolbar?) {
36 | delegate.setSupportActionBar(toolbar)
37 | }
38 |
39 | override fun getMenuInflater(): MenuInflater {
40 | return delegate.menuInflater
41 | }
42 |
43 | override fun setContentView(@LayoutRes layoutResID: Int) {
44 | delegate.setContentView(layoutResID)
45 | }
46 |
47 | override fun setContentView(view: View) {
48 | delegate.setContentView(view)
49 | }
50 |
51 | override fun setContentView(view: View, params: ViewGroup.LayoutParams) {
52 | delegate.setContentView(view, params)
53 | }
54 |
55 | override fun addContentView(view: View, params: ViewGroup.LayoutParams) {
56 | delegate.addContentView(view, params)
57 | }
58 |
59 | override fun onPostResume() {
60 | super.onPostResume()
61 | delegate.onPostResume()
62 | }
63 |
64 | override fun onTitleChanged(title: CharSequence, color: Int) {
65 | super.onTitleChanged(title, color)
66 | delegate.setTitle(title)
67 | }
68 |
69 | override fun onConfigurationChanged(newConfig: Configuration) {
70 | super.onConfigurationChanged(newConfig)
71 | delegate.onConfigurationChanged(newConfig)
72 | }
73 |
74 | override fun onStop() {
75 | super.onStop()
76 | delegate.onStop()
77 | }
78 |
79 | override fun onDestroy() {
80 | super.onDestroy()
81 | delegate.onDestroy()
82 | }
83 |
84 | override fun invalidateOptionsMenu() {
85 | delegate.invalidateOptionsMenu()
86 | }
87 |
88 | private val delegate: AppCompatDelegate
89 | get() {
90 | var delegate = mDelegate
91 | if (delegate == null) {
92 | delegate = AppCompatDelegate.create(this, null)
93 | mDelegate = delegate
94 | }
95 | return delegate
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 | @rem SPDX-License-Identifier: Apache-2.0
17 | @rem
18 |
19 | @if "%DEBUG%"=="" @echo off
20 | @rem ##########################################################################
21 | @rem
22 | @rem Gradle startup script for Windows
23 | @rem
24 | @rem ##########################################################################
25 |
26 | @rem Set local scope for the variables with windows NT shell
27 | if "%OS%"=="Windows_NT" setlocal
28 |
29 | set DIRNAME=%~dp0
30 | if "%DIRNAME%"=="" set DIRNAME=.
31 | @rem This is normally unused
32 | set APP_BASE_NAME=%~n0
33 | set APP_HOME=%DIRNAME%
34 |
35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
37 |
38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
40 |
41 | @rem Find java.exe
42 | if defined JAVA_HOME goto findJavaFromJavaHome
43 |
44 | set JAVA_EXE=java.exe
45 | %JAVA_EXE% -version >NUL 2>&1
46 | if %ERRORLEVEL% equ 0 goto execute
47 |
48 | echo. 1>&2
49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
50 | echo. 1>&2
51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
52 | echo location of your Java installation. 1>&2
53 |
54 | goto fail
55 |
56 | :findJavaFromJavaHome
57 | set JAVA_HOME=%JAVA_HOME:"=%
58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
59 |
60 | if exist "%JAVA_EXE%" goto execute
61 |
62 | echo. 1>&2
63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
64 | echo. 1>&2
65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
66 | echo location of your Java installation. 1>&2
67 |
68 | goto fail
69 |
70 | :execute
71 | @rem Setup the command line
72 |
73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
74 |
75 |
76 | @rem Execute Gradle
77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
78 |
79 | :end
80 | @rem End local scope for the variables with windows NT shell
81 | if %ERRORLEVEL% equ 0 goto mainEnd
82 |
83 | :fail
84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
85 | rem the _cmd.exe /c_ return code!
86 | set EXIT_CODE=%ERRORLEVEL%
87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
89 | exit /b %EXIT_CODE%
90 |
91 | :mainEnd
92 | if "%OS%"=="Windows_NT" endlocal
93 |
94 | :omega
95 |
--------------------------------------------------------------------------------
/app/src/main/java/org/secuso/privacyfriendlybattleship/util/PrefManager.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * This file is part of Privacy Friendly Battleship.
3 | *
4 | * Privacy Friendly Battleship is free software:
5 | * you can redistribute it and/or modify it under the terms of the
6 | * GNU General Public License as published by the Free Software Foundation,
7 | * either version 3 of the License, or any later version.
8 | * Privacy Friendly Password Generator is distributed in the hope
9 | * that it will be useful, but WITHOUT ANY WARRANTY; without even
10 | * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 | * See the GNU General Public License for more details.
12 | * You should have received a copy of the GNU General Public License
13 | * along with Privacy Friendly Password Generator. If not, see //www.gnu.org/licenses/>.
14 | */
15 | package org.secuso.privacyfriendlybattleship.util
16 |
17 | import android.content.Context
18 | import androidx.core.content.edit
19 | import androidx.preference.PreferenceManager
20 | import org.secuso.privacyfriendlybattleship.game.GameMode
21 | import org.secuso.privacyfriendlybattleship.game.GridSize
22 |
23 | /**
24 | * Class structure taken from tutorial at http://www.androidhive.info/2016/05/android-build-intro-slider-app/
25 | * @author Karola Marky
26 | * @version 20170518
27 | */
28 | class PrefManager(context: Context) {
29 | private val pref = PreferenceManager.getDefaultSharedPreferences(context)
30 |
31 | var isFirstTutorialStart: Boolean
32 | get() = pref.getBoolean(FIRST_TUTORIAL_START, true)
33 | set(value) = pref.edit(commit = true) { putBoolean(FIRST_TUTORIAL_START, value) }
34 |
35 | var isFirstPlacementStart: Boolean
36 | get() = pref.getBoolean(FIRST_PLACEMENT_START, true)
37 | set(value) = pref.edit(commit = true) { putBoolean(FIRST_PLACEMENT_START, value) }
38 |
39 | var isFirstGameStart: Boolean
40 | get() = pref.getBoolean(FIRST_GAME_START, true)
41 | set(value) = pref.edit(commit = true) { putBoolean(FIRST_GAME_START, value) }
42 |
43 | var isFirstShipSetStart: Boolean
44 | get() = pref.getBoolean(FIRST_SHIP_SET_START, true)
45 | set(value) = pref.edit(commit = true) { putBoolean(FIRST_SHIP_SET_START, value) }
46 |
47 | var lastGameMode: GameMode
48 | get() = GameMode.fromOrdinal(pref.getInt(LAST_GAME_MODE, GameMode.VS_PLAYER.ordinal), GameMode.VS_PLAYER)
49 | set(value) = pref.edit(commit = true) { putInt(LAST_GAME_MODE, value.ordinal) }
50 |
51 | var lastGridSize: GridSize
52 | get() = GridSize.fromOrdinal(pref.getInt(LAST_GRID_SIZE, GridSize.SIZE_5X5.ordinal), GridSize.SIZE_5X5)
53 | set(value) = pref.edit(commit = true) { putInt(LAST_GRID_SIZE, value.ordinal) }
54 |
55 | companion object {
56 | // Shared preference keys
57 | private const val FIRST_TUTORIAL_START: String = "FIRST_TUTORIAL_START"
58 | private const val FIRST_PLACEMENT_START: String = "FIRST_PLACEMENT_START"
59 | private const val FIRST_GAME_START: String = "FIRST_GAME_START"
60 | private const val FIRST_SHIP_SET_START: String = "FIRST_SHIP_SET_START"
61 | private const val LAST_GAME_MODE: String = "LAST_GAME_MODE"
62 | private const val LAST_GRID_SIZE: String = "LAST_GRID_SIZE"
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to contribute
2 |
3 | We encourage open source developers to support the Privacy Friendly Apps.
4 | We also wish to keep it as easy as possible to contribute. There are a few
5 | guidelines that we need contributors to follow.
6 | For further questions we refer to the contact details on the [Privacy Friendly Apps website](https://secuso.org/pfa).
7 |
8 | ## Reporting of Issues
9 |
10 | * Make sure you have a [GitHub account](https://github.com/signup/free).
11 | * Open an issue in the corresponding app's repository, assuming one does not already exist.
12 | * Clearly describe the issue including steps to reproduce when it is a bug.
13 | In some cases screenshots can be supportive.
14 | * Make sure you mention the Android version and the device you have used when
15 | you encountered the issue.
16 | * Make your description as precise as possible.
17 |
18 | ## Making Changes
19 |
20 | * Make sure you have a [GitHub account](https://github.com/signup/free).
21 | * Find an issue that you wish to close. If the issue you wish to close is not
22 | present, open it. Make sure that the issue has one of the following labels
23 | which are set by our team:
24 | * Bug
25 | * Enhancement
26 | * Help wanted
27 | * No integration planned
28 | That means that we have already reviewed the issue. If you wish to add a
29 | translation, opening an issue is not required.
30 | * Fork the repository on GitHub.
31 | * Create a topic branch from where you want to base your work (usually master branch).
32 | * To quickly create a topic branch based on master, run `git checkout -b
33 | fix/master/my_contribution master`.
34 | * Please avoid working directly on the `master` branch.
35 | * Make commits of logical units in english language.
36 | * Make sure your commit messages are in the proper format. If the commit
37 | addresses an issue filed in the Github repository, start the first line
38 | of the commit with a hash followed by the issue number (e.g. #42).
39 | * Make sure you have added the necessary tests for your changes.
40 | * Run all available tests to assure nothing else was accidentally broken.
41 |
42 | ### Unwanted Changes
43 |
44 | The Privacy Friendly Apps are a group of Android apps that are optimized regarding
45 | the user's privacy. Therefore, Pull Requests that contain the following functionality
46 | will be rejected:
47 | * Analytics or advertisement frameworks
48 | * User tracking (e.g. sending of data to a third party)
49 | * Any that use of libraries that do not comply the license of the corresponding Privacy
50 | Friendly App (GPLv3 or Apache2).
51 | * Unnecessary use of Android permissions. If new functionality is added that requires
52 | the usage of an Android permission you should clearly explain the Pull Request why
53 | this permission is required.
54 | * New translations/languages
55 |
56 | ## Submitting Changes
57 |
58 | * Push your changes to a topic branch in your fork of the repository.
59 | * Submit a Pull Request to the repository of the corresponding Privacy Friendly App.
60 | * Indicate that you have read this policy by writing the second word of the section "unwanted changes"
61 | * Our team looks at Pull Requests on a regular basis and assigns a reviewer.
62 | * After feedback has been given we expect responses within one month. After one
63 | month we might close the pull request if no activity is shown.
64 |
65 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/help.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
15 |
20 |
21 |
22 |
23 |
27 |
28 |
29 |
30 |
34 |
38 |
39 |
40 |
41 |
45 |
49 |
53 |
57 |
61 |
62 |
63 |
64 |
68 |
69 |
70 |
71 |
75 |
76 |
77 |
78 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
15 |
16 |
17 |
18 |
19 |
20 |
24 |
25 |
28 |
29 |
33 |
36 |
37 |
42 |
45 |
46 |
51 |
54 |
55 |
60 |
63 |
64 |
69 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_game.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
16 |
17 |
22 |
23 |
29 |
37 |
38 |
44 |
45 |
51 |
52 |
58 |
59 |
65 |
66 |
71 |
72 |
73 |
74 |
75 |
76 |
80 |
81 |
82 |
83 |
91 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/app/src/main/java/org/secuso/privacyfriendlybattleship/game/GameGrid.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2017 Alexander Müller, Ali Kalsen
3 |
4 | This file is part of Privacy Friendly Battleships.
5 |
6 | Privacy Friendly Battleships is free software: you can redistribute
7 | it and/or modify it under the terms of the GNU General Public License
8 | as published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | Privacy Friendly Battleships is distributed in the hope that it will
12 | be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13 | of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with Foobar. If not, see http://www.gnu.org/licenses/.
18 | */
19 | package org.secuso.privacyfriendlybattleship.game
20 |
21 | import android.os.Parcel
22 | import android.os.Parcelable
23 | import android.os.Parcelable.Creator
24 | import java.util.Random
25 |
26 | /**
27 | * This class represents a players grid for the battleships game. It
28 | * provides access to its cells or its set of ships and is assigned to
29 | * one of the two players (or the AI) of the game.
30 | *
31 | * @author Alexander Müller, Ali Kalsen
32 | */
33 | class GameGrid : Parcelable {
34 | private var cellGrid: Array?>
35 | var size: Int
36 | private set
37 | var shipSet: GameShipSet
38 | private set
39 |
40 | constructor(size: Int, shipCount: IntArray) {
41 | this.size = size
42 | this.cellGrid = Array(this.size) { arrayOfNulls(this.size) }
43 | this.shipSet = GameShipSet(
44 | this,
45 | shipCount[0], shipCount[1], shipCount[2], shipCount[3]
46 | )
47 |
48 | for (i in 0 until size) {
49 | for (j in 0 until size) {
50 | cellGrid[i]!![j] = GameCell(i, j, this)
51 | }
52 | }
53 | }
54 |
55 | /**
56 | * Returns the cell at the given row and column. Rows and columns start with 0.
57 | * @param col Column of the cell to be returned
58 | * @param row Row of the cell to be returned
59 | * @return The cell at the given row and column
60 | */
61 | fun getCell(col: Int, row: Int): GameCell {
62 | require(!(col >= size || row >= size || col < 0 || row < 0)) { "Column or row exceeds the limits of the grid." }
63 | return cellGrid[col]!![row]!!
64 | }
65 |
66 | val randomCell: GameCell
67 | get() {
68 | val ranGen = Random()
69 | return this.getCell(
70 | ranGen.nextInt(this.size),
71 | ranGen.nextInt(this.size)
72 | )
73 | }
74 |
75 | override fun describeContents(): Int {
76 | return 0
77 | }
78 |
79 | override fun writeToParcel(out: Parcel, flags: Int) {
80 | out.writeInt(this.size)
81 | for (i in 0 until this.size) {
82 | out.writeTypedArray(cellGrid[i], 0)
83 | }
84 |
85 | out.writeTypedArray(arrayOf(this.shipSet), 0)
86 | }
87 |
88 | private constructor(parcel: Parcel) {
89 | this.size = parcel.readInt()
90 | this.cellGrid = Array(this.size) { arrayOfNulls(this.size) }
91 | for (i in 0 until this.size) {
92 | cellGrid[i] = parcel.createTypedArray(GameCell.CREATOR)
93 | }
94 | for (i in 0 until this.size) {
95 | for (j in 0 until this.size) {
96 | cellGrid[i]!![j]!!.grid = this
97 | }
98 | }
99 |
100 | this.shipSet = parcel.createTypedArray(GameShipSet.CREATOR)!![0]
101 | shipSet.recreateShipSet(this)
102 | }
103 |
104 | companion object {
105 | @JvmField
106 | val CREATOR: Creator = object : Creator {
107 | override fun createFromParcel(parcel: Parcel): GameGrid {
108 | return GameGrid(parcel)
109 | }
110 |
111 | override fun newArray(size: Int): Array {
112 | return arrayOfNulls(size)
113 | }
114 | }
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/.github/workflows/android-test.yml:
--------------------------------------------------------------------------------
1 | name: Android Emulator Tests
2 | on: [ push, pull_request ]
3 |
4 | jobs:
5 | check-if-tests-exist:
6 | runs-on: ubuntu-latest
7 | outputs:
8 | status: ${{ steps.check-androidTest.outputs.NOT_EMPTY }}
9 | min-sdk-version: ${{ steps.get-sdk-version.outputs.MIN_SDK_VERSION }}
10 | target-sdk-version: ${{ steps.get-sdk-version.outputs.TARGET_SDK_VERSION }}
11 | app-id: ${{ steps.get-app-id.outputs.APP_ID }}
12 | steps:
13 | - name: Checkout
14 | uses: actions/checkout@v3
15 | with:
16 | submodules: "recursive"
17 | - name: Check if androidTest folder is not empty
18 | run: |
19 | echo "NOT_EMPTY=$([ "$(ls -A app/src/androidTest)" ] && echo 'true' || echo 'false')"
20 | echo "NOT_EMPTY=$([ "$(ls -A app/src/androidTest)" ] && echo 'true' || echo 'false')" >> $GITHUB_OUTPUT
21 | id: check-androidTest
22 | - name: Get min and target sdk
23 | if: steps.check-androidTest.outputs.NOT_EMPTY == 'true'
24 | id: get-sdk-version
25 | run: |
26 | echo "MIN_SDK_VERSION=$(cat app/build.gradle | grep minSdkVersion | rev | cut -d' ' -f 1 | rev)" >> $GITHUB_OUTPUT
27 | echo "TARGET_SDK_VERSION=$(cat app/build.gradle | grep targetSdkVersion | rev | cut -d' ' -f 1 | rev)" >> $GITHUB_OUTPUT
28 | - name: Get app ID
29 | id: get-app-id
30 | run: |
31 | echo "APP_ID=$(cat app/build.gradle | grep applicationId | rev | cut -d' ' -f 1 | rev | tr -d '"')" >> $GITHUB_OUTPUT
32 |
33 | test:
34 | needs: check-if-tests-exist
35 | if: needs.check-if-tests-exist.outputs.status == 'true'
36 | runs-on: ubuntu-latest
37 | strategy:
38 | matrix:
39 | api-level: [34, "${{ needs.check-if-tests-exist.outputs.min-sdk-version }}", "${{ needs.check-if-tests-exist.outputs.target-sdk-version }}"]
40 | steps:
41 | - name: Checkout
42 | uses: actions/checkout@v3
43 | with:
44 | submodules: 'recursive'
45 |
46 | - name: Enable KVM group perms
47 | run: |
48 | echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
49 | sudo udevadm control --reload-rules
50 | sudo udevadm trigger --name-match=kvm
51 |
52 | - name: Gradle cache
53 | uses: gradle/gradle-build-action@v3
54 |
55 | - name: AVD cache
56 | uses: actions/cache@v4
57 | id: avd-cache
58 | with:
59 | path: |
60 | ~/.android/avd/*
61 | ~/.android/adb*
62 | key: avd-${{ matrix.api-level }}
63 |
64 | - name: Set up JDK environment
65 | uses: actions/setup-java@v3
66 | with:
67 | distribution: 'zulu'
68 | java-version: 21
69 |
70 | - name: create AVD and generate snapshot for caching
71 | if: steps.avd-cache.outputs.cache-hit != 'true'
72 | uses: reactivecircus/android-emulator-runner@v2
73 | with:
74 | api-level: ${{ matrix.api-level }}
75 | target: ${{ matrix.api-level >= 30 && 'google_apis' || 'default' }}
76 | arch: ${{ matrix.api-level < 21 && 'x86' || 'x86_64' }}
77 | force-avd-creation: false
78 | emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
79 | disable-animations: false
80 | script: echo "Generated AVD snapshot for caching."
81 |
82 | - name: Run connected tests
83 | uses: ReactiveCircus/android-emulator-runner@v2
84 | with:
85 | api-level: ${{ matrix.api-level }}
86 | target: ${{ matrix.api-level >= 30 && 'google_apis' || 'default' }}
87 | arch: ${{ matrix.api-level < 21 && 'x86' || 'x86_64' }}
88 | force-avd-creation: false
89 | emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
90 | disable-animations: true
91 | script: |
92 | adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}} || true
93 | adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}}.test || true
94 | adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}}.androidTest || true
95 | chmod +x gradlew
96 | ./gradlew :app:connectedCheck --stacktrace
97 | adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}} || true
98 | adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}}.test || true
99 | adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}}.androidTest || true
100 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_place_ship.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
22 |
23 |
32 |
33 |
41 |
42 |
47 |
48 |
56 |
57 |
65 |
66 |
67 |
68 |
76 |
77 |
82 |
83 |
92 |
93 |
102 |
103 |
104 |
105 |
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/app/src/main/java/org/secuso/privacyfriendlybattleship/ui/GameGridAdapter.kt:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017, Alexander Müller, Ali Kalsen and affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * GameGridAdapter.java is part of Privacy Friendly Battleship.
6 | *
7 | * Privacy Friendly Battleship is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Privacy Friendly Battleship is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Privacy Friendly Battleship. If not, see //www.gnu.org/licenses/>.
19 | */
20 | package org.secuso.privacyfriendlybattleship.ui
21 |
22 | import android.app.Activity
23 | import android.graphics.Color
24 | import android.view.View
25 | import android.view.ViewGroup
26 | import android.widget.AbsListView
27 | import android.widget.BaseAdapter
28 | import android.widget.ImageView
29 | import androidx.core.content.ContextCompat
30 | import org.secuso.privacyfriendlybattleship.R
31 | import org.secuso.privacyfriendlybattleship.game.GameController
32 |
33 | /**
34 | * This class implements an adapter for the grid view in the GameActivity, which changes the color
35 | * of a cell when an action is executed on the grid, e.g clicking on the grid. Created on 27.01.2017.
36 | *
37 | * @author Ali Kalsen
38 | */
39 | class GameGridAdapter : BaseAdapter {
40 | @JvmField
41 | var context: Activity
42 | var game: GameController
43 | private var layoutProvider: GameActivityLayoutProvider
44 | private var gridSize: Int
45 | private var isMainGrid: Boolean // Denotes whether the big or the small grid view is chosen
46 | private var showShips: Boolean
47 |
48 | constructor(
49 | context: Activity,
50 | layout: GameActivityLayoutProvider,
51 | game: GameController,
52 | isMainGrid: Boolean
53 | ) {
54 | this.context = context
55 | this.layoutProvider = layout
56 | this.game = game
57 | this.gridSize = game.gridSize
58 | this.isMainGrid = isMainGrid
59 | this.showShips = false
60 | }
61 |
62 | constructor(
63 | context: Activity,
64 | layout: GameActivityLayoutProvider,
65 | game: GameController,
66 | isMainGrid: Boolean,
67 | showShips: Boolean
68 | ) {
69 | this.context = context
70 | this.layoutProvider = layout
71 | this.game = game
72 | this.gridSize = game.gridSize
73 | this.isMainGrid = isMainGrid
74 | this.showShips = showShips
75 | }
76 |
77 | // Return the number of all grid cells.
78 | override fun getCount(): Int {
79 | return this.gridSize * this.gridSize
80 | }
81 |
82 | override fun getItem(i: Int): Any? {
83 | return null
84 | }
85 |
86 | override fun getItemId(i: Int): Long {
87 | return 0
88 | }
89 |
90 | override fun getView(cellIndex: Int, view: View?, viewGroup: ViewGroup): View {
91 | val gridCell: ImageView
92 | /*
93 | Get the grid cell of the current player. Therefore, get the row and the column of that
94 | grid cell. Note that the GridView enumerates the grid cells from left to right and
95 | from the top to the bottom.
96 | */
97 | val cellColumn = cellIndex % this.gridSize
98 | val cellRow = cellIndex / this.gridSize
99 | val currentCell =
100 | if (showShips) {
101 | game.currentGrid.getCell(cellColumn, cellRow)
102 | } else if ((isMainGrid xor game.currentPlayer)) {
103 | game.gridSecondPlayer.getCell(cellColumn, cellRow)
104 | } else {
105 | game.gridFirstPlayer.getCell(cellColumn, cellRow)
106 | }
107 |
108 | if (view is ImageView) {
109 | gridCell = view
110 | } else {
111 | gridCell = ImageView(this.context)
112 | gridCell.scaleType = ImageView.ScaleType.CENTER_CROP
113 | gridCell.setBackgroundColor(Color.WHITE)
114 | // Set the grid cell of the current player
115 | if (currentCell.isShip && !isMainGrid || currentCell.isShip && showShips) {
116 | gridCell.setImageResource(currentCell.resourceId)
117 | }
118 | }
119 |
120 | // Scale the grid cells by using the GameActivityLayoutProvider
121 | // Note: If grid gets set-up, its size is not available which results in cell size 0.
122 | val cellSize = if (isMainGrid) {
123 | layoutProvider.mainGridCellSizeInPixel
124 | } else {
125 | layoutProvider.miniGridCellSizeInPixel
126 | }
127 | if (null == gridCell.layoutParams || gridCell.layoutParams.width != cellSize) {
128 | gridCell.layoutParams = AbsListView.LayoutParams(cellSize, cellSize)
129 | }
130 |
131 | if (currentCell.isHit) {
132 | if (currentCell.isShip) {
133 | gridCell.setBackgroundColor(ContextCompat.getColor(context, R.color.red))
134 | } else {
135 | gridCell.setBackgroundColor(ContextCompat.getColor(context, R.color.lightblue))
136 | }
137 | }
138 | return gridCell
139 | }
140 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout-land/content_place_ship.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
22 |
23 |
32 |
33 |
39 |
40 |
41 |
49 |
50 |
55 |
56 |
64 |
65 |
73 |
74 |
75 |
76 |
84 |
85 |
86 |
87 |
92 |
93 |
102 |
103 |
106 |
107 |
116 |
117 |
118 |
119 |
130 |
131 |
132 |
133 |
134 |
--------------------------------------------------------------------------------
/app/src/main/java/org/secuso/privacyfriendlybattleship/game/GameCell.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2017 Alexander Müller, Ali Kalsen
3 |
4 | This file is part of Privacy Friendly Battleships.
5 |
6 | Privacy Friendly Battleships is free software: you can redistribute
7 | it and/or modify it under the terms of the GNU General Public License
8 | as published by the Free Software Foundation, either version 3 of the
9 | License, or (at your option) any later version.
10 |
11 | Privacy Friendly Battleships is distributed in the hope that it will
12 | be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13 | of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with Foobar. If not, see http://www.gnu.org/licenses/.
18 | */
19 | package org.secuso.privacyfriendlybattleship.game
20 |
21 | import android.os.Parcel
22 | import android.os.Parcelable
23 | import android.os.Parcelable.Creator
24 | import org.secuso.privacyfriendlybattleship.R
25 | import kotlin.math.abs
26 | import kotlin.math.max
27 |
28 | /**
29 | * This class represents a cell of an battleships grid. A grid of size N
30 | * consists of N*N cells, each of which can be either water or part of a
31 | * ship.
32 | *
33 | * @author Alexander Müller, Ali Kalsen
34 | */
35 | class GameCell : Parcelable {
36 | var col: Int //Column of the Cell
37 | private set
38 | var row: Int //Row of the Cell
39 | private set
40 | @JvmField
41 | var isShip: Boolean = false //false if this cell contains water, true if it contains a ship
42 | var isHit: Boolean = false //false if this cell was not hit yet, true if it was
43 | var grid: GameGrid?
44 |
45 |
46 | constructor(col: Int, row: Int, grid: GameGrid?) {
47 | this.col = col
48 | this.row = row
49 | this.grid = grid
50 | }
51 |
52 | /**
53 | * Returns true if the cells are adjacent to each other or have the same coordinates and false
54 | * if they have at least one cell in between. Cells diagonal to each other are considered
55 | * adjacent.
56 | * @param other Cell to compare to
57 | * @return True if the the given cell is adjacent
58 | */
59 | fun isNextTo(other: GameCell): Boolean {
60 | val distance = max(
61 | abs((this.col - other.col).toDouble()),
62 | abs((this.row - other.row).toDouble())
63 | ).toInt()
64 | if (distance > 1) return false
65 | return true
66 | }
67 |
68 | val resourceId: Int
69 | get() {
70 | if (!this.isShip) {
71 | return 0
72 | }
73 |
74 | val ship =
75 | grid!!.shipSet.findShipContainingCell(this)
76 | when (ship!!.orientation) {
77 | Direction.NORTH -> {
78 | if (this == ship.firstCell) {
79 | //return North-start
80 | return R.drawable.ship_front_up
81 | }
82 | if (this == ship.lastCell) {
83 | //return North-end
84 | return R.drawable.ship_back_up
85 | }
86 | return R.drawable.ship_middle_up
87 | }
88 |
89 | Direction.EAST -> {
90 | if (this == ship.firstCell) {
91 | //return East-start
92 | return R.drawable.ship_front_right
93 | }
94 | if (this == ship.lastCell) {
95 | //return East-end
96 | return R.drawable.ship_back_right
97 | }
98 | return R.drawable.ship_middle_right
99 | }
100 |
101 | Direction.SOUTH -> {
102 | if (this == ship.firstCell) {
103 | //return South-start
104 | return R.drawable.ship_front_down
105 | }
106 | if (this == ship.lastCell) {
107 | //return South-end
108 | return R.drawable.ship_back_down
109 | }
110 | return R.drawable.ship_middle_down
111 | }
112 |
113 | Direction.WEST -> {
114 | if (this == ship.firstCell) {
115 | //return West-start
116 | return R.drawable.ship_front_left
117 | }
118 | if (this == ship.lastCell) {
119 | //return West-end
120 | return R.drawable.ship_back_left
121 | }
122 | return R.drawable.ship_middle_left
123 | }
124 | }
125 | return R.drawable.ic_info_black_24dp
126 | }
127 |
128 | override fun describeContents(): Int {
129 | return 0
130 | }
131 |
132 | override fun writeToParcel(out: Parcel, flags: Int) {
133 | out.writeInt(this.col)
134 | out.writeInt(this.row)
135 | out.writeBooleanArray(booleanArrayOf(this.isShip, this.isHit))
136 | }
137 |
138 | private constructor(parcel: Parcel) {
139 | this.col = parcel.readInt()
140 | this.row = parcel.readInt()
141 | val shipHit = BooleanArray(2)
142 | parcel.readBooleanArray(shipHit)
143 | this.isShip = shipHit[0]
144 | this.isHit = shipHit[1]
145 | this.grid = null
146 | }
147 |
148 | companion object {
149 | @JvmField
150 | val CREATOR: Creator = object : Creator {
151 | override fun createFromParcel(parcel: Parcel): GameCell {
152 | return GameCell(parcel)
153 | }
154 |
155 | override fun newArray(size: Int): Array {
156 | return arrayOfNulls(size)
157 | }
158 | }
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/win_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
17 |
25 |
31 |
37 |
38 |
39 |
49 |
58 |
67 |
74 |
82 |
89 |
96 |
97 |
98 |
102 |
108 |
109 |
110 |
117 |
123 |
129 |
130 |
131 |
132 |
133 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-land/win_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
18 |
26 |
32 |
38 |
39 |
40 |
50 |
59 |
68 |
75 |
83 |
90 |
97 |
98 |
99 |
103 |
109 |
110 |
111 |
118 |
124 |
130 |
131 |
132 |
133 |
134 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-land/content_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
21 |
22 |
31 |
32 |
38 |
39 |
50 |
51 |
62 |
63 |
64 |
68 |
69 |
78 |
79 |
85 |
86 |
97 |
98 |
109 |
110 |
111 |
117 |
118 |
127 |
128 |
137 |
138 |
139 |
140 |
141 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
23 |
24 |
28 |
29 |
35 |
36 |
37 |
38 |
45 |
46 |
52 |
53 |
59 |
60 |
67 |
68 |
69 |
70 |
77 |
78 |
84 |
85 |
90 |
91 |
98 |
99 |
100 |
101 |
102 |
110 |
111 |
117 |
118 |
125 |
126 |
133 |
134 |
141 |
142 |
150 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-land/activity_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
23 |
24 |
28 |
29 |
35 |
36 |
37 |
38 |
45 |
46 |
52 |
53 |
59 |
60 |
67 |
68 |
69 |
70 |
77 |
78 |
84 |
85 |
90 |
91 |
98 |
99 |
100 |
101 |
102 |
110 |
111 |
117 |
118 |
125 |
126 |
133 |
134 |
141 |
142 |
150 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-xlarge/activity_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
23 |
24 |
28 |
29 |
35 |
36 |
37 |
38 |
45 |
46 |
52 |
53 |
59 |
60 |
67 |
68 |
69 |
70 |
77 |
78 |
84 |
85 |
90 |
91 |
98 |
99 |
100 |
101 |
102 |
110 |
111 |
117 |
118 |
125 |
126 |
133 |
134 |
141 |
142 |
150 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-xlarge-land/activity_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
23 |
24 |
28 |
29 |
35 |
36 |
37 |
38 |
45 |
46 |
52 |
53 |
59 |
60 |
67 |
68 |
69 |
70 |
77 |
78 |
84 |
85 |
90 |
91 |
98 |
99 |
100 |
101 |
102 |
110 |
111 |
117 |
118 |
125 |
126 |
133 |
134 |
141 |
142 |
150 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-xlarge/content_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
22 |
23 |
28 |
29 |
39 |
40 |
52 |
53 |
65 |
66 |
67 |
72 |
73 |
83 |
84 |
89 |
90 |
102 |
103 |
115 |
116 |
117 |
126 |
127 |
135 |
136 |
137 |
--------------------------------------------------------------------------------