Bash version of the Russian square

xiaoxiao2021-03-06  97

#! / bin / bash

# TETRIS GAME

# $ ID $

#

# Copyright (c) xhchen

# All rights reserved.

#

# $ Log $

#

# Color definition

CRED = 1

CGreen = 2

Cyellow = 3

CBLUE = 4

Cfuchsia = 5

Ccyan = 6

CWHITE = 7

ColORTABLE = ($ CRED $ CGREEN $ CYELLOW $ CFUE $ CFUCHSIA $ CCYAN $ CWHITE)

# Location and size

Ileft = 3

ITOP = 2

((ItRayeft = Ileft 2)))

((straytop = ITOP 1)))

((straywidth = 10)))

((strayheight = 15))

# Color setting

CBORDER = $ cgreen

Cscore = $ cfuchsia

Cscorevalue = $ ccyan

#control signal

# Change the game Use two processes, one for receiving input, one for game flow and display interface;

# When the current person receives a button, the back and so on, the latter is notified by sending the Signal to the latter.

Sigrotate = 25

SigLeft = 26

Sigright = 27

Sigdown = 28

SigalLDown = 29

SiGexit = 30

# 七 中 不同 方 方 定

# By rotating, there may be several styles of each block display

Box0 = (0 0 0 1 1 0 1 1)

Box1 = (0 2 1 2 2 2 3 2 1 0 1 1 1 2 1 3)

Box2 = (0 0 0 1 1 1 1 2 0 1 1 0 1 1 2 0)

Box3 = (0 1 0 2 1 0 1 1 0 0 1 0 1 1 2 1)

Box4 = (0 1 0 2 1 1 2 1 1 0 1 1 2 2 2 0 1 1 2 0 2 1 0 0 1 0 1 1 1 2)

Box5 = (0 1 1 1 2 1 2 2 1 0 1 1 1 2 2 0 0 0 1 1 1 2 1 0 2 1 0 1 1 1 2)

Box6 = (0 1 1 1 1 2 2 1 1 0 1 1 1 2 2 1 0 1 1 1 1 2 1 0 1 1 0 1 1 1 2)

# All of them definitions in the Box variable

Box = ($ {Box0 [@]} $ {box1 [@]} $ {box3 [@]} $ {box4 [@]} $ {box5 [@]} $ {box6 [@]} $ { ]})

# Various squares of various squares

Countbox = (1 2 2 2 4 4 4)

# Offset in various squares re-box arrays

OFFSETBOX = (0 1 3 5 7 11 15)

# Each time to increase the score required to accumulate

Iscoreeachleevel = 50 #be Greater Than 7

# 运 运 数据 数据

SIG = 0 # received Signal

ISCORE = 0 # 000

Ilevel = 0 # speed level

Boxnew = () # 新 新 块 块 位置 位置

CBOXNEW = 0 # color of new drops

IBOXNewType = 0 # Novetical Categories

IBOXNEWROTATE = 0 # rotation angle of the new drops

Boxcur = () # The location definition of the current square

CBOXCUR = 0 # Current square color

iBoxCurtype = 0 # Type IBoxCurrotate = 0 # Current square rotation angle

Boxcurx = -1 # Current block X coordinate position

BoxCURY = -1 # Current block Y coordinate position

IMAP = () # Background block diagram

# Initialize all background squares to -1, indicating that there is no block

