Создайте игру «Змея» в консоли / терминале


25

Игры веселые

этот кодегольф здесь был настолько веселым, что мне пришлось сделать версию для других классических игр, похожих по сложности. Кратчайший путь создания базовой игры Space Invaders на Python

На этот раз, однако, попытайтесь воссоздать классическую игру «Змея», в которой вы начинаете как маленькая фигура, постоянно переходя к сбору фигур, чтобы увеличить свой счет. Когда вы собираете кусок, ваш «хвост» растет, что следует по пути, который вы сделали. Цель состоит в том, чтобы продержаться как можно дольше, не врезаясь в собственный хвост или в стены

Квалификация:

  • Вы, персонажи, составляющие хвост, стены и предметы, которые вы собираете, должны быть разными персонажами.
  • показать HUD с оценкой. Счет увеличивается на 1 очко за каждый собранный вами предмет.
  • Игрок проигрывает, когда сталкивается со своим хвостом или стеной
  • фигура появляется в случайной области сразу после того, как фигура собрана, не говоря уже о начале игры
  • Скорость игры не имеет значения, если она последовательна
  • «Ячейки» должны быть размером 2х1, так как высота символов блока в два раза больше ширины Может быть 1х1, потому что 2х1 просто уродливо, и я действительно не думал об этом
  • Ключи для изменения направления должны быть awsd , влево, вверх, вниз, вправо соответственно
  • начальное направление всегда должно быть вверх
  • Вы должны показать края стены. Счет может перекрывать стены

Самый короткий код, отвечающий вышеуказанным критериям, выигрывает. Воображаемые бонусные баллы за креативность


Змея не должна расти во время еды?
перестал поворачиваться против часовой стрелки с

гм? «Когда вы собираете кусок, ваш« хвост »растет, что следует по пути, который вы сделали», так что да, змея растет.
Блейзер

2
Без awsdи с starting direction should always be upтребованиями, M-x snakeбудет работать
scrblnrd3

1
@ scrblnrd3 M-: (progn(define-key snake-mode-map"a"'snake-move-left)...(setq snake-initial-velocity-x 0 snake-initial-velocity-y 1)(snake))сделает то же самое.
Джонатан Лич-Пепин

Связанный: Nibbles Nostalgia
sergiol

Ответы:


32

JavaScript ( 553 512 байт)

Ссылка на воспроизводимую версию

c=0;a=b=d=-1;e=[f=[20,7],[20,8]];i=Math.random;~function n(){if(c&&(87==a||83==a
))c=0,d=87==a?-1:1;if(d&&(65==a||68==a))d=0,c=65==a?-1:1;p([j=e[0][0]+c,k=e[0][1
]+d])||!j||39==j||!k||10==k?b+=" | GAME OVER":(e.unshift([j,k]),p(f)?(f=[1+38*i(
)|0,1+9*i()|0],b++):e.pop());for(m=h="";11>h;h++){for(g=0;40>g;g++)l=g+","+h,m+=
!g||39==g||!h||10==h?"X":e[0]==l?"O":p(l)?"*":f==l?"%":" ";m+="\n"}x.innerHTML=m
+b;!b.sup&&setTimeout(n,99)}();onkeydown=function(o){a=o.keyCode};function p(o){
return e.join(p).indexOf(p+o)+1}

Сначала я попытался вывести его на реальную консоль (с помощью console.logи console.clear), но он слишком сильно мерцал, поэтому я поместил его в консольный HTML. Это будет работать с этим:

<pre id=x>

Также я сначала реализовал это с ячейками 2x1, но это выглядело хуже, чем 1x1. Это было бы небольшое изменение, хотя.

Использует awsdклавиши на клавиатуре.

Обновить:

Мне удалось сократить его до 512 (ровно 0x200) байтов, улучшив поиск хвоста и выполнив еще немного волшебства.

Теперь вы получаете 2 очка, когда фигура появляется в вашем хвосте (это особенность). Я также исправил перекрытие, когда змея кусает себя.


1
прекрасный! и вы правы, это выглядит лучше как 1x1, чем 2x1. единственное беспокойство, которое у меня действительно было, было то, что вверх и вниз было намного быстрее, чем влево и вправо, но это выполнимо, учитывая ограничения. Вспышка в консоли, я не очень против (см. Мою программу космических захватчиков, она довольно мерцает), но я полагаю, что веб-страница в виде простого текста тоже работает! хотя одно недоумение ... есть ли способ перезагрузить компьютер без необходимости обновления? :(
Блейзер

Не работает сawsd
Нафтали ака Нил

@Blazer Это займет больше 13 символов: - / ... и у вас все равно будет клавиша F5.
скопировать

@Neal Да, я использовал клавиши со стрелками, но исправил это сейчас.
скопировать

@ Копия Полагаю, я не сделал это обязательным требованием
Blazer

21

Машинный код x86 (128 байт)

Так же, как и в моем материале « Создание фрактала Mandlebrot» , я написал программу для игры в змею размером 128 байт. Он не полностью отвечает требованиям задачи (он начинает двигаться правильно, не все стены прорисованы), но я публикую его, потому что считаю его интересным и креативным решением. Оценка отображается в двоичном виде справа, клавиши со стрелками управляют направлением движения, «еда» выбрасывается случайным образом и заканчивается, если вы ударите себя, стену или край экрана.

Ссылка на исполняемый файл и исходный код

Скриншот

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


Почему DOSBox считается обманом? Это совершенно законная платформа.
dfeuer

9

16 бит 8086

526 байт / 390 байт

Расшифруйте его с помощью декодера Base64 и назовите его «snake.com», а затем выполните из командной строки Windows. Протестировано на WinXP, вам может понадобиться использовать DosBox, чтобы получить правильный режим видео. Управляющими клавишами являются 'wasd' и место для выхода. Нажмите «w», чтобы начать.

uBMAzRC5AD+2AOipAb1AAbgAoI7Auf//v4sMsAHzqrgAtLksAfOqg8cU/sx19OgsAYs+8gKwAuj4
ALQAzRpCiRYOA4kWEAPouAC0C80hCsB0IbQIzSG+ygKDxgOAPAB0EjgEdfSLRAGzAP/Qo1cBiB7w
AulqAIEGdAGu/7P+uNECgMMEw7MCuNsCgMMGw4s+8gKLHvACisPolwADv+YCJoo16I0AiT7yAoD+
A775AnREiz70AiaKHbAA6HUAA7/mAok+9AKA/gB0FscGVwHNAoEudAGu/zPJtj/o2QDofQC0AM0a
OxYOA3X2/wYOA+lZ/8YEAE7+BIA8CnT16F4AaOAB6EQAM9K5LQD38YvCweACBQoA9+WL+OguALlL
ADPS9/HB4gKDwgsD+iaAPQB10rADiMRXq4HHPQGrq4HHPAGrq4HHPQGrX8OhEAO62wD34rntf/fx
iRYQA4vCw772Ar8K9bUEshCstACL2AHDi4f6ArMDtwXR+LEAwNEC/smA4Q8miA0p7/7PdevoIQA6
xHQE/st13ugKAP7NdcroAwB1+8O3BSbGBQEp7/7PdfaBx0EG/srDuBAQM9uAwwLNEID7CnX2w7gD
AM0QzSB3dgEgxgIAYYcBZIUBIMYCAHd8AXN+ASDGAgAA+wAF/P8EAAIAH4ofigAAAADRxeD/TJlO
gQPvQrVA4++BVdVjgQ==

Вот версия в символьном режиме длиной 390 байт:

uAMAzRC4ALiOwLlQADP/uCCf86uzF6u4AA+xTvOruCCfq7LdfCxUPOr6BgBiz5+AqF8Aqu0AM0aQ
okWhgKJFogC6MUAtAvNIQrAdCG0CM0hvlYCg8YDgDwAdBI4BHX0i0QBswD/0KNSAYgefALpdgCBB
m8Bov+z/rhdAoDDBMOzArhnAoDDBsOLPn4Cix58AiaJHQOclgmijUmiR2JPn4CgP4DvoUCdFOLPo
ACJoodJscFAAADv3JYiT6AAoD+AHQkxwZSAVkCgS5vAaL/vwEAudAHJoA9qnUEJsYFzIPHAuLx6F
4AtADNGjsWhgJ19oMGhgIC6Uz/xgQATv4EgDwKdPXoPgBo5wHoIgC5FwD38Wn6oADoFgC5TgD38U
ID0gP6JoA9AHXhJscFA93DoYgCutsA9+K57X/38YkWiAKLwjPSw76CAr8CALkEALSfrAQwq+L6w8
0gd3EBIFcCAGGCAWSAASBXAgB3dwFzeQEgVwIAYP+gAP7/AgACqtAH0AcAAAAA

В этом режиме персонажа на три байта длиннее (но змея лучше):

uAMAzRC4ALiOwLlQADP/uCCf86uzF6u4AA+xTvOruCCfq/7LdfCxUPOr6BsBiz6BAibHBQEKtADN
GkKJFokCiRaLAujHALQLzSEKwHQhtAjNIb5ZAoPGA4A8AHQSOAR19ItEAbMA/9CjUwGIHn8C6XgA
gQZwAaD/s/64YAKAwwTDswK4agKAwwbDiz6BAosefwImiR0Dv3VYJoo1JscFAQqJPoECgP4DvogC
dFOLPoMCJoodJscFAAADv3VYiT6DAoD+AHQkxwZTAVwCgS5wAaD/vwEAudAHJoA9qnUEJsYFzIPH
AuLx6F4AtADNGjsWiQJ19oMGiQIE6Ur/xgQATv4EgDwKdPXoPgBo6gHoIgC5FwD38Wn6oADoFgC5
TgD38UID0gP6JoA9AHXhJscFA93DoYsCutsA9+K57X/38YkWiwKLwjPSw76FAr8CALkEALSfrAQw
q+L6w80gd3IBIFoCAGGDAWSBASBaAgB3eAFzegEgWgIAYP+gAP7/AgACqtAH0AcAAAAA

Очки за креативность, но я думаю, что использование dosbox - это обман, потому что задача состоит в том, чтобы заставить игру работать в консоли или терминале ascii, а не в dosbox. Кроме того, не должен ли код гольфа быть исходным кодом, а не двоичным?
Блейзер

7
@Blazer: Это исходный код - я набрал машинный код с помощью шестнадцатеричного редактора - вот какой я 337! ;-) DosBox необходим только в том случае, если у ваших видеодрайверов проблемы с графикой в ​​режиме 13 (с моей картой все в порядке). Не составит труда сделать версию ASCII (возможно, тоже меньше)
Skizz

«390-байтовая» версия декодирует только до 388 байт и зависает при запуске под dosbox. Похоже, что-то могло быть потеряно при передаче. :( Тем не менее, две другие версии очень крутые!
Илмари Каронен

Есть ли версия кода без присмотра? (Я не знаю этого языка)
AL

1
@ n.1: Программа представляет собой машинный код 8086, вы можете загрузить его в отладчик (D86) и просмотреть код в письменном виде, хотя и без имен меток.
Skizz

6

ракушка / ш, 578 символов

Я пытался быть POSIX-совместимым (будучи максимально переносимым и избегать ошибок, даже генератор случайных чисел не нуждается в / proc). Например, вы можете воспроизвести его в своем родном терминале или через SSH-сессию: запустите с помощью 'dash -c ./snake'. Существует также не читаемый / читаемый вариант в ~ 2800 байт, который можно увидеть здесь .

Некоторые примечания: shell-скриптинг не подходит для кодирования игр 8-)

  • чтобы быть справедливым, мы использовали только так называемые «встроенные», что означает:
    • нет внешних вызовов таких программ, как 'clear', 'stty' или 'tput'
    • из-за этого мы перерисовываем весь экран при каждом движении
    • единственные используемые встроенные команды (также известные как команды):
      • echo, eval, while-loop, let, break, read, case, test, set, shift, alias, source
  • нет генератора случайных чисел (PRNG), поэтому мы должны построить свой собственный
  • получать блоки нажатия клавиш, поэтому мы должны порождать другой поток
    • для получения события в parent-task мы используем временный файл (некрасиво!)
  • Сама змея - это список, который дешев:
    • каждый элемент представляет собой (x, y)-кортеж
    • потеря хвоста означает: сдвинуть список на 1
    • добавление (нового) заголовка означает: добавить строку
  • сетка является массивом, но shell / sh не знает этого:
    • мы "эмулировали" массив (x, y) через некрасивый eval-вызов с глобальными переменными
  • и наконец: нам было очень весело!
#!/bin/sh
alias J=do T=let E=echo D=done W=while\ let
p(){ eval A$1x$2=${3:-#};}
g(){ eval F="\${A$1x$2:- }";}
r(){
E $((1+(99*I)%$1))
}
X=9
Y=8
L="8 8 $X $Y"
I=41
W I-=1
J
p $I 1
p $I 21
p 1 $I
p 41 $I
D
p 3 3 :
>L
W I+=1
J
E -ne \\033[H
y=22
W y-=1
J
Z=
x=42
W x-=1
J
g $x $y
Z=$Z$F
D
E "$Z"
D
E $B
. ./L
case $D in
a)T X+=1;;d)T X-=1;;s)T Y-=1;;*)T Y+=1;;esac
g $X $Y
case $F in
\ |:)p $X $Y O
L="$L $X $Y"
case $F in
:)W I+=1
J
x=`r 39`
y=`r 19`
g $x $y
[ "$F" = \  ]&&{
p $x $y :
break
}
D
T B+=1;;*)set $L
p $1 $2 \ 
shift 2
L=$@;;esac;;*).;;
esac
D&
while read -sn1 K
J
E D=$K>L
D

