├── .all-contributorsrc ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── dummy-google-services.json ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── bebetterprogrammer │ │ └── tictactoe │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ └── winner_anim.json │ ├── ic_launcher-playstore.png │ ├── java │ │ └── com │ │ │ └── bebetterprogrammer │ │ │ └── tictactoe │ │ │ ├── activities │ │ │ ├── BaseActivity.kt │ │ │ ├── GamePlayActivity.kt │ │ │ ├── HomePageActivity.kt │ │ │ ├── MusicService.kt │ │ │ ├── PlayWithFriendActivity.kt │ │ │ └── PlayWithJarvisActivity.kt │ │ │ └── utils │ │ │ ├── GamePlayUtility.kt │ │ │ ├── GetPosition.kt │ │ │ └── Result.kt │ └── res │ │ ├── anim │ │ ├── fade_in.xml │ │ ├── result_fade_in.xml │ │ ├── result_fade_out.xml │ │ └── vibrate.xml │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── ic_circle_secondary.xml │ │ ├── ic_circle_white.xml │ │ ├── ic_cross_secondary.xml │ │ ├── ic_cross_white.xml │ │ ├── ic_cross_yellow.xml │ │ ├── ic_game_board.xml │ │ ├── ic_launcher_background.xml │ │ ├── ic_music_off.xml │ │ ├── ic_music_on.xml │ │ ├── ic_rating.xml │ │ ├── ic_setting_secondary.xml │ │ ├── ic_settings.xml │ │ ├── ic_share.xml │ │ ├── ic_trophy_golden.xml │ │ ├── ic_trophy_grey.xml │ │ ├── ic_trophy_lost.xml │ │ ├── ic_trophy_tie.xml │ │ ├── ic_trophy_won.xml │ │ ├── layout_bg.xml │ │ ├── layout_button.xml │ │ ├── layout_dialog.xml │ │ ├── layout_difficulty_button.xml │ │ ├── layout_difficulty_button_secondary.xml │ │ ├── layout_play_button.xml │ │ └── layout_quit_button.xml │ │ ├── font │ │ ├── righteous.ttf │ │ └── snell_round_hand.ttf │ │ ├── layout │ │ ├── activity_gameplay.xml │ │ ├── activity_home_page.xml │ │ ├── activity_play_with_friend.xml │ │ ├── activity_play_with_jarvis.xml │ │ └── result_dialog.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── raw │ │ ├── cartoon_pop_mouth_004.mp3 │ │ ├── cartoon_pop_small_lid.mp3 │ │ ├── game_designed_bubble_pop_03.mp3 │ │ ├── game_sound_double_short_generic_click_pop_002.mp3 │ │ ├── game_sound_double_short_generic_click_pop_003.mp3 │ │ ├── game_sound_single_short_generic_click_pop.mp3 │ │ └── sky_puzzle.mp3 │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── ic_launcher_background.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── bebetterprogrammer │ └── tictactoe │ └── ExampleUnitTest.kt ├── build.gradle ├── design ├── .DS_Store ├── playstore │ ├── Cover.png │ ├── Cover_5x.png │ ├── SS_1.png │ ├── SS_2.png │ ├── SS_3.png │ ├── SS_4.png │ └── SS_5.png ├── v1.0 │ └── plan │ │ ├── 1.Home.png │ │ ├── 10.VsFriendTie.png │ │ ├── 2.VsJarvisSetup.png │ │ ├── 3.VsJarvisPlay.png │ │ ├── 4.VsJarvisWon.png │ │ ├── 5.VsJarvisTie.png │ │ ├── 6.VsJarvisLost.png │ │ ├── 7.VsFriendSetup.png │ │ ├── 8.VsFriendPlay.png │ │ └── 9.VsFriendWon.png └── videos │ └── v1.0.mp4 ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "README.md" 4 | ], 5 | "imageSize": 100, 6 | "commit": false, 7 | "contributors": [ 8 | { 9 | "login": "meetkparmar", 10 | "name": "Meet K Parmar", 11 | "avatar_url": "https://avatars1.githubusercontent.com/u/40732154?v=4", 12 | "profile": "https://www.linkedin.com/in/meetkparmar/", 13 | "contributions": [ 14 | "code", 15 | "bug", 16 | "design" 17 | ] 18 | }, 19 | { 20 | "login": "anandkumarkparmar", 21 | "name": "Anand K Parmar", 22 | "avatar_url": "https://avatars2.githubusercontent.com/u/20661863?v=4", 23 | "profile": "http://linkedin.com/in/anandkparmar", 24 | "contributions": [ 25 | "code", 26 | "projectManagement", 27 | "review", 28 | "design" 29 | ] 30 | }, 31 | { 32 | "login": "all-contributors", 33 | "name": "All Contributors", 34 | "avatar_url": "https://avatars1.githubusercontent.com/u/46410174?v=4", 35 | "profile": "https://allcontributors.org", 36 | "contributions": [ 37 | "doc" 38 | ] 39 | }, 40 | { 41 | "login": "UmangGoti", 42 | "name": "UmangGoti", 43 | "avatar_url": "https://avatars3.githubusercontent.com/u/64679424?v=4", 44 | "profile": "https://github.com/UmangGoti", 45 | "contributions": [ 46 | "code" 47 | ] 48 | }, 49 | { 50 | "login": "HAP28", 51 | "name": "Harshit Parikh", 52 | "avatar_url": "https://avatars2.githubusercontent.com/u/33604059?v=4", 53 | "profile": "https://github.com/HAP28", 54 | "contributions": [ 55 | "code" 56 | ] 57 | } 58 | ], 59 | "contributorsPerLine": 7, 60 | "projectName": "Tic-Tac-Toe", 61 | "projectOwner": "Be-Better-Programmer", 62 | "repoType": "github", 63 | "repoHost": "https://github.com", 64 | "skipCi": true 65 | } 66 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.aar 4 | *.ap_ 5 | *.aab 6 | 7 | # Files for the ART/Dalvik VM 8 | *.dex 9 | 10 | # Java class files 11 | *.class 12 | 13 | # Generated files 14 | bin/ 15 | gen/ 16 | out/ 17 | # Uncomment the following line in case you need and you don't have the release build type files in your app 18 | release/ 19 | 20 | # Gradle files 21 | .gradle/ 22 | build/ 23 | 24 | # Local configuration file (sdk path, etc) 25 | local.properties 26 | 27 | # Proguard folder generated by Eclipse 28 | proguard/ 29 | 30 | # Log Files 31 | *.log 32 | 33 | # Android Studio Navigation editor temp files 34 | .navigation/ 35 | 36 | # Android Studio captures folder 37 | captures/ 38 | 39 | # IntelliJ 40 | *.iml 41 | .idea/workspace.xml 42 | .idea/tasks.xml 43 | .idea/gradle.xml 44 | .idea/assetWizardSettings.xml 45 | .idea/dictionaries 46 | .idea/libraries 47 | # Android Studio 3 in .gitignore file. 48 | .idea/caches 49 | .idea/modules.xml 50 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you 51 | .idea/navEditor.xml 52 | .idea/ 53 | 54 | # Keystore files 55 | # Uncomment the following lines if you do not want to check your keystore files in. 56 | #*.jks 57 | #*.keystore 58 | 59 | # External native build folder generated in Android Studio 2.2 and later 60 | .externalNativeBuild 61 | .cxx/ 62 | 63 | # Google Services (e.g. APIs or Firebase) 64 | app/google-services.json 65 | 66 | # Freeline 67 | freeline.py 68 | freeline/ 69 | freeline_project_description.json 70 | 71 | # fastlane 72 | fastlane/report.xml 73 | fastlane/Preview.html 74 | fastlane/screenshots 75 | fastlane/test_output 76 | fastlane/readme.md 77 | 78 | # Version control 79 | vcs.xml 80 | 81 | # lint 82 | lint/intermediates/ 83 | lint/generated/ 84 | lint/outputs/ 85 | lint/tmp/ 86 | # lint/reports/ 87 | 88 | *.DS_Store -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | jdk: oraclejdk8 3 | sudo: false 4 | dist: trusty 5 | 6 | android: 7 | components: 8 | - tools 9 | - platform-tools 10 | - build-tools-29.0.2 11 | - android-29 12 | 13 | # Extra 14 | - extra-google-google_play_services 15 | - extra-google-m2repository 16 | - extra-android-m2repository 17 | 18 | # Emulator 19 | - sys-img-x86-android-29 20 | 21 | licenses: 22 | - 'android-sdk-preview-license-.+' 23 | - 'android-sdk-license-.+' 24 | - 'google-gdk-license-.+' 25 | 26 | branches: 27 | only: 28 | - master 29 | - develop 30 | 31 | before_install: 32 | - yes | sdkmanager "platforms;android-28" 33 | - chmod +x gradlew 34 | 35 | before_cache: 36 | - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock 37 | - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ 38 | 39 | cache: 40 | directories: 41 | - $HOME/.gradle/caches/ 42 | - $HOME/.gradle/wrapper/ 43 | - $HOME/.android/build-cache 44 | 45 | script: 46 | - mv ./app/dummy-google-services.json ./app/google-services.json 47 | - chmod +x ./gradlew 48 | - ./gradlew ktlintCheck 49 | - ./gradlew assembleDebug assembleRelease 50 | - ./gradlew test 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ![Cover Image](https://github.com/Be-Better-Programmer/Tic-Tac-Toe/blob/develop/design/playstore/Cover_5x.png) 3 | 4 | # Tic-Tac-Toe 5 | [![All Contributors](https://img.shields.io/badge/all_contributors-5-orange.svg?style=flat-square)](#contributors-) 6 | [![ktlint](https://img.shields.io/badge/code%20style-%E2%9D%A4-FF4081.svg)](https://ktlint.github.io/) 7 | [![Join the chat at https://bebetterprogrammer.slack.com/](https://img.shields.io/badge/slack-bebetterprogrammer-blue?logo=slack)](https://bebetterprogrammer.slack.com/) 8 | [![Build Status](https://api.travis-ci.com/Be-Better-Programmer/Tic-Tac-Toe.svg?branch=develop)](https://travis-ci.com/github/Be-Better-Programmer/Tic-Tac-Toe) 9 | 10 | An Interesting and well-known Tic Tac Toe Game with Single And Multi-Player functionality 11 | 12 | ### Features 13 | - Single Player Mode - Play with Jarvis (The Computer) 14 | - Multi Player Mode - Play with Friends 15 | - Jarvis with 3 difficulty levels - Low, Medium and High 16 | 17 | ### Screens 18 | | | | | | | 19 | |:----:|:----:|:----:|:----:|:----:| 20 | | SS_1 | SS_2 | SS_3 | SS_4 | SS_5 | 21 | 22 | ## Contributors ✨ 23 | 24 | Thanks goes to these wonderful people: 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |

Meet K Parmar

💻 🐛 🎨

Anand K Parmar

💻 📆 👀 🎨

All Contributors

📖

UmangGoti

💻

Harshit Parikh

💻
38 | 39 | 40 | 41 | 42 | 43 | Note: This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! Reference - [emoji key](https://allcontributors.org/docs/en/emoji-key) 44 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | apply plugin: 'com.google.gms.google-services' 5 | apply plugin: 'com.google.firebase.crashlytics' 6 | 7 | 8 | android { 9 | compileSdkVersion 29 10 | 11 | defaultConfig { 12 | applicationId "com.bebetterprogrammer.tictactoe" 13 | minSdkVersion 21 14 | targetSdkVersion 29 15 | versionCode 2 16 | versionName "1.1" 17 | 18 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 19 | } 20 | 21 | buildTypes { 22 | debug { 23 | minifyEnabled false 24 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 25 | } 26 | release { 27 | minifyEnabled true 28 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 29 | } 30 | } 31 | } 32 | 33 | dependencies { 34 | implementation fileTree(dir: 'libs', include: ['*.jar']) 35 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 36 | 37 | // androidx 38 | implementation 'androidx.appcompat:appcompat:1.0.2' 39 | implementation 'androidx.core:core-ktx:1.0.2' 40 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 41 | 42 | // unit test 43 | testImplementation 'junit:junit:4.12' 44 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 45 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 46 | 47 | // firebase 48 | implementation 'com.google.firebase:firebase-analytics:17.4.2' 49 | implementation 'com.google.firebase:firebase-crashlytics:17.0.0' 50 | 51 | // animation 52 | implementation "com.airbnb.android:lottie:3.4.0" 53 | } 54 | -------------------------------------------------------------------------------- /app/dummy-google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "", 4 | "firebase_url": "", 5 | "project_id": "", 6 | "storage_bucket": "" 7 | }, 8 | "client": [ 9 | { 10 | "client_info": { 11 | "mobilesdk_app_id": "1:10227262756:android:a7fae8ea9c753722cc3fb1", 12 | "android_client_info": { 13 | "package_name": "com.bebetterprogrammer.tictactoe" 14 | } 15 | }, 16 | "oauth_client": [ 17 | { 18 | "client_id": "", 19 | "client_type": 3 20 | } 21 | ], 22 | "api_key": [ 23 | { 24 | "current_key": "" 25 | } 26 | ], 27 | "services": { 28 | "appinvite_service": { 29 | "other_platform_oauth_client": [ 30 | { 31 | "client_id": "", 32 | "client_type": 3 33 | } 34 | ] 35 | } 36 | } 37 | } 38 | ], 39 | "configuration_version": "1" 40 | } 41 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/bebetterprogrammer/tictactoe/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.bebetterprogrammer.tictactoe 2 | 3 | import androidx.test.ext.junit.runners.AndroidJUnit4 4 | import androidx.test.platform.app.InstrumentationRegistry 5 | import org.junit.Assert.assertEquals 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | /** 10 | * Instrumented test, which will execute on an Android device. 11 | * 12 | * See [testing documentation](http://d.android.com/tools/testing). 13 | */ 14 | @RunWith(AndroidJUnit4::class) 15 | class ExampleInstrumentedTest { 16 | @Test 17 | fun useAppContext() { 18 | // Context of the app under test. 19 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 20 | assertEquals("com.bebetterprogrammer.tictactoe", appContext.packageName) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 14 | 16 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Be-Better-Programmer/Tic-Tac-Toe/356b0900b9bb5a54c336516cbe366ddf0b440dc1/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /app/src/main/java/com/bebetterprogrammer/tictactoe/activities/BaseActivity.kt: -------------------------------------------------------------------------------- 1 | package com.bebetterprogrammer.tictactoe.activities 2 | 3 | import android.content.Intent 4 | import androidx.appcompat.app.AppCompatActivity 5 | 6 | open class BaseActivity : AppCompatActivity() { 7 | 8 | override fun onStart() { 9 | super.onStart() 10 | // startService(Intent(this@BaseActivity, MusicService::class.java)) 11 | } 12 | 13 | override fun onStop() { 14 | super.onStop() 15 | stopService(Intent(this@BaseActivity, MusicService::class.java)) 16 | } 17 | 18 | override fun onDestroy() { 19 | super.onDestroy() 20 | stopService(Intent(this@BaseActivity, MusicService::class.java)) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/bebetterprogrammer/tictactoe/activities/GamePlayActivity.kt: -------------------------------------------------------------------------------- 1 | package com.bebetterprogrammer.tictactoe.activities 2 | 3 | import android.app.AlertDialog 4 | import android.media.MediaPlayer 5 | import android.os.Bundle 6 | import android.os.Handler 7 | import android.view.LayoutInflater 8 | import android.view.View 9 | import android.view.ViewGroup 10 | import android.view.animation.AnimationUtils 11 | import android.widget.ImageView 12 | import com.bebetterprogrammer.tictactoe.BuildConfig 13 | import com.bebetterprogrammer.tictactoe.R 14 | import com.bebetterprogrammer.tictactoe.utils.GamePlayUtility 15 | import com.bebetterprogrammer.tictactoe.utils.GetPosition 16 | import com.bebetterprogrammer.tictactoe.utils.Result 17 | import kotlin.properties.Delegates 18 | import kotlinx.android.synthetic.main.activity_gameplay.* 19 | import kotlinx.android.synthetic.main.result_dialog.view.* 20 | 21 | class GamePlayActivity : BaseActivity() { 22 | var x: Int = 0 23 | var turn: Int = 0 24 | var first: Int = 0 25 | var pl: Int = 0 26 | var fl: Int = 0 27 | var gameState = arrayOf(2, 2, 2, 2, 2, 2, 2, 2, 2) 28 | lateinit var p1: String 29 | lateinit var p2: String 30 | var player by Delegates.notNull() 31 | var vsWhom by Delegates.notNull() 32 | var weapon by Delegates.notNull() 33 | var jarvis by Delegates.notNull() 34 | var whichFirst by Delegates.notNull() 35 | var whichLevel by Delegates.notNull() 36 | var done = 0 37 | var getP = GetPosition() 38 | var flag = false 39 | var played = 0 40 | var mFlag = false 41 | 42 | // 0 = O 1 = X 2 = blank 43 | private val obj = GamePlayUtility() 44 | var list = listOf(0, 1, 2, 3, 4, 5, 6, 7, 8).toMutableList() 45 | var isclicked = 0 46 | 47 | fun playerClick(view: View) { 48 | val img = view as ImageView 49 | val tappedImage = img.tag.toString().toInt() 50 | if (vsWhom == 0) { 51 | if (gameState[tappedImage] == 2 && obj.result != Result.TIE && obj.result != Result.WON) { 52 | gameState[tappedImage] = turn 53 | if (turn == 0) { 54 | tv_turn.text = "$p2's Turn" 55 | img.setImageResource(R.drawable.ic_circle_secondary) 56 | val animFadeIn = 57 | AnimationUtils.loadAnimation(applicationContext, R.anim.fade_in) 58 | img.startAnimation(animFadeIn) 59 | } else if (turn == 1) { 60 | tv_turn.text = "$p1's Turn" 61 | img.setImageResource(R.drawable.ic_cross_yellow) 62 | val animFadeIn = 63 | AnimationUtils.loadAnimation(applicationContext, R.anim.fade_in) 64 | img.startAnimation(animFadeIn) 65 | } 66 | obj.isWin( 67 | gameState, 68 | vsWhom, 69 | turn, 70 | p1_winning, 71 | p2_winning, 72 | -1, 73 | player1_trophy, 74 | player2_trophy 75 | ) 76 | if (obj.result == Result.WON && turn == 1) { 77 | openDialogBox(view, p2) 78 | } else if (obj.result == Result.WON && turn == 0) { 79 | openDialogBox(view, p1) 80 | } else if (obj.result == Result.TIE) { 81 | openDialogBox(view, "That was a Tie!") 82 | } 83 | if (obj.result != Result.TIE && obj.result != Result.WON) { 84 | turn++ 85 | turn %= 2 86 | } 87 | } 88 | } else if (vsWhom == 1 && done % 2 == 1) { 89 | if (gameState[tappedImage] == 2 && obj.result != Result.TIE && obj.result != Result.WON && obj.result != Result.LOST && turn == weapon) { 90 | gameState[tappedImage] = turn 91 | list.remove(tappedImage) 92 | if (turn == weapon) { 93 | tv_turn.text = "Jarvis's Turn" 94 | } else { 95 | tv_turn.text = "Your Turn" 96 | } 97 | if (turn == 0) { 98 | img.setImageResource(R.drawable.ic_circle_secondary) 99 | val animFadeIn = 100 | AnimationUtils.loadAnimation(applicationContext, R.anim.fade_in) 101 | img.startAnimation(animFadeIn) 102 | } else if (turn == 1) { 103 | img.setImageResource(R.drawable.ic_cross_yellow) 104 | val animFadeIn = 105 | AnimationUtils.loadAnimation(applicationContext, R.anim.fade_in) 106 | img.startAnimation(animFadeIn) 107 | } 108 | done++ 109 | obj.isWin( 110 | gameState, 111 | vsWhom, 112 | turn, 113 | p1_winning, 114 | p2_winning, 115 | weapon, 116 | player1_trophy, 117 | player2_trophy 118 | ) 119 | if (obj.result != Result.TIE && obj.result != Result.WON) { 120 | turn++ 121 | turn %= 2 122 | putNew(getRandom()) 123 | } 124 | if (obj.result == Result.WON) { 125 | openDialogBox(view, "YOU") 126 | } else if (obj.result == Result.TIE) { 127 | if (!flag) { 128 | openDialogBox(view, "TIE") 129 | } 130 | } 131 | } 132 | } 133 | } 134 | 135 | private fun getRandom(): ImageView { 136 | val r = getP.getPos(list, whichLevel, gameState, jarvis, weapon) 137 | isclicked = r 138 | val q = listOf(btn1, btn2, btn3, btn4, btn5, btn6, btn7, btn8, btn9) 139 | for (i: ImageView in q) { 140 | if (gameState[isclicked] == 2) { 141 | return q[isclicked] 142 | } 143 | } 144 | return getRandom() 145 | } 146 | 147 | private fun putNew(o: ImageView) { 148 | if (turn == 0) { 149 | Handler().postDelayed({ 150 | tv_turn.text = "Your Turn" 151 | o.setImageResource(R.drawable.ic_circle_secondary) 152 | val animFadeIn = AnimationUtils.loadAnimation(applicationContext, R.anim.fade_in) 153 | o.startAnimation(animFadeIn) 154 | done++ 155 | }, 400) 156 | } else if (turn == 1) { 157 | Handler().postDelayed({ 158 | tv_turn.text = "Your Turn" 159 | o.setImageResource(R.drawable.ic_cross_yellow) 160 | val animFadeIn = AnimationUtils.loadAnimation(applicationContext, R.anim.fade_in) 161 | o.startAnimation(animFadeIn) 162 | done++ 163 | }, 400) 164 | } 165 | gameState[isclicked] = turn 166 | list.remove(isclicked) 167 | obj.isWin( 168 | gameState, 169 | vsWhom, 170 | turn, 171 | p1_winning, 172 | p2_winning, 173 | weapon, 174 | player1_trophy, 175 | player2_trophy 176 | ) 177 | if (obj.result == Result.LOST) { 178 | openDialogBox(o, "JARVIS") 179 | } else if (obj.result == Result.TIE) { 180 | flag = true 181 | openDialogBox(o, "TIE") 182 | } 183 | if (obj.result != Result.TIE && obj.result != Result.WON) { 184 | turn++ 185 | turn %= 2 186 | } 187 | } 188 | 189 | private fun openDialogBox(v: View, playerName: String) { 190 | val builder: AlertDialog.Builder = AlertDialog.Builder(this, R.style.CustomAlertDialog) 191 | val viewGroup = findViewById(android.R.id.content) 192 | val dialogView: View = LayoutInflater.from(v.context).inflate(R.layout.result_dialog, viewGroup, false) 193 | builder.setView(dialogView) 194 | val alertDialog: AlertDialog = builder.create() 195 | if (vsWhom == 0) { 196 | if (obj.result == Result.WON) { 197 | mFlag = true 198 | dialogView.resultTrophy.setImageResource(R.drawable.ic_trophy_won) 199 | dialogView.result.text = "Yeppii.. $playerName Won!" 200 | dialogView.animation_view.visibility = View.VISIBLE 201 | music(mFlag) 202 | } else if (obj.result == Result.TIE) { 203 | mFlag = true 204 | dialogView.resultTrophy.setImageResource(R.drawable.ic_trophy_tie) 205 | dialogView.result.text = playerName 206 | dialogView.animation_view.visibility = View.VISIBLE 207 | music(mFlag) 208 | } 209 | } else if (vsWhom == 1) { 210 | if (obj.result != Result.TIE) { 211 | if (obj.playerWon) { 212 | mFlag = true 213 | dialogView.resultTrophy.setImageResource(R.drawable.ic_trophy_won) 214 | dialogView.result.text = "Yeppii.. You Won!" 215 | dialogView.animation_view.visibility = View.VISIBLE 216 | music(mFlag) 217 | } else if (obj.result == Result.LOST) { 218 | mFlag = true 219 | dialogView.resultTrophy.setImageResource(R.drawable.ic_trophy_lost) 220 | dialogView.result.text = "Ohh... You Lost!" 221 | music(mFlag) 222 | } 223 | } else { 224 | mFlag = true 225 | dialogView.resultTrophy.setImageResource(R.drawable.ic_trophy_tie) 226 | dialogView.result.text = "That was a tie!" 227 | dialogView.animation_view.visibility = View.VISIBLE 228 | music(mFlag) 229 | } 230 | } 231 | alertDialog.setCancelable(false) 232 | 233 | val animFadeIn = AnimationUtils.loadAnimation(applicationContext, R.anim.result_fade_in) 234 | Handler().postDelayed({ 235 | dialogView.startAnimation(animFadeIn) 236 | alertDialog.show() 237 | }, 500) 238 | 239 | dialogView.btnRematch.setOnClickListener { 240 | val animFadeOut = 241 | AnimationUtils.loadAnimation(applicationContext, R.anim.result_fade_out) 242 | dialogView.startAnimation(animFadeOut) 243 | Handler().postDelayed({ 244 | reset() 245 | alertDialog.dismiss() 246 | }, 500) 247 | } 248 | 249 | dialogView.btnQuit.setOnClickListener { 250 | val animFadeOut = 251 | AnimationUtils.loadAnimation(applicationContext, R.anim.result_fade_out) 252 | dialogView.startAnimation(animFadeOut) 253 | Handler().postDelayed({ 254 | finish() 255 | }, 400) 256 | } 257 | } 258 | 259 | private fun music(musicFlag: Boolean) { 260 | var winMusic = MediaPlayer.create(this@GamePlayActivity, R.raw.game_sound_single_short_generic_click_pop) 261 | var lostMusic = MediaPlayer.create(this@GamePlayActivity, R.raw.cartoon_pop_mouth_004) 262 | var tieMusic = MediaPlayer.create(this@GamePlayActivity, R.raw.game_sound_double_short_generic_click_pop_002) 263 | if (musicFlag == true) { 264 | if (obj.result == Result.WON) { 265 | mFlag = false 266 | Handler().postDelayed({ 267 | winMusic.start() 268 | }, 500) 269 | } else if (obj.result == Result.LOST) { 270 | mFlag = false 271 | Handler().postDelayed({ 272 | lostMusic.start() 273 | }, 500) 274 | } else { 275 | mFlag = false 276 | Handler().postDelayed({ 277 | tieMusic.start() 278 | }, 500) 279 | } 280 | } else { 281 | winMusic.stop() 282 | lostMusic.stop() 283 | tieMusic.stop() 284 | } 285 | } 286 | 287 | private fun reset() { 288 | flag = false 289 | for (i in 0..8) { 290 | gameState[i] = 2 291 | } 292 | var q = listOf(btn1, btn2, btn3, btn4, btn5, btn6, btn7, btn8, btn9) 293 | for (i: ImageView in q) { 294 | i.setImageResource(0) 295 | } 296 | player = pl 297 | if (x == 0) { 298 | turn = pl 299 | first = fl 300 | } 301 | obj.playerWon = false 302 | list = listOf(0, 1, 2, 3, 4, 5, 6, 7, 8).toMutableList() 303 | obj.result = null 304 | if (vsWhom == 1) { 305 | if (turn != first && played == 1) { 306 | first = turn 307 | x = 1 308 | } 309 | if (turn == first && played == 0) { 310 | x = 0 311 | first++ 312 | first %= 2 313 | played = 1 314 | } 315 | if (first == turn) { 316 | played = 0 317 | } 318 | if (turn != first) { 319 | done = 0 320 | turn = if (turn == 0) { 321 | 1 322 | } else { 323 | 0 324 | } 325 | putNew(getRandom()) 326 | } else { 327 | done = 1 328 | } 329 | if (turn == weapon) { 330 | tv_turn.text = "Your Turn" 331 | } else { 332 | tv_turn.text = "Jarvis's Turn" 333 | } 334 | } else if (vsWhom == 0) { 335 | if (pl == 0) { 336 | pl = 1 337 | } else { 338 | pl = 0 339 | } 340 | if (player == 0) { 341 | tv_turn.text = "$p1's Turn" 342 | } else if (player == 1) { 343 | tv_turn.text = "$p2's Turn" 344 | } 345 | } 346 | } 347 | 348 | override fun onCreate(savedInstanceState: Bundle?) { 349 | super.onCreate(savedInstanceState) 350 | setContentView(R.layout.activity_gameplay) 351 | val versionName = BuildConfig.VERSION_NAME 352 | appBottomLine.text = "Designed @ bebetterprogrammer.com | v$versionName" 353 | p1 = intent.getStringExtra("Player1") ?: "Player1" 354 | p2 = intent.getStringExtra("Player2") ?: "Player2" 355 | player = intent.getIntExtra("Player", 0) 356 | weapon = intent.getIntExtra("Flag1", 0) 357 | whichFirst = intent.getIntExtra("Flag2", 0) 358 | whichLevel = intent.getIntExtra("Flag", 0) 359 | vsWhom = intent.getIntExtra("vsWhom", 2) 360 | if (vsWhom == 0) { // Vs Friend 361 | Player1.text = p1 // First Player Name 362 | Player2.text = p2 // Second Player Name 363 | if (player == 0) { 364 | tv_turn.text = "$p1's Turn" 365 | turn = 0 366 | pl = 1 367 | } else if (player == 1) { 368 | tv_turn.text = "$p2's Turn" 369 | turn = 1 370 | pl = 0 371 | } 372 | } else if (vsWhom == 1) { // Vs Jarvis 373 | played++ 374 | Player1.text = "YOU" 375 | Player2.text = "JARVIS" 376 | if (whichLevel == 0 || whichLevel == 1 || whichLevel == 2) { 377 | if (whichFirst == 0) { 378 | first = 0 // O 379 | fl = 0 380 | } else if (whichFirst == 1) { 381 | first = 1 // X 382 | fl = 1 383 | } 384 | if ((whichFirst == 0 && weapon == 0) || (whichFirst == 1 && weapon == 1)) { 385 | tv_turn.text = "Your Turn" 386 | } else { 387 | tv_turn.text = "Jarvis's Turn" 388 | } 389 | if (weapon == 0) { 390 | turn = 0 // your O 391 | pl = 0 392 | jarvis = 1 393 | done = 1 394 | } else if (weapon == 1) { 395 | turn = 1 // your X 396 | pl = 1 397 | jarvis = 0 398 | done = 1 399 | } 400 | if (turn != first) { 401 | played = 1 402 | done = 0 403 | turn = if (turn == 0) { 404 | 1 405 | } else { 406 | 0 407 | } 408 | putNew(getRandom()) 409 | } else { 410 | played = 0 411 | } 412 | } 413 | } 414 | btnQuit.setOnClickListener { 415 | finish() 416 | } 417 | } 418 | } 419 | -------------------------------------------------------------------------------- /app/src/main/java/com/bebetterprogrammer/tictactoe/activities/HomePageActivity.kt: -------------------------------------------------------------------------------- 1 | package com.bebetterprogrammer.tictactoe.activities 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.content.SharedPreferences 6 | import android.net.Uri 7 | import android.os.Bundle 8 | import androidx.core.view.isVisible 9 | import com.bebetterprogrammer.tictactoe.BuildConfig 10 | import com.bebetterprogrammer.tictactoe.R 11 | import kotlinx.android.synthetic.main.activity_home_page.* 12 | 13 | class HomePageActivity : BaseActivity() { 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | super.onCreate(savedInstanceState) 16 | setContentView(R.layout.activity_home_page) 17 | 18 | val versionName = BuildConfig.VERSION_NAME 19 | appBottomLine.text = "Designed @ bebetterprogrammer.com | v$versionName" 20 | 21 | var musicPref: SharedPreferences = this.getSharedPreferences("Music", Context.MODE_PRIVATE) 22 | var pref = musicPref.getInt("Pref", 1) 23 | var editor: SharedPreferences.Editor = musicPref.edit() 24 | 25 | if (pref == 0) { 26 | musicOnbtn.isVisible = true 27 | musicOffbtn.isVisible = false 28 | startService(Intent(this, MusicService::class.java)) 29 | } else { 30 | musicOnbtn.isVisible = false 31 | musicOffbtn.isVisible = true 32 | stopService(Intent(this, MusicService::class.java)) 33 | } 34 | 35 | playWithJarvis.setOnClickListener { 36 | val intent = Intent(this, PlayWithJarvisActivity::class.java) 37 | startActivity(intent) 38 | } 39 | playWithFriend.setOnClickListener { 40 | val intent = Intent(this, PlayWithFriendActivity::class.java) 41 | startActivity(intent) 42 | } 43 | shareBtn.setOnClickListener { 44 | val shareIntent = Intent() 45 | shareIntent.action = Intent.ACTION_SEND 46 | shareIntent.putExtra( 47 | Intent.EXTRA_TEXT, 48 | "https://play.google.com/store/apps/details?id=com.bebetterprogrammer.tictactoe" 49 | ) 50 | shareIntent.type = "text/plain" 51 | startActivity(Intent.createChooser(shareIntent, "Share via")) 52 | } 53 | ratingBtn.setOnClickListener { 54 | val uri = Uri.parse("https://play.google.com/store/apps/details?id=com.bebetterprogrammer.tictactoe") 55 | val rateIntent = Intent(Intent.ACTION_VIEW, uri) 56 | startActivity(rateIntent) 57 | } 58 | musicOffbtn.setOnClickListener { 59 | musicOnbtn.isVisible = true 60 | musicOffbtn.isVisible = false 61 | editor.putInt("Pref", 0) 62 | editor.commit() 63 | startService(Intent(this, MusicService::class.java)) 64 | } 65 | musicOnbtn.setOnClickListener { 66 | musicOnbtn.isVisible = false 67 | musicOffbtn.isVisible = true 68 | editor.putInt("Pref", 1) 69 | editor.commit() 70 | stopService(Intent(this, MusicService::class.java)) 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /app/src/main/java/com/bebetterprogrammer/tictactoe/activities/MusicService.kt: -------------------------------------------------------------------------------- 1 | package com.bebetterprogrammer.tictactoe.activities 2 | 3 | import android.app.Service 4 | import android.content.Intent 5 | import android.media.MediaPlayer 6 | import android.os.IBinder 7 | import com.bebetterprogrammer.tictactoe.R 8 | 9 | class MusicService : Service() { 10 | protected lateinit var music: MediaPlayer 11 | override fun onBind(intent: Intent?): IBinder? { 12 | return null 13 | } 14 | 15 | override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { 16 | music = MediaPlayer.create(this, R.raw.sky_puzzle) 17 | music.isLooping = true 18 | music.setVolume(90.0f, 90.0f) 19 | music.start() 20 | return START_STICKY 21 | } 22 | 23 | override fun onDestroy() { 24 | music.stop() 25 | music.release() 26 | super.onDestroy() 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/bebetterprogrammer/tictactoe/activities/PlayWithFriendActivity.kt: -------------------------------------------------------------------------------- 1 | package com.bebetterprogrammer.tictactoe.activities 2 | 3 | import android.content.Intent 4 | import android.os.Bundle 5 | import android.text.TextUtils 6 | import android.view.View 7 | import android.widget.Toast 8 | import com.bebetterprogrammer.tictactoe.BuildConfig 9 | import com.bebetterprogrammer.tictactoe.R 10 | import kotlinx.android.synthetic.main.activity_play_with_friend.* 11 | 12 | class PlayWithFriendActivity : BaseActivity() { 13 | 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | super.onCreate(savedInstanceState) 16 | setContentView(R.layout.activity_play_with_friend) 17 | 18 | val versionName = BuildConfig.VERSION_NAME 19 | appBottomLine.text = "Designed @ bebetterprogrammer.com | v$versionName" 20 | 21 | var flag: Int = 0 22 | 23 | circle.setImageResource(R.drawable.ic_circle_secondary) 24 | 25 | circle.setOnClickListener(View.OnClickListener { 26 | cross.setImageResource(R.drawable.ic_cross_white) 27 | circle.setImageResource(R.drawable.ic_circle_secondary) 28 | flag = 0 29 | }) 30 | 31 | cross.setOnClickListener(View.OnClickListener { 32 | circle.setImageResource(R.drawable.ic_circle_white) 33 | cross.setImageResource(R.drawable.ic_cross_secondary) 34 | flag = 1 35 | }) 36 | 37 | btnPlay.setOnClickListener(View.OnClickListener { 38 | if (TextUtils.isEmpty(player_one.text) || TextUtils.isEmpty(player_two.text)) { 39 | if (TextUtils.isEmpty(player_one.text) && TextUtils.isEmpty(player_two.text)) { 40 | Toast.makeText(this, "Enter Player Name", Toast.LENGTH_SHORT).show() 41 | } else if (TextUtils.isEmpty(player_one.text)) { 42 | Toast.makeText(this, "Enter Player_1 Name", Toast.LENGTH_SHORT).show() 43 | } else { 44 | Toast.makeText(this, "Enter Player_2 Name", Toast.LENGTH_SHORT).show() 45 | } 46 | } else { 47 | val intent = Intent(this, GamePlayActivity::class.java) 48 | intent.putExtra("Player1", player_one.text.toString()) 49 | intent.putExtra("Player2", player_two.text.toString()) 50 | intent.putExtra("vsWhom", 0) // Vs Friend 51 | if (flag == 0) { 52 | intent.putExtra("Player", 0) // O will move first 53 | } else if (flag == 1) { 54 | intent.putExtra("Player", 1) // X will move first 55 | } 56 | startActivity(intent) 57 | finish() 58 | } 59 | }) 60 | btnQuit.setOnClickListener(View.OnClickListener { 61 | finish() 62 | }) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/com/bebetterprogrammer/tictactoe/activities/PlayWithJarvisActivity.kt: -------------------------------------------------------------------------------- 1 | package com.bebetterprogrammer.tictactoe.activities 2 | 3 | import android.content.Intent 4 | import android.os.Bundle 5 | import android.view.View 6 | import com.bebetterprogrammer.tictactoe.BuildConfig 7 | import com.bebetterprogrammer.tictactoe.R 8 | import kotlinx.android.synthetic.main.activity_play_with_jarvis.* 9 | 10 | class PlayWithJarvisActivity : BaseActivity() { 11 | 12 | override fun onCreate(savedInstanceState: Bundle?) { 13 | super.onCreate(savedInstanceState) 14 | setContentView(R.layout.activity_play_with_jarvis) 15 | 16 | val versionName = BuildConfig.VERSION_NAME 17 | appBottomLine.text = "Designed @ bebetterprogrammer.com | v$versionName" 18 | 19 | var flag: Int = 0 20 | var flag1: Int = 0 21 | var flag2: Int = 0 22 | 23 | diff_low.setBackgroundResource(R.drawable.layout_difficulty_button_secondary) 24 | weapon_circle.setImageResource(R.drawable.ic_circle_secondary) 25 | circle_move.setImageResource(R.drawable.ic_circle_secondary) 26 | 27 | diff_low.setOnClickListener(View.OnClickListener { 28 | diff_low.setBackgroundResource(R.drawable.layout_difficulty_button_secondary) 29 | diff_medium.setBackgroundResource(R.drawable.layout_difficulty_button) 30 | diff_high.setBackgroundResource(R.drawable.layout_difficulty_button) 31 | flag = 0 32 | }) 33 | diff_medium.setOnClickListener(View.OnClickListener { 34 | diff_low.setBackgroundResource(R.drawable.layout_difficulty_button) 35 | diff_medium.setBackgroundResource(R.drawable.layout_difficulty_button_secondary) 36 | diff_high.setBackgroundResource(R.drawable.layout_difficulty_button) 37 | flag = 1 38 | }) 39 | diff_high.setOnClickListener(View.OnClickListener { 40 | diff_low.setBackgroundResource(R.drawable.layout_difficulty_button) 41 | diff_medium.setBackgroundResource(R.drawable.layout_difficulty_button) 42 | diff_high.setBackgroundResource(R.drawable.layout_difficulty_button_secondary) 43 | flag = 2 44 | }) 45 | 46 | weapon_circle.setOnClickListener(View.OnClickListener { 47 | weapon_circle.setImageResource(R.drawable.ic_circle_secondary) 48 | weapon_cross.setImageResource(R.drawable.ic_cross_white) 49 | flag1 = 0 50 | }) 51 | weapon_cross.setOnClickListener(View.OnClickListener { 52 | weapon_circle.setImageResource(R.drawable.ic_circle_white) 53 | weapon_cross.setImageResource(R.drawable.ic_cross_secondary) 54 | flag1 = 1 55 | }) 56 | circle_move.setOnClickListener(View.OnClickListener { 57 | circle_move.setImageResource(R.drawable.ic_circle_secondary) 58 | cross_move.setImageResource(R.drawable.ic_cross_white) 59 | flag2 = 0 60 | }) 61 | cross_move.setOnClickListener(View.OnClickListener { 62 | circle_move.setImageResource(R.drawable.ic_circle_white) 63 | cross_move.setImageResource(R.drawable.ic_cross_secondary) 64 | flag2 = 1 65 | }) 66 | 67 | btnPlay.setOnClickListener(View.OnClickListener { 68 | moveFirst(flag, flag1, flag2) 69 | }) 70 | btnQuit.setOnClickListener(View.OnClickListener { 71 | finish() 72 | }) 73 | } 74 | 75 | private fun moveFirst(flag: Int, flag1: Int, flag2: Int) { 76 | val intent = Intent(this, GamePlayActivity::class.java) 77 | intent.putExtra("Flag", flag) // flag for difficulty level 78 | intent.putExtra("Flag1", flag1) // Player Weapon 79 | intent.putExtra("Flag2", flag2) // Who will move first 80 | intent.putExtra("vsWhom", 1) // Vs Jarvis 81 | startActivity(intent) 82 | finish() 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /app/src/main/java/com/bebetterprogrammer/tictactoe/utils/GamePlayUtility.kt: -------------------------------------------------------------------------------- 1 | package com.bebetterprogrammer.tictactoe.utils 2 | 3 | import android.view.animation.AnimationUtils 4 | import android.widget.ImageView 5 | import android.widget.TextView 6 | import com.bebetterprogrammer.tictactoe.R 7 | 8 | class GamePlayUtility { 9 | var winPosition = arrayOf( 10 | arrayOf(0, 1, 2), arrayOf(3, 4, 5), arrayOf(6, 7, 8), arrayOf(0, 3, 6), 11 | arrayOf(1, 4, 7), arrayOf(2, 5, 8), arrayOf(0, 4, 8), arrayOf(2, 4, 6) 12 | ) 13 | var p1 = 0 14 | var p2 = 0 15 | var playerWon = false 16 | var result: Result? = null 17 | fun isWin( 18 | gameState: Array, 19 | vsWhom: Int, 20 | turn: Int, 21 | p1_winning: TextView, 22 | p2_winning: TextView, 23 | weapon: Int, 24 | player1_trophy: ImageView, 25 | player2_trophy: ImageView 26 | ) { 27 | for (winPosition in winPosition) { 28 | if (gameState[winPosition[0]] == gameState[winPosition[1]] && gameState[winPosition[1]] == gameState[winPosition[2]] && gameState[winPosition[0]] != 2) { 29 | if (vsWhom == 0) { // Vs Friend 30 | if (turn == 0) { 31 | result = Result.WON 32 | p1 = p1_winning.text.toString().toInt() 33 | p1++ 34 | p1_winning.text = p1.toString() 35 | } else { 36 | result = Result.WON 37 | p2 = p2_winning.text.toString().toInt() 38 | p2++ 39 | p2_winning.text = p2.toString() 40 | } 41 | } else if (vsWhom == 1) { // Vs Jarvis 42 | if (turn == weapon) { 43 | result = Result.WON 44 | playerWon = true 45 | p1 = p1_winning.text.toString().toInt() 46 | p1++ 47 | p1_winning.text = p1.toString() 48 | } else { 49 | result = Result.LOST 50 | p2 = p2_winning.text.toString().toInt() 51 | p2++ 52 | p2_winning.text = p2.toString() 53 | } 54 | } 55 | when { 56 | p1 > p2 -> { 57 | player1_trophy.setImageResource(R.drawable.ic_trophy_golden) 58 | val animFadeIn = 59 | AnimationUtils.loadAnimation(player1_trophy.context, R.anim.vibrate) 60 | player1_trophy.startAnimation(animFadeIn) 61 | player2_trophy.setImageResource(R.drawable.ic_trophy_grey) 62 | } 63 | p2 > p1 -> { 64 | player2_trophy.setImageResource(R.drawable.ic_trophy_golden) 65 | val animFadeIn = 66 | AnimationUtils.loadAnimation(player2_trophy.context, R.anim.vibrate) 67 | player2_trophy.startAnimation(animFadeIn) 68 | player1_trophy.setImageResource(R.drawable.ic_trophy_grey) 69 | } 70 | else -> { 71 | player2_trophy.setImageResource(R.drawable.ic_trophy_grey) 72 | player1_trophy.setImageResource(R.drawable.ic_trophy_grey) 73 | } 74 | } 75 | } 76 | } 77 | for (i in 0..8) { 78 | if (gameState[i] != 2 && (result != Result.WON && result != Result.LOST)) { 79 | result = Result.TIE 80 | } else { 81 | if (result != Result.LOST && result != Result.WON) { 82 | result = null 83 | break 84 | } 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /app/src/main/java/com/bebetterprogrammer/tictactoe/utils/GetPosition.kt: -------------------------------------------------------------------------------- 1 | package com.bebetterprogrammer.tictactoe.utils 2 | 3 | import kotlin.random.Random 4 | import kotlin.random.nextInt 5 | 6 | class GetPosition { 7 | private fun jarvisWin( 8 | list: List, 9 | gameState: Array, 10 | jarvis: Int 11 | ): Int { 12 | var r: Int 13 | if (!list.contains(0) && !list.contains(1) && list.contains(2) && (gameState[0] == jarvis && gameState[1] == jarvis)) { 14 | r = 2 15 | } else if (!list.contains(5) && !list.contains(8) && list.contains(2) && (gameState[5] == jarvis && gameState[8] == jarvis)) { 16 | r = 2 17 | } else if (!list.contains(4) && !list.contains(6) && list.contains(2) && (gameState[4] == jarvis && gameState[6] == jarvis)) { 18 | r = 2 19 | } else if (!list.contains(1) && !list.contains(2) && list.contains(0) && (gameState[1] == jarvis && gameState[2] == jarvis)) { 20 | r = 0 21 | } else if (!list.contains(3) && !list.contains(6) && list.contains(0) && (gameState[3] == jarvis && gameState[6] == jarvis)) { 22 | r = 0 23 | } else if (!list.contains(4) && !list.contains(8) && list.contains(0) && (gameState[4] == jarvis && gameState[8] == jarvis)) { 24 | r = 0 25 | } else if (!list.contains(0) && !list.contains(2) && list.contains(1) && (gameState[0] == jarvis && gameState[2] == jarvis)) { 26 | r = 1 27 | } else if (!list.contains(4) && !list.contains(7) && list.contains(1) && (gameState[4] == jarvis && gameState[7] == jarvis)) { 28 | r = 1 29 | } else if (!list.contains(3) && !list.contains(4) && list.contains(5) && (gameState[3] == jarvis && gameState[4] == jarvis)) { 30 | r = 5 31 | } else if (!list.contains(2) && !list.contains(8) && list.contains(5) && (gameState[2] == jarvis && gameState[8] == jarvis)) { 32 | r = 5 33 | } else if (!list.contains(4) && !list.contains(5) && list.contains(3) && (gameState[4] == jarvis && gameState[5] == jarvis)) { 34 | r = 3 35 | } else if (!list.contains(0) && !list.contains(6) && list.contains(3) && (gameState[0] == jarvis && gameState[6] == jarvis)) { 36 | r = 3 37 | } else if (!list.contains(3) && !list.contains(5) && list.contains(4) && (gameState[3] == jarvis && gameState[5] == jarvis)) { 38 | r = 4 39 | } else if (!list.contains(1) && !list.contains(7) && list.contains(4) && (gameState[1] == jarvis && gameState[7] == jarvis)) { 40 | r = 4 41 | } else if (!list.contains(0) && !list.contains(8) && list.contains(4) && (gameState[0] == jarvis && gameState[8] == jarvis)) { 42 | r = 4 43 | } else if (!list.contains(2) && !list.contains(6) && list.contains(4) && (gameState[2] == jarvis && gameState[6] == jarvis)) { 44 | r = 4 45 | } else if (!list.contains(6) && !list.contains(7) && list.contains(8) && (gameState[6] == jarvis && gameState[7] == jarvis)) { 46 | r = 8 47 | } else if (!list.contains(2) && !list.contains(5) && list.contains(8) && (gameState[2] == jarvis && gameState[5] == jarvis)) { 48 | r = 8 49 | } else if (!list.contains(7) && !list.contains(8) && list.contains(6) && (gameState[7] == jarvis && gameState[8] == jarvis)) { 50 | r = 6 51 | } else if (!list.contains(0) && !list.contains(3) && list.contains(6) && (gameState[0] == jarvis && gameState[3] == jarvis)) { 52 | r = 6 53 | } else if (!list.contains(2) && !list.contains(4) && list.contains(6) && (gameState[2] == jarvis && gameState[4] == jarvis)) { 54 | r = 6 55 | } else if (!list.contains(6) && !list.contains(8) && list.contains(7) && (gameState[6] == jarvis && gameState[8] == jarvis)) { 56 | r = 7 57 | } else if (!list.contains(1) && !list.contains(4) && list.contains(7) && (gameState[1] == jarvis && gameState[4] == jarvis)) { 58 | r = 7 59 | } else if (!list.contains(0) && !list.contains(4) && list.contains(8) && (gameState[0] == jarvis && gameState[4] == jarvis)) { 60 | r = 8 61 | } else { 62 | r = -1 63 | } 64 | return r 65 | } 66 | 67 | private fun breakPlayer( 68 | list: List, 69 | gameState: Array, 70 | weapon: Int 71 | ): Int { 72 | var r: Int 73 | if (!list.contains(0) && !list.contains(1) && list.contains(2) && (gameState[0] == weapon && gameState[1] == weapon)) { 74 | r = 2 75 | } else if (!list.contains(5) && !list.contains(8) && list.contains(2) && (gameState[5] == weapon && gameState[8] == weapon)) { 76 | r = 2 77 | } else if (!list.contains(4) && !list.contains(6) && list.contains(2) && (gameState[4] == weapon && gameState[6] == weapon)) { 78 | r = 2 79 | } else if (!list.contains(1) && !list.contains(2) && list.contains(0) && (gameState[1] == weapon && gameState[2] == weapon)) { 80 | r = 0 81 | } else if (!list.contains(3) && !list.contains(6) && list.contains(0) && (gameState[3] == weapon && gameState[6] == weapon)) { 82 | r = 0 83 | } else if (!list.contains(4) && !list.contains(8) && list.contains(0) && (gameState[4] == weapon && gameState[8] == weapon)) { 84 | r = 0 85 | } else if (!list.contains(0) && !list.contains(2) && list.contains(1) && (gameState[0] == weapon && gameState[2] == weapon)) { 86 | r = 1 87 | } else if (!list.contains(4) && !list.contains(7) && list.contains(1) && (gameState[4] == weapon && gameState[7] == weapon)) { 88 | r = 1 89 | } else if (!list.contains(3) && !list.contains(4) && list.contains(5) && (gameState[3] == weapon && gameState[4] == weapon)) { 90 | r = 5 91 | } else if (!list.contains(2) && !list.contains(8) && list.contains(5) && (gameState[2] == weapon && gameState[8] == weapon)) { 92 | r = 5 93 | } else if (!list.contains(4) && !list.contains(5) && list.contains(3) && (gameState[4] == weapon && gameState[5] == weapon)) { 94 | r = 3 95 | } else if (!list.contains(0) && !list.contains(6) && list.contains(3) && (gameState[0] == weapon && gameState[6] == weapon)) { 96 | r = 3 97 | } else if (!list.contains(3) && !list.contains(5) && list.contains(4) && (gameState[3] == weapon && gameState[5] == weapon)) { 98 | r = 4 99 | } else if (!list.contains(1) && !list.contains(7) && list.contains(4) && (gameState[1] == weapon && gameState[7] == weapon)) { 100 | r = 4 101 | } else if (!list.contains(0) && !list.contains(8) && list.contains(4) && (gameState[0] == weapon && gameState[8] == weapon)) { 102 | r = 4 103 | } else if (!list.contains(2) && !list.contains(6) && list.contains(4) && (gameState[2] == weapon && gameState[6] == weapon)) { 104 | r = 4 105 | } else if (!list.contains(6) && !list.contains(7) && list.contains(8) && (gameState[6] == weapon && gameState[7] == weapon)) { 106 | r = 8 107 | } else if (!list.contains(2) && !list.contains(5) && list.contains(8) && (gameState[2] == weapon && gameState[5] == weapon)) { 108 | r = 8 109 | } else if (!list.contains(7) && !list.contains(8) && list.contains(6) && (gameState[7] == weapon && gameState[8] == weapon)) { 110 | r = 6 111 | } else if (!list.contains(0) && !list.contains(3) && list.contains(6) && (gameState[0] == weapon && gameState[3] == weapon)) { 112 | r = 6 113 | } else if (!list.contains(2) && !list.contains(4) && list.contains(6) && (gameState[2] == weapon && gameState[4] == weapon)) { 114 | r = 6 115 | } else if (!list.contains(6) && !list.contains(8) && list.contains(7) && (gameState[6] == weapon && gameState[8] == weapon)) { 116 | r = 7 117 | } else if (!list.contains(1) && !list.contains(4) && list.contains(7) && (gameState[1] == weapon && gameState[4] == weapon)) { 118 | r = 7 119 | } else if (!list.contains(0) && !list.contains(4) && list.contains(8) && (gameState[0] == weapon && gameState[4] == weapon)) { 120 | r = 8 121 | } else { 122 | r = -1 123 | } 124 | return r 125 | } 126 | 127 | fun getPos( 128 | list: List, 129 | whichLevel: Int, 130 | gameState: Array, 131 | jarvis: Int, 132 | weapon: Int 133 | ): Int { 134 | var r: Int 135 | when (whichLevel) { 136 | 0 -> { 137 | r = jarvisWin(list, gameState, jarvis) 138 | if (r == -1) { 139 | r = breakPlayer(list, gameState, weapon) 140 | if (r == -1) { 141 | r = list[Random.nextInt(0..list.size - 1)] 142 | } 143 | } 144 | return r 145 | } 146 | 1 -> { 147 | r = jarvisWin(list, gameState, jarvis) 148 | if (r == -1) { 149 | r = breakPlayer(list, gameState, weapon) 150 | if (r == -1) { 151 | if (!list.containsAll( 152 | listOf( 153 | 8, 154 | 4 155 | ) 156 | ) && gameState[8] == weapon && gameState[4] == weapon && (list.contains( 157 | 6 158 | ) || list.contains(2)) 159 | ) { 160 | if (list.containsAll(listOf(2, 6))) { 161 | r = listOf(2, 6).random() 162 | } else if (list.containsAll(listOf(3, 6))) { 163 | r = 6 164 | } else if (list.containsAll(listOf(2, 1))) { 165 | r = 2 166 | } 167 | } else if (!list.containsAll( 168 | listOf( 169 | 6, 170 | 4 171 | ) 172 | ) && gameState[6] == weapon && gameState[4] == weapon && (list.contains( 173 | 0 174 | ) || list.contains(8)) 175 | ) { 176 | if (list.containsAll(listOf(0, 8))) { 177 | r = listOf(0, 8).random() 178 | } else if (list.containsAll(listOf(0, 1))) { 179 | r = 0 180 | } else if (list.containsAll(listOf(8, 5))) { 181 | r = 8 182 | } 183 | } else if (!list.containsAll( 184 | listOf( 185 | 0, 186 | 4 187 | ) 188 | ) && gameState[0] == weapon && gameState[4] == weapon && (list.contains( 189 | 6 190 | ) || list.contains(2)) 191 | ) { 192 | if (list.containsAll(listOf(2, 6))) { 193 | r = listOf(2, 6).random() 194 | } else if (list.containsAll(listOf(6, 3))) { 195 | r = 6 196 | } else if (list.containsAll(listOf(2, 1))) { 197 | r = 2 198 | } 199 | } else if (!list.containsAll( 200 | listOf( 201 | 2, 202 | 4 203 | ) 204 | ) && gameState[2] == weapon && gameState[4] == weapon && (list.contains( 205 | 0 206 | ) || list.contains(8)) 207 | ) { 208 | if (list.containsAll(listOf(0, 8))) { 209 | r = listOf(0, 8).random() 210 | } else if (list.containsAll(listOf(0, 1))) { 211 | r = 0 212 | } else if (list.containsAll(listOf(8, 5))) { 213 | r = 8 214 | } 215 | } else { 216 | r = list[Random.nextInt(0..list.size - 1)] 217 | } 218 | } 219 | } 220 | if (r == -1) { 221 | r = list[Random.nextInt(0..list.size - 1)] 222 | } 223 | return r 224 | } 225 | 2 -> { 226 | r = jarvisWin(list, gameState, jarvis) 227 | if (r == -1) { 228 | r = breakPlayer(list, gameState, weapon) 229 | if (r == -1) { 230 | if ((!list.contains(0) && gameState[0] == weapon && list.containsAll( 231 | listOf( 232 | 2, 233 | 4, 234 | 6, 235 | 8 236 | ) 237 | )) || (!list.contains(2) && gameState[2] == weapon && list.containsAll( 238 | listOf( 239 | 0, 240 | 4, 241 | 6, 242 | 8 243 | ) 244 | )) || (!list.contains( 245 | 6 246 | ) && gameState[6] == weapon && list.containsAll( 247 | listOf( 248 | 2, 249 | 4, 250 | 0, 251 | 8 252 | ) 253 | )) || (!list.contains(8) && gameState[8] == weapon && list.containsAll( 254 | listOf( 255 | 2, 256 | 4, 257 | 6, 258 | 0 259 | ) 260 | )) || (!list.contains(1) && gameState[1] == weapon && list.containsAll( 261 | listOf( 262 | 3, 263 | 4, 264 | 5, 265 | 7 266 | ) 267 | )) || (!list.contains(3) && gameState[3] == weapon && list.containsAll( 268 | listOf( 269 | 1, 270 | 4, 271 | 5, 272 | 7 273 | ) 274 | )) || (!list.contains(5) && gameState[5] == weapon && list.containsAll( 275 | listOf( 276 | 3, 277 | 4, 278 | 1, 279 | 7 280 | ) 281 | )) || (!list.contains(7) && gameState[7] == weapon && list.containsAll( 282 | listOf( 283 | 3, 284 | 4, 285 | 5, 286 | 1 287 | ) 288 | )) 289 | ) { 290 | r = 4 291 | } else if ((!list.contains(4) && gameState[4] == weapon && list.containsAll( 292 | listOf( 293 | 0, 294 | 2, 295 | 6, 296 | 8 297 | ) 298 | )) 299 | ) { 300 | r = listOf(0, 2, 6, 8).random() 301 | } else if (((!list.containsAll( 302 | listOf( 303 | 2, 304 | 6 305 | ) 306 | ) && gameState[2] == weapon && gameState[6] == weapon) || (!list.containsAll( 307 | listOf(0, 8) 308 | ) && gameState[0] == weapon && gameState[8] == weapon)) && list.containsAll( 309 | listOf( 310 | 3, 311 | 5 312 | ) 313 | ) 314 | ) { 315 | r = listOf(3, 5).random() 316 | } else if (!list.containsAll( 317 | listOf( 318 | 1, 319 | 3 320 | ) 321 | ) && gameState[1] == weapon && gameState[3] == weapon && list.contains(0) 322 | ) { 323 | r = 0 324 | } else if (!list.containsAll( 325 | listOf(5, 7) 326 | ) && gameState[5] == weapon && gameState[7] == weapon && list.contains(8) 327 | ) { 328 | r = 8 329 | } else if (!list.containsAll( 330 | listOf( 331 | 7, 332 | 3 333 | ) 334 | ) && gameState[7] == weapon && gameState[3] == weapon && list.contains(6) 335 | ) { 336 | r = 6 337 | } else if (!list.containsAll( 338 | listOf( 339 | 1, 340 | 5 341 | ) 342 | ) && gameState[5] == jarvis && gameState[1] == jarvis && list.contains(2) 343 | ) { 344 | r = 2 345 | } // new code 346 | else if (!list.containsAll( 347 | listOf( 348 | 0, 349 | 4 350 | ) 351 | ) && gameState[0] == jarvis && gameState[4] == jarvis && list.containsAll( 352 | listOf(1, 2) 353 | ) 354 | ) { 355 | if (list.contains(6)) { 356 | r = 2 357 | } else if (list.contains(7)) { 358 | r = 1 359 | } 360 | } else if (!list.containsAll( 361 | listOf( 362 | 0, 363 | 4 364 | ) 365 | ) && gameState[0] == jarvis && gameState[4] == jarvis && list.containsAll( 366 | listOf(3, 6) 367 | ) 368 | ) { 369 | if (list.contains(2)) { 370 | r = 6 371 | } else if (list.contains(5)) { 372 | r = 3 373 | } 374 | } else if (!list.containsAll( 375 | listOf( 376 | 2, 377 | 4 378 | ) 379 | ) && gameState[2] == jarvis && gameState[4] == jarvis && list.containsAll( 380 | listOf(1, 0) 381 | ) 382 | ) { 383 | if (list.contains(8)) { 384 | r = 0 385 | } else if (list.contains(7)) { 386 | r = 1 387 | } 388 | } else if (!list.containsAll( 389 | listOf( 390 | 2, 391 | 4 392 | ) 393 | ) && gameState[2] == jarvis && gameState[4] == jarvis && list.containsAll( 394 | listOf(5, 8) 395 | ) 396 | ) { 397 | if (list.contains(0)) { 398 | r = 8 399 | } else if (list.contains(3)) { 400 | r = 5 401 | } 402 | } else if (!list.containsAll( 403 | listOf( 404 | 6, 405 | 4 406 | ) 407 | ) && gameState[6] == jarvis && gameState[4] == jarvis && list.containsAll( 408 | listOf(7, 8) 409 | ) 410 | ) { 411 | if (list.contains(1)) { 412 | r = 7 413 | } else if (list.contains(0)) { 414 | r = 8 415 | } 416 | } else if (!list.containsAll( 417 | listOf( 418 | 6, 419 | 4 420 | ) 421 | ) && gameState[6] == jarvis && gameState[4] == jarvis && list.containsAll( 422 | listOf(0, 3) 423 | ) 424 | ) { 425 | if (list.contains(5)) { 426 | r = 3 427 | } else if (list.contains(8)) { 428 | r = 0 429 | } 430 | } else if (!list.containsAll( 431 | listOf( 432 | 8, 433 | 4 434 | ) 435 | ) && gameState[8] == jarvis && gameState[4] == jarvis && list.containsAll( 436 | listOf(5, 2) 437 | ) 438 | ) { 439 | if (list.contains(3)) { 440 | r = 5 441 | } else if (list.contains(6)) { 442 | r = 2 443 | } 444 | } else if (!list.containsAll( 445 | listOf( 446 | 8, 447 | 4 448 | ) 449 | ) && gameState[8] == jarvis && gameState[4] == jarvis && list.containsAll( 450 | listOf(6, 7) 451 | ) 452 | ) { 453 | if (list.contains(1)) { 454 | r = 7 455 | } else if (list.contains(2)) { 456 | r = 6 457 | } 458 | } // player break 459 | else if (!list.containsAll( 460 | listOf( 461 | 8, 462 | 4 463 | ) 464 | ) && gameState[8] == weapon && gameState[4] == weapon && (list.contains( 465 | 6 466 | ) || list.contains(2)) 467 | ) { 468 | if (list.containsAll(listOf(2, 6))) { 469 | r = listOf(2, 6).random() 470 | } else if (list.containsAll(listOf(3, 6))) { 471 | r = 6 472 | } else if (list.containsAll(listOf(2, 1))) { 473 | r = 2 474 | } 475 | } else if (!list.containsAll( 476 | listOf( 477 | 6, 478 | 4 479 | ) 480 | ) && gameState[6] == weapon && gameState[4] == weapon && (list.contains( 481 | 0 482 | ) || list.contains(8)) 483 | ) { 484 | if (list.containsAll(listOf(0, 8))) { 485 | r = listOf(0, 8).random() 486 | } else if (list.containsAll(listOf(0, 1))) { 487 | r = 0 488 | } else if (list.containsAll(listOf(8, 5))) { 489 | r = 8 490 | } 491 | } else if (!list.containsAll( 492 | listOf( 493 | 0, 494 | 4 495 | ) 496 | ) && gameState[0] == weapon && gameState[4] == weapon && (list.contains( 497 | 6 498 | ) || list.contains(2)) 499 | ) { 500 | if (list.containsAll(listOf(2, 6))) { 501 | r = listOf(2, 6).random() 502 | } else if (list.containsAll(listOf(6, 3))) { 503 | r = 6 504 | } else if (list.containsAll(listOf(2, 1))) { 505 | r = 2 506 | } 507 | } else if (!list.containsAll( 508 | listOf( 509 | 2, 510 | 4 511 | ) 512 | ) && gameState[2] == weapon && gameState[4] == weapon && (list.contains( 513 | 0 514 | ) || list.contains(8)) 515 | ) { 516 | if (list.containsAll(listOf(0, 8))) { 517 | r = listOf(0, 8).random() 518 | } else if (list.containsAll(listOf(0, 1))) { 519 | r = 0 520 | } else if (list.containsAll(listOf(8, 5))) { 521 | r = 8 522 | } 523 | } else { 524 | r = list[Random.nextInt(0..list.size - 1)] 525 | } 526 | } 527 | } 528 | if (r == -1) { 529 | r = list[Random.nextInt(0..list.size - 1)] 530 | } 531 | return r 532 | } 533 | } 534 | return -1 535 | } 536 | } 537 | -------------------------------------------------------------------------------- /app/src/main/java/com/bebetterprogrammer/tictactoe/utils/Result.kt: -------------------------------------------------------------------------------- 1 | package com.bebetterprogrammer.tictactoe.utils 2 | 3 | enum class Result { 4 | WON, LOST, TIE 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/res/anim/fade_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/anim/result_fade_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/anim/result_fade_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/anim/vibrate.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 9 | 15 | 21 | 27 | 33 | 39 | 45 | 51 | 57 | 63 | 69 | 75 | 81 | 89 | 95 | 96 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_circle_secondary.xml: -------------------------------------------------------------------------------- 1 | 6 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_circle_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cross_secondary.xml: -------------------------------------------------------------------------------- 1 | 6 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cross_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cross_yellow.xml: -------------------------------------------------------------------------------- 1 | 6 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_game_board.xml: -------------------------------------------------------------------------------- 1 | 6 | 12 | 18 | 24 | 30 | 36 | 42 | 48 | 54 | 60 | 66 | 72 | 73 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_music_off.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_music_on.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_rating.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_setting_secondary.xml: -------------------------------------------------------------------------------- 1 | 6 | 14 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_settings.xml: -------------------------------------------------------------------------------- 1 | 6 | 14 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_share.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_trophy_golden.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_trophy_grey.xml: -------------------------------------------------------------------------------- 1 | 6 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_trophy_lost.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 20 | 21 | 22 | 23 | 24 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_trophy_tie.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 20 | 21 | 22 | 23 | 24 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_trophy_won.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 20 | 21 | 22 | 23 | 24 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/layout_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/layout_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 11 | 12 | 13 | 17 | 18 | 19 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/layout_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/layout_difficulty_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/layout_difficulty_button_secondary.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/layout_play_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 11 | 12 | 13 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/layout_quit_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/font/righteous.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Be-Better-Programmer/Tic-Tac-Toe/356b0900b9bb5a54c336516cbe366ddf0b440dc1/app/src/main/res/font/righteous.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/snell_round_hand.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Be-Better-Programmer/Tic-Tac-Toe/356b0900b9bb5a54c336516cbe366ddf0b440dc1/app/src/main/res/font/snell_round_hand.ttf -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_gameplay.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 22 | 23 | 34 | 35 | 44 | 45 | 52 | 53 | 60 | 61 | 67 | 68 | 69 | 77 | 78 | 84 | 85 | 86 | 87 | 94 | 95 | 101 | 102 | 103 | 104 | 105 | 106 | 114 | 115 | 122 | 123 | 129 | 130 | 131 | 132 | 140 | 141 | 147 | 148 | 149 | 156 | 157 | 163 | 164 | 165 | 166 | 167 | 174 | 175 | 182 | 183 | 189 | 190 | 191 | 199 | 200 | 206 | 207 | 208 | 215 | 216 | 222 | 223 | 224 | 225 | 226 | 235 | 236 | 242 | 243 | 252 | 253 | 263 | 264 | 265 | 266 | 271 | 272 | 279 | 280 | 287 | 288 | 289 | 290 | 295 | 296 | 305 | 306 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 328 | 329 | 344 | 345 | 359 | 360 | 361 | 362 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_home_page.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 20 | 21 | 32 | 42 | 43 | 53 | 54 | 65 | 66 | 75 | 76 | 89 | 90 | 102 | 103 | 104 | 118 | 119 | 126 | 127 | 137 | 138 | 149 | 150 | 162 | 163 | 174 | 175 | 176 | 177 | 188 | 189 | 200 | 201 | 213 | 214 | 225 | 226 | 227 | 228 | 241 | 242 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_play_with_friend.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 23 | 24 | 33 | 34 | 47 | 48 | 60 | 61 | 62 | 71 | 72 | 84 | 85 | 98 | 99 | 113 | 114 | 129 | 130 | 143 | 144 | 156 | 157 | 169 | 170 | 171 | 178 | 179 | 193 | 194 | 209 | 210 | 223 | 224 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_play_with_jarvis.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 23 | 24 | 33 | 34 | 47 | 48 | 60 | 61 | 62 | 71 | 72 | 82 | 83 |