For ((i = 0; i

#How to receive the main function of the input process

Function RunasKeyReceiver ()

{

Local Piddisplayer Key Akey Sig Cesc Stty

piddisplayer = $ 1

Akey = (0 0 0)

CESC = `echo -ne" / 33 "`

CSPACE = `Echo -ne" / 40 "`

# Save Terminal Properties. When the terminal key is read in the read -s, the attributes of the terminal will be temporarily changed.

# If the program is unfortunate in Read -S, it may cause the terminal to be confusing.

# Require terminal attribute when the program exits.

Stty = `stty -g`

# Capture exit signal

TRAP "MyExit;" INT TERM

TRAP "MyExitnosub;" $ SIGEXIT

# Hidden cursor

echo -ne "/ 33 [? 25L"

While [[1]]

DO

# Read input. Note -s does not return, -n reads a character to return immediately

Read -s -n 1 Key

Akey [0] = $ {akey [1]}

akey [1] = $ {akey [2]}

Akey [2] = $ key

SIG = 0

# 输入 输入 输入 输入

IF [[$ key == $ CESC && $ {akey [1]} == $ cESC]]

THEN

#ESC

MyExit

Elif [[$ {akey [0]} == $ CESC && $ {akey [1]} == "["]]

THEN

IF [[$ key == "a"]]; THEN SIG = $ sigrotate #

Elif [[$ key == "b"]]; THEN SIG = $ SIGDOWN #

Elif [[$ key == "D"]]; the Sig = $ SIGLEFT # <向 左键>

Elif [[$ key == "c"]]; then sig = $ sigright #

Fi

Elif [[$ key == "W" || $ key == "w"]]; the Sig = $ sigrotate #w, w

Elif [[$ key == "S" || $ key == "s"]]; the Sig = $ sigdown #s, s

Elif [[$ key == "a" || $ key == "a"]]; the number = $ sigleft #a, a

Elif [[$ key == "D" || $ key == "D"]]; Then Sig = $ sigright #d, Delif [["[$ key]" == "[]"]]; the SIG = $ SIGALLDOWN # Spacebar

Elif [[$ key == "q" || $ key == "q"]] #q, q

THEN

MyExit

Fi

IF [$ SIG! = 0]]]]]]]

THEN

# Send a message to another process

KILL - $ SIG $ PIDDISPLAYER

Fi

DONE

}

# 退 退

Function myexitnosub ()

{

Local Y

# Restore Terminal Attributes

Stty $ stty

((y = ITOP ItrayHeight 4)))

# Display cursor

echo -e "/ 33 [? 25h / 33 [$ {y}; 0H"

exit

}

Function myexit ()

{

# 通 显示 Display process needs to exit

KILL - $ SiGexit $ PIDISPLAYER

MyExitnosub

}

# Handle the main function of display and game flow

Function RunasDisplayer ()

{

Local Sigthis

Initdraw

# Mount various signal processing functions

Trap "SIG = $ SIGROTATE;" $ SIGROTATE

TRAP "SIG = $ SIGLEFT;" $ SIGLEFT

TRAP "SIG = $ sigright;" $ SIGRIGHT

TRAP "SIG = $ sigdown;" $ SIGDOWN

Trap "SIG = $ sigalldown;" $ SIGALLDOWN

TRAP "Showexit;" $ SIGEXIT

While [[1]]

DO

# Different from the current speed level Ilevel, set the number of times the corresponding loop

For ((i = 0; i <21 - ilevel; i ))

DO

Usleep 20000

Sigthis = $ SIG

SIG = 0

# Depending on whether the SIG variable determines whether the corresponding signal is accepted

IF ((sigthis == sigrotate); then boxrotate; #

Elif ((sigthis == sigleft); the boxleft; # 移 一 列

Elif ((sigthis == sigright)); the BoxRight; # 一 一 列

Elif ((sigthis == sigdown); the BoxDown; # fallen

Elif ((sigthis == sigalldown); the boxalldown; # fallen to the end

Fi

DONE

#kill - $ SIGDOWN $$

Boxdown # drops

DONE

}

#Boxmove (y, x), can test whether the blocks in the movement into (x, y), return 0, 1

Function boxmove ()

{

Local J i x y xtest ytest

Ytest = $ 1

Xtest = $ 2

For ((j = 0; j <8; j = 2))

DO

((i = j 1)))

((y = $ {Boxcur [$ j]} ytest))

((x = $ {Boxcur [$ I]} xtest)))

IF ((y <0 || y> = strayheight || x <0 || x> = straywidth))

THEN

# 到 wall

Return 1

Fi

IF ($ {IMAP [Y * ItRaywidth x]}! = -1)))

THEN

# 到 的 有 有 有 有 有 有

Return 1

Fi

DONE

Return 0;

}

# Put the squares in the current move in the background square,

# And calculate new scores and speed levels. (Ie, the square falls to the bottom)

Function Box2map ()

{

Local J i x y xp yp line

# Put the squares in the current move in the background block

For ((j = 0; j <8; j = 2))

DO

((i = j 1)))

((y = $ {boxcur [$ j]} boxcury)))

((x = $ {Boxcur [$ I]} boxcurx))

((i = y * straywidth x))))

IMAP [$ I] = $ CBOXCUR

DONE

# 消 消 可 行 行

Line = 0

For ((j = 0; j

DO

For ((i = j itraywidth - 1; i> = j; i -))

DO

IF (($ {IMAP [$ I]} == -1)); Then Break; Fi

DONE

IF ((i> = j)); the continue; fi

((Line )))

For ((i = j - 1; i> = 0; i -)))

DO

((x = i itraywidth)))

IMAP [$ x] = $ {IMAP [$ I]}

DONE

For ((i = 0; i

DO

IMAP [$ I] = - 1

DONE

DONE

IF ((line == 0)); the return; Fi

# Calculate the score and speed level according to the number of lines of the elimination

((x = ILEFT ItrayWidth * 2 7))))))

((Y = ITOP 11)))

((Iscore = line * 2 - 1))))

# Display new score

Echo -ne "/ 33 [1M / 33 [3 $ {CSCoreValue} m / 33 [$ {y}; $ {x} h $ {iscore}

IF (ISCORE% Iscoreeachlevel

THEN

IF ((Ilevel <20))

THEN

((iLEVEL )))

((y = ITOP 14)))

# Show new speed level

echo -ne "/ 33 [3 $ {cscorevalue} m / 33 [$ {y}; $ {x} h $ {ilevel}"

Fi

Fi

echo -ne "/ 33 [0m"

# Re-display the background block

for ((y = 0; y

DO

((YP = Y ItRaytop 1)))

((XP = ItRayeft 1))))

((i = y * straywidth) Echo -ne "/ 33 [$ {yp}; $ {xp} h"

For ((x = 0; x

DO

((j = i x))))

IF ($ {IMAP [$ j]} == -1))))

THEN

echo -ne ""

Else

Echo -ne "/ 33 [1M / 33 [7M / 33 [3 $ {IMAP [$ J]} m / 33 [4 $ {IMAP [$ J]} M [] / 33 [0M"

Fi

DONE

DONE

}

# 倒 一 行

Function BoxDown ()

{

Local y

((Y = BoxCury 1) #nioted Y coordinate

If Boxmove $ y $ boxcurx # testing can be dropped

THEN

s = "` drawcurbox 0` "# 抹 块 块

((BoxCury = Y))

S = "$ s`drawcurbox 1`" # Show new drops behind

Echo -ne $ s

Else

# 走 到 儿, if you can't fall

Box2map # puts the blocks in the current move to the background block

Randombox # Generate new blocks

Fi

}

# 移

Function boxleft ()

{

Local x s

((x = boxcurx - 1))))

IF Boxmove $ BoxCury $ X

THEN

s = `drawcurbox 0`

((BoxCurx = x))

S = $ s`drawcurbox 1`

Echo -ne $ s

Fi

}

# 一一 列

Function BoxRight ()

{

Local x s

((x = boxcurx 1))))

IF Boxmove $ BoxCury $ X

THEN

s = `drawcurbox 0`

((BoxCurx = x))

S = $ s`drawcurbox 1`

Echo -ne $ s

Fi

}

# 下 下

Function BoxallDown ()

{

Local K J i x y idown s

IDown = $ itHeyheight

# Calculate how much it takes to drop

For ((j = 0; j <8; j = 2))

DO

((i = j 1)))

((y = $ {boxcur [$ j]} boxcury)))

((x = $ {Boxcur [$ I]} boxcurx))

