См. Ссылку на предыдущий пост по этой теме Создание математических вопросов и ответов
У меня есть приложение-викторина для Android, которое я создаю, чтобы научиться разрабатывать приложения kotlin / android. Вот объект, который у меня есть, который действует как один из многих построителей вопросов.
С момента моего последнего сообщения у меня есть:
- разбил основной метод на более мелкие методы в соответствии с данным советом
- переименовал переменные / значения, чтобы они имели лучший смысл
- начал использовать val вместо var, где это возможно — Установка vals в
when
операторы, кажется, не работают для меня, это пример, где var лучше всего использовать, как я, или есть способ заставить работать vals здесь тоже? - переключился с использования безопасного случайного выбора, который не был необходим для моего варианта использования
- удалил некоторое дублирование и даже жестко закодировал некоторые значения, где раньше я использовал переменную, которая задавалась и использовалась в той же строке кода
Мой объект:
object test{
fun newQ(context: Context,mainLevel:Int, subLevel:Int, isBonusRound:Boolean, gameType:String): SingleQuestion {
val level = determineLevel(gameType, mainLevel) // Used to determine the level which can vary between mini games
var numbers = initialiseNumbers() // Set an array of Int's to be used when creating a sum (question)
val operations = determineOperations(level) // how many mathematical calculations will be needed to get to the correct answer?
numbers = processNumbersStep2(isBonusRound,mainLevel,subLevel,numbers) //adjust numbers to suit level / bonus game
val (question,answer) = createQuestion(context,isBonusRound,operations,numbers,level) //create the question and the answer
val timeLimitPerQuestion = getTimeLimit(isBonusRound,operations,level) // how many seconds (as an Int) to give them to answer this question
return SingleQuestion(question,answer,timeLimitPerQuestion) // return the question, the answer and the time limit
}
}
// Function to provide a random number. Set the lowest number and highest number.
private fun rand(start: Int, end: Int): Int {
require(start <= end) { "Illegal Argument" }
val random = Random.Default
return random.nextInt(start, end + 1)
}
// function to determine level due to differences in how mini games are structured (one had less levels so I map them here to the broader level structure)
private fun determineLevel(gameType:String,mainLevel:Int):Int{
var updatedMainLevel = 0
if (gameType=="FreeStyle"){
when (mainLevel){
1->{updatedMainLevel = rand(1,3)} // aka Easy
2->{updatedMainLevel = rand(4,5)} // aka Normal
3->{updatedMainLevel = rand(6,8)} // aka Hard
4->{updatedMainLevel = rand(9,10)} // aka Impossible
}
} else {updatedMainLevel = mainLevel
}; return updatedMainLevel
}
// create base numbers for use in sums, these may manipulated later depending on level etc
private fun initialiseNumbers() :Array<Int>{
var num1 = 0;var num2 = 0;var num3 = 0;var num4 = 0
when(rand(1,23)){
1->{num1 = rand(1,5); num2 = rand(1,5)}
2->{num1 = rand(2,6);num2 = rand(1,5)}
3->{num1 = rand(3,7);num2 = rand(1,5)}
4->{num1 = rand(4,8);num2 = rand(1,5)}
5->{num1 = rand(5,9);num2 = rand(1,5)}
6->{num1 = rand(6,10);num2 = rand(7,11)}
7->{num1 = rand(1,5);num2 = rand(6,10)}
8->{num1 = rand(2,6);num2 = rand(5,9)}
9->{num1 = rand(3,7);num2 = rand(4,8)}
10->{num1 = rand(4,8);num2 = rand(3,7)}
11->{num1 = rand(5,9);num2 = rand(2,6)}
12->{num1 = rand(6,10);num2 = rand(1,5)}
13->{num1 = rand(1,5);num2 = rand(1,5)}
14->{num1 = rand(2,6);num2 = rand(2,6)}
15->{num1 = rand(3,7);num2 = rand(3,7)}
16->{num1 = rand(4,8);num2 = rand(4,8)}
17->{num1 = rand(5,9);num2 = rand(5,9)}
18->{num1 = rand(6,10);num2 = rand(6,10)}
19->{num1 = rand(1,5);num2 = rand(1,5)}
20->{num1 = rand(1,5);num2 = rand(2,6)}
21->{num1 = rand(1,5);num2 = rand(3,7)}
22->{num1 = rand(1,5);num2 = rand(4,8)}
23->{num1 = rand(1,5);num2 = rand(5,9)}
else->{num1 = rand(1,5);num2 = rand(5,9)}
}
num3 = rand(2,6);num4 = rand(4,8)
return arrayOf(num1,num2,num3,num4)
}
private fun determineOperations(level:Int):Int{
var calculationsRequired = 0
when(level){
in 1..5-> calculationsRequired = 1
in 6..10-> calculationsRequired = 2
else -> calculationsRequired = 1
}
return calculationsRequired
}
private fun processNumbersStep2(isBonusRound: Boolean,mainLevel: Int,subLevel: Int,numbers:Array<Int>):Array<Int>{
var num1=0;var num2=0;var num3=0;var num4=0
if (!isBonusRound){
when(mainLevel){
1->{num1 = subLevelModifier(subLevel,numbers[0],0);num2 = subLevelModifier(subLevel,numbers[1],0)}
2->{num1 = subLevelModifier(subLevel,numbers[0],1);num2 = subLevelModifier(subLevel,numbers[1],1)}
3->{num1 = subLevelModifier(subLevel,numbers[0],2);num2 = subLevelModifier(subLevel,numbers[1],2)}
4->{num1 = subLevelModifier(subLevel,numbers[0],3);num2 = subLevelModifier(subLevel,numbers[1],3)}
5->{num1 = subLevelModifier(subLevel,numbers[0],4);num2 = subLevelModifier(subLevel,numbers[1],4)}
6->{num1 = subLevelModifier(subLevel,numbers[0],0);num2 = subLevelModifier(subLevel,numbers[1],0);num3 = subLevelModifier(subLevel,numbers[0],0)}
7->{num1 = subLevelModifier(subLevel,numbers[0],1);num2 = subLevelModifier(subLevel,numbers[1],1);num3 = subLevelModifier(subLevel,numbers[0],1)}
8->{num1 = subLevelModifier(subLevel,numbers[0],2);num2 = subLevelModifier(subLevel,numbers[1],2);num3 = subLevelModifier(subLevel,numbers[0],2)}
9->{num1 = subLevelModifier(subLevel,numbers[0],3);num2 = subLevelModifier(subLevel,numbers[1],3);num3 = subLevelModifier(subLevel,numbers[0],3)}
10->{num1 = subLevelModifier(subLevel,numbers[0],4);num2 = subLevelModifier(subLevel,numbers[1],4);num3 = subLevelModifier(subLevel,numbers[0],4)}
}
} else {
when(mainLevel){
in 1..3->{num1 = subLevelModifier(subLevel,numbers[0],0);num2 = subLevelModifier(subLevel,numbers[1],0);num3 = subLevelModifier(subLevel,numbers[2],0);num4 = subLevelModifier(subLevel,numbers[3],0)}
in 4..5->{num1 = subLevelModifier(subLevel,numbers[0],2);num2 = subLevelModifier(subLevel,numbers[1],2);num3 = subLevelModifier(subLevel,numbers[2],2);num4 = subLevelModifier(subLevel,numbers[3],2)}
in 6..8->{num1 = subLevelModifier(subLevel,numbers[0],4);num2 = subLevelModifier(subLevel,numbers[1],4);num3 = subLevelModifier(subLevel,numbers[2],4);num4 = subLevelModifier(subLevel,numbers[3],4)}
in 9..10->{num1 = subLevelModifier(subLevel,numbers[0],6);num2 = subLevelModifier(subLevel,numbers[1],6);num3 = subLevelModifier(subLevel,numbers[2],6);num4 = subLevelModifier(subLevel,numbers[3],6)}
}
}
return arrayOf(num1,num2,num3,num4)
}
private fun createQuestion(context: Context,isBonusRound: Boolean,operations:Int,numbers:Array<Int>,level:Int):Pair<String,Int>{
var question = "";var answer = 0
if (!isBonusRound){
when (operations){
1-> {
answer = numbers[0] * numbers[1]
question = context.getString(R.string.mulQ_num1_x_num2,numbers[0],numbers[1])}
2-> {
answer = (numbers[0] * numbers[1]) * numbers[2]
question = context.getString(R.string.mulQ_num1_x_num2_x_num3,numbers[0],numbers[1],numbers[2])}
else->{
answer = numbers[0] * numbers[1]
question = context.getString(R.string.mulQ_num1_x_num2,numbers[0],numbers[1])}
}
} else {
when (rand(1,4)){
1->{
answer = (numbers[0] * numbers[1]) + (numbers[2] * numbers[3])
question = context.getString(R.string.mulQ_num1_x_num2_add_num3_x_num4,numbers[0],numbers[1],numbers[2],numbers[3])}
2->{
answer = numbers[0] + (numbers[1] * numbers[2]) + numbers[3]
question =context.getString(R.string.mulQ_num1_add_num2_x_num3_add_num4,numbers[0],numbers[1],numbers[2],numbers[3])}
3->{
answer = ((numbers[0] * numbers[1]) + numbers[2]) - numbers[3]
question =context.getString(R.string.mulQ_num1_x_num2_add_num3_minus_num4,numbers[0],numbers[1],numbers[2],numbers[3])}
4->{
answer = numbers[0] + (numbers[1] * numbers[2]) - numbers[3]
question =context.getString(R.string.mulQ_num1_x_num2_add_num3_minus_num4,numbers[0],numbers[1],numbers[2],numbers[3])}
}
}
return Pair(question,answer)
}
//This function is aimed at providing an optimisation capability.
// sb levels are 1-25 e.g sub level 1 increases each number by 1.01% up to 1.25% (1% increase to 25% increase)
// you can lower the division factor (e.g. /100 to /50) to create bigger gaps between sub levels
private fun subLevelModifier(subLevel:Int, num:Int, increment:Int):Int{
var multiplier = ((subLevel /100 )+1).toDouble()
var newNum = ((num + increment) * multiplier).roundToInt()
return newNum
}
private fun getTimeLimit(isBonusRound: Boolean, operations: Int, level: Int): Int {
var addTimeForBonusRound = 0;var addTimeForOperations = 0
if (isBonusRound) {addTimeForBonusRound = +2}
if (operations>1) {addTimeForOperations = +1}
val addTimeForLevel = ((level*0.6)+2).roundToInt()
return (addTimeForBonusRound+addTimeForOperations+addTimeForLevel)
}