введите описание изображения здесь


Это на самом деле работает ? если змея идет направо и вы нажимаете, aона останавливается. Weird.
gniourf_gniourf

Да потому что ты кусаешь себя - так оно и должно быть ИМХО. Мы обсуждали это внутренне, и все согласны с этим.
Бастиан Битторф

echo -nопределенно не портативный Если первый операнд -n, или если любой из операндов содержит символ обратной косой черты ('\'), результаты определяются реализацией. Использование echo для всего, кроме буквального текста, без каких-либо переключателей не является переносимым. pubs.opengroup.org/onlinepubs/009604599/utilities/echo.html
nyuszika7h

nyuszika7h: есть идеи как обойти это?
Бастиан Битторф

nyuszika7h: я нашел способ удалить основной вызов 'echo -n' - так что остался только один вызов. он вызывает escape-последовательность для 'go to home-position (0,0)'
Бастиан Битторф,

4

Ruby 1.9 / только для Windows / ( 354 337 355 346 байт)

require'Win32API';G=(W=Win32API).new g="crtdll","_getch",t=[],?I
B=(c=?#*39+h="#
#")+((S=' ')*38+h)*20+c;n=proc{c while B[c=rand(800)]!=S;B[c]=?*;S}
n[h=760];k={97=>-1,100=>1,119=>d=-41,115=>41}
(B[h]=?O;system'cls';$><<B<<$.;sleep 0.1
d=k[G.call]if W.new(g,"_kbhit",[],?I).call>0
t<<h;B[h]=?o;B[h+=d]==?*?B[h]=n[$.+=1]:B[t.shift]=S)while B[h]==S

Играет на доске 20х40 в консоли Windows. Оценка показана под доской. Используйте WASDдля управления змеей, любой другой ключ для выхода (принудительно!). Отредактируйте время ожидания в конце строки 5, чтобы контролировать скорость. (Или сохраните 10 символов и сделайте его практически неиграбельным, удалив сон полностью!)

Бонусная функция: случайно не запускается (когда начальная часть генерируется в месте змеи).

Мне нужно ~ 100 символов, чтобы обойти отсутствие неблокирующего getchar. Очевидно, Ruby 1.9.3 включает библиотеку «io / console», которая бы сохранила примерно половину из них. И это решение специфично для Windows. Существуют опубликованные решения для подобных вещей в системах * nix, но я не проверял их для сравнения количества символов.

Редактировать:

Пришлось добавить 18 байт после того, как я понял, что хвост растет только после еды, а не после каждого шага.

Редактировать 2: (возможно) исправлена ​​проблема с аварийным завершением, сохранялись 9 байтов, ограничиваясь одним элементом питания.


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

Вы добавили комментарий, пока я работала над его исправлением ... Если предполагается, что будет только одна часть, я могу удалить 9.times{}, сохранив 9 символов.
AShelly

единственное требование состоит в том, чтобы за один раз было по 1 и более кусочкам еды, так что да, вы можете просто сделать это по 1 кусочку за раз, сохранив несколько символов
Blazer

игра случайно упала на меня на ~ 140 баллов, не знаю почему. но в остальном очень приятно
Блейзер

Исправлено падение, я думаю. Если снова произойдет сбой, сообщите мне об ошибке ruby.
AShelly

4

Applesoft Basic - 478 (462)

Это был мой первый кодовый гольф, но он был написан еще в 1989 году, и он в основном реализует игру змей по запросу (но без еды, змей просто непрерывно растет, и на самом деле это два игрока, а не один), используя только две линии Applesoft Basic.

В то время было несколько конкурсов двухстрочных программ, например, в журнале Dr. Dobbs. Я потратил 6 месяцев на то, чтобы разобраться, как вписать это в две строки, которые имеют ограничение в 255 символов (и только одну ветку).

Более подробная информация на: http://davesource.com/Projects/SpeedWaller/

Программа набрана ровно в две строки:

1ONSCRN(X,Y)<>7ANDB<>0ANDSCRN(U,V)<>7GOTO2:HOME:GR:X=10:Y=20:U=30:V=Y:I=201:J=202:K=203:M=205:W=215:A=193:S=211:Z=218:O=1:Q=-1:P=49152:COLOR=7:HLIN0,39AT0:HLIN0,39AT39:VLIN0,39AT0:VLIN0,39AT39:VTAB22: ?"WASZ IJKM  "C:ONB=0GOTO2:CALL-678:RUN
2PLOTX,Y:PLOTU,V:B=PEEK(P):G=B<>ZANDB<>W:H=B<>AANDB<>S:O=G*(O*H+(B=S)-(B=A)):L=H*(L*G+(B=Z)-(B=W)):G=B<>IANDB<>M:H=B<>JANDB<>K:Q=G*(Q*H+(B=K)-(B=J)):R=H*(R*G+(B=M)-(B=I)):X=X+O:Y=Y+L:U=U+Q:V=V+R:FORN=1TO99:NEXT:C=C+1:VTAB22:HTAB12:?C:GOTO1

Листинг в отформатированном виде выглядит так:

1 ONSCRN(X,Y)<>7 AND B<>0 AND SCRN(U,V) <> 7 GOTO 2: HOME : GR :
  X=10 : Y=20 : U=30 : V=Y : I=201 : J=202 : K=203 : M=205 : W=215 :
  A=193 : S=211 : Z=218 : O=1 : Q=-1 : P=49152 : COLOR=7 : HLIN 0,39
  AT 0 : HLIN 0,39 AT 39 : VLIN 0,39 AT 0 : VLIN 0,39 AT 39 : VTAB 22 :
  ? "WASZ IJKM  "C : ON B=0 GOTO 2 : CALL -678 : RUN
2 PLOT X,Y : PLOT U,V : B=PEEK(P) : G= B<>Z AND B<>W: H=B<>A AND B<>S :
  O=G*(O*H+(B=S)-(B=A)) : L=H*(L*G+(B=Z)-(B=W)) : G=B<>I AND B<>M :
  H=B<>J AND B<>K : Q=G*(Q*H+(B=K)-(B=J)) : R=H*(R*G+(B=M)-(B=I)) :
  X=X+O : Y=Y+L : U=U+Q : V=V+R : FOR N=1 TO 99 : NEXT : C=C+1 :
  VTAB 22 : HTAB 12 : ? C : GOTO 1

На самом деле в игре участвуют два игрока. В нижней части страницы находятся «инструкции» с клавишами и счетчиком, чтобы вы могли увидеть, сколько шагов вы пережили. Это 478 символов, из них 16 команд и вывод счетчика, поэтому 462, если вы хотите сбрить их.


4

C # .NET Framework 4.7.2 Console ( 2456 2440 2424 2408 2052 1.973 1747 1686 байт)

Это было весело, но мне действительно нужно было подумать, что это за переменные, потому что они всего одна буква.

using m=System.Console;using System;using System.Collections.Generic;using System.Threading;class s{static void Main(){m.CursorVisible=0>1;new s()._();}int l;Action<string> w=(x)=>m.Write(x);Action<int,int>n=(x,y)=>m.SetCursorPosition(x,y);(int x,int y)d,c,a;int h,u;List<(int x,int y)>p;void _(){while(1>0){f();h=25;u=25;p=new List<(int x,int y)>();l=0;d=(0,-1);c=(u/2,h/2);e();m.SetWindowSize(u+4,h+4);m.SetBufferSize(u+4,h+4);while(1>0){k();if(t())break;g();r();}f();m.SetWindowSize(u+4,h+6);m.SetBufferSize(u+4,h+6);n(1,h+3);w("        Game over,\n   press any key to retry.");f();m.ReadKey(1>0);m.Clear();}}private bool t(){if(c.x<0||c.y<0||c.x>=u||c.y>=h){r();n(c.x+2,c.y+2);w("X");return 1>0;}for(i=0;i<p.Count;i++){for(int j=0;j<i;j++){if(p[i].x==p[j].x&&p[i].y==p[j].y){r();n(c.x+2,c.y+2);w("X");return 1>0;}}}return 0>1;}private void e(){a=(z.Next(u),z.Next(h));l++;}void f(){while(m.KeyAvailable)m.ReadKey(1>0);}int i;void k(){var b=DateTime.Now;while((DateTime.Now-b).TotalMilliseconds<230)Thread.Sleep(10);if(!m.KeyAvailable)return;var a=m.ReadKey(1>0).Key;switch(a){case ConsoleKey.A:if(d.x==0)d=(-1,0);break;case ConsoleKey.W:if(d.y==0)d=(0,-1);break;case ConsoleKey.S:if(d.y==0)d=(0,1);break;case ConsoleKey.D:if(d.x==0)d=(1,0);break;}f();}void g(){c.x+=d.x;c.y+=d.y;p.Add((c.x,c.y));while(p.Count>l)p.RemoveAt(0);if(c.x==a.x&&c.y==a.y)e();}void r(){n(1,1);w("/");w(new string('-',u));w("\\");n(1,h+2);w("\\");w(new string('-',u));w("/");for(i=0;i<h;i++){n(1,i+2);w("|");n(u+2,i+2);w("|");}for(i=0;i<h;i++){for(int j=0;j<u;j++){n(i+2,j+2);w(" ");}}n(a.x+2,a.y+2);w("@");for(i=0;i<p.Count;i++){n(p[i].x+2,p[i].y+2);w("#");}n(2,0);w("Score:"+l);}Random z=new Random();}

Некоторые скриншоты:

Змея со счетом 10 Снейк разбился со счетом 4

Двоичный файл: https://github.com/wooden-utensil/snakeCodeGolf/releases/tag/v1.0.0.0

GitHub репозиторий: https://github.com/wooden-utensil/snakeCodeGolf

Журнал изменений: https://github.com/wooden-utensil/snakeCodeGolf/releases


1
Console.Write("Score:"+l);Console.WriteLine()->Console.WriteLine("Score:"+l)
Стивен

1
Вы пробовали кортежи как в (int X,int Y)d; ...; d=(0,-1)? Это может сэкономить байты. Я также не понимаю, почему ты делаешь Vector2 d;Vector2 c;Vector2 a;вместо Vector2 d,c,a. Я думаю, вы также можете сохранить функцию Console.SetCursorPosition в виде Action<...>однобуквенной переменной. Вы можете вычесть DateTime с помощью оператора -. Вы также можете объявлять переменные цикла глобально и просто обнулять их при необходимости, не объявляя их.
мое местоимение monicareinstate

1
[предложения продолжаются] Вы можете использовать 1>0или хранить trueв переменной вместо использования ключевого слова. Вы можете использовать великолепный оператор -> в циклах. В DateTime b = DateTime.Nowчасти, bможет быть var. Вы можете или не сможете сохранить некоторые байты с помощью dynamic(часто позволяет объединять объявления разных типов).
мое местоимение monicareinstate

1
Использование m.write(String)собственной функции,
состоящей из

1
Есть также несколько блоков, которые используют, b.widthи b.heightмного, которые, вероятно, могут быть сохранены в другой 1-буквенный локальный вар
Веска

3

Питон 3 - 644

from curses import *
import time
from collections import deque
from random import randrange as R
N,W,S,E=z=119,97,115,100
t=tuple
u=0,0
def m(s):
 a=lambda o,y,x:y.addch(o[0],o[1],x);q=lambda:(R(L-2),R(C-2));L,C=s.getmaxyx();curs_set(0);s.nodelay(1);s.border();s.refresh();r=newwin(L-2,C-2,1,1);n=deque();y,x=[L-2,0];d=N;n.append(u);c=N;p=q();a(p,r,N);a(u,s,48)
 while 1:
  if c in z:d=c
  if d==N:y-=1
  if d==S:y+=1
  if d==W:x-=1
  if d==E:x+=1
  l=n.pop()
  if (y,x) in n:return
  if (y,x)==p:p=q();a(p,r,N);n.append(l);s.addstr(0,0,str(len(n)))
  n.appendleft((y,x));a((y,x),r,S);a(l,r,32);r.refresh();time.sleep(.2);c=s.getch()
wrapper(m)

Не выходит чисто. Часть может исчезнуть, если она появляется на вершине змеи.


1

Баш (слишком много символов: около 1522)

t=tput
tc="$t cup"
tr="$t rev"
ts="$t sgr0"
ox=5
oy=5
((w=$($t cols)-2-2*ox))
((h=$($t lines)-2-2*oy))
trap "$t rmcup
stty echo
echo 'Thanks for playing snake!'
" EXIT
$t smcup
$t civis
stty -echo
clear
printf -v hs %$((w+2))s
printf -v v "|%${w}s|"
$tc $oy $ox
printf %s ${hs// /_}
for((i=1;i<=h+1;++i)); do
$tc $((oy+i)) $ox
printf %s "$v"
done
$tc $((oy+h+2)) $ox
printf %s ${hs// /¯}
dx=0
dy=-1
hx=$((w/2))
hy=$((h-2))
l=2
xa=($hx $hx)
ya=($hy $((hy+1)))
$tr
for((i=0;i<${#xa[@]};++i)); do
$tc $((ya[i]+1+oy)) $((xa[i]+1+ox))
printf \ 
done
$ts
print_food() {
$tc $((fy+1+oy)) $((fx+1+ox))
printf "*"
}
nf() {
rf=1
while((rf))
do
rf=0
((fx=RANDOM%w))
((fy=RANDOM%h))
for ((i=0;i<${#ya[@]};++i))
do
if((ya[i]==fy&&xa[i]==fx))
then
rf=1
break
fi
done
done
print_food
}
nf
ps() {
s="SCORE: $l"
$tc $((oy-1)) $((ox+(w-${#s})/2))
printf "$s"
}
ps
while :
do
read -t 0.2 -s -n1 k
if (($?==0))
then
case $k in
w|W)((dy==0))&&{ dx=0;dy=-1;};;
a|A)((dx==0))&&{ dx=-1;dy=0;};;
s|S)((dy==0))&&{ dx=0;dy=1;};;
d|D)((dx==0))&&{ dx=1; dy=0;};;
q|Q)break;;
esac
fi
((hx=${xa[0]}+dx))
((hy=${ya[0]}+dy))
if((hx<0||hy<0||hx>w||hy>h))
then
go=1
break
fi
for((i=1;i<${#ya[@]}-1;++i))
do
if((hx==xa[i]&&hy==ya[i]))
then
go=1
break 2
fi
done
$tc $((ya[-1]+1+oy)) $((xa[-1]+1+ox))
printf \ 
$tr
$tc $((hy+1+oy)) $((hx+1+ox))
printf \ 
$ts
if((hx==fx&&hy==fy))
then
((++l))
ps
nf
else
ya=(${ya[@]::${#ya[@]}-1})
xa=(${xa[@]::${#xa[@]}-1})
fi
ya=($hy ${ya[@]})
xa=($hx ${xa[@]})
done
if((go))
then
$tc 3 3
echo GAME OVER
read -t 3 -s -n1
fi

Скриншот

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.