LINUX.ORG.RU

Крестики-нолики на Хацкеле.

 


0

1

К сожалению, на работе котируются только плюсы и матлаб. А на досуге я играюсь с божественным цацкелем, вот наваял игру «Крестики-нолики». Если кто-то захочет поиграть, то координаты поля считываются как (x,y) (так называемый tuple), где x и y лежат в промежутке от 1 до 3.

★★★★★

allWinPos = [ [(1,1), (1,2), (1,3)]
            , [(2,1), (2,2), (2,3)]
            , [(3,1), (3,2), (3,3)]
            , [(1,1), (2,1), (3,1)]
            , [(1,2), (2,2), (3,2)]
            , [(1,3), (2,3), (3,3)]
            , [(1,1), (2,2), (3,3)]
            , [(1,3), (2,2), (3,1)]
            ]

Кошмар какой.

Myau ★★★★
()
allWinPos = [ [(1,1), (1,2), (1,3)]
            , [(2,1), (2,2), (2,3)]
            , [(3,1), (3,2), (3,3)]
            , [(1,1), (2,1), (3,1)]
            , [(1,2), (2,2), (3,2)]
            , [(1,3), (2,3), (3,3)]
            , [(1,1), (2,2), (3,3)]
            , [(1,3), (2,2), (3,1)]
            ]

Я же не усну теперь!

olibjerd ★★★★★
()
Ответ на: комментарий от anonymous

Сишечка

на плюсах ты так же матлабишь?

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

Camel ★★★★★
()
Ответ на: Сишечка от Camel

ну хоть один раз-то можно вычислить!

nokachi
()
Ответ на: комментарий от Valdor

Почему-то распространено мнение, что вместо Хаскеля можно взять stl и писать хоть в функциональном, хоть в императивном стиле. А раз так, то зачем учить что-то помимо плюсов? И это мнение хрен оспоришь :-(

iVS ★★★★★
() автор топика
Ответ на: комментарий от iVS

Так и не нужно с идиотами спорить.

anonymous
()
Ответ на: комментарий от iVS

Но ведь хаскель так же уродлив как и плюсы. Зачем учить еще одни плюсы? Не лучше ли потратить время на какй-нибудь нормальный язык?

anonymous
()
Ответ на: комментарий от iVS

А как на хаскеле писать объектно-ориентированные программы?

anonymous
()
Ответ на: комментарий от anonymous

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

peregrine ★★★★★
()

Ну и мусор. Алгоритмы императивны, игра по определению процесс интерактивный, нафига это пихать в pure-функциональщину, прикрывая неудобные места монадами?

backburner
()
Ответ на: комментарий от peregrine

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

Заблуждение ваше в том, что при других размерах поля и выигрышной линии не придется менять самого алгоритма. Для примера возьмем другую (весьма распространненную) разновидность: поле 15x15 и длина выигрышной линии 5. В данном случае нет смысла все поле проверять на выигрышные линии, в то время как при поле 3x3 это естественно. При поле 15x15 (и даже больше) справедлив другой подход: рассмотреть только линии, включающие позицию последнего хода, т.е., не более квадрата 9x9. Почему-то все помнят про масштабирование данных, а про масштабирование алгоритмов забывают.

iVS ★★★★★
() автор топика
Ответ на: комментарий от backburner

Алгоритмы императивны, игра по определению процесс интерактивный, нафига это пихать в pure-функциональщину, прикрывая неудобные места монадами?

Уважаемый, вы за пальцем не видите Луны.

iVS ★★★★★
() автор топика
Ответ на: комментарий от peregrine

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

Всегда закладываешь в архитектуру программы высосанные и пальца невероятные сценарии?

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

Что если через год скажут, что выигрышные комбинации должны быть в виде буквы Г?

anonymous
()
Ответ на: комментарий от Valdor

«Не просто так» не мешает котировать тот же Lua.

olibjerd ★★★★★
()
Ответ на: комментарий от iVS

рассмотреть только линии, включающие позицию последнего хода

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

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 1)
Ответ на: комментарий от anonymous

Всегда закладываешь в архитектуру программы высосанные и пальца невероятные сценарии?

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

peregrine ★★★★★
()
Ответ на: комментарий от backburner

Алгоритмы императивны

Вот это поворот!

ovk48 ★★★
()
Ответ на: комментарий от peregrine

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

iVS ★★★★★
() автор топика
Последнее исправление: iVS (всего исправлений: 1)
Ответ на: комментарий от peregrine

Но предпочитаю более абстрактный код

Ну ты хоть в курсе, что абстракции бывают разные? Для произвольного размера доски нужно выбирать одни абстракции, для произвольных выигрывающих линий (буква Г, например) — другие, для ботов — третьи. Поэтому фраза о более абстрактном коде пустая, пока не скажешь, абстракции на какой случай тебе нужны. А мы тогда обсудим разумность твоих абстракций.

iVS ★★★★★
() автор топика
Ответ на: комментарий от anonymous

И благородный дон нам сейчас расскажет, чем же он оправдан.

Насколько я понимаю, ТС написал это for fun, но лично я не вижу никакого фана в написании алгоритма уровня

if dummy_player
then i_win
else draw_game
Хотя крестики-нолики сами по себе пример плохой игры, даже тут можно было хоть как-нибудь поэкспериментировать.

Myau ★★★★
()
Ответ на: комментарий от Myau

можно было хоть как-нибудь поэкспериментировать

чего останавливаться - «AI» крестиков-ноликов 3х3 можно вообще захардкодить в стиле TC, и если учесть симметричность поля это возможно было-бы даже короче.

MKuznetsov ★★★★★
()
Ответ на: комментарий от Myau

<pre> Prelude> let ns = [1..3] Prelude> let allWinPos = [(1,3),(2,2),(3,1)]:[(a,a)|a<-ns]:[[(a,b)|b<-ns]|a<-ns] Prelude> length allWinPos 5 </pre>

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

anonymous
()
Ответ на: комментарий от iVS

Сорри, надо

let ns = [1..3]
allWinPos = [(a,4-a)|a<-ns]:[(a,a)|a<-ns]:([[(a,b)|b<-ns]|a<-ns]++[[(b,a)|b<-ns]|a<-ns])
Myau, ну и чем твоя абракадабра лучше?

iVS ★★★★★
() автор топика
Ответ на: комментарий от anonymous
allWinPos = [(a,4-a)|a<-ns]:[(a,a)|a<-ns]:[[(a,b)|b<-ns]|a<-ns]++[[(b,a)|b<-ns]|a<-ns]

Возьми с полки пирожок.

Myau ★★★★
()
Ответ на: комментарий от iVS

В случае с полем 3х3 - получилось, что практически ничем :( Хотя ИМХО пописать такую фигню прикольнее.

А в целом я уже написал про неспортивность такого подхода с моей точки зрения.

Myau ★★★★
()
Ответ на: комментарий от anonymous

Щито поделать, аллергия на гору механической работы не всегда бывает оправданной.

Myau ★★★★
()

Странно, на JS такая программа реализуется полностью в 29 строк кода, не считая разметки

<html>
<head>
<style>
 table,tr,td{
  border: 1px solid black;
}
 td{width: 30px; height: 30px}
 
</style>

</head>
<body>

<table >
 <tr id="line0"> <td></td> <td></td> <td></td> </tr>
 <tr id="line1"> <td></td> <td></td> <td></td> </tr>
 <tr id="line2"> <td></td> <td></td> <td></td> </tr>
</table>

<script>

getCells=function(line, f){
 return [].map.call(line.children, f)
}
withAllSels=function(f){
 ;[].forEach.call(line0.children, f)
 ;[].forEach.call(line1.children, f)
 ;[].forEach.call(line2.children, f)
}

check=function(){
 var result, l0, l1, l2
;[
l0=getCells(line0, function(x){return x}),
l1=getCells(line1, function(x){return x}),
l2=getCells(line2, function(x){return x}),
[l0[0], l1[0], l2[0]],
[l0[1], l1[1], l2[1]],
[l0[2], l1[2], l2[2]],
[l0[0], l1[1], l2[2]],
[l0[2], l1[1], l2[0]]
].some(function(l){return result=/XXX|OOO/.test(l.map(function(x){return x.innerHTML}).join(""))})
return result
}

current="X"
withAllSels(function(x){x.onclick=function(){
 if(this.innerHTML) return
 this.innerHTML=current
 if(check()) return document.write(current+" wins")
 if(current==="X") return current="O"; current="X"
}})


</script>
</body>
</html>
А у вас порядка 100 строк. Почему же тогда говорят, что хаскель выигрывает в лаконичности на задачах, связанных с обработкой списков?

anonymous
()
Ответ на: комментарий от anonymous

В данном случае из беглого сравнения вижу только одну разницу: в императивном языке можно взять матрицу M (состояние доски на текущий момент) и поместить новый элемент как-то так: M(i,j)=X. В хаскеле подобный трюк не уместен из-за иммутабельности данных. Поэтому пришлось идти в обход и рекурсивно обрабатывать список списков (ф-ции addMark, addMarkToLine и addMarkToQuad).

iVS ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Ананiмас, прекрати семенить.

Deleted
()
Ответ на: комментарий от iVS

А почему бы и нет? Ведь JS поимеет хашкель в хвост и в гриву на большинстве real задач. К тому же он умеет в ООП, в отличии от.

anonymous
()
Ответ на: комментарий от anonymous

Ведь JS поимеет хашкель в хвост и в гриву на большинстве real задач.

Да у JS и нет никаких real задач, кроме веба. Туда и возвращайся, анон.

iVS ★★★★★
() автор топика
Ответ на: комментарий от anonymous

withAllSels
Sels

Спалился семенчик.

anonymous
()
Ответ на: комментарий от Myau

как-нибудь поэкспериментировать

Крестики-нолики на «бесконечном» поле, например. Составивший 5 в линию либо выигрывает, либо записывает себе очко (и так пока не надоест, хе-хе).

al_exquemelin ★★★
()
Ответ на: комментарий от tuxin

Надо же, даже сраные говноплюсы нагнули хваленый хашкель.

anonymous
()
Ответ на: комментарий от tuxin

Нет слов, побитовое сравнение тут и вправду дает существенный выигрыш.

iVS ★★★★★
() автор топика
Ответ на: комментарий от nezamudich

Не виноватая я! Он сам пришел! ©

iVS ★★★★★
() автор топика
Ответ на: комментарий от nezamudich

Какой ты тут троллинг увидел? Просто хаскелефилов люто опустили ниже плинтуса, вот и все. Не выдумывай.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.