标题: 彩色版俄罗斯方块[BAT+POWERSHELL混编] [打印本页]
作者: aa77dd@163.com 时间: 2016-10-7 17:33 标题: 彩色版俄罗斯方块[BAT+POWERSHELL混编]
本帖最后由 aa77dd@163.com 于 2016-10-7 17:37 编辑
转自 Dostips
http://www.dostips.com/forum/vie ... &p=46206#p46206
我一直不想学 Powershell, 不过现在看到这个东东弄彩色, 感觉也蛮好玩的
又发现, 还有鼠标可以控制方块左右移动, Powershell 这东东还是有点用啊, 哈哈
Ohohohoh, 它用的 850 代码页, 我们是 936 DANG 啊, 有点水土不服, 先看颜色吧, 这个代码页主要就关系到显示能不能正常了, 比如字符形状, 位置, 谁感兴趣修改下, 或者我某时再改下
原帖下面没几楼还有个 彩色版的 2048 [2048 是啥? 君请自行gg吧]
- @echo off
- setlocal EnableDelayedExpansion
-
- if "%~1" neq "" goto %1
-
- rem Written by Antonio Perez Ayala
- rem http://www.dostips.com/forum/viewtopic.php?f=3&t=6812
- rem Reference: http://colinfahey.com/tetris/tetris.html
- rem 2015/11/27 - version 1.0
- rem 2016/03/31 - version 2.0: Use PowerShell to read arrow keys and mouse movements
- rem 2016/04/11 - version 3.0: Use PowerShell to show text in color
- rem 2016/04/12 - version 3.1: Synchronization problem fixed, change window/buffer size bug fixed
- rem http://www.dostips.com/forum/viewtopic.php?f=3&t=6936&p=46206#p46206
-
- rem The best appearance is obtained with a square font, like Raster Font 8x8
-
- color 0F
- chcp 850 > NUL
- cls
- echo/
- echo === Pure .BATch-file Tetris game by Aacini ===
- echo/
- echo/
- echo Tetris pieces are controlled with these keys:
- echo/
- echo rot.right
- echo ^^
- echo rot. rot. move ^| move
- echo left ^<ÄÄ A S D ÄÄ^> right left ^<ÄÄúÄÄ^> right
- echo ^| ^|
- echo v v
- echo soft drop hard drop
- echo/
- echo Mouse movements emulate arrow key presses,
- echo left button pause/continue the game.
- echo/
- echo/
- echo Press P to pause/continue; press N to end game.
- echo/
- echo/
- pause
- cls
-
- rem Field dimensions
- set /A cols=10, lines=20
-
- set /P "=Loading PS engine..." < NUL
- cd . > pipeFile.txt
- "%~F0" Input >> pipeFile.txt | "%~F0" Main < pipeFile.txt | "%~F0" Output
- ping localhost -n 2 > NUL
- del pipeFile.txt
- goto :EOF
-
-
-
- :Input
- set "letter=ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- for /L %%i in (0,1,25) do (
- set /A "Letter!letter:~%%i,1!=%%i+65"
- )
- set /A "LeftArrow=37, UpArrow=38, RightArrow=39, DownArrow=40"
- PowerShell ^
- $mouseSens = 10; ^
- $command = @{ ^
- %LeftArrow% = 'Dx=-1'; ^
- %RightArrow% = 'Dx=1'; ^
- %DownArrow% = 'del=3'; ^
- %UpArrow% = 'R=-1'; ^
- %LetterA% = 'R=1'; ^
- %LetterD% = 'R=-1'; ^
- %LetterS% = 'Dy=-1'; ^
- %LetterY% = 'Y'; ^
- %LetterN% = 'N=1'; ^
- %LetterP% = 'pause=1'; ^
- }; ^
- [Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms') ^| Out-Null; ^
- $lX = [System.Windows.Forms.Control]::MousePosition.X; ^
- $lY = [System.Windows.Forms.Control]::MousePosition.Y; ^
- Start-Sleep -m 1500; ^
- Write-Output 0; ^
- while ( $key -ne %LetterN% ) { ^
- if ( $Host.UI.RawUI.KeyAvailable ) { ^
- $key = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyUp').VirtualKeyCode; ^
- Write-Output $command[$key]; ^
- } else { ^
- $mX = [System.Windows.Forms.Control]::MousePosition.X; ^
- $mY = [System.Windows.Forms.Control]::MousePosition.Y; ^
- $mB = [System.Windows.Forms.Control]::MouseButtons; ^
- $dX = $mX - $lX; $dY = $mY - $lY; ^
- if ( [math]::abs($dX) -gt $mouseSens ) { ^
- $if = if ($dX -lt 0) {%LeftArrow%} else {%RightArrow%}; ^
- Write-Output $command[$if]; ^
- $lX = $mX; $lY = $mY; ^
- } else { if ( [math]::abs($dY) -gt $mouseSens ) { ^
- $if = if ($dY -lt 0) {%UpArrow%} else {%DownArrow%}; ^
- Write-Output $command[$if]; ^
- $lX = $mX; $lY = $mY; ^
- } else { if ( $mB -eq 'Left' ) { ^
- Write-Output $command[%LetterP%]; ^
- }}} ^
- } ^
- Start-Sleep -m 100; ^
- }
- %End PowerShell%
- echo Ending game... > CON
- exit
-
-
-
- :Output
- rem Parameters received via lines read have one of these four forms:
- rem - 'cls' = Clear screen and initialize the field
- rem - X,Y = Move cursor to X,Y position
- rem - X,Y,'ColorString' = Move cursor to such position and show the "Color Codes String"
- rem - X,Y,Color,Wide = Move cursor to such position and show Wide chars in given Color;
- rem if Color is '=', show an equal-sign character Wide times
- rem - 'del',Filename = Delete the given file (for synchro purposes)
- PowerShell ^
- function ClearScreen () { ^
- cls; for ( $i=0; $i -lt $lnN; ++$i ) { Write-Host; Write-Host } ^
- Write-Host -NoNewLine (' '*2); Write-Host "ú$frame¿"; ^
- for ( $i=1; $i -le %lines%*$lnN; ++$i ) { Write-Host -NoNewLine (' '*2); Write-Host "3$spc3" } ^
- Write-Host -NoNewLine (' '*2); Write-Host "à$frameù"; ^
- Write-Host -NoNewLine (' '*2); Write-Host ' Level: 1'; ^
- Write-Host -NoNewLine (' '*3); Write-Host ' Rows: 0'; ^
- Write-Host -NoNewLine (' '*2); Write-Host ' Score: 0'; ^
- } ^
- $console = $Host.UI.RawUI; ^
- $console.WindowTitle = 'Tetris.BAT by Aacini'; ^
- $curSize = $console.CursorSize; ^
- $console.CursorSize = 0; ^
- for ( $i=1; $i -le 3; ++$i ) { ^
- if ( $i*(%lines%+2)+6 -le $console.MaxPhysicalWindowSize.Height ) { $lnN = $i } ^
- } ^
- $col = $lnN*%cols%+6; $lin = $lnN*(%lines%+2)+6; ^
- $winSize = $console.WindowSize; $bufSize = $console.BufferSize; ^
- $winSize.Width = $col; $bufSize.Width = $col; ^
- if ( $col -lt $console.WindowSize.Width ) { ^
- $console.WindowSize = $winSize; $console.BufferSize = $bufSize; ^
- } else { ^
- $console.BufferSize = $bufSize; $console.WindowSize = $winSize; ^
- } ^
- $winSize.Height = $lin; $bufSize.Height = $lin; ^
- if ( $lin -lt $console.WindowSize.Height ) { ^
- $console.WindowSize = $winSize; $console.BufferSize = $bufSize; ^
- } else { ^
- $console.BufferSize = $bufSize; $console.WindowSize = $winSize; ^
- } ^
- $ln = ( ('X'), ('úa','àù'), ('úÄ¿','3 3','àÄù') )[$lnN-1]; ^
- $frame = ''; $spc = ''; for ( $i=1; $i -le $col-6; ++$i ) { $frame+='Ä'; $spc+=' '; } ^
- $coords = $console.CursorPosition; ^
- foreach ( $line in $input ) { ^
- $X,$Y,$Color,$Wide = $line.Split(','); ^
- if ( $X -eq 'cls' ) { ^
- ClearScreen ^
- } else { if ($X -eq 'del') { ^
- del $Y ^
- } else { ^
- $coords.X = 3 + ([int]$X-1) * $lnN; ^
- $Y = [int]$Y; $coords.Y = (%lines%+3-$Y) * $lnN ; ^
- if ( $Y -le %lines% ) { $coords.Y -= $lnN-1 } ^
- if ( $Y -lt 0 ) { $coords.Y += $Y*($lnN-1) } ^
- $console.CursorPosition = $coords; ^
- if ( $Wide ) { ^
- $Wide = [int]$Wide; ^
- if ( $Color -ne '=' ) { ^
- $Color = [int]('0x'+$Color); ^
- for ( $i=0; $i -lt $lnN; ++$i ) { ^
- for ( $j=0; $j -lt $Wide; ++$j ) { ^
- Write-Host -BackgroundColor $Color -ForegroundColor 'Black' -NoNewLine $ln[$i] ^
- } ^
- ++$coords.Y; $console.CursorPosition = $coords; ^
- } ^
- } else { ^
- for ( $i=0; $i -lt $lnN; ++$i ) { ^
- Write-Host ('='*($Wide*$lnN)); ^
- ++$coords.Y; $console.CursorPosition = $coords; ^
- } ^
- } ^
- } else { if ( $Color ) { ^
- for ( $i=0; $i -lt $lnN; ++$i ) { ^
- for ( $j=0; $j -lt $Color.Length; ++$j ) { ^
- $colr = [int]('0x'+$Color[$j]); ^
- Write-Host -BackgroundColor $colr -ForegroundColor 'Black' -NoNewLine $ln[$i] ^
- } ^
- ++$coords.Y; $console.CursorPosition = $coords; ^
- } ^
- }} ^
- }} ^
- } ^
- $console.CursorSize = $curSize;
- %End PowerShell%
- exit /B
-
-
-
- :Main
-
- (
- for /F "delims==" %%v in ('set') do set "%%v="
- set /A cols=%cols%, lines=%lines%
- )
-
- rem Initialize the Field
- for /L %%i in (1,1,%cols%) do set "spc=!spc!0"
- for /L %%i in (1,1,%lines%) do set "F%%i=3%spc%3"
- set /A "Level=1, Rows=0, Score=0, top=lines+3, delay=50"
-
- rem The pieces are defined via 3 groups of values: Piece : Color : Orientations
- rem The ":orientations:" (piece positions) are defined via "triplets":
- rem (offset Y . offset X . length X); one "triplet" for each horizontal line
- rem See: http://colinfahey.com/tetris/tetris.html
- set "pcs="
- for %%t in ( "O:9:0.-1.2 -1.-1.2"
- "I:C:0.-2.4:1.0.1 0.0.1 -1.0.1 -2.0.1"
- "S:A:0.0.2 -1.-1.2:1.0.1 0.0.2 -1.1.1"
- "Z:B:0.-1.2 -1.0.2:1.1.1 0.0.2 -1.0.1"
- "L:D:0.-1.3 -1.-1.1:1.0.1 0.0.1 -1.0.2:1.1.1 0.-1.3:1.-1.2 0.0.1 -1.0.1"
- "J:7:0.-1.3 -1.1.1:1.0.2 0.0.1 -1.0.1:1.-1.1 0.-1.3:1.0.1 0.0.1 -1.-1.2"
- "T:E:0.-1.3 -1.0.1:1.0.1 0.0.2 -1.0.1:1.0.1 0.-1.3:1.0.1 0.-1.2 -1.0.1" ) do (
- set "pc=%%~t" & set "i=-2"
- for /F "delims=" %%p in (^"!pc::^=^
- % New line %
- !^") do (
- if !i! equ -2 (
- set "pc=%%p" & set "pcs=!pcs!%%p"
- ) else if !i! equ -1 (
- set "!pc!R=%%p"
- ) else (
- set "!pc!!i!=%%p"
- )
- set /A i+=1
- )
- set "!pc!N=!i!"
- )
-
- :WaitPS for PowerShell Input part start signal
- set /P "com="
- if not defined com goto WaitPS
- set "com="
-
- set "init=1"
- for /L %%# in () do (
-
- if defined init (
- setlocal EnableDelayedExpansion
- set "init="
- echo cls
-
- rem Create the first "previous" -hidden- piece
- for /L %%i in (0,1,!time:~-1!) do set /A p=!random!%%7
- for %%p in (!p!) do set "p2=!pcs:~%%p,1!"
- for %%p in (!p2!) do set "p3=!%%p0!" & set "p4=!%%pN!" & set "p5=!%%pR!!%%pR!!%%pR!!%%pR!"
-
- set "new=1"
- )
-
- if defined new (
- set "new="
-
- rem Take the "previous" piece as current one
- set "pc=!p2!" & set "p0=!p3!" & set "pN=!p4!" & set "pR=!p5!"
-
- rem Create a new "previous" piece
- for /L %%i in (1,1,2) do (
- set /A p=!random!*7/32768
- for %%p in (!p!) do (
- set "p=!pcs:~%%p,1!"
- if !p! neq !pc! set "p2=!p!"
- )
- )
- for %%p in (!p2!) do set "p3=!%%p0!" & set "p4=!%%pN!" & set "p5=!%%pR!!%%pR!!%%pR!!%%pR!"
-
- rem Show the new "previous" piece in its place, above Field
- set /A x=cols/2-1
- for %%p in (!p3!) do (
- for /F "tokens=1-3 delims=." %%i in ("%%p") do (
- set /A yp=top+%%i, xp=2+%%j, xL=xp+%%k
- for /F "tokens=1,2" %%a in ("!xp! !xL!") do (
- set "pce=0000"
- set "pce=!pce:~0,%%a!!p5:~0,%%k!!pce:~%%b!"
- echo !x!,!yp!,!pce!
- )
- )
- )
- if !p2! equ I set /A yp=top-1 & echo !x!,!yp!,0000
-
- rem Try to insert the new current piece in the Field...
- set /A x=cols/2+1, y=lines, b=1
- for %%p in (!p0!) do (
- for /F "tokens=1-3 delims=." %%i in ("%%p") do (
- set /A yp=y+%%i, xp=x+%%j, xL=xp+%%k
- for /F "tokens=1-3" %%a in ("!yp! !xp! !xL!") do (
- if "!F%%a:~%%b,%%k!" neq "!spc:~0,%%k!" set "b="
- set "F%%a=!F%%a:~0,%%b!!pR:~0,%%k!!F%%a:~%%c!"
- echo %%b,%%a,!F%%a:~%%b,1!,%%k
- )
- )
- )
-
- rem ... if that was not possible:
- if not defined b call :endGame & endlocal
-
- set "p1=!p0!"
- set /A "pI=0, del=delay, b=1!time:~-2!"
-
- )
-
- rem Control module: move the piece as requested via a key, or down one row each %del% centiseconds
- set "move="
- set /A "Dy=Dx=0"
- set /P "com="
- if defined com (
- set /A "!com!, move=1"
- set "com="
- if defined N exit
- if "!pause!" equ "1" call :Pause & set "move="
- set "b=1!time:~-2!"
- ) else (
- set /A "e=1!time:~-2!, elap=e-b, elap-=(elap>>31)*100"
- if !elap! geq !del! set /A b=e, Dy=move=-1
- )
-
- if defined move (
-
- rem Delete the piece from its current position in the field, and store current coordinates
- set i=0
- for %%p in (!p0!) do for /F "tokens=1-3 delims=." %%i in ("%%p") do (
- set /A yp=y+%%i, xp=x+%%j, xL=xp+%%k
- for /F "tokens=1-3" %%a in ("!yp! !xp! !xL!") do (
- set "F%%a=!F%%a:~0,%%b!!spc:~0,%%k!!F%%a:~%%c!"
- set /A i+=1
- set "c!i!=%%a %%b %%c %%k"
- )
- )
-
- rem If move is Rotate: get rotated piece
- if defined R (
- set /A "p=(pI+R+pN)%%pN"
- for /F "tokens=1,2" %%i in ("!pc! !p!") do set "p1=!%%i%%j!"
- )
-
- rem Test if the piece can be placed at the new position, and store new coordinates
- set j=0
- for %%p in (!p1!) do if defined move (
- for /F "tokens=1-3 delims=." %%i in ("%%p") do (
- set /A yp=y+%%i+Dy, xp=x+%%j+Dx, xL=xp+%%k
- for /F "tokens=1-3" %%a in ("!yp! !xp! !xL!") do (
- if "!F%%a:~%%b,%%k!" equ "!spc:~0,%%k!" (
- set /A j+=1
- set "n!j!=%%a %%b %%c %%k"
- ) else (
- set "move="
- )
- )
- )
- )
-
- if defined move (
-
- rem Clear the piece from its current position, on the screen
- for /L %%i in (1,1,!i!) do (
- for /F "tokens=1-4" %%a in ("!c%%i!") do (
- echo %%b,%%a,!F%%a:~%%b,1!,%%d
- )
- )
-
- rem Place the piece at the new position, both in field and screen
- for /L %%j in (1,1,!j!) do (
- for /F "tokens=1-4" %%a in ("!n%%j!") do (
- set "F%%a=!F%%a:~0,%%b!!pR:~0,%%d!!F%%a:~%%c!"
- echo %%b,%%a,!F%%a:~%%b,1!,%%d
- )
- )
-
- rem Update any changes in the piece
- set /A y+=Dy, x+=Dx
- if defined R set "p0=!p1!" & set "pI=!p!" & set "R="
-
- ) else ( rem The piece can not be moved
-
- rem Recover the piece at its current position, in the field
- for /L %%i in (1,1,!i!) do (
- for /F "tokens=1-4" %%a in ("!c%%i!") do (
- set "F%%a=!F%%a:~0,%%b!!pR:~0,%%d!!F%%a:~%%c!"
- )
- )
- if defined R set "p1=!p0!" & set "R="
-
- if !Dy! neq 0 ( rem The piece "lands"
-
- rem Check completed lines
- set "j=" & set "m=0"
- for /L %%i in (1,1,!i!) do for /F %%a in ("!c%%i!") do (
- if "!F%%a:0=!" equ "!F%%a!" (
- set "F%%a=X"
- set "j=!j! %%a"
- set /A m+=1
- )
- )
-
- if !m! gtr 0 (
-
- rem Blink completed lines on screen
- for %%i in (!j!) do (
- echo 1,%%i,=,%cols%
- )
-
- rem Update level and scores
- rem See: N-Blox at http://www.tetrisfriends.com/help/tips_appendix.php#rankingsystem
- set /A "xp=Level*(40+((j-2>>31)+1)*60+((j-3>>31)+1)*200+((j-4>>31)+1)*900)"
- set /A "Score+=xp, Rows+=j, xL=Level, Level=(Rows-1)/10+1"
- if !Level! neq !xL! if !delay! gtr 5 set /A delay-=5
- rem BEL Ctrl-G Ascii-7:
- set /P "=" < NUL > CON
-
- rem Remove completed lines from field
- set "i=1"
- for /L %%i in (1,1,%lines%) do (
- set "F!i!=!F%%i!"
- if "!F%%i!" neq "X" set /A i+=1
- )
- for /L %%i in (!i!,1,%lines%) do set "F%%i=3%spc%3"
-
- rem Update scores and the whole field on screen
- echo 1,-1
- call :Delay 95
- (
- echo Level: !Level!
- echo Rows: !Rows!
- echo Score: !Score!
- ) > CON
- echo X > PSbusy.txt
- for /L %%i in (%lines%,-1,1) do echo 1,%%i,!F%%i:~1,-1!
- echo del,PSbusy.txt
- call :WaitPSbusy
-
- )
-
- rem Request to show a new piece
- set "new=1"
-
- )
-
- )
-
- )
-
- )
-
-
- :endGame
- echo 1,-4
- echo X > PSbusy.txt
- echo del,PSbusy.txt
- call :WaitPSbusy
- set /P "=Play again? " < NUL > CON
- :choice
- set /P "com="
- if not defined com goto choice
- if "%com%" equ "Y" exit /B
- if "%com:~0,1%" neq "N" set "com=" & goto choice
- echo N > CON
- exit
-
-
- :WaitPSbusy
- if exist PSbusy.txt goto WaitPSbusy
- exit /B
-
-
- :Pause
- title PAUSED
- :wait
- set /P "com="
- if not defined com goto wait
- if "%com%" neq "pause=1" set "com=" & goto wait
- set "com="
- set "pause="
- title Tetris.BAT by Aacini
- exit /B
-
-
- :Delay centisecs
- set "b=1%time:~-2%"
- :wait2
- set /A "e=1%time:~-2%, elap=e-b, elap-=(elap>>31)*100"
- if %elap% lss %1 goto wait2
- set "b=1%time:~-2%"
- exit /B
复制代码
作者: 523066680 时间: 2016-10-7 18:12
光看代码就觉得,代价比学Csharp C 做同样的事情要麻烦。
作者: aa77dd@163.com 时间: 2016-10-7 18:38
回复 2# 523066680
一直不怎么喜欢用 VBS, 尽管最早学的语言就是 QB, 还做过一段时间的 ASP 开发, 可还是不待见 VBS, 而 BAT 呢, 如果要搞什么专业的东东, 根本使不上, 当然除了简单文件管理, 简单文本处理等等这些
而 BAT 的特色也就 简单灵活吧, 也就这点好玩了, 随时可以写, 不用编译, 有 windows 有 cmd 就成,
而 powershell , 好象 MS 把它定位成 BAT 接班的, 可是就是感觉不到一点血缘关系啊
作者: 523066680 时间: 2016-10-7 19:42
本帖最后由 523066680 于 2016-10-7 21:43 编辑
回复 3# aa77dd@163.com
最初凭兴趣学过c和bat,一点vbs,后来学过一段时间Perl。当我看到 Powershell,一点兴趣都没有,关键我也不是系统维护方面的工作,
它的那些优势对我来说一点用都没有,要方便有perl和python,要语法糖有ruby。加上论坛之前出现一个奇葩,自称Powershell传教士,直接
让我对powershell产生反感。
抛开这些不说,我还是应该补补数学和物理
之前用Perl的Win32::Console模块做终端Wiki管理工具,用来做终端游戏应该还算方便。而做游戏,主要还是缺少时间和耐心,什么语言什么库已经不是大问题。
作者: LJY4.0 时间: 2022-6-5 21:39
好像有unicode字符
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |