TypeScript (не Tcl)

Описание: Наиболее перспективное направление развития компьютерных наук. Надо быть в теме!

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#1 dyvniy » Ср, 25 ноября 2015, 13:54:11

https://ru.wikipedia.org/wiki/TypeScript
http://habrahabr.ru/post/153077/
Одно плохо - его мелкософт придумал ((((

Спойлер
Пятнашки на TCL в 10 строк
http://habrahabr.ru/post/89919/
Спойлер
Реверси в 64 строки уже есть. Теперь напишем пятнашки.

Исходный код (upuzzle.tcl)
package require Tk
foreach {p} {7 2 10 11 5 4 9 12 13 8 3 14 15 1 6} {i} {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14} {
button .$p -relief solid -bd 1 -width 8 -height 4 -text $p -command "move $p"
grid .$p -row [expr {$i/4}] -column [expr {$i%4}] -padx 1 -pady 1}
proc move {b} {
lassign [list [dict get [grid info .$b] -column] [dict get [grid info .$b] -row]] x y
foreach {ix iy} {0 -1 0 1 -1 0 1 0} {
lassign [list [expr {$x+$ix}] [expr {$y+$iy}]] i j
if {$i>=0 && $i<=3 && $j>=0 && $j<=3 && ![llength [grid slaves . -col $i -row $j]]} {
grid configure .$b -column $i -row $j}}}


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

Процедура move для заданной костяшки проверяет все возможные перемещения (вверх, вниз, влево, вправо), и при необходимости меняет положение кнопки в таблице.

Реверси на TCL в 64 строки
http://habrahabr.ru/post/89822/
Спойлер
На хабре уже есть топики про написание игры Реверси (Отелло) на Python, Silverlight.
Изобретем велосипед на Tcl/Tk. Кроссплатформенно (работает даже на Windows Mobile при небольшой модификации), всего в 64 строки.

image

Код, небольшое описание и скрин с WinMobile под хабракатом.


Исходник (reversi.tcl):
package require Tk 8.5
for {set i 0} {$i<64} {incr i} {lappend icells [expr {$i/8}] [expr {$i%8}]}
array set vs [list 1 2 2 1 cl,1 black cl,2 white pn,1 черные pn,2 белые]
ttk::button .b1 -text "Новая игра" -command {newgame 1 2}
ttk::button .b2 -text "Выход" -command {exit}
ttk::label .l1 -text "Добро пожаловать в игру Реверси"
canvas .cv -width 479 -height 479
grid rowconfigure . 1 -weight 1
grid columnconfigure . 2 -weight 1
grid .b1 .b2 .l1 -padx 4 -pady 4 -sticky e
grid .cv -padx 4 -pady 4 -columnspan 3
foreach {x y} $icells {
set cr1 [list [expr {$x*60+2}] [expr {$y*60+2}] [expr {$x*60+60}] [expr {$y*60+60}]]
set cr2 [list [expr {$x*60+4}] [expr {$y*60+4}] [expr {$x*60+58}] [expr {$y*60+58}]]
.cv create rectangle $cr1 -fill gray -tag "cell,$x,$y"
.cv create oval $cr2 -state hidden -tag "piece $x,$y"
.cv bind cell,$x,$y <1> [list evuser $x $y]}
proc pieceset {x y p} {
.cv itemconfigure $x,$y -state normal -fill $::vs(cl,$p)
incr ::score($p) [expr {+($::board($x,$y) != $p)}]
incr ::score($::vs($p)) [expr {-($::board($x,$y) == $::vs($p))}]
set ::board($x,$y) [list $p]}
proc newgame {p1 p2} {
.cv itemconfigure piece -state hidden
array set ::score [list 0 0 1 0 2 0]
array set ::player [list 1 $p1 2 $p2]
foreach {x y} $::icells {set ::board($x,$y) 0}
foreach {x y s} {3 3 2 4 4 2 3 4 1 4 3 1} {pieceset $x $y $s}
set ::cur 1; waitturn}
proc getflips {x y p} {
if {$::board($x,$y) != 0} return;
set result {}
foreach {ix iy} {0 -1 0 1 -1 0 1 0 -1 -1 1 1 1 -1 -1 1} {
set temp {}
for {set i [expr {$x+$ix}]; set j [expr {$y+$iy}]} \
{[info exists ::board($i,$j)]} {incr i $ix; incr j $iy} {
switch -- $::board($i,$j) \
$::vs($p) {lappend temp $i $j} \
$p {foreach {m n} $temp {lappend result $m $n}; break} \
0 {break}
}}
return $result}
proc waitturn {} {
.l1 configure -text "Ходят $::vs(pn,$::cur) ($::score(1):$::score(2))"
array set v [list $::cur {} $::vs($::cur) {}]
foreach {x y} $::icells {
set l [getflips $x $y $::cur]; if {[llength $l]} {lappend v($::cur) [list $x $y]}
set l [getflips $x $y $::vs($::cur)]; if {[llength $l]} {lappend v($::vs($::cur)) [list $x $y]}}
if {[llength $v($::cur)] == 0 && [llength $v($::vs($::cur))] == 0} {
tk_messageBox -title "Reversi" -message "Игра окончена"; return}
if {$::player($::cur) == 1 && [llength $v($::cur)]} {
set ::waituser 1; return}
if {$::player($::cur) == 2 && [llength $v($::cur)]} {
set ::waituser 0
set ::flip [lindex $v($::cur) [expr {int([llength $v($::cur)]*rand())}]]
turn [lindex $::flip 0] [lindex $::flip 1] $::cur}
set ::cur $::vs($::cur); after idle waitturn}
proc evuser {x y} {
if {[info exists ::waituser] && $::waituser && [turn $x $y $::cur]} {
set ::cur $::vs($::cur); after idle waitturn}}
proc turn {x y p} {
set flips [getflips $x $y $p]
foreach {i j} $flips {pieceset $i $j $p}
if {[llength $flips]} {pieceset $x $y $p; return 1} else {return 0}}


Чтобы удобней было работать с координатами, создадим список icells (0 0 0 1… 1 1 1 2..).
В дальнейшем вместо вложенного цикла можем пользоваться foreach {x y} $icells.

Далее идет создание интерфейса, работа с канвой и привязка события (evuser) при нажатии на клетку.

Глобальные переменные:
vs — хеш массив, определяет ID противников, цвета фишек. vs(1) = 2; vs(2) = 1.
score — счет (количество черных и белых фишек)
player — конфигурация игроков (1 — человек, 2 — компьютер)
board — игровое поле
cur — идентификатор текущего игрока
waituser — флаг ожидания хода пользователя

Рассмотрим объявленные функции.
newgame {p1 p2}
Начало новой игры. Аргументы определяют тип игрока:
1 — Человек
2 — Компьютер

В прочем, AI здесь совершенно нет, но можно посмотреть как будут играть Random vs Random передав {2 2}

pieceset {x y p}
Устанавливает фишку игрока p, в клетку x,y
Пересчитывает текущий счет. Здесь небольшая магия
incr ::score($p) [expr {+($::board($x,$y) != $p)}]
incr ::score($::vs($p)) [expr {-($::board($x,$y) == $::vs($p))}].


Мы увеличиваем счет текущего игрока p, и его оппонента $vs($p)
Для текущего игрока, если его фишка еще не стояла в клетке, то +1 иначе +0
Если стоила фишка противника, то ему уменьшаем счет на -1.

getflips {x y p}
Возвращает список всех возможных фишек, который игрок (p) может захватить сходив в x y

waitturn {}
Ожидание хода.
Определяет количество всех возможных ходов для каждого игрока. Решает, когда игра окончена и кто сейчас должен сделать ход.

evuser {x y}
Процедура вызываемая каждый раз, когда человек нажимает на одну из клеток.
Если установлена глобальная переменная ::waituser и есть возможность сходить текущему пользователю, то передаем управление оппоненту:
set ::cur $::vs($::cur); after idle waitturn}}

turn {x y p}
Сделать ход в x y. Перевернуть захваченные фишки противника, если получилось — возвращает 1, иначе 0.

И вообще сёч на хабре
http://habrahabr.ru/search/?q=tcl
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#2 dyvniy » Ср, 25 ноября 2015, 14:35:33

Изображение


Название раздела: Web на стороне клиента, Java Script
Описание: Наиболее перспективное направление развития компьютерных наук. Надо быть в теме!

Быстрый ответ


Введите код в точности так, как вы его видите. Регистр символов не имеет значения.
Код подтверждения
:) ;) :hihi: :P :hah: :haha: :angel: :( :st: :_( :cool: 8-| :beee: :ham: :rrr: :grr: :* :secret: :stupid: :music: Ещё смайлики…
   

Вернуться в «Web на стороне клиента, Java Script»

Кто сейчас на форуме (по активности за 15 минут)

Сейчас этот раздел просматривают: 5 гостей