Вики ZooBC
Приложения и разработка на ZooBC

Многопользовательские приложения

В настольные игры и игры в кости в ZooBC играют от двух до четырёх человек, и каждый ход — это транзакция, которую каждый узел проверяет по одним и тем же правилам. Ставки образуют банк, который протокол выплачивает, когда игра заканчивается, за вычетом рейка 1 % в пользу пула приложений, если только игра не заканчивается вничью.

Открытие и присоединение

Игрок открывает игру транзакцией CreateApp, выбирая тип и от 2 до 4 мест (в морском бое всегда ровно 2), и вносит первую ставку. Игра становится открытой (Open). Каждая JoinApp вносит равную ставку, и когда занято последнее место, игра становится активной (Active). Необязательно названный соперник превращает игру в прямой вызов, к которому может присоединиться только этот аккаунт.

Для места нужен 36-байтовый аккаунт, например нативный аккаунт ZooBC. Аккаунты с 24-байтовыми адресами, типы Ethereum и хеша Bitcoin, занять место не могут, хотя сообщение об ошибке гласит «multiplayer apps require a ZBC account» (ключи и типы аккаунтов). Одиночные ставки принимают любой аккаунт.

Кто ходит первым

То, кто начинает, может иметь значение, поэтому никто не может знать этого заранее или повлиять на это. Когда занято последнее место, ход находится в ожидании: ничьи часы не идут, и каждый ход — пустая операция. Через два блока механизм разрешения разыгрывает место, которое начинает, — как хеш сида этого блока и идентификатора приложения по модулю числа мест. Производитель блока с последним присоединением знает собственный сид, но не сид двумя блоками позже, поэтому не может включить или не включить присоединение в зависимости от того, кто начнёт. Ни создатель, ни последний присоединившийся не начинают по правилу. Исключение — морской бой: первым ходит присоединившийся, фиксируя свою доску.

В четырёх играх в кости (лудо, свинья, гонка и мини-монополия) ход применяется не в том блоке, который его включает. Он сохраняется как ожидающий и применяется следующим блоком, по сиду этого блока и с ключом по идентификатору транзакции хода, поэтому производитель, включивший ход, никогда не видит бросок. Одновременно допускается один ожидающий ход, а ход, который тем временем стал недопустимым, отбрасывается.

Часы хода

Когда присоединяется последнее место, а затем после каждого принятого хода, срок устанавливается на 240 блоков вперёд, примерно на час. Игрок, чей ход, должен сходить до этого срока или отправить AppMove с пустым ходом — оплаченное поддержание, которое отодвигает срок ещё на 240 блоков. Ход от игрока, чьи часы не идут, или недопустимый ход отклоняется при отправке; если он всё же попадает в блок, это пустая операция, за которую комиссия не взимается.

Часы хода: через 240 блоков после последнего хода ожидающий игрок может потребовать банк за вычетом рейка 1 %.
Часы хода: через 240 блоков после последнего хода ожидающий игрок может потребовать банк за вычетом рейка 1 %.

Как заканчивается игра

ИсходКакВыплата
Победаход выигрывает игрубанк за вычетом рейка 1 % — победителю
Ничьяход заканчивает игру вничьюкаждое место получает свою ставку обратно; рейка нет
Сдачаигрок отправляет ResignAppбанк за вычетом рейка делится поровну между остальными местами, остаток — первому из них
Тайм-аутсидящий игрок, чьи часы не идут, отправляет ClaimAppTimeout начиная со срока + 1банк за вычетом рейка делится между всеми местами, кроме того, чьи часы идут

Рейк равен floor(банк × 100 ÷ 10 000), то есть 1 % банка: два игрока со ставками по 1 ZBC образуют банк в 2 ZBC, и победитель получает 1,98 ZBC в блоке победного хода. Производитель блока ничего из банка не берёт. Ничто не заканчивается само собой: после пропущенного срока игра ждёт, пока игрок не решит отправить требование, и никто, включая ZooBC Foundation, не может отменить игру.

Движки

Движок каждой игры — часть узла, с несколькими упрощениями, которые стоит знать:

  • в шахматах нет рокировки и взятия на проходе, а пешки всегда превращаются в ферзя;
  • в шашках взятие обязательно, а множественные прыжки продолжаются;
  • в реверси место без допустимого хода пропускает ход;
  • в «точках и квадратах» завершение квадрата даёт ещё один ход;
  • в свинье побеждает тот, кто набрал 100, а гонка, игра «змеи и лестницы», заканчивается на 49;
  • в лудо у каждого места четыре фишки;
  • в мини-монополии каждое место начинает с 1 500 и получает 200 за прохождение поля GO.

Морской бой: секреты в публичной цепочке

Морскому бою нужна скрытая информация в цепочке, где всё публично, и он получает её по схеме «обязательство и раскрытие». Перед игрой каждый игрок выбирает секретную 32-байтовую соль для каждой из 100 клеток доски 10 × 10 и публикует SHA3-256(is_ship ‖ salt) для каждой клетки: 100 хешей, всего 3 200 байт. Создатель отправляет своё обязательство вместе с CreateApp, а присоединившийся — своё в качестве первого хода. Поскольку каждая соль случайна, хеши ничего не раскрывают.

Игрок стреляет ходом [0, cell]. Владелец этой доски должен раскрыть клетку, по которой выстрелили, ходом [1, is_ship, salt], и каждый узел проверяет, что их хеш совпадает с зафиксированным значением. Ложь даёт другой хеш и отклоняется, поэтому владелец может только сказать правду или исчерпать время и проиграть по ClaimAppTimeout. Побеждает первый игрок, поразивший 17 клеток кораблей. Зафиксировать меньше клеток кораблей ничего не даёт: как только стреляющий сделал все 100 выстрелов, а раскрыто меньше 17 клеток кораблей, побеждает стреляющий.

Морской бой по схеме «обязательство и раскрытие»: хеши в цепочке, выстрел и раскрытие, которое проверяет каждый узел.
Морской бой по схеме «обязательство и раскрытие»: хеши в цепочке, выстрел и раскрытие, которое проверяет каждый узел.

См. также