Вероятно, многим уже надоели заголовки типа «ХХХ в 30 строк», но я рискну написать ещё один пост. Дабы хоть как-то сгладить злость отдельных хабралюдей, я расскажу что в этом скрипте делает каждая строка.
В качестве игры я выбрал Блэкджек. Напомню правила:
Ссылка на jsfiddle.
Сам код:
Итак, рассмотрим каждую его строчку.
В первой строке инициализируется массив с «изображениями» карт.
Во второй строке инициализируется массив с картами, каждая карта представляет массив с тремя элементами: координаты изображения карты и её стоимость. При этом для тузов хранится false, так как он обрабатывается отдельно.
В третьей строке массив карт копируется в другой массив, так как при дальнейших действиях первый массив будет попорчен.
В четвертой и пятой строках объявляется функция перемешивания колоды.
В шестой строке объявляется короткая функция для замены длинного document.getElementById.
В седьмой строке объявляются наборы карт игрока и дилера, а также ссылки на размер ставки, количество денег игрока, текущий кон, контейнер с картами игрока и дилера и место для показа сообщений.
Восьмая строчка. Функция добавления карты дилеру.
Девятая строчка. Функция вывода сообщений.
В десятой строчке объявляется и выносится в глобальную область видимости функция добавления карты игроку.
11-12 строчки. Функция сброса для нового кона. У дилера и игрока забираются карты, создается и перемешивается новая колода, очищается окошко сообщений.
13-19 строчки. Функция подсчета суммы. Суммируем все карты, считаем количество тузов, в конце считаем их, пытаясь уложиться в 21.
Двадцатая строчка. Делаем ставку, проверяем, что денег достаточно.
Двадцать первая строчка. Удваиваем ставку.
Двадцать вторая строчка. Раздаем начальные карты.
23-30. Если карт достаточно, дилер набирает себе карты, после чего сравниваются очки.
В качестве игры я выбрал Блэкджек. Напомню правила:
- Игрок играет с дилером
- Вначале игроку раздается 2 карты, а дилеру одна, все карты видны
- Каждая карта даёт определенное количество очков (цифры согласно своему значению, картинки — 10, туз — 11 или 1, как выгоднее)
- Задача набрать побольше очков, но не больше 21
- Для увеличения очков нужно брать дополнительные карты
Ссылка на jsfiddle.
Сам код:
cards = [['\ud83c\udca1', '\ud83c\udca2', '\ud83c\udca3', '\ud83c\udca4', '\ud83c\udca5', '\ud83c\udca6', '\ud83c\udca7', '\ud83c\udca8', '\ud83c\udca9', '\ud83c\udcaa', '\ud83c\udcab', '\ud83c\udcad', '\ud83c\udcae',] ['\ud83c\udcb1', '\ud83c\udcb2', '\ud83c\udcb3', '\ud83c\udcb4', '\ud83c\udcb5', '\ud83c\udcb6', '\ud83c\udcb7', '\ud83c\udcb8', '\ud83c\udcb9', '\ud83c\udcba', '\ud83c\udcbb', '\ud83c\udcbd', '\ud83c\udcbe',] ['\ud83c\udcc1', '\ud83c\udcc2', '\ud83c\udcc3', '\ud83c\udcc4', '\ud83c\udcc5', '\ud83c\udcc6', '\ud83c\udcc7', '\ud83c\udcc8', '\ud83c\udcc9', '\ud83c\udcca', '\ud83c\udccb', '\ud83c\udccd', '\ud83c\udcce',] ['\ud83c\udcd1', '\ud83c\udcd2', '\ud83c\udcd3', '\ud83c\udcd4', '\ud83c\udcd5', '\ud83c\udcd6', '\ud83c\udcd7', '\ud83c\udcd8', '\ud83c\udcd9', '\ud83c\udcda', '\ud83c\udcdb', '\ud83c\udcdd', '\ud83c\udcde']]
deck=[[0 0 false ] [0 1 2] [0 2 3] [0 3 4] [0 4 5] [0 5 6] [0 6 7] [0 7 8] [0 8 9] [0 9 10] [0 10 10] [0 11 10] [0 12 10] [1 0 false ] [1 1 2] [1 2 3] [1 3 4] [1 4 5] [1 5 6] [1 6 7] [1 7 8] [1 8 9] [1 9 10] [1 10 10] [1 11 10] [1 12 10] [2 0 false ] [2 1 2] [2 2 3] [2 3 4] [2 4 5] [2 5 6] [2 6 7] [2 7 8] [2 8 9] [2 9 10] [2 10 10] [2 11 10] [2 12 10] [3 0 false ] [3 1 2] [3 2 3] [3 3 4] [3 4 5] [3 5 6] [3 6 7] [3 7 8] [3 8 9] [3 9 10] [3 10 10] [3 11 10] [3 12 10] ]
sdeck=JSON.parse JSON.stringify deck
shuffle = !-> for x,i in deck when (x=Math.floor(Math.random() * (i + 1));true)
[deck[i],deck[x]] = [deck[x],deck[i]]
gid=(id) -> document.getElementById(id)
window.mca=mc=[];window.dca=dc=[];defbet=gid("defbet");m=gid("money");bet=gid("bet");mch=gid("mcards");dch=gid("dcards");l=gid("log")
tod = !-> dc.push (c=deck.pop!); dch.innerHTML+=cards[c[0]][c[1]]
log = (msg)!-> l.innerHTML=msg
window.more = tom = !-> mc.push (c=deck.pop!); mch.innerHTML+=cards[c[0]][c[1]]; summ(mc)>21 and (log "Перебор";gid("d").disabled=gid("m").disabled=gid("e").disabled=true;gid("g").disabled=false)
clear = !->
gid("g").disabled=!(gid("d").disabled=gid("m").disabled=gid("e").disabled=false);log "";bet.innerHTML=0;mch.innerHTML=dch.innerHTML="";mc.length=0;dc.length=0;deck:=JSON.parse JSON.stringify sdeck;shuffle!
window.s=summ = (ar)->
sum=0;tzs=0
for c in ar
(c[2] and sum+=c[2]) or tzs++
for i in [1 to tzs]
(sum+11>21 and sum+=1) or sum+=11
sum
betbet = -> if +m.innerHTML<+defbet.value then log "У вас нет столько денег!"; false else bet.innerHTML=+defbet.value;m.innerHTML-=+defbet.value;true
window.dub = !-> if +m.innerHTML<+bet.innerHTML then log "У вас нет столько денег!" else m.innerHTML-=+bet.innerHTML;bet.innerHTML*=2;tom!
window.give = !-> (clear!; betbet!) and (tom!;tom!;tod!;true) or gid("g").disabled=false;!mc[0][2] and !mc[1][2] and (log "Вы выиграли!"; m.innerHTML = +m.innerHTML + +bet.innerHTML*3;gid("e").disabled=true;gid("g").disabled=false)
window.enough = !->
win=true;nothing=false
while summ(dc) < 17
tod!
log if summ(dc)>21 or summ(dc)<summ(mc) then "Вы выиграли!" else if summ(dc)==summ(mc) then (nothing=true; "Ничья") else (win=false; "Вы проиграли")
gid("g").disabled=false
gid("e").disabled=true
m.innerHTML = +m.innerHTML + (+bet.innerHTML)*(if nothing then 1 else if win then 2 else 0)
Итак, рассмотрим каждую его строчку.
В первой строке инициализируется массив с «изображениями» карт.
cards = [['\ud83c\udca1', '\ud83c\udca2', '\ud83c\udca3', '\ud83c\udca4', '\ud83c\udca5', '\ud83c\udca6', '\ud83c\udca7', '\ud83c\udca8', '\ud83c\udca9', '\ud83c\udcaa', '\ud83c\udcab', '\ud83c\udcad', '\ud83c\udcae',] ['\ud83c\udcb1', '\ud83c\udcb2', '\ud83c\udcb3', '\ud83c\udcb4', '\ud83c\udcb5', '\ud83c\udcb6', '\ud83c\udcb7', '\ud83c\udcb8', '\ud83c\udcb9', '\ud83c\udcba', '\ud83c\udcbb', '\ud83c\udcbd', '\ud83c\udcbe',] ['\ud83c\udcc1', '\ud83c\udcc2', '\ud83c\udcc3', '\ud83c\udcc4', '\ud83c\udcc5', '\ud83c\udcc6', '\ud83c\udcc7', '\ud83c\udcc8', '\ud83c\udcc9', '\ud83c\udcca', '\ud83c\udccb', '\ud83c\udccd', '\ud83c\udcce',] ['\ud83c\udcd1', '\ud83c\udcd2', '\ud83c\udcd3', '\ud83c\udcd4', '\ud83c\udcd5', '\ud83c\udcd6', '\ud83c\udcd7', '\ud83c\udcd8', '\ud83c\udcd9', '\ud83c\udcda', '\ud83c\udcdb', '\ud83c\udcdd', '\ud83c\udcde']]
Во второй строке инициализируется массив с картами, каждая карта представляет массив с тремя элементами: координаты изображения карты и её стоимость. При этом для тузов хранится false, так как он обрабатывается отдельно.
deck=[[0 0 false ] [0 1 2] [0 2 3] [0 3 4] [0 4 5] [0 5 6] [0 6 7] [0 7 8] [0 8 9] [0 9 10] [0 10 10] [0 11 10] [0 12 10] [1 0 false ] [1 1 2] [1 2 3] [1 3 4] [1 4 5] [1 5 6] [1 6 7] [1 7 8] [1 8 9] [1 9 10] [1 10 10] [1 11 10] [1 12 10] [2 0 false ] [2 1 2] [2 2 3] [2 3 4] [2 4 5] [2 5 6] [2 6 7] [2 7 8] [2 8 9] [2 9 10] [2 10 10] [2 11 10] [2 12 10] [3 0 false ] [3 1 2] [3 2 3] [3 3 4] [3 4 5] [3 5 6] [3 6 7] [3 7 8] [3 8 9] [3 9 10] [3 10 10] [3 11 10] [3 12 10] ]
В третьей строке массив карт копируется в другой массив, так как при дальнейших действиях первый массив будет попорчен.
sdeck=JSON.parse JSON.stringify deck
В четвертой и пятой строках объявляется функция перемешивания колоды.
shuffle = !-> for x,i in deck when (x=Math.floor(Math.random() * (i + 1));true)
[deck[i],deck[x]] = [deck[x],deck[i]]
В шестой строке объявляется короткая функция для замены длинного document.getElementById.
gid=(id) -> document.getElementById(id)
В седьмой строке объявляются наборы карт игрока и дилера, а также ссылки на размер ставки, количество денег игрока, текущий кон, контейнер с картами игрока и дилера и место для показа сообщений.
window.mca=mc=[];window.dca=dc=[];defbet=gid("defbet");m=gid("money");bet=gid("bet");mch=gid("mcards");dch=gid("dcards");l=gid("log")
Восьмая строчка. Функция добавления карты дилеру.
tod = !-> dc.push (c=deck.pop!); dch.innerHTML+=cards[c[0]][c[1]]
Девятая строчка. Функция вывода сообщений.
log = (msg)!-> l.innerHTML=msg
В десятой строчке объявляется и выносится в глобальную область видимости функция добавления карты игроку.
window.more = tom = !-> mc.push (c=deck.pop!); mch.innerHTML+=cards[c[0]][c[1]]; summ(mc)>21 and (log "Перебор";gid("d").disabled=gid("m").disabled=gid("e").disabled=true;gid("g").disabled=false)
11-12 строчки. Функция сброса для нового кона. У дилера и игрока забираются карты, создается и перемешивается новая колода, очищается окошко сообщений.
clear = !->
gid("g").disabled=!(gid("d").disabled=gid("m").disabled=gid("e").disabled=false);log "";bet.innerHTML=0;mch.innerHTML=dch.innerHTML="";mc.length=0;dc.length=0;deck:=JSON.parse JSON.stringify sdeck;shuffle!
13-19 строчки. Функция подсчета суммы. Суммируем все карты, считаем количество тузов, в конце считаем их, пытаясь уложиться в 21.
window.s=summ = (ar)->
sum=0;tzs=0
for c in ar
(c[2] and sum+=c[2]) or tzs++
for i in [1 to tzs]
(sum+11>21 and sum+=1) or sum+=11
sum
Двадцатая строчка. Делаем ставку, проверяем, что денег достаточно.
betbet = -> if +m.innerHTML<+defbet.value then log "У вас нет столько денег!"; false else bet.innerHTML=+defbet.value;m.innerHTML-=+defbet.value;true
Двадцать первая строчка. Удваиваем ставку.
window.dub = !-> if +m.innerHTML<+bet.innerHTML then log "У вас нет столько денег!" else m.innerHTML-=+bet.innerHTML;bet.innerHTML*=2;tom!
Двадцать вторая строчка. Раздаем начальные карты.
window.give = !-> (clear!; betbet!) and (tom!;tom!;tod!;true) or gid("g").disabled=false;!mc[0][2] and !mc[1][2] and (log "Вы выиграли!"; m.innerHTML = +m.innerHTML + +bet.innerHTML*3;gid("e").disabled=true;gid("g").disabled=false)
23-30. Если карт достаточно, дилер набирает себе карты, после чего сравниваются очки.
window.enough = !->
win=true;nothing=false
while summ(dc) < 17
tod!
log if summ(dc)>21 or summ(dc)<summ(mc) then "Вы выиграли!" else if summ(dc)==summ(mc) then (nothing=true; "Ничья") else (win=false; "Вы проиграли")
gid("g").disabled=false
gid("e").disabled=true
m.innerHTML = +m.innerHTML + (+bet.innerHTML)*(if nothing then 1 else if win then 2 else 0)