Пишу, по большей части, про историю, свою жизнь и немного про программирование.

«Словохват»

Вчера подсел на игру «Словохват», вроде игра незамысловатая, но очень интересная.

Словохват (85.68КиБ)

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

Клетку можно использовать, только если она примыкает к клетке вашего цвета. Клетки чужого цвета захватываются по тому же правилу, но в первый раз они становятся серыми и только в следующий — вашего цвета.

На медиане поля действуют ещё какие-то законы, пока не разбирался, правила есть на сайте. Длина слов важна — упрощённо, чем длинее слово, тем больше вам даётся очков, за очки можно «покупать» различные штуки — дополнительное время, дополнительную букву, «молнию» (вычищает близкорасположенную клетку от цвета противника).

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

Словохватохват (18.24КиБ)

Работает неспешно, я оптимизировать не стал, времени, даваемого игрой, на поиск вполне хватает (по крайней мере на моём ноуте). Если кому-то захочется оптимизации, то просто посмотрите как преобразуется словарь и закешируйте преобразованный вариант.

У меня на каждом запуске словарь преобразуется заново. Естественно, в словаре, помимо разрешённых частей речи, есть прилагательные, глаголы и так далее — их я не отфильтровываю, в словаре нет для этого информации.

# coding: utf-8
import itertools
import sys
import codecs

# дружим с консолью
sys.stdin = codecs.getreader('utf-8')(sys.stdin)
sys.stdout = codecs.getwriter('utf-8')(sys.stdout)

# строки с пропусками любых букв в любом количестве
def combinations(str):
    for l in xrange(2, len(str)+1):
        yield itertools.combinations(str, l)

# собираем каждую в строку
def iterstr(str):
    for s in itertools.chain(*combinations(str)):
        yield u''.join(s)

# все наши комбинации
def uniqcombinations(str):
    return set(iterstr(sorted(str)))

# проходим по словарю
def iterdict(name, min, max):
    with open(name, 'r') as f:
        for line in f:
            line = line.strip().decode('cp1251')

            # текущее слово должно содержать только буквы и быть не больше искомого слова
            if max >= len(line) >= min and line.isalpha():
                yield u''.join(sorted(line)), line

# ищем наше слово
def find(word, dictname):
    words = uniqcombinations(word)

    for line, original in iterdict(dictname, 3, len(word)):
        if line in words: print(original)

# запуск программы и небольшая помощь
try:
    find(sys.argv[2].decode('utf-8'), sys.argv[1].decode('utf-8'))
except IndexError:
    print(u'Запуск: {0} <словарь> <буквы в наличии>'.format(sys.argv[0]))

Писал именно на Пайтоне из-за прекрасного модуля itertools, на этот раз он пригодился функцией combinations — она выдаёт генератор всех комбинаций букв, заданной длины, без изменения их порядка. Очень хорошо, что не пришлось писать этот скучный кусок кода самостоятельно.

Если вы думаете, что выиграть можно бездумно подставляя слова из моей программы, то сильно ошибаетесь — на сайте попадаются противники, которые вас с таким подходом разнесут в пух и прах.

22 комментария
Бабаев Александр (bealex.moikrug.ru) 2013

Letterpress ( http://www.atebits.com/letterpress/ ) наше все :-)

Евгений Степанищев (bolknote.ru) 2013

Комментарий для bealex.moikrug.ru:

На инглише что ли? :)

Бабаев Александр (bealex.moikrug.ru) 2013

Комментарий для Евгения Степанищева:

Угу. Она была первой такой. Бешеная популярность. Очень, очень захватывает. При этом правила сильно проще, чем те, которые ты описал.

Есть и русские варианты, это просто первая.

Евгений Степанищев (bolknote.ru) 2013

Комментарий для bealex.moikrug.ru:

