From a96870a010ae631c78d2d3c7f915ea04d85c1318 Mon Sep 17 00:00:00 2001 From: Andrey Stoyan Date: Thu, 5 Mar 2020 04:00:00 +0300 Subject: [PATCH 01/45] #2.4 add braille letter correctness check --- android/app/src/main/AndroidManifest.xml | 2 + .../amd/learnbraille/PracticeFragment.kt | 148 +++++++++++++++-- .../src/main/res/layout/fragment_practice.xml | 151 ++++++++++-------- 3 files changed, 224 insertions(+), 77 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 2742b8a4..afb46556 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -2,6 +2,8 @@ + + + + private var enteredDots = BrailleDots(E, E, E, E, E, E) + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ) = DataBindingUtil.inflate( inflater, R.layout.fragment_practice, container, false ).apply { - letter.text = randomLetter() - mainMenuButton.setOnClickListener( - Navigation.createNavigateOnClickListener(R.id.action_practiceFragment_to_menuFragment) + assert(dotsToRuLetters.size == 33) { + "33 letters are in russian" + } + + binding = this + vibrator = context!!.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator + dotCheckBoxes = arrayOf( + dotButton1, dotButton2, dotButton3, + dotButton4, dotButton5, dotButton6 + ) + + val navigate = Navigation.createNavigateOnClickListener( + R.id.action_practiceFragment_to_menuFragment ) + mainMenuButton.setOnClickListener(navigate) + nextButton.setOnClickListener { - letter.text = randomLetter() + if (checkRuLetter()) { + correctAnswer() + } else { + incorrectAnswer() + } + } + + assert(dotCheckBoxes.size == 6) + dotCheckBoxes.forEachIndexed { index, checkBox -> + checkBox.setOnCheckedChangeListener { _, isChecked -> + val toSet = if (isChecked) F else E + enteredDots = when (index + 1) { + 1 -> enteredDots.copy(b1 = toSet) + 2 -> enteredDots.copy(b2 = toSet) + 3 -> enteredDots.copy(b3 = toSet) + 4 -> enteredDots.copy(b4 = toSet) + 5 -> enteredDots.copy(b5 = toSet) + 6 -> enteredDots.copy(b6 = toSet) + else -> throw IllegalArgumentException( + "Wrong button index: $index, not in range from 0 to 5 inclusive" + ) + } + } } + + updateCard() + }.root - private fun randomLetter() = Random - .nextInt('A'.toInt(), 'Z'.toInt() + 1) - .toChar() - .toString() + private fun updateCard() { + enteredDots = BrailleDots() + binding.letter.text = randomRuLetter() + clearCheckBoxes() + } + + private fun clearCheckBoxes() = dotCheckBoxes.forEach { + if (it.isChecked) { + it.toggle() + } + } + + private fun correctAnswer() { + Log.i( + "PracticeFragment", + "Correct: letter = ${binding.letter.text}, dots = $enteredDots" + ) // Logging should be before clearing checkboxes + updateCard() + vibrator.vibrate(correctVibrationDuration) // Use deprecated for API level compatibility + Toast.makeText(context, "Correct! :)", Toast.LENGTH_SHORT).show() + } + + private fun incorrectAnswer() { + Log.i( + "PracticeFragment", + "Incorrect: letter = ${binding.letter.text}, dots = $enteredDots" + ) // Logging should be before clearing checkboxes + clearCheckBoxes() + vibrator.vibrate(incorrectVibrationDiration) // Use deprecated for API level compatibility + Toast.makeText(context,"Incorrect! :(", Toast.LENGTH_SHORT).show() + } + + private fun randomRuLetter() = dotsToRuLetters.values.random().toString() + + private fun checkRuLetter() = dotsToRuLetters[enteredDots].toString() == binding.letter.text + + private companion object { + private const val correctVibrationDuration = 100L + private const val incorrectVibrationDiration = 500L + private val dotsToRuLetters = mapOf( + BrailleDots(F, E, E, E, E, E) to 'А', + BrailleDots(F, F, E, E, E, E) to 'Б', + BrailleDots(E, F, E, F, F, F) to 'В', + BrailleDots(F, F, E, F, F, E) to 'Г', + BrailleDots(F, E, E, F, F, E) to 'Д', + BrailleDots(F, E, E, E, F, E) to 'Е', + BrailleDots(F, E, E, E, E, F) to 'Ё', + BrailleDots(E, F, E, F, F, E) to 'Ж', + BrailleDots(F, E, F, E, F, F) to 'З', + BrailleDots(E, F, E, F, E, E) to 'И', + BrailleDots(F, F, F, F, E, F) to 'Й', + BrailleDots(F, E, F, E, E, E) to 'К', + BrailleDots(F, F, F, E, E, E) to 'Л', + BrailleDots(F, E, F, F, E, E) to 'М', + BrailleDots(F, E, F, F, F, E) to 'Н', + BrailleDots(F, E, F, E, F, E) to 'О', + BrailleDots(F, F, F, F, E, E) to 'П', + BrailleDots(F, F, F, E, F, E) to 'Р', + BrailleDots(E, F, F, F, E, E) to 'С', + BrailleDots(E, F, F, F, F, E) to 'Т', + BrailleDots(F, E, F, E, E, F) to 'У', + BrailleDots(F, F, E, F, E, E) to 'Ф', + BrailleDots(F, F, E, E, F, E) to 'Х', + BrailleDots(F, E, E, F, E, E) to 'Ц', + BrailleDots(F, F, F, F, F, E) to 'Ч', + BrailleDots(F, E, E, E, F, F) to 'Ш', + BrailleDots(F, E, F, F, E, F) to 'Щ', + BrailleDots(F, F, F, E, F, F) to 'Ъ', + BrailleDots(E, F, F, F, E, F) to 'Ы', + BrailleDots(E, F, F, F, F, F) to 'Ь', + BrailleDots(E, F, E, F, E, F) to 'Э', + BrailleDots(F, F, E, E, F, F) to 'Ю', + BrailleDots(F, F, E, F, E, F) to 'Я' + ) + } } + +private enum class BrailleDot { + E, // Empty + F // Filled +} + +private data class BrailleDots( + val b1: BrailleDot = E, val b2: BrailleDot = E, val b3: BrailleDot = E, + val b4: BrailleDot = E, val b5: BrailleDot = E, val b6: BrailleDot = E +) diff --git a/android/app/src/main/res/layout/fragment_practice.xml b/android/app/src/main/res/layout/fragment_practice.xml index a4e3455f..4bff4153 100644 --- a/android/app/src/main/res/layout/fragment_practice.xml +++ b/android/app/src/main/res/layout/fragment_practice.xml @@ -1,76 +1,14 @@ - + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + \ No newline at end of file From 2dc6cb057fb252f6f4779dab85128cb261c7e65b Mon Sep 17 00:00:00 2001 From: Andrey Stoyan Date: Thu, 5 Mar 2020 04:08:02 +0300 Subject: [PATCH 02/45] Fix type safety --- .../spbstu/amd/learnbraille/ExitFragment.kt | 13 +-- .../app/src/main/res/layout/fragment_exit.xml | 86 ++++++++++--------- 2 files changed, 51 insertions(+), 48 deletions(-) diff --git a/android/app/src/main/java/ru/spbstu/amd/learnbraille/ExitFragment.kt b/android/app/src/main/java/ru/spbstu/amd/learnbraille/ExitFragment.kt index cca04cce..0b85e85c 100644 --- a/android/app/src/main/java/ru/spbstu/amd/learnbraille/ExitFragment.kt +++ b/android/app/src/main/java/ru/spbstu/amd/learnbraille/ExitFragment.kt @@ -3,19 +3,20 @@ package ru.spbstu.amd.learnbraille import android.os.Bundle import android.view.LayoutInflater import android.view.ViewGroup -import android.widget.Button +import androidx.databinding.DataBindingUtil import androidx.fragment.app.Fragment -import androidx.navigation.Navigation +import ru.spbstu.amd.learnbraille.databinding.FragmentExitBinding import kotlin.system.exitProcess class ExitFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? - ) = inflater.inflate(R.layout.fragment_exit, container, false).apply{ - val exitButton: Button = findViewById(R.id.exit_button) - exitButton.setOnClickListener{ + ) = DataBindingUtil.inflate( + inflater, R.layout.fragment_exit, container, false + ).apply { + exitButton.setOnClickListener { exitProcess(0) } - } + }.root } diff --git a/android/app/src/main/res/layout/fragment_exit.xml b/android/app/src/main/res/layout/fragment_exit.xml index 9f3d05cd..b5c93d1a 100644 --- a/android/app/src/main/res/layout/fragment_exit.xml +++ b/android/app/src/main/res/layout/fragment_exit.xml @@ -1,46 +1,48 @@ - + - + -