For ((k = y 1; k

DO

((i = k * straywidth x)))

IF ($ {IMAP [$ I]}! = -1)); the Break; Fi

DONE

((k - = y 1)))))

IF (($ IDOWN> $ K)); Then iDown = $ K; FI

DONE

s = `drawcurbox 0` # Wipe the old square

((BoxCury = iDown)))

s = $ s`drawcurbox 1` # Shows the new drops after the new drops

Echo -ne $ s

Box2map # puts the blocks in the current move to the background block

Randombox # Generate new blocks

}

# 方块

Function Boxrotate ()

{

Local iCount ITESTROTATE BOXTEST J I Sicount = $ {CountBox [$ IBoxCurtype]} # The current number of styles that can be generated by rotation

# Calculate new style after rotation

((ITESTROTATE = IBoxCurrotate 1)))

IF ((ITESTROTATE> = iCount)))

THEN

((ITESTROTATE = 0)))

Fi

# Update to a new style, save old style (but not)

For ((j = 0, i = ($ {OFFSetBox [$ IBoxCurtype]} $ itestrotate) * 8; J <8; J , i ))

DO

Boxtest [$ j] = $ {boxcur [$ j]}

Boxcur [$ j] = $ {box [$ I]}

DONE

If Boxmove $ BoxCury $ BoxCurx # Is there a spatial place after the rotation

THEN

# 方 方

For ((j = 0; j <8; j ))

DO

Boxcur [$ j] = $ {boxtest [$ j]}

DONE

s = `drawcurbox 0`

# 画 新 方 方

For ((j = 0, i = ($ {OFFSetBox [$ IBoxCurtype]} $ itestrotate) * 8; J <8; J , i ))

DO

Boxcur [$ j] = $ {box [$ I]}

DONE

S = $ s`drawcurbox 1`

Echo -ne $ s

Iboxcurrotate = $ itestrotate

Else

# Can't rotate, or continue to use old style

For ((j = 0; j <8; j ))

DO

Boxcur [$ j] = $ {boxtest [$ j]}

DONE

Fi

}

#Drawcurbox (bdraw), drawing the blocks in the current move, BDRAW is 1, draw, BDRAW is 0, erase the square.

Function drawcurbox ()

{

Local I J T BDRAW SBOX S

BDRAW = $ 1

s = ""

IF ((BDRAW == 0))))

THEN

Sbox = "/ 40/40"

Else

sbox = "[]"

S = $ S "/ 33 [1M / 33 [7M / 33 [3 $ {CBoxCur} m / 33 [4 $ {cboxcur} M"

Fi

For ((j = 0; j <8; j = 2))

DO

((i = straytop 1 $ {Boxcur [$ j]} boxcury))))

((T = ItRayeft 1 2 * (BoxCurx $ {Boxcur [$ J 1]})))))))

# / 33 [y; XH, cursor to (x, y)

S = $ S "/ 33 [$ {i}; $ {t} h $ {sbox}"

DONE

s = $ s "/ 33 [0m"

echo -n $ s

}

# Update new square

Function randombox ()

{

Local i J t

# Update the current mobile block

Iboxcurtype = $ {iboxnewtype}

Iboxcurrotate = $ {iboxnewrotate}

CBoxcur = $ {CBoxnew}

For ((j = 0; j <$ {boxnew [@]}; j ))

Boxcur [$ j] = $ {boxnew [$ j]}

DONE

# Display the current movement

IF (($ {# boxcur [@]} == 8)))))

THEN

# Calculate the current square which is "take" from the top

For ((j = 0, t = 4; j <8; j = 2)))

DO

IF ($ {Boxcur [$ J]}

DONE

((BoxCury = -T))

For ((j = 1, i = -4, t = 20; j <8; j = 2)))

DO

IF ($ {BoxCur [$ J]}> i)); Then i = $ {Boxcur [$ J]}; fi

IF ($ {Boxcur [$ J]}

DONE

((BoxCurx = (straywidth - 1 - i - t) / 2))

# Display the current movement

Echo -ne `drawcurbox 1`

# If the square is coming out, Game over!

IF! Boxmove $ BoxCury $ BoxCurx

THEN

Kill - $ SiGexit $ {PPID}

Showexit

Fi

Fi

# 清除 预 预

For ((j = 0; j <4; j ))

DO

((i = ITOP 1 J))))

((t = ILEFT 2 * ItrayWidth 7))))

Echo -ne "/ 33 [$ {i}; $ {t} h"

DONE

# Randomly generate new squares

((iBoxNewType = random% $ {OFFSETBOX [@]}))

((iBoxNewrotate = Random% $ {Countbox [$ IBOXNEWTYPE]}))

For ((j = 0, i = ($ {OFFSETBOX [$ IBOXNEWTYPE) * 8; J <8; J , i ))))))

DO

Boxnew [$ j] = $ {box [$ i]};

DONE

((CBOXNEW = $ {ColORTABLE [Random% $ {# colorTable [@]}]})

# Show the square pre-displayed on the right

Echo -ne "/ 33 [1M / 33 [7M / 33 [3 $ {CBOXNEW} m / 33 [4 $ {CBOXNEW} M"

For ((j = 0; j <8; j = 2))

DO

((i = ITOP 1 $ {BoxNew [$ j]})))

((T = Ileft 2 * ItrayWidth 7 2 * $ {Boxnew [$ J 1]})

echo -ne "/ 33 [$ {}; $ {t} h []"

DONE

echo -ne "/ 33 [0m"

}

# Initial drawing

Function initdraw ()

{

Clear

Randombox # randomly generates square, then there is a faster in the right pre-display window.

Randombox # Create blocks, the squares in the right pre-display window are updated, the original block will start falling

LOCAL I T1 T2 T3 # Display Border

echo -ne "/ 33 [1m"

echo -ne "/ 33 [3 $ {cborder} m / 33 [4 $ {cborder} m"

((t2 = ILEFT 1)))

((T3 = ILEFT ITRAYWIDTH * 2 3))))

For ((i = 0; i

DO

((T1 = i ITOP 2)))

Echo -ne "/ 33 [$ {t1}; $ {t2} h ||

Echo -ne "/ 33 [$ {t1}; $ {t3} h ||"

DONE

((T2 = ITOP ItrayHeight 2)))

For ((i = 0; i

DO

((t1 = i * 2 Ileft 1)))

Echo -ne "/ 33 [$ i straytop}; $ {t1} h =="

echo -ne "/ 33 [$ {t2}; $ {t1} h =="

DONE

echo -ne "/ 33 [0m"

# Display "Score" and "Level" words

echo -ne "/ 33 [1m"

((T1 = ILEFT ITRAYWIDTH * 2 7))))

((T2 = ITOP 10)))

Echo -ne "/ 33 [3 $ {cscore} m / 33 [$ {t2}; $ {t1} hscore"

((t2 = ITOP 11)))

Echo -ne "/ 33 [3 $ {cscorevalue} m / 33 [$ {t2}; $ {t1} h $ {iscore}

((T2 = ITOP 13)))

Echo -ne "/ 33 [3 $ {cscore} m / 33 [$ {t2}; $ {t1} hlease"

((T2 = ITOP 14)))

Echo -ne "/ 33 [3 $ {cscorevalue} m / 33 [$ {t2}; $ {t1} h $ {ilevel}"

echo -ne "/ 33 [0m"

}

# Display GameOver when exiting!

Function showexit ()

{

Local Y

((y = strayheight straytop 3)))))

Echo -e "/ 33 [$ {y}; 0hgameover! / 33 [0m"

exit

}

#Game main program start here.

IF [[$ 1! = "--show"]]]

THEN

Bash $ 0 --SHOW & # Running this program again with parameters - SHOW

RunaskeyReceiver $! # The process number of the process generated by the above line as a parameter

exit

Else

# When you find a parameter -show, run the display function

RunasDisplayer

exit

Fi

转载请注明原文地址:https://www.9cbs.com/read-123206.html

New Post(0)