Если проще, значит это совсем другая игра. У меня сегодня утром за завтраком, произошла эпичнейшая битва — я проморгал твёрдый знак, противник его занял и пока я отвлёкся на проход к «столице», противник на этом плацдарме обосновался и выиграл меня. С другими правилами это нереально :)

Бабаев Александр (bealex.moikrug.ru) 2013

Конечно, я не спорю. Просто увидел похожую картинку и вспомнил про Letterpress. Там тоже бывают эпические битвы, стратегии...

Евгений Степанищев (bolknote.ru) 2013

Отказался от регулярок, сделал массив комбинаций и поиск по нему, стало побыстрее.

Denis Ibaev (dionys.moikrug.ru) 2013

Комментарий для Евгения Степанищева:

Смысл-то игры не только в тактике, но и в эрудированности. А так можно было бы просто генерировать случайное число — сколько клеток тебе можно занять. Но это была бы уже другая игра. И я встречался с соперниками, которые, видно по лексикону, не сами находят слова. Играть с ними довольно трудно и не интересно, как с роботом.

Евгений Степанищев (bolknote.ru) 2013

Комментарий для dionys.moikrug.ru:

У меня эрудированность есть, но «программы перебора» в мозгу нет.

Denis Ibaev (dionys.moikrug.ru) 2013

Комментарий для Евгения Степанищева:

Развивай.

Евгений Степанищев (bolknote.ru) 2013

Комментарий для dionys.moikrug.ru:

А зачем? Где это может пригодиться?

Denis Ibaev (dionys.moikrug.ru) 2013

Комментарий для Евгения Степанищева:

В игре «Словохват».

Евгений Степанищев (bolknote.ru) 2013

Комментарий для dionys.moikrug.ru:

Да я как-то не планировал выделять этой игре хоть сколько заметное место в моей жизни :)

Denis Ibaev (dionys.moikrug.ru) 2013

Комментарий для Евгения Степанищева:

Но ты же «подсел» по собственным словам, значит играть будешь достаточно часто. А я описал свои ощущения от подобных соперников. Вероятно, подобное отношение не только у меня.

Евгений Степанищев (bolknote.ru) 2013

Комментарий для dionys.moikrug.ru:

Я вообще ни во что не играю. Так что для меня «подсел» ≈ «провёл один вечер с этой игрой».

Евгений Степанищев (bolknote.ru) 2013

Комментарий для dionys.moikrug.ru:

А я описал свои ощущения от подобных соперников. Вероятно, подобное отношение не только у меня.

Если я не буду пользоваться своей программой, слова будут те же, просто я их буду медленнее подбирать и в таймер буду чаще не укладываться. Так что у тебя будет ощущение, что кто-то листает словарь медленно.

bolknote.ru 2013

Сейчас пришёл домой, попытался сыграть без программы этой. Выиграл.

Denis Ibaev (dionys.moikrug.ru) 2013

Комментарий для Евгения Степанищева:

Если я не буду пользоваться своей программой, слова будут те же, просто я их буду медленнее подбирать и в таймер буду чаще не укладываться. Так что у тебя будет ощущение, что кто-то листает словарь медленно.

Нет, не правда, слова нужно не только знать, но и «увидеть» среди этих букв. Так что без словаря ты не сможешь выдавать серии 10-буквенных слов, как на приведённом тобой скриншоте. (Такие серии, кстати, показатель, что играет не человек.) Разве что время будет не ограничено, да.

Евгений Степанищев (bolknote.ru) 2013

Комментарий для dionys.moikrug.ru:

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

Vladimir Moskva (fulc.ru) 2013

Комментарий для Евгения Степанищева:

Мне играть было скучновато

Неужели с программой стало интереснее? :)

Евгений Степанищев (bolknote.ru) 2013

Комментарий для fulc.ru:

С программой я хоть вечер поиграл и утром чуть :)

Olyezheek 8 мес

Есть ли сейчас где-то эта игра с живыми игроками?

Евгений Степанищев 8 мес

Не знаю.