Home > Back-end >  Why is containsAll with multi-dimensional lists always returning false?
Why is containsAll with multi-dimensional lists always returning false?

Time:11-26

There's a code where I am trying to create Tic-Tac-Toe. When I tried to compare two lists to see if X or O won, I always got a false. Why? Is there another way to test for equality between lists?

fun main() {
    val userInput = readln()
    val gameBoard = mutableListOf(
        mutableListOf(userInput[0], userInput[1], userInput[2]),
        mutableListOf(userInput[3], userInput[4], userInput[5]),
        mutableListOf(userInput[6], userInput[7], userInput[8])
    )
    val decisions = listOf(
        listOf(0, 1, 2), listOf(3, 4, 5), listOf(6, 7, 8),
        listOf(0, 3, 6), listOf(1, 4, 7), listOf(2, 6, 8),
        listOf(0, 4, 8), listOf(2, 4, 6)
    )
    val whereXPlaced = MutableList(3) { (MutableList(3) { 0 }) }
    val whereOPlaced = MutableList(3) { (MutableList(3) { 0 }) }
    for (i in 0 until gameBoard.size) {
        for (j in 0 until gameBoard.size) {
            if (gameBoard[i][j] == 'X') {
                whereXPlaced[i][j] = j
            } else if (gameBoard[i][j] == 'O') {
                whereOPlaced[i][j] = j
            }
        }
    }
    if (decisions.containsAll(whereXPlaced)) {
        println("x win")
    } else if(decisions.containsAll(whereOPlaced)) {
        println("o win")
    }
}

CodePudding user response:

about the implementation itself, it's not quite right, let's assume the input is "XXX00O00O" , with your impl. you will get:

whereXPlaced = [[0,1,2],[0,0,0],[0,0,0]]
whereOPlaced = [[0,0,0],[0,0,2],[0,0,2]]

and containsAll checks if a list contains all the items in another list, for example:

val m1 = listOf(1,2,3,4,5)
val m2 = listOf(1,2)
m1.containsAll(m2) // true

// or using 2D lists
val m1 = listOf( listOf(1,2,3), listOf(4,5,6), listOf(7,8,9),)
val m2 = listOf( listOf(1,2,3), listOf(4,5,6),)
m1.containsAll(m2) // true

if you want to keep the same decisions list then you can use this:

fun main() {
  val userInput ="XXX--O--O"

  val gameBoard = mutableListOf(
     mutableListOf(userInput[0], userInput[1], userInput[2]),
     mutableListOf(userInput[3], userInput[4], userInput[5]),
     mutableListOf(userInput[6], userInput[7], userInput[8])
  )
  val decisions = listOf(
     listOf(0, 1, 2), listOf(3, 4, 5), listOf(6, 7, 8),
     listOf(0, 3, 6), listOf(1, 4, 7), listOf(2, 6, 8),
     listOf(0, 4, 8), listOf(2, 4, 6)
  )

  val whereXPlaced = mutableListOf<Int>()
  val whereOPlaced = mutableListOf<Int>()
  for (i in 0 until gameBoard.size) {
     for (j in 0 until gameBoard.size) {
        if (gameBoard[i][j] == 'X') {
          whereXPlaced.add((i*gameBoard.size) j)
        } else if (gameBoard[i][j] == 'O') {
          whereOPlaced.add((i*gameBoard.size) j)
        }
     }
  }

  if (decisions.contains(whereXPlaced)) {
     println("x win")
  } else if(decisions.contains(whereOPlaced)) {
     println("o win")
  }
}

note that we're using 1D lists for whereXPlaced and whereXPlaced because decisions list contains 1D lists, and we're using a simple contains , also (i*gameBoard.size) j so if i = 2 and j = 0 then the flattened index is (2*3) 0 == 6

or if you want to keep the same decisions list and a 2D whereXPlaced/whereOPlaced then you can use something like this:

fun main() {
  val userInput = "xxx--o--o"
  val gameBoard = mutableListOf(
     mutableListOf(userInput[0], userInput[1], userInput[2]),
     mutableListOf(userInput[3], userInput[4], userInput[5]),
     mutableListOf(userInput[6], userInput[7], userInput[8])
  )
  val decisions = listOf(
     listOf(0, 1, 2), listOf(3, 4, 5), listOf(6, 7, 8),
     listOf(0, 3, 6), listOf(1, 4, 7), listOf(2, 6, 8),
     listOf(0, 4, 8), listOf(2, 4, 6)
  )
  val whereXPlaced = MutableList(3) { (MutableList(3) { false }) }
  val whereOPlaced = MutableList(3) { (MutableList(3) { false }) }
  for (i in 0 until gameBoard.size) {
     for (j in 0 until gameBoard.size) {
        if (gameBoard[i][j] == 'x') {
          whereXPlaced[i][j] = true
        } else if (gameBoard[i][j] == 'o') {
          whereOPlaced[i][j] = true
        }
     }
  }

  val x_indices = whereXPlaced.flatten().foldIndexed(mutableListOf<Int>()) { index, acc, b -> 
     if (b) acc.add(index) ; acc }
  val o_indices = whereOPlaced.flatten().foldIndexed(mutableListOf<Int>()) { index, acc, b ->
     if (b) acc.add(index) ; acc }


  if (decisions.contains(x_indices)) {
     println("x win")
  } else if(decisions.contains(o_indices)) {
     println("o win")
  }
}
  • Related