Tetris/Phix: Difference between revisions
< Tetris
Content added Content deleted
m (font) |
m (Fixed syntax highlighting.) |
||
(2 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
<span style='font-size:220%;'>[[Phix]]</span><br> |
<span style='font-size:220%;'>[[Phix]]</span><br> |
||
{{libheader|Phix/pGUI}} |
|||
{{libheader|Phix/online}} |
|||
You can run this online [http://phix.x10.mx/p2js/tetris.htm here]. |
|||
For instructions, see key_cb() |
For instructions, see key_cb() |
||
<!--<syntaxhighlight lang="phix">(phixonline)--> |
|||
<lang Phix>-- demo\rosetta\Tetrominoes.exw |
|||
<span style="color: #000080;font-style:italic;">-- |
|||
include pGUI.e |
|||
-- demo\rosetta\Tetrominoes.exw |
|||
-- ============================ |
|||
Ihandle canvas, dialog, timer |
|||
-- |
|||
cdCanvas cddbuffer, cdcanvas |
|||
-- Author Pete Lomax, Jan 2020 |
|||
-- |
|||
constant TITLE = "Tetrominoes", |
|||
-- 1. A robot may not injure a human being, or, through inaction, |
|||
lct = {{'I',CD_CYAN, {{-2, 0},{-1, 0},{ 0, 0},{ 1, 0}}}, |
|||
-- allow a human being to come to harm. |
|||
{'T',CD_PURPLE, {{-1, 0},{ 0, 0},{ 1, 0},{ 0, 1}}}, |
|||
-- |
|||
{'O',CD_YELLOW, {{-1, 0},{ 0, 0},{-1, 1},{ 0, 1}}}, |
|||
-- 2. A robot must obey the orders given it by human beings |
|||
{'S',CD_GREEN, {{-1, 1},{ 0, 1},{ 0, 0},{ 1, 0}}}, |
|||
-- except where such orders would conflict with the First Law. |
|||
{'Z',CD_RED, {{-1, 0},{ 0, 0},{ 0, 1},{ 1, 1}}}, |
|||
-- |
|||
{'J',CD_BLUE, {{-1, 0},{ 0, 0},{ 1, 0},{ 1, 1}}}, |
|||
-- 3. A robot must protect its own existence as long as such |
|||
{'L',CD_ORANGE, {{-1, 1},{-1, 0},{ 0, 0},{ 1, 0}}}}, |
|||
-- protection does not conflict with the First or Second Law. |
|||
{letters,colours,tiles} = columnize(lct), |
|||
-- |
|||
topbot = {repeat('*',12)}, |
|||
-- 4. A robot must never place the long skinny ones horizontally, |
|||
clear_line = '*'&repeat(' ',10)&'*', |
|||
-- unless it leads to a long skinny vertical hole so 4 rows can |
|||
full_line = '*'&repeat('Z',10)&'*', |
|||
-- be cleared at once the next time a long skinny one comes |
|||
init_board = topbot&repeat(clear_line,20)&topbot, |
|||
-- around. |
|||
directions = {{0,+1}, -- DOWN |
|||
--</span> |
|||
{-1,0}, -- LEFT |
|||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
|||
{+1,0}} -- RIGHT |
|||
<span style="color: #008080;">include</span> <span style="color: #000000;">pGUI</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span> |
|||
enum type direction DOWN, LEFT, RIGHT end type |
|||
<span style="color: #004080;">Ihandle</span> <span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">dialog</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">timer</span> |
|||
<span style="color: #004080;">cdCanvas</span> <span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cdcanvas</span> |
|||
sequence board, -- (nb 2-based indexing!) |
|||
tile |
|||
<span style="color: #008080;">constant</span> <span style="color: #000000;">TITLE</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"Tetrominoes"</span><span style="color: #0000FF;">,</span> |
|||
integer px, py, preview, level, |
|||
<span style="color: #000000;">lct</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #008000;">'I'</span><span style="color: #0000FF;">,</span><span style="color: #004600;">CD_CYAN</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{{-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">},{-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">},{</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">},{</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">}}},</span> |
|||
completed, -- (the first complete line found, cleared soon) |
|||
<span style="color: #0000FF;">{</span><span style="color: #008000;">'T'</span><span style="color: #0000FF;">,</span><span style="color: #004600;">CD_PURPLE</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{{-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">},{</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">},{</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">},{</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">}}},</span> |
|||
completen, -- (number of "" "" s "" "" "" ) |
|||
<span style="color: #0000FF;">{</span><span style="color: #008000;">'O'</span><span style="color: #0000FF;">,</span><span style="color: #004600;">CD_YELLOW</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{{-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">},{</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">},{-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">},{</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">}}},</span> |
|||
completot -- (the running total, used to update the level) |
|||
<span style="color: #0000FF;">{</span><span style="color: #008000;">'S'</span><span style="color: #0000FF;">,</span><span style="color: #004600;">CD_GREEN</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{{-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">},{</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">},{</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">},{</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">}}},</span> |
|||
<span style="color: #0000FF;">{</span><span style="color: #008000;">'Z'</span><span style="color: #0000FF;">,</span><span style="color: #004600;">CD_RED</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{{-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">},{</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">},{</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">},{</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">}}},</span> |
|||
function check(sequence this, that, integer nx, ny) |
|||
<span style="color: #0000FF;">{</span><span style="color: #008000;">'J'</span><span style="color: #0000FF;">,</span><span style="color: #004600;">CD_BLUE</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{{-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">},{</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">},{</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">},{</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">}}},</span> |
|||
-- (common code for move and rotate) |
|||
<span style="color: #0000FF;">{</span><span style="color: #008000;">'L'</span><span style="color: #0000FF;">,</span><span style="color: #004600;">CD_ORANGE</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{{-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">},{-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">},{</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">},{</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">}}}},</span> |
|||
integer tx, ty, what |
|||
<span style="color: #0000FF;">{</span><span style="color: #000000;">letters</span><span style="color: #0000FF;">,</span><span style="color: #000000;">colours</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tiles</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">columnize</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lct</span><span style="color: #0000FF;">),</span> |
|||
for i=1 to length(that) do -- check tgt free |
|||
<span style="color: #000000;">topbot</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'*'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">12</span><span style="color: #0000FF;">)},</span> |
|||
sequence ti = that[i] |
|||
<span style="color: #000000;">clear_line</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'*'</span><span style="color: #0000FF;">&</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)&</span><span style="color: #008000;">'*'</span><span style="color: #0000FF;">,</span> |
|||
if not find(ti,this) then |
|||
<span style="color: #000000;">full_line</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'*'</span><span style="color: #0000FF;">&</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'Z'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)&</span><span style="color: #008000;">'*'</span><span style="color: #0000FF;">,</span> |
|||
{tx,ty} = ti |
|||
<span style="color: #000000;">init_board</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">topbot</span><span style="color: #0000FF;">&</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">clear_line</span><span style="color: #0000FF;">,</span><span style="color: #000000;">20</span><span style="color: #0000FF;">)&</span><span style="color: #000000;">topbot</span><span style="color: #0000FF;">,</span> |
|||
if tx>11 or board[ty,tx]!=' ' then |
|||
<span style="color: #000000;">directions</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- DOWN</span> |
|||
return false |
|||
<span style="color: #0000FF;">{-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- LEFT</span> |
|||
end if |
|||
<span style="color: #0000FF;">{+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">}}</span> <span style="color: #000080;font-style:italic;">-- RIGHT |
|||
end if |
|||
end for |
|||
--enum type direction DOWN, LEFT, RIGHT end type</span> |
|||
for i=1 to 4 do -- clear current |
|||
<span style="color: #008080;">enum</span> <span style="color: #000000;">DOWN</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">LEFT</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">RIGHT</span> |
|||
{tx,ty} = this[i] |
|||
<span style="color: #008080;">type</span> <span style="color: #000000;">direction</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">DOWN</span> <span style="color: #008080;">and</span> <span style="color: #000000;">d</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">RIGHT</span> <span style="color: #008080;">end</span> <span style="color: #008080;">type</span> |
|||
what = board[ty,tx] |
|||
board[ty,tx]=' ' |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (nb 2-based indexing!)</span> |
|||
end for |
|||
<span style="color: #000000;">tile</span> |
|||
for i=1 to 4 do -- set new position |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">px</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">py</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">preview</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">level</span><span style="color: #0000FF;">,</span> |
|||
{tx,ty} = that[i] |
|||
<span style="color: #000000;">completed</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (the first complete line found, cleared soon)</span> |
|||
board[ty,tx] = what |
|||
<span style="color: #000000;">completen</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (number of "" "" s "" "" "" )</span> |
|||
end for |
|||
<span style="color: #000000;">completot</span> <span style="color: #000080;font-style:italic;">-- (the running total, used to update the level)</span> |
|||
{px,py} = {nx,ny} |
|||
IupUpdate(canvas) |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">check</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">curr</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">next</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">nx</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ny</span><span style="color: #0000FF;">)</span> |
|||
return true |
|||
<span style="color: #000080;font-style:italic;">-- (common code for move and rotate)</span> |
|||
end function |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">tx</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ty</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">what</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">next</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- check tgt free</span> |
|||
function move(direction d, bool place=false, what=' ') |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">ti</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">next</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
-- returns true/false to allow detection of "game over", drop new, etc |
|||
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">,</span><span style="color: #000000;">curr</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> |
|||
integer {dx,dy} = directions[d], tx, ty, x, y |
|||
<span style="color: #0000FF;">{</span><span style="color: #000000;">tx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ty</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ti</span> |
|||
sequence {this, that} @= repeat({},4) |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">tx</span><span style="color: #0000FF;">></span><span style="color: #000000;">11</span> <span style="color: #008080;">or</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ty</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tx</span><span style="color: #0000FF;">]!=</span><span style="color: #008000;">' '</span> <span style="color: #008080;">then</span> |
|||
for i=1 to length(tile) do |
|||
<span style="color: #008080;">return</span> <span style="color: #004600;">false</span> |
|||
{tx,ty} = tile[i] |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
{x,y} = {px+tx+1,py+ty+1} |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
this[i] = {x,y} |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
that[i] = {x+dx,y+dy} |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">4</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- clear current</span> |
|||
if place then board[y,x] = what end if |
|||
<span style="color: #0000FF;">{</span><span style="color: #000000;">tx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ty</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">curr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
end for |
|||
<span style="color: #000000;">what</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ty</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tx</span><span style="color: #0000FF;">]</span> |
|||
return check(this,that,px+dx,py+dy) |
|||
<span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ty</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tx</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">' '</span> |
|||
end function |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">4</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- set new position</span> |
|||
procedure rotate() |
|||
<span style="color: #0000FF;">{</span><span style="color: #000000;">tx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ty</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">next</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
-- 90 degrees anti-clockwise |
|||
<span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ty</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">what</span> |
|||
sequence rile = tile, |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
{this, that} @= repeat({},4) |
|||
<span style="color: #0000FF;">{</span><span style="color: #000000;">px</span><span style="color: #0000FF;">,</span><span style="color: #000000;">py</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">nx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ny</span><span style="color: #0000FF;">}</span> |
|||
for i=1 to length(tile) do |
|||
<span style="color: #7060A8;">IupUpdate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">)</span> |
|||
integer {tx,ty} = tile[i] |
|||
<span style="color: #008080;">return</span> <span style="color: #004600;">true</span> |
|||
rile[i] = {ty,-tx} |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
this[i] = {px+tx+1,py+ty+1} |
|||
that[i] = {px+ty+1,py-tx+1} |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">move</span><span style="color: #0000FF;">(</span><span style="color: #000000;">direction</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">bool</span> <span style="color: #000000;">place</span><span style="color: #0000FF;">=</span><span style="color: #004600;">false</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">what</span><span style="color: #0000FF;">=</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">)</span> |
|||
end for |
|||
<span style="color: #000080;font-style:italic;">-- returns true/false to allow detection of "game over", drop new, etc</span> |
|||
if check(this,that,px,py) then |
|||
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dy</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">directions</span><span style="color: #0000FF;">[</span><span style="color: #000000;">d</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">tx</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ty</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span> |
|||
tile = rile |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">curr</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">({},</span><span style="color: #000000;">4</span><span style="color: #0000FF;">),</span> |
|||
end if |
|||
<span style="color: #000000;">next</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">({},</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)</span> |
|||
end procedure |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tile</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #0000FF;">{</span><span style="color: #000000;">tx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ty</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tile</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
procedure set_level(integer nl) |
|||
<span style="color: #0000FF;">{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">px</span><span style="color: #0000FF;">+</span><span style="color: #000000;">tx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">py</span><span style="color: #0000FF;">+</span><span style="color: #000000;">ty</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}</span> |
|||
level = nl |
|||
<span style="color: #000000;">curr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">}</span> |
|||
IupSetInt(timer,"RUN",false) |
|||
<span style="color: #000000;">next</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dy</span><span style="color: #0000FF;">}</span> |
|||
IupSetInt(timer,"TIME",50*(11-level)) |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">place</span> <span style="color: #008080;">then</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">what</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
IupSetInt(timer,"RUN",true) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
IupSetStrAttribute(dialog,"TITLE","%s - level %d",{TITLE,level}) |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">check</span><span style="color: #0000FF;">(</span><span style="color: #000000;">curr</span><span style="color: #0000FF;">,</span><span style="color: #000000;">next</span><span style="color: #0000FF;">,</span><span style="color: #000000;">px</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">py</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dy</span><span style="color: #0000FF;">)</span> |
|||
end procedure |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
procedure drop(bool bStart=false) |
|||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">rotate</span><span style="color: #0000FF;">()</span> |
|||
if bStart then |
|||
<span style="color: #000080;font-style:italic;">-- 90 degrees anti-clockwise</span> |
|||
{board,preview,completed,completot} = {init_board,rand(7),0,0} |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">rile</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tile</span><span style="color: #0000FF;">),</span> |
|||
set_level(1) |
|||
<span style="color: #000000;">curr</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">({},</span><span style="color: #000000;">4</span><span style="color: #0000FF;">),</span> |
|||
else |
|||
<span style="color: #000000;">next</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">({},</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)</span> |
|||
while move(DOWN) do end while |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tile</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
for i=2 to 21 do |
|||
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">tx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ty</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tile</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
if not find(' ',board[i]) then |
|||
<span style="color: #000000;">rile</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">ty</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">tx</span><span style="color: #0000FF;">}</span> |
|||
completed = i |
|||
<span style="color: #000000;">curr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">px</span><span style="color: #0000FF;">+</span><span style="color: #000000;">tx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">py</span><span style="color: #0000FF;">+</span><span style="color: #000000;">ty</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}</span> |
|||
for j=i+1 to 22 do |
|||
<span style="color: #000000;">next</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">px</span><span style="color: #0000FF;">+</span><span style="color: #000000;">ty</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">py</span><span style="color: #0000FF;">-</span><span style="color: #000000;">tx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}</span> |
|||
board[j-1] = full_line |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
if j=22 or find(' ',board[j]) then |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">check</span><span style="color: #0000FF;">(</span><span style="color: #000000;">curr</span><span style="color: #0000FF;">,</span><span style="color: #000000;">next</span><span style="color: #0000FF;">,</span><span style="color: #000000;">px</span><span style="color: #0000FF;">,</span><span style="color: #000000;">py</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> |
|||
completen = j-i |
|||
<span style="color: #000000;">tile</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rile</span> |
|||
IupUpdate(canvas) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
return -- (show it with a brief pause) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span> |
|||
end if |
|||
end for |
|||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">set_level</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">nl</span><span style="color: #0000FF;">)</span> |
|||
end if |
|||
<span style="color: #000000;">level</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nl</span> |
|||
end for |
|||
<span style="color: #7060A8;">IupSetInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">timer</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"RUN"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">)</span> |
|||
end if |
|||
<span style="color: #7060A8;">IupSetInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">timer</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TIME"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">50</span><span style="color: #0000FF;">*(</span><span style="color: #000000;">11</span><span style="color: #0000FF;">-</span><span style="color: #000000;">level</span><span style="color: #0000FF;">))</span> |
|||
integer t = preview |
|||
<span style="color: #7060A8;">IupSetInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">timer</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"RUN"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span> |
|||
preview = rand(7) |
|||
<span style="color: #7060A8;">IupSetStrAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dialog</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TITLE"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s - level %d"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">TITLE</span><span style="color: #0000FF;">,</span><span style="color: #000000;">level</span><span style="color: #0000FF;">})</span> |
|||
{px,py,tile} = {6,1,tiles[t]} |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span> |
|||
if not move(DOWN,true,letters[t]) then |
|||
IupSetStrAttribute(dialog,"TITLE","%s - GAME OVER",{TITLE}) |
|||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">drop</span><span style="color: #0000FF;">(</span><span style="color: #004080;">bool</span> <span style="color: #000000;">bStart</span><span style="color: #0000FF;">=</span><span style="color: #004600;">false</span><span style="color: #0000FF;">)</span> |
|||
IupSetInt(timer,"RUN",false) |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">bStart</span> <span style="color: #008080;">then</span> |
|||
end if |
|||
<span style="color: #000000;">board</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">init_board</span><span style="color: #0000FF;">)</span> |
|||
end procedure |
|||
<span style="color: #000000;">preview</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">7</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">completed</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> |
|||
procedure new_game() |
|||
<span style="color: #000000;">completot</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> |
|||
drop(bStart:=true) |
|||
<span style="color: #000000;">set_level</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> |
|||
end procedure |
|||
<span style="color: #008080;">else</span> |
|||
<span style="color: #008080;">while</span> <span style="color: #000000;">move</span><span style="color: #0000FF;">(</span><span style="color: #000000;">DOWN</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> <span style="color: #008080;">end</span> <span style="color: #008080;">while</span> |
|||
procedure clear() |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #000000;">21</span> <span style="color: #008080;">do</span> |
|||
completot += completen |
|||
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">,</span><span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span> |
|||
integer nl = floor(min(completot-1,90)/10)+1 |
|||
<span style="color: #000000;">completed</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span> |
|||
if nl!=level then set_level(nl) end if |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">22</span> <span style="color: #008080;">do</span> |
|||
for i=completed+completen-1 to 3 by -1 do |
|||
<span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">full_line</span> |
|||
completed -= (completed>2) |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">22</span> <span style="color: #008080;">or</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">,</span><span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span> |
|||
board[i] = board[completed] |
|||
<span style="color: #000000;">completen</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">-</span><span style="color: #000000;">i</span> |
|||
end for |
|||
<span style="color: #7060A8;">IupUpdate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">)</span> |
|||
board[2] = clear_line |
|||
<span style="color: #008080;">return</span> <span style="color: #000080;font-style:italic;">-- (show it with a brief pause)</span> |
|||
completed = 0 |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
end procedure |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
function redraw_cb(Ihandle /*canvas*/, integer /*posx*/, integer /*posy*/) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
integer {cw,ch} = IupGetIntInt(canvas, "DRAWSIZE"), |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
dx = min(floor(cw/10), floor(ch/20))-1, |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">preview</span> |
|||
mx = floor((cw-10*dx-11)/2), |
|||
<span style="color: #000000;">preview</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">7</span><span style="color: #0000FF;">)</span> |
|||
my = floor((ch-20*dx-21)/2), |
|||
<span style="color: #0000FF;">{</span><span style="color: #000000;">px</span><span style="color: #0000FF;">,</span><span style="color: #000000;">py</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tile</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tiles</span><span style="color: #0000FF;">[</span><span style="color: #000000;">t</span><span style="color: #0000FF;">]}</span> |
|||
gx, gy, sq |
|||
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">move</span><span style="color: #0000FF;">(</span><span style="color: #000000;">DOWN</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #000000;">letters</span><span style="color: #0000FF;">[</span><span style="color: #000000;">t</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #7060A8;">IupSetStrAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dialog</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TITLE"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s - GAME OVER"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">TITLE</span><span style="color: #0000FF;">})</span> |
|||
cdCanvasActivate(cddbuffer) |
|||
<span style="color: #7060A8;">IupSetInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">timer</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"RUN"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">)</span> |
|||
cdCanvasSetBackground(cddbuffer, CD_DARK_GREY) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
cdCanvasClear(cddbuffer) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span> |
|||
for y=1 to 20 do |
|||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">new_game</span><span style="color: #0000FF;">()</span> |
|||
gy = my+(20-y)*(dx+1)+1 |
|||
<span style="color: #000000;">drop</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bStart</span><span style="color: #0000FF;">:=</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span> |
|||
for x=1 to 10 do |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span> |
|||
sq = board[y+1,x+1] |
|||
if sq!=' ' then |
|||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">clear</span><span style="color: #0000FF;">()</span> |
|||
cdCanvasSetForeground(cddbuffer,colours[find(sq,letters)]) |
|||
<span style="color: #000000;">completot</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">completen</span> |
|||
gx = mx+(x-1)*(dx+1)+1 |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">nl</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">completot</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">90</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span> |
|||
cdCanvasBox(cddbuffer, gx, gx+dx-1, gy, gy+dx-1) |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">nl</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">level</span> <span style="color: #008080;">then</span> <span style="color: #000000;">set_level</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nl</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
end if |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">completed</span><span style="color: #0000FF;">+</span><span style="color: #000000;">completen</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">3</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span> |
|||
end for |
|||
<span style="color: #000000;">completed</span> <span style="color: #0000FF;">-=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">completed</span><span style="color: #0000FF;">></span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span> |
|||
end for |
|||
<span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">completed</span><span style="color: #0000FF;">]</span> |
|||
cdCanvasSetForeground(cddbuffer,colours[preview]) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
gx = mx+9*(dx+1)+1 |
|||
<span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">clear_line</span> |
|||
gy = my+19*(dx+1)+1 |
|||
<span style="color: #000000;">completed</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> |
|||
dx = floor(dx/4) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span> |
|||
sequence ptile = sq_add(repeat({gx+dx*2,gy+dx*2},4),sq_mul(tiles[preview],dx)) |
|||
for i=1 to 4 do |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">redraw_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*canvas*/</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000080;font-style:italic;">/*posx*/</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">/*posy*/</span><span style="color: #0000FF;">)</span> |
|||
{gx,gy} = ptile[i] |
|||
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">cw</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupGetIntInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"DRAWSIZE"</span><span style="color: #0000FF;">),</span> |
|||
cdCanvasBox(cddbuffer, gx, gx+dx-1, gy, gy+dx-1) |
|||
<span style="color: #000000;">dx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cw</span><span style="color: #0000FF;">/</span><span style="color: #000000;">10</span><span style="color: #0000FF;">),</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">/</span><span style="color: #000000;">20</span><span style="color: #0000FF;">))-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> |
|||
end for |
|||
<span style="color: #000000;">mx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">((</span><span style="color: #000000;">cw</span><span style="color: #0000FF;">-</span><span style="color: #000000;">10</span><span style="color: #0000FF;">*</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">-</span><span style="color: #000000;">11</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">),</span> |
|||
cdCanvasFlush(cddbuffer) |
|||
<span style="color: #000000;">my</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">((</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">-</span><span style="color: #000000;">20</span><span style="color: #0000FF;">*</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">-</span><span style="color: #000000;">21</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">),</span> |
|||
return IUP_DEFAULT |
|||
<span style="color: #000000;">gx</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">gy</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">sq</span> |
|||
end function |
|||
<span style="color: #7060A8;">cdCanvasActivate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span> |
|||
function map_cb(Ihandle ih) |
|||
<span style="color: #7060A8;">cdCanvasSetBackground</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">CD_DARK_GREY</span><span style="color: #0000FF;">)</span> |
|||
cdcanvas = cdCreateCanvas(CD_IUP, ih) |
|||
<span style="color: #7060A8;">cdCanvasClear</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span> |
|||
cddbuffer = cdCreateCanvas(CD_DBUFFER, cdcanvas) |
|||
return IUP_DEFAULT |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">20</span> <span style="color: #008080;">do</span> |
|||
end function |
|||
<span style="color: #000000;">gy</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">my</span><span style="color: #0000FF;">+(</span><span style="color: #000000;">20</span><span style="color: #0000FF;">-</span><span style="color: #000000;">y</span><span style="color: #0000FF;">)*(</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">10</span> <span style="color: #008080;">do</span> |
|||
function key_cb(Ihandle /*ih*/, atom c) |
|||
<span style="color: #000000;">sq</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> |
|||
if c=K_CR or c=K_SP then new_game() |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">sq</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">' '</span> <span style="color: #008080;">then</span> |
|||
elsif c=K_LEFT then {} = move(LEFT) |
|||
<span style="color: #7060A8;">cdCanvasSetForeground</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span><span style="color: #000000;">colours</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sq</span><span style="color: #0000FF;">,</span><span style="color: #000000;">letters</span><span style="color: #0000FF;">)])</span> |
|||
elsif c=K_RIGHT then {} = move(RIGHT) |
|||
<span style="color: #000000;">gx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">mx</span><span style="color: #0000FF;">+(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)*(</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span> |
|||
elsif c=K_UP then rotate() |
|||
<span style="color: #7060A8;">cdCanvasBox</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">gx</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">gx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">gy</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">gy</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> |
|||
elsif c=K_DOWN then drop() |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
elsif c=K_ESC then return IUP_CLOSE |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
end if |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
return IUP_CONTINUE |
|||
<span style="color: #7060A8;">cdCanvasSetForeground</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span><span style="color: #000000;">colours</span><span style="color: #0000FF;">[</span><span style="color: #000000;">preview</span><span style="color: #0000FF;">])</span> |
|||
end function |
|||
<span style="color: #000000;">gx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">mx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">9</span><span style="color: #0000FF;">*(</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span> |
|||
<span style="color: #000000;">gy</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">my</span><span style="color: #0000FF;">+</span><span style="color: #000000;">19</span><span style="color: #0000FF;">*(</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span> |
|||
function timer_cb(Ihandle /*timer*/) |
|||
<span style="color: #000000;">dx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">/</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)</span> |
|||
if completed then clear() |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">ptile</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_add</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">({</span><span style="color: #000000;">gx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">*</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">gy</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">*</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},</span><span style="color: #000000;">4</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">sq_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tiles</span><span style="color: #0000FF;">[</span><span style="color: #000000;">preview</span><span style="color: #0000FF;">],</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">))</span> |
|||
elsif not move(DOWN) then drop() |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">4</span> <span style="color: #008080;">do</span> |
|||
end if |
|||
<span style="color: #0000FF;">{</span><span style="color: #000000;">gx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">gy</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ptile</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
return IUP_DEFAULT |
|||
<span style="color: #7060A8;">cdCanvasBox</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">gx</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">gx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">gy</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">gy</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> |
|||
end function |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #7060A8;">cdCanvasFlush</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span> |
|||
procedure main() |
|||
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span> |
|||
IupOpen() |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
canvas = IupCanvas("RASTERSIZE=350x675") |
|||
IupSetCallback(canvas, "MAP_CB", Icallback("map_cb")) |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">map_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000000;">ih</span><span style="color: #0000FF;">)</span> |
|||
IupSetCallback(canvas, "ACTION", Icallback("redraw_cb")) |
|||
<span style="color: #000000;">cdcanvas</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">cdCreateCanvas</span><span style="color: #0000FF;">(</span><span style="color: #004600;">CD_IUP</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ih</span><span style="color: #0000FF;">)</span> |
|||
dialog = IupDialog(canvas) |
|||
<span style="color: #000000;">cddbuffer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">cdCreateCanvas</span><span style="color: #0000FF;">(</span><span style="color: #004600;">CD_DBUFFER</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cdcanvas</span><span style="color: #0000FF;">)</span> |
|||
IupSetAttribute(dialog,"TITLE",TITLE) |
|||
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span> |
|||
IupSetCallback(dialog, "K_ANY", Icallback("key_cb")); |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
timer = IupTimer(Icallback("timer_cb"), 500) |
|||
new_game() |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">key_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*ih*/</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">)</span> |
|||
IupShow(dialog) |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_CR</span> <span style="color: #008080;">or</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_SP</span> <span style="color: #008080;">then</span> <span style="color: #000000;">new_game</span><span style="color: #0000FF;">()</span> |
|||
IupSetAttribute(canvas, "RASTERSIZE", NULL) |
|||
<span style="color: #008080;">elsif</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_LEFT</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">move</span><span style="color: #0000FF;">(</span><span style="color: #000000;">LEFT</span><span style="color: #0000FF;">)</span> |
|||
IupMainLoop() |
|||
<span style="color: #008080;">elsif</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_RIGHT</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">move</span><span style="color: #0000FF;">(</span><span style="color: #000000;">RIGHT</span><span style="color: #0000FF;">)</span> |
|||
IupClose() |
|||
<span style="color: #008080;">elsif</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_UP</span> <span style="color: #008080;">then</span> <span style="color: #000000;">rotate</span><span style="color: #0000FF;">()</span> |
|||
end procedure |
|||
<span style="color: #008080;">elsif</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_DOWN</span> <span style="color: #008080;">then</span> <span style="color: #000000;">drop</span><span style="color: #0000FF;">()</span> |
|||
main()</lang> |
|||
<span style="color: #008080;">elsif</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_ESC</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">IUP_CLOSE</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_CONTINUE</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">timer_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*timer*/</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">completed</span> <span style="color: #008080;">then</span> <span style="color: #000000;">clear</span><span style="color: #0000FF;">()</span> |
|||
<span style="color: #008080;">elsif</span> <span style="color: #008080;">not</span> <span style="color: #000000;">move</span><span style="color: #0000FF;">(</span><span style="color: #000000;">DOWN</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #000000;">drop</span><span style="color: #0000FF;">()</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">()</span> |
|||
<span style="color: #7060A8;">IupOpen</span><span style="color: #0000FF;">()</span> |
|||
<span style="color: #000000;">canvas</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupCanvas</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"RASTERSIZE=350x675"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #7060A8;">IupSetCallback</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"MAP_CB"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"map_cb"</span><span style="color: #0000FF;">))</span> |
|||
<span style="color: #7060A8;">IupSetCallback</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"ACTION"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"redraw_cb"</span><span style="color: #0000FF;">))</span> |
|||
<span style="color: #000000;">dialog</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupDialog</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dialog</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TITLE"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">TITLE</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #7060A8;">IupSetCallback</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dialog</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"K_ANY"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"key_cb"</span><span style="color: #0000FF;">));</span> |
|||
<span style="color: #000000;">timer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupTimer</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"timer_cb"</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">500</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">new_game</span><span style="color: #0000FF;">()</span> |
|||
<span style="color: #7060A8;">IupShow</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dialog</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"RASTERSIZE"</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">NULL</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()!=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #7060A8;">IupMainLoop</span><span style="color: #0000FF;">()</span> |
|||
<span style="color: #7060A8;">IupClose</span><span style="color: #0000FF;">()</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span> |
|||
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span> |
|||
<!--</syntaxhighlight>--> |
Latest revision as of 15:45, 29 August 2022
You can run this online here. For instructions, see key_cb()
-- -- demo\rosetta\Tetrominoes.exw -- ============================ -- -- Author Pete Lomax, Jan 2020 -- -- 1. A robot may not injure a human being, or, through inaction, -- allow a human being to come to harm. -- -- 2. A robot must obey the orders given it by human beings -- except where such orders would conflict with the First Law. -- -- 3. A robot must protect its own existence as long as such -- protection does not conflict with the First or Second Law. -- -- 4. A robot must never place the long skinny ones horizontally, -- unless it leads to a long skinny vertical hole so 4 rows can -- be cleared at once the next time a long skinny one comes -- around. -- with javascript_semantics include pGUI.e Ihandle canvas, dialog, timer cdCanvas cddbuffer, cdcanvas constant TITLE = "Tetrominoes", lct = {{'I',CD_CYAN, {{-2, 0},{-1, 0},{ 0, 0},{ 1, 0}}}, {'T',CD_PURPLE, {{-1, 0},{ 0, 0},{ 1, 0},{ 0, 1}}}, {'O',CD_YELLOW, {{-1, 0},{ 0, 0},{-1, 1},{ 0, 1}}}, {'S',CD_GREEN, {{-1, 1},{ 0, 1},{ 0, 0},{ 1, 0}}}, {'Z',CD_RED, {{-1, 0},{ 0, 0},{ 0, 1},{ 1, 1}}}, {'J',CD_BLUE, {{-1, 0},{ 0, 0},{ 1, 0},{ 1, 1}}}, {'L',CD_ORANGE, {{-1, 1},{-1, 0},{ 0, 0},{ 1, 0}}}}, {letters,colours,tiles} = columnize(lct), topbot = {repeat('*',12)}, clear_line = '*'&repeat(' ',10)&'*', full_line = '*'&repeat('Z',10)&'*', init_board = topbot&repeat(clear_line,20)&topbot, directions = {{0,+1}, -- DOWN {-1,0}, -- LEFT {+1,0}} -- RIGHT --enum type direction DOWN, LEFT, RIGHT end type enum DOWN, LEFT, RIGHT type direction(integer d) return d>=DOWN and d<=RIGHT end type sequence board, -- (nb 2-based indexing!) tile integer px, py, preview, level, completed, -- (the first complete line found, cleared soon) completen, -- (number of "" "" s "" "" "" ) completot -- (the running total, used to update the level) function check(sequence curr, next, integer nx, ny) -- (common code for move and rotate) integer tx, ty, what for i=1 to length(next) do -- check tgt free sequence ti = next[i] if not find(ti,curr) then {tx,ty} = ti if tx>11 or board[ty,tx]!=' ' then return false end if end if end for for i=1 to 4 do -- clear current {tx,ty} = curr[i] what = board[ty,tx] board[ty,tx]=' ' end for for i=1 to 4 do -- set new position {tx,ty} = next[i] board[ty,tx] = what end for {px,py} = {nx,ny} IupUpdate(canvas) return true end function function move(direction d, bool place=false, what=' ') -- returns true/false to allow detection of "game over", drop new, etc integer {dx,dy} = directions[d], tx, ty, x, y sequence curr = repeat({},4), next = repeat({},4) for i=1 to length(tile) do {tx,ty} = tile[i] {x,y} = {px+tx+1,py+ty+1} curr[i] = {x,y} next[i] = {x+dx,y+dy} if place then board[y,x] = what end if end for return check(curr,next,px+dx,py+dy) end function procedure rotate() -- 90 degrees anti-clockwise sequence rile = deep_copy(tile), curr = repeat({},4), next = repeat({},4) for i=1 to length(tile) do integer {tx,ty} = tile[i] rile[i] = {ty,-tx} curr[i] = {px+tx+1,py+ty+1} next[i] = {px+ty+1,py-tx+1} end for if check(curr,next,px,py) then tile = rile end if end procedure procedure set_level(integer nl) level = nl IupSetInt(timer,"RUN",false) IupSetInt(timer,"TIME",50*(11-level)) IupSetInt(timer,"RUN",true) IupSetStrAttribute(dialog,"TITLE","%s - level %d",{TITLE,level}) end procedure procedure drop(bool bStart=false) if bStart then board = deep_copy(init_board) preview = rand(7) completed = 0 completot = 0 set_level(1) else while move(DOWN) do end while for i=2 to 21 do if not find(' ',board[i]) then completed = i for j=i+1 to 22 do board[j-1] = full_line if j=22 or find(' ',board[j]) then completen = j-i IupUpdate(canvas) return -- (show it with a brief pause) end if end for end if end for end if integer t = preview preview = rand(7) {px,py,tile} = {6,1,tiles[t]} if not move(DOWN,true,letters[t]) then IupSetStrAttribute(dialog,"TITLE","%s - GAME OVER",{TITLE}) IupSetInt(timer,"RUN",false) end if end procedure procedure new_game() drop(bStart:=true) end procedure procedure clear() completot += completen integer nl = floor(min(completot-1,90)/10)+1 if nl!=level then set_level(nl) end if for i=completed+completen-1 to 3 by -1 do completed -= (completed>2) board[i] = board[completed] end for board[2] = clear_line completed = 0 end procedure function redraw_cb(Ihandle /*canvas*/, integer /*posx*/, /*posy*/) integer {cw,ch} = IupGetIntInt(canvas, "DRAWSIZE"), dx = min(floor(cw/10), floor(ch/20))-1, mx = floor((cw-10*dx-11)/2), my = floor((ch-20*dx-21)/2), gx, gy, sq cdCanvasActivate(cddbuffer) cdCanvasSetBackground(cddbuffer, CD_DARK_GREY) cdCanvasClear(cddbuffer) for y=1 to 20 do gy = my+(20-y)*(dx+1)+1 for x=1 to 10 do sq = board[y+1,x+1] if sq!=' ' then cdCanvasSetForeground(cddbuffer,colours[find(sq,letters)]) gx = mx+(x-1)*(dx+1)+1 cdCanvasBox(cddbuffer, gx, gx+dx-1, gy, gy+dx-1) end if end for end for cdCanvasSetForeground(cddbuffer,colours[preview]) gx = mx+9*(dx+1)+1 gy = my+19*(dx+1)+1 dx = floor(dx/4) sequence ptile = sq_add(repeat({gx+dx*2,gy+dx*2},4),sq_mul(tiles[preview],dx)) for i=1 to 4 do {gx,gy} = ptile[i] cdCanvasBox(cddbuffer, gx, gx+dx-1, gy, gy+dx-1) end for cdCanvasFlush(cddbuffer) return IUP_DEFAULT end function function map_cb(Ihandle ih) cdcanvas = cdCreateCanvas(CD_IUP, ih) cddbuffer = cdCreateCanvas(CD_DBUFFER, cdcanvas) return IUP_DEFAULT end function function key_cb(Ihandle /*ih*/, atom c) if c=K_CR or c=K_SP then new_game() elsif c=K_LEFT then {} = move(LEFT) elsif c=K_RIGHT then {} = move(RIGHT) elsif c=K_UP then rotate() elsif c=K_DOWN then drop() elsif c=K_ESC then return IUP_CLOSE end if return IUP_CONTINUE end function function timer_cb(Ihandle /*timer*/) if completed then clear() elsif not move(DOWN) then drop() end if return IUP_DEFAULT end function procedure main() IupOpen() canvas = IupCanvas("RASTERSIZE=350x675") IupSetCallback(canvas, "MAP_CB", Icallback("map_cb")) IupSetCallback(canvas, "ACTION", Icallback("redraw_cb")) dialog = IupDialog(canvas) IupSetAttribute(dialog,"TITLE",TITLE) IupSetCallback(dialog, "K_ANY", Icallback("key_cb")); timer = IupTimer(Icallback("timer_cb"), 500) new_game() IupShow(dialog) IupSetAttribute(canvas, "RASTERSIZE", NULL) if platform()!=JS then IupMainLoop() IupClose() end if end procedure main()