Сыграли на выходных в «Шепот за стеной». Эта настолка в своё время хорошо собрала на Кикстартере, а потом издательство Низа Гамс договорилось о локализации и привезло её в Россию. Кстати, Низа Гамс выросли из настольного видеоблога, при этом ребятам удаётся подписывать по-настоящему интересные и неординарные проекты.
Так вот, «Шёпот за стеной» это асимметричная игра, где один игрок управляет маньяком-убийцей, а 1-3 других игроков становятся жертвами. Игра идёт в стиле классических ужастиков вроде «Пятницы 13»: злодей фактически неуязвим, и от него можно только спрятаться или убежать. Персонажи перемещаются по большому старинному особняку, но фокус в том, что убийца не знает точное положение жертв и должен косвенно вычислять их по издаваемому шуму (шум это специальные жетоны, которые жертвы выкладывают при выполнении нужных им действий). Жертвы могут выиграть двумя способами: сбежать, найдя ключи от особняка, или вызвать полицию, починив телефон. Маньяк, понятное дело, должен для победы кого-то убить.
Прелесть «Шепота» в том, что броский внешний вид, в отличие от многих проектов, не оттеняет бедность игровых механик, а, наоборот, служит для их усиления. Красивая конструкция в виде дома — это и разделитель между полями (чтобы игроки не видели положение друг друга) и встроенная башенка для броска кубиков. Миниатюрки это не просто способ продать коробку подороже, а по-настоящему нужный элемент быстрой оценки диспозиции на поле. Вообще, многие мелочи здесь продуманы очень хорошо и прекрасно работают: так, например, с течением партии силы маньяка растут, что является естественным таймером конца игры без всяких там «после N ходов вы проиграли».
Правила простые, партии не очень длинные, даунтайма почти нет, в игре есть и блеф, и напряжённость и стратегия. Хотелось бы сказать, что она вообще идеальна во всём, но минус присутствует: совсем хорошо играется только на четверых. Любым другим составом уже чуть менее удобно, потому что одному игроку приходится брать нескольких персонажей. Хотя тоже возможно, у нас даже двое за убийцу играли (что правилами не предусмотрено).
Тем не менее, я купил базу и все дополнения, и очень советую. В базе пять персонажей жертв и три вида убийц с разными особыми свойствами, в дополнениях в основном ещё убийцы плюс новые виды особняков. Кстати, несмотря на тематику и надпись 18+, никакой жестокости тут нет, и можно без проблем играть с подростком 12-13 лет и старше.
#games
https://docs.python.org/3/library/functools.html#functools.partialmethod
class #functools.partialmethod(func, *args, **keywords)
Return a new #partialmethod descriptor which behaves like partial except that it is designed to be used as a method definition rather than being directly callable.
func must be a descriptor or a callable (objects which are both, like normal functions, are handled as descriptors).
When func is a descriptor (such as a normal Python function, classmethod(), staticmethod(), abstractmethod() or another instance of partialmethod), calls to __get__ are delegated to the underlying descriptor, and an appropriate partial object returned as the result.
When func is a non-descriptor callable, an appropriate bound method is created dynamically. This behaves like a normal Python function when used as a method: the self argument will be inserted as the first positional argument, even before the args and keywords supplied to the partialmethod constructor.
https://www.python.org/dev/peps/pep-0443/
This PEP proposes a new mechanism in the #functools standard library module that provides a simple form of generic programming known as #single_dispatch#generic functions.
A generic function is composed of multiple functions implementing the same operation for different types. Which implementation should be used during a call is determined by the #dispatch algorithm. When the implementation is chosen based on the type of a single argument, this is known as #single_dispatch .
#overloading
https://docs.python.org/3/library/asyncio-eventloop.html
#Calls
Most #asyncio functions don’t accept keywords. If you want to pass #keywords to your callback, use #functools.partial(). For example, #loop.#call_soon(functools.partial(print, "Hello", flush=True)) will call print("Hello", flush=True).
#Note
functools.partial() is better than lambda functions, because asyncio can inspect functools.partial() object to display parameters in debug mode, whereas lambda functions have a poor representation.
BaseEventLoop.call_soon(callback, *args)
Arrange for a callback to be called as soon as possible. The callback is called after call_soon() returns, when control returns to the event loop.
This operates as a FIFO queue, callbacks are called in the order in which they are registered. Each callback will be called exactly once.
Any positional arguments after the callback will be passed to the callback when it is called.
An instance of asyncio.Handle is returned, which can be used to cancel the callback.
Use functools.partial to pass keywords to the callback.
BaseEventLoop.call_soon_threadsafe(callback, *args)
Like call_soon(), but thread safe.
See the concurrency and multithreading section of the documentation.