Шахматные доски в котлине. Какой тип данных?

Я думаю, что этот вопрос еще не задан.

Дело в том, что в шахматах мы используем битовые доски для ускорения циклов генерации ходов, представляя позицию битом = 1, а другую - битом = 0. В шахматах у нас 8*8 позиций. В сочетании с современным процессором рекомендуется реализовать это в 64-битных целых числах без знака. В C++ мы можем использовать беззнаковый 64-битный адрес int64_t и присвоить ему что-то вроде этого:

Однако мой вопрос в том, как бы мы это сделали в Котлине. Поскольку kotlin наследует типы данных java, у нас не может быть беззнаковой 64-битной битовой доски, только 63 бита, а для шахмат этого недостаточно. Например.

val whiteInit = 0b11111111_11111111_00000000_00000000_00000000_00000000_00000000_00000000L // cant dos this (=>out of range)
val blackInit = 0b00000000_00000000_00000000_00000000_00000000_00000000_11111111_11111111L // this works

Я не хочу усугублять ситуацию и разбивать строки в разных массивах, как я читал несколько раз, потому что это уродливо и, вероятно, не так быстро.

Итак, я наткнулся на тип данных ULong в «kotlin-stdlib/kotlin/Experimental», и то, что я написал, выглядит многообещающе. Итак, во-первых, спасибо за то, что дочитали до сюда, а во-вторых, это правильный путь или я упускаю что-то лучшее?


person Plagueis    schedule 03.07.2020    source источник


Ответы (1)


Для растровой доски вам нужно иметь 64 бита, но вам не нужна интерпретация как числа. Таким образом, Long будет работать так же хорошо, если я что-то не упустил (и то же самое сделал бы Double, если бы для него были определены побитовые операции). Или вы можете использовать java.util.BitSet, хотя, вероятно, это будет медленнее.

person Alexey Romanov    schedule 03.07.2020
comment
Теоретически я могу отстать от этого, пока (долго: D) у вас есть 64-битная версия, которую вы запустите. С твиками я даже представить себе меньше не могу. Но, я спрашиваю вас, как бы вы это записали: val whiteInit = 0b11111111_11111111_00000000_00000000_00000000_00000000_00000000_00000000L // не могу это сделать (=›вне диапазона) - person Plagueis; 03.07.2020
comment
Самый простой способ, который я могу придумать, это BigInteger("1111111111111111000000000000000000000000000000000000000000000000", 2).toLong() (импорт java.math.BigInteger). Или разделить на 2 части: (0b11111111_11111111_00000000_00000000L shl 32) + 0b00000000_00000000_00000000_00000000L. - person Alexey Romanov; 03.07.2020
comment
Это может сработать, но меня это ужасно раздражает. У меня есть пара сотен битбордов. Я просто буду придерживаться ULong, я не думаю, что они избавятся от него, и они не могут кардинально измениться, чтобы он больше не работал в моем коде. Оценил! - person Plagueis; 04.07.2020