I am fairly new to Android + Kotlin, however I am wondering if there is a faster way to read a text (.pgn) file and mark pointers to places in the file for later reference.
At the moment I am using RandomAccessFile however it is incredible slow for a process that should be extremely quick.
This is my code at the moment:
private fun loadPGN() {
try {
val selectedPGN = File((context as MainActivity).filesDir, "mygames.pgn")
val raf = RandomAccessFile(selectedPGN, "r")
val length = raf.length()
raf.seek(0)
charPosition = raf.filePointer
while (charPosition < length) {
val str : String = raf.readLine()
if (str.contains("[Event ")) {
mutableListEvent += charPosition
findMoves = true
}
if (findMoves && ((str.startsWith(str.filter { it.isDigit() }) && !str.startsWith("[")) || str.startsWith("{ "))) {
mutableListMoves += charPosition
findMoves = false
}
charPosition = raf.filePointer
}
for (i in 0 until mutableListEvent.size) {
val event = if (mutableListEvent[i] != mutableListEvent[mutableListEvent.size - 1]) mutableListEvent[i + 1] else length
val moves = mutableListMoves[i]
raf.seek(mutableListEvent[i])
eventStr = raf.readLine().removeRange(0,8).replace("\"]", "")
eventMutableList.add(eventStr)
difference += (event - moves)
headerLength += (mutableListMoves[i] - mutableListEvent[i])
raf.seek(moves)
val byteArray = ByteArray(difference[i].toInt())
raf.readFully(byteArray)
val string = String(byteArray)
var stringEdited = String(byteArray).replace("\n","")
if (stringEdited.contains("{[")) {
val re = "\\{\\[.*?]}".toRegex()
stringEdited = re.replace(stringEdited,"")
}
gamePlayMutableList.add(string)
}
// Header Information
for (i in 0 until headerLength.size) {
raf.seek(mutableListEvent[i])
charPosition = raf.filePointer
while (charPosition < mutableListMoves[i]) {
val str = raf.readLine()
if (str.contains("[Site \"") || str.contains("[Date \"") || str.contains("[Round \"") || str.contains("[White \"") || str.contains(
"[Black \""
) || str.contains("[Result \"") || str.contains("[EventDate \"") || str.contains("[PlyCount \"")
) {
if (str.contains("[Site \"")) {
siteMutableList += str.replace("[Site \"", "").replace("\"]", "")
}
if (str.contains("[Date \"")) {
dateMutableList += str.replace("[Date \"", "").replace("\"]", "")
}
if (str.contains("[Round \"")) {
roundMutableList += str.replace("[Round \"", "").replace("\"]", "")
}
if (str.contains("[White \"")) {
whiteMutableList += str.replace("[White \"", "").replace("\"]", "")
}
if (str.contains("[Black \"")) {
blackMutableList += str.replace("[Black \"", "").replace("\"]", "")
}
if (str.contains("[Result \"")) {
resultMutableList += str.replace("[Result \"", "").replace("\"]", "")
}
if (str.contains("[EventDate \"")) {
eventDateMutableList += str
}
if (str.contains("[PlyCount \"")) {
plyCountMutableList += str
}
}
charPosition = raf.filePointer
}
}
} catch (e: IOException) {
e.printStackTrace()
}
}
}
Once I have the pointers, I then load the information in a recycler view so as you're able to select which game (with information visible) you wish.
I have crawled stack overflow regarding this, however the majority of questions are just to read a whole text file and return that, not put pointers into places for reference
So I managed to figure out the 'issues' regarding this. raf.readLine() is EXTREMELY slow. This is a known problem, but not really talked about so much. Anyway I now use .readFully(), which is substantially faster.
Related
I am building a calculator with Kotlin and android studio (my first project). All equations were working properly until recent tweaks with decimal format. Now large division operations returns inaccurate results.
For example 99,999,999 / 9% (0.09) = 1.11111110000E9
But 9% / 99,999,999 = 0 when it should = 9.0000000009E-10
Is this because the current DecimalFormat cannot return the negative exponent?
EDIT: after more testing I've found that changing division method to
doubleNum = doubleNum.divide(numBigDecimal, 10, BigDecimal.ROUND_HALF_UP).stripTrailingZeros()
running the same equation will return 9E-10 before formatting. After decimal format the result shows as "." only with no digits
// enum class and class properties
enum class LogicTypes {
None,Add,Subtract,Multiply,Divide
}
class MainActivity : AppCompatActivity() {
private var logicActive = false
private var currentLogic = LogicTypes.None
private var currentNum = BigDecimal.ZERO
private var displayNum = ""
private var memoryNum = BigDecimal.ZERO
// add num function - buttons 0-9 send indices to num arg
fun addNum(num: BigDecimal) {
val inputNum = num.toString()
if (displayNum == "0" && inputNum == "0") {
return
}
if (displayNum.contains(".")) {
val stringForm = displayNum.substring(displayNum.indexOf('.'), displayNum.length)
if (stringForm.length > 10) {
clearCalc()
Toast.makeText(this, "Only 10 digits after decimal point allowed.", Toast.LENGTH_SHORT).show()
return
}
}
if (displayNum.length >= 15 && !displayNum.contains(".")) {
clearCalc()
Toast.makeText(this, "Maximum of 15 digits allowed.", Toast.LENGTH_SHORT).show()
return
}
if (inputNum == "0" && currentNum.toDouble() == 0.0 && displayNum.contains(".")) {
if (displayNum.length > 11) {
clearCalc()
Toast.makeText(this, "Only 10 digits after decimal point allowed.", Toast.LENGTH_SHORT).show()
return
}
displayNum = "$displayNum$inputNum"
textView.text = displayNum
return
}
if (logicActive) {
logicActive = false
displayNum = "0"
}
displayNum = "$displayNum$inputNum"
updateDisplayNum()
}
// set currentNum and send to numFormat function to update textView
fun updateDisplayNum() {
if (currentNum.toString().length > 15) {
clearCalc()
Toast.makeText(this, "Maximum of 15 digits allowed.", Toast.LENGTH_SHORT).show()
return
}
val numBigDecimal = displayNum.toBigDecimal()
if(currentLogic == LogicTypes.None) {
if(displayNum.contains("-") && currentNum == BigDecimal.ZERO) {
textView.text = displayNum
return
} else {
currentNum = numBigDecimal
}
}
numFormat()
}
// format decimal and integers and update textview with exponent
fun numFormat() {
val numBigDecimal = displayNum.toBigDecimal()
if(displayNum.contains(".")) {
val stringForm = displayNum.substring(displayNum.indexOf('.'), displayNum.length)
var numFormat = "#,##0."
if(stringForm.length > 1) {
for (num in stringForm.indices-1) {
numFormat += "0"
}
}
if (displayNum.length > 16 || stringForm.length > 9) {
// stringform length > 9 works for division result - anything higher returns trailing zeros.
// anything under 11 for stringform condition results in inaccurate input -
// adding decimal through addNum() will return Exponential notation before logic
// I only want E notation on result only- have yet to test other equations -
// this can also make it impossible to take the result and conduct another logic operation as the result appends E0
// and thus the trailing digits after decimal is greater than 10
numFormat = "0.0000000000E0"
}
val df = DecimalFormat(numFormat)
textView.text = df.format(numBigDecimal)
return
}
var df = DecimalFormat("#,###")
if (displayNum.length > 15) {
df = DecimalFormat("0.0000000000E0")
}
textView.text = df.format(numBigDecimal)
}
// change logic to enum mode when button operator pressed
fun changeLogic(mode: LogicTypes) {
currentLogic = mode
logicActive = true
}
// calculate function
fun calculate() {
if (logicActive || currentLogic == LogicTypes.Divide && displayNum.toBigDecimal() == BigDecimal.ZERO
|| currentNum == BigDecimal.ZERO) {
Log.i(LOG_TAG, "caught the zero")
return
}
val numBigDecimal = displayNum.toBigDecimal()
var doubleNum = currentNum
val currentNumString = doubleNum.stripTrailingZeros().toPlainString()
val numBigDecimalString = numBigDecimal.stripTrailingZeros().toPlainString()
val addMsg = getString(R.string.calc_message, currentNumString, "+", numBigDecimalString)
val subMsg = getString(R.string.calc_message, currentNumString, "-", numBigDecimalString)
val multiMsg = getString(R.string.calc_message, currentNumString, "*", numBigDecimalString)
val divMsg = getString(R.string.calc_message, currentNumString, "/", numBigDecimalString)
when(currentLogic) {
LogicTypes.Add -> {
hintView.text = addMsg
doubleNum += numBigDecimal
doubleNum = doubleNum.stripTrailingZeros()
}
LogicTypes.Subtract -> {
hintView.text = subMsg
doubleNum -= numBigDecimal
doubleNum = doubleNum.stripTrailingZeros()
}
LogicTypes.Multiply -> {
hintView.text = multiMsg
doubleNum *= numBigDecimal
doubleNum = doubleNum.stripTrailingZeros()
}
LogicTypes.Divide -> {
hintView.text = divMsg
doubleNum /= numBigDecimal
doubleNum = doubleNum.stripTrailingZeros()
}
LogicTypes.None -> return
}
currentLogic = LogicTypes.None
displayNum = doubleNum.toString()
updateDisplayNum()
logicActive = true
}
Ok the issue was that I was using this in the calculate function.
displayNum = doubleNum.toString()
Changing to .toPlainString() gives correct notations. There are still issues with formatting but I'll see if I can work those out on my own
EDIT: I solved the formatting issue in the numFormat by creating a boolean property, setting it to true in the calculation function, and passing it to the numFormat condition:
if (displayNum.length > 16 || stringForm.length > 9 && resultActive) {
numFormat = "0.0000000000E0"
resultActive = false
}
This way the format only applies to calculated numbers
I also passed it to the addNum function for calculations made after the first calculation
if(resultActive) {
resultActive = false
}
I am receiving date string 2021-06-13T15:00:00.000Z from rest api call. I have to parse this date string that match will start in 5 hours or today
You can try something like below.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault());
LocalDateTime eventDate = LocalDateTime.parse("2021-06-15T21:00:00.000Z", formatter);
LocalDateTime now = LocalDateTime.now();
Duration dur = Duration.between(now, eventDate);
if (dur.isNegative()) {
Log.d("DINKAR", "Time Already Passed");
} else if (dur.isZero()) {
Log.d("DINKAR", "Its happening now");
} else {
if (dur.getSeconds() > 0 && dur.getSeconds() < 60) {
Log.d("DINKAR", String.format("Match will start in %d seconds", dur.getSeconds()));
} else if (dur.toMinutes() > 0 && dur.toMinutes() < 60) {
Log.d("DINKAR", String.format("Match will start in %d minutes", dur.toMinutes()));
} else if (dur.toHours() > 0 && dur.toHours() < 24) {
Log.d("DINKAR", String.format("Match will start in %d hours", dur.toHours()));
} else if (dur.toDays() > 0) {
Log.d("DINKAR", String.format("Match will start in %d days", dur.toDays()));
}
}
For API below 26 Please also add the following in your build.gradle
android {
defaultConfig {
// Required when setting minSdkVersion to 20 or lower
multiDexEnabled = true
}
compileOptions {
// Flag to enable support for the new language APIs
coreLibraryDesugaringEnabled = true
// Sets Java compatibility to Java 8
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
}
dependencies {
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.5")
}
The following code snippet might help:
val timeInString = "2021-06-16T05:00:00.000Z"
val givenTime = ZonedDateTime.parse(timeInString).toLocalDateTime()
val currentTime = ZonedDateTime.now().toLocalDateTime()
val difference = Duration.between(currentTime, givenTime)
val matchTimeMessage = when {
difference.isNegative -> "The match is already over"
difference.toHours() < 24 -> "The match will start in ${difference.toHours()} hours"
else -> "The match will start in ${difference.toDays()} days"
}
println(matchTimeMessage)
You can simply calculate the difference of hours between the present time and given time. There are more than one ways to do this. Here are some
val givenTime = Instant.parse("2021-06-13T15:00:00.000Z")
val currentTime = Instant.now()
val difference1 = ChronoUnit.HOURS.between(currentTime, givenTime) // Use Chronounit
val difference2 = Duration.between(currentTime, givenTime).toHours() // Use Duration
private fun getAppropriateTimeDiffResolution(
start: Date?,
end: Date?
): String {
return if (start != null && end != null) {
val diffInMs: Long = end.time - start.time
val diffInMins: Long = TimeUnit.MILLISECONDS.toMinutes(diffInMs)
val diffInHrs: Long = TimeUnit.MILLISECONDS.toHours(diffInMs)
val diffInDays: Long = TimeUnit.MILLISECONDS.toDays(diffInMs)
val diffInMonth: Long = TimeUnit.MILLISECONDS.toDays(diffInMs) / 30
val diffInYear = diffInMonth / 12
val stringBuilder = StringBuilder()
if (diffInMins < 60) {
if (diffInMins > 1) stringBuilder.append(diffInMins)
.append(" Mins Ago")
.toString() else if (diffInMins == 0L) "Now" else stringBuilder.append(
diffInMins
).append(" Mins Ago").toString()
} else if (diffInHrs < 24) {
stringBuilder.append(diffInHrs)
.append(" Hours Ago")
.toString()
} else if (diffInDays < 30) {
stringBuilder.append(diffInDays)
.append(" Days Ago").toString()
} else if (diffInMonth < 12) {
stringBuilder.append(diffInMonth)
.append(" Months Ago")
.toString()
} else {
stringBuilder.append(diffInYear)
.append(" Years Ago").toString()
}
} else {
"--"
}
}
private fun getFormattedTime(#NonNull time: String): String {
Log.e("BindingAdapter", time)
val input = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX", Locale.getDefault())
var d: Date?
try {
d = input.parse(time)
return getAppropriateTimeDiffResolution(d, Date())
} catch (e: ParseException) {
try {
val fallback =
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.getDefault())
d = fallback.parse(time)
return getAppropriateTimeDiffResolution(d, Date())
} catch (e2: ParseException) {
return "--"
}
}
}
I am using MP chart to display trip count, everything is working fine except that the the Y-axis values are displaying as a floating value instead of Integer.
I have integer value in jan,feb,etc... and I want to display it in y axis as integer format but it displays as float values, for ex. jan =10 and it has been converted into 10.0.
This is the code I am using:
//Variables
var barData: BarData? = null
var barDataSet: BarDataSet? = null
var barEntries: java.util.ArrayList<BarEntry>? = null
var jan =""
var feb=""
var mar=""
var apr=""
var may=""
var jun=""
var jul=""
var aug=""
var sep=""
var oct=""
var nov=""
var dec=""
//Method to call at OnCreate
private fun getEntries() {
barEntries = java.util.ArrayList<BarEntry>()
myUID = userSP.getString("userId")
myUID?.let {
db.collection("OperatorUsers").document(it)
.collection("Completed Services").document(myUID!!).addSnapshotListener { value: DocumentSnapshot?, error: FirebaseFirestoreException? ->
try {
if (value!!.exists()) {
jan = value.getLong("january").toString()
feb = value.getLong("february").toString()
mar = value.getLong("march").toString()
apr = value.getLong("april").toString()
may = value.getLong("may").toString()
jun = value.getLong("june").toString()
jul = value.getLong("july").toString()
aug = value.getLong("august").toString()
sep = value.getLong("september").toString()
oct = value.getLong("october").toString()
nov = value.getLong("november").toString()
dec = value.getLong("december").toString()
setBarChart()
}
} catch (e: java.lang.Exception) {
e.printStackTrace()
Log.d("fs", e.message!!)
setBarChart()
}
}
}
}
private fun setBarChart() {
if (jan != "null") {
barEntries?.add(BarEntry(1f, jan.toFloat()))
} else {
barEntries?.add(BarEntry(1f, 0.0f))
}
if (feb != "null") {
barEntries?.add(BarEntry(2f, feb.toFloat()))
} else {
barEntries?.add(BarEntry(2f, 0.0f))
}
if (mar != "null") {
barEntries?.add(BarEntry(3f, mar.toFloat()))
} else {
barEntries?.add(BarEntry(3f, 0.0f))
}
if (apr != "null") {
barEntries?.add(BarEntry(4f, apr.toFloat()))
} else {
barEntries?.add(BarEntry(4f, 0.0f))
}
if (may != "null") {
barEntries?.add(BarEntry(5f, may.toFloat()))
} else {
barEntries?.add(BarEntry(5f, 0.0f))
}
if (jun != "null") {
barEntries?.add(BarEntry(6f, jun.toFloat()))
} else {
barEntries?.add(BarEntry(6f, 0.0f))
}
if (jul != "null") {
barEntries?.add(BarEntry(7f, jul.toFloat()))
} else {
barEntries?.add(BarEntry(7f, 0.0f))
}
if (aug != "null") {
barEntries?.add(BarEntry(8f, aug.toFloat()))
} else {
barEntries?.add(BarEntry(8f, 0.0f))
}
if (sep != "null") {
barEntries?.add(BarEntry(9f, sep.toFloat()))
} else {
barEntries?.add(BarEntry(9f, 0.0f))
}
if (oct != "null") {
barEntries?.add(BarEntry(10.0f, oct.toFloat()))
} else {
barEntries?.add(BarEntry(10.0f, 0.0f))
}
if (nov != "null") {
barEntries?.add(BarEntry(11f, nov.toFloat()))
} else {
barEntries?.add(BarEntry(11f, 0.0f))
}
if (dec != "null") {
barEntries?.add(BarEntry(12f, dec.toFloat()))
} else {
barEntries?.add(BarEntry(12f, 0.0f))
}
val labels = arrayOf("Dummy", "Jan", "Feb", "March", "April", "May",
"June", "July", "Aug", "Sept", "Oct", "Nov", "Dec")
val xAxis: XAxis = mpBarChart.xAxis
val leftAxis : YAxis = mpBarChart.axisLeft
xAxis.valueFormatter = IndexAxisValueFormatter(labels)
xAxis.granularity = 1f
xAxis.isGranularityEnabled = true
leftAxis.setGranularity(1.0f);
leftAxis.setGranularityEnabled(true); // Required to enable granularity
barDataSet = BarDataSet(barEntries, "No.of Trips")
barData = BarData(barDataSet)
mpBarChart.data=barData
mpBarChart.description.text="Month wise Dashboard"
barDataSet!!.setColors(*ColorTemplate.MATERIAL_COLORS)
barDataSet!!.setValueTextSize(8f)
barDataSet!!.setValueTextColor(Color.BLACK)
//mpBarChart.setBackgroundResource(R.drawable.card_search)
mpBarChart.getAxisLeft().setDrawGridLines(false)
mpBarChart.getXAxis().setDrawGridLines(false)
mpBarChart.getAxisRight().setDrawGridLines(false)
}
I found many answers like value formatter but they are in java and I tried to converts it in Kotlin but it didn't help .
So please help anyone , Thanks in advance !
Besides the multiple issues with that code regarding null safety and lack of kotlin understanding, you can simply achieve this by removing unnecessary code.
You have a DocumentSnapshot that can give you a Long, and yet you transform that into a String
You then take that String and make it into something that you don't want, a Float.
The only reason you got to this predicament is because you are not handling the possibility of a null coming from getFloat().
A Long is an integer, the only difference is that Long is a 64 bit integer and Int is a 32 bit integer, so you already had what you needed from the start.
var jan = 0L
//...//
value.getLong("january")?.let { jan = it }
//or
jan = value.getLong("january") ?: 0L
//...//
barEntries?.add(BarEntry(1f, jan))
I don't know what params the constructor of BarEntry can take, in the possibility that it can't take a Float, check the docs of the library you are using and change that Long into whatever it requires.
Hope you are fine what I am trying to achieve is to get all the duplications from the internal storage, for that, I am already using a method I don't know what I am doing wrong please have a look,
private fun getDuplicateItems() {
var tempDuplicateItem: DuplicateItemModel
GlobalScope.launch(Dispatchers.IO) {
for (i in 0 until listOfAllFiles.size) {
for (j in i until listOfAllFiles.size) {
if(!File(listOfAllFiles[i].directoryPath).isDirectory && !File(listOfAllFiles[j].directoryPath).isDirectory ){
if (listOfAllFiles[i].fileName == listOfAllFiles[j].fileName && listOfAllFiles[i].fileSize == listOfAllFiles[j].fileSize &&
!listOfAllFiles[i].fileName.endsWith(".tmp") && !listOfAllFiles[j].fileName.endsWith(".tmp") &&
!listOfAllFiles[i].fileName.endsWith(".chck") && !listOfAllFiles[j].fileName.endsWith(".chck") &&
!listOfAllFiles[i].fileName.startsWith(".") && !listOfAllFiles[j].fileName.startsWith(".")
) {
tempDuplicateItem = DuplicateItemModel(
"$i${listOfAllFiles[i].fileName}",
listOfAllFiles[i].fileName,
listOfAllFiles[i].absolutePath,
listOfAllFiles[i].fileModificationDateAndTime,
File(listOfAllFiles[i].directoryPath).length(),
false,
false,
)
tempArrayListOfDuplicateItemsSingle.add(
DuplicateItemModel(
"$i${listOfAllFiles[i].fileName}",
listOfAllFiles[j].fileName,
listOfAllFiles[j].absolutePath,
listOfAllFiles[j].fileModificationDateAndTime,
File(listOfAllFiles[j].directoryPath).length(),
true,
true,
)
)
tempArrayListOfDuplicateItems.add(
DuplicateItemArrayListItem(
tempDuplicateItem,
tempArrayListOfDuplicateItemsSingle
)
)
}
}
}
}
}.invokeOnCompletion {
var tempTotalDuplicateSize: Double = 0.0
GlobalScope.launch(Dispatchers.Main) {
progressBarDuplicateFiles.visibility = View.INVISIBLE
imageViewNextDuplicateFiles.visibility = View.VISIBLE
for (x in 0 until tempArrayListOfDuplicateItems.size) {
tempArrayListOfDuplicateItems[x].listOfDuplicationSubItems.forEach { duplicateItem ->
tempTotalDuplicateSize += duplicateItem.fileSize
}
}
//UI Stuff
textViewTotalSizeOfDuplications.text = "total Size of Duplicate Files (${HelperClass.readableFileSize(tempTotalDuplicateSize.toLong())})"
textViewTotalFolderFilesDuplicateItem.text = "${tempArrayListOfDuplicateItems.size} Item(s)"
relativeLayoutDuplicateItem.isClickable = true
}
}
}
I am using MediaLoader, a library which gives me all the files on internal storage, and through those files, I am checking the data if the data is equal or not but getting the stream of data which I don't know is correct or not,
This should help you get started:
File f = new File("your_relevant_path");
File[] files = f.listFiles();
HashSet<String> mHashSet = new HashSet<>();
for (File currFile :
files) {
if (!mHashSet.add(currFile.getName()))
{
// Here there is a duplication of a file
}
}
Im followed a tutorial to create a maze with Recursive Backtracking and it works great.
Im trying to create a game where people get on the same maze, and if someone wins, it creates a new maze and everyones current maze gets updated.
So what i was thinking is to have a seed to create the same maze and pass that seed to all the players so they can have the same maze.
Is there a way to modify it so i can give the maze a seed and it creates always the same maze?
This is what i have now:
It uses a Cell class (posx,posy)
class Cell(var col:Int = 0, var row: Int = 0){
var topWall = true
var leftWall = true
var bottomWall = true
var rightWall = true
var visited = false
}
fun createMaze(){
var stack = Stack<Cell>()
var current:Cell
var next:Cell?
for(x in 0 until COLS){
for(y in 0 until ROWS){
cells[x][y] = Cell(x,y)
}
}
player = cells[0][0]
exit = cells [COLS-1][ROWS-1]
current = cells[0][0]
current.visited = true
do{
next = getNeighbour(current)
if(next != null) {
removeWall(current, next)
stack.push(current)
current = next
current.visited = true
}else{
current = stack.pop()
}
}while (!stack.empty())
}
fun getNeighbour(cell:Cell): Cell? {
var vecinos: ArrayList<Cell> = ArrayList()
//vecino izquierda
if(cell.col > 0) {
if (!cells[cell.col - 1][cell.row].visited) {
vecinos.add(cells[cell.col - 1][cell.row])
}
}
//vecino derecha
if(cell.col < COLS - 1) {
if (!cells[cell.col + 1][cell.row].visited) {
vecinos.add(cells[cell.col + 1][cell.row])
}
}
//vecino arriba
if(cell.row > 0) {
if (!cells[cell.col][cell.row - 1].visited) {
vecinos.add(cells[cell.col ][cell.row - 1])
}
}
//vecino abajo
if(cell.row < ROWS - 1) {
if (!cells[cell.col][cell.row + 1].visited) {
vecinos.add(cells[cell.col][cell.row + 1])
}
}
if (vecinos.size > 0) {
var index = random.nextInt(vecinos.size)
return vecinos[index]
}else {
return null
}
}
fun removeWall(current:Cell,next:Cell){
if (current.col == next.col && current.row == next.row +1){
current.topWall = false
next.bottomWall = false
}
if (current.col == next.col && current.row == next.row -1){
current.bottomWall = false
next.topWall = false
}
if (current.col == next.col + 1 && current.row == next.row){
current.leftWall = false
next.rightWall = false
}
if (current.col == next.col - 1 && current.row == next.row){
current.rightWall = false
next.leftWall = false
}
}
If you want to pass a seed to create the maze, then you have to make sure that all of the players are using the same random number generator. Which means you have to supply your own random number generator implementation.
The application would seed the random number generator with the value you pass, and then it should deterministically generate the same sequence of random numbers for each client.
Note also that you can't ever change the random number generator implementation unless you can prove that the new implementation will generate exactly the same sequence of numbers that the original did.