forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   2D-программирование (http://forum.boolean.name/forumdisplay.php?f=109)
-   -   Гнусный Тетрис (http://forum.boolean.name/showthread.php?t=17157)

Matt Merkulov 08.08.2012 06:31

Гнусный Тетрис
 
он будет каждый раз выдавать вам самую неудобную фигуру
попробуйте хотя бы немного продержаться и с позором проиграйте

управление:
стрелки - двигать фигуру
q, w - вращать фигуру

Скачать скомпиленную версию ( 150KB )

Исходники:
Код:

SuperStrict

Framework brl.glmax2d
Import brl.random

SeedRnd Millisecs()

Const SquareSize:Int = 24

Global World:Int[ 21, 23 ]
Global TempWorld:Int[ 21, 23 ]
Global Figure:Int[ 7, 4, 4, 4 ]
Global Phases:Int[ 7 ]
Global XShift:Int[][] = [ [ 0 ], [ 0, 0 ], [ 0, 0 ], [ 1, 0 ], [ 0, 1, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 1, 0, 0 ] ]
Global YShift:Int[][] = [ [ 2 ], [ 2, 2 ], [ 3, 1 ], [ 4, 2 ], [ 2, 3, 2, 3 ], [ 2, 3, 3, 1 ], [ 2, 3, 2, 2 ] ]

Local M:Int = 0
For Local S:String = Eachin "ABEF,AEFJEFBC,IEFBABFG,BFJNEFGH,AEFGCBFJEFGKIJFB,EFGCBFJKIEFGABFJ,EFBGBFGJEFGJBEFJ".Split(",")
        Phases[ M ] = S.Length / 4 - 1
        For Local I:Int = 0 To Phases[ M ]
                For Local J:Int = 0 To 3
                        Local A:Int = S[ I * 4 + J ] - 65
                        Figure[ M, I, A & 3, A Shr 2 ] = True
                Next
        Next
        M :+ 1
Next

Graphics SquareSize * 14, SquareSize * 21 + 16

For Local I:Int = 0 To 20
        World[ 1, I ] = True
        World[ 12, I ] = True
        World[ I, 20 ] = True
Next

Local X:Int = 0, Y:Int = 19, R:Int = 0, T:Int = 0, N:Int = 0, Score:Int = 0

Repeat
        Cls
        For Local I:Int = 0 To 20
                For Local J:Int = 1 To 12
                        If World[ J, I ] Then DrawRect J * SquareSize, I * SquareSize, SquareSize, SquareSize
                Next
        Next
       
        For Local I:Int = 0 To 3
                For Local J:Int = 0 To 3
                        If Figure[ N, R, I, J ] Then DrawRect ( X + I ) * SquareSize, ( Y + J ) * SquareSize, SquareSize, SquareSize
                Next
        Next
       
        DrawText "Score: " + Score, SquareSize * 7 - 4 * ( 7 + String( Score ).Length ), SquareSize * 21
       
        Flip
       
        Local A:Int = X + KeyHit( KEY_RIGHT ) - KeyHit( KEY_LEFT )
        Local B:Int = Y + KeyDown( KEY_DOWN )
        Local Q:Int = ( R + KeyHit( KEY_W ) - KeyHit( KEY_Q ) ) & Phases[ N ]
       
        IF Not CheckPosition( A, B, N, Q ) Then
                X = A
                Y = B
                R = Q
        End If
       
        Local M:Int = Millisecs()
       
        If M > T Then
                T = M + 999
               
                If CheckPosition( X, Y + 1, N, R ) Then
                        If Y = 0 Then End
                       
                        For Local I:Int = 0 To 3
                                For Local J:Int = 0 To 3
                                        If Figure[ N, R, I, J ] Then World[ X + I, Y + J ] = True
                                Next
                        Next
                       
                        Local Counter:Int = 0
                        Local D:Int = 0
                        For Local J:Int = 19 To 0 Step -1
                                Local Quantity:Int = 0
                                For Local I:Int = 2 To 11
                                        If World[ I, J ] Then Quantity :+ 1
                                        World[ I, J + D ] = World[ I, J ]
                                Next
                                If Quantity > 9 Then
                                        D :+ 1
                                        Counter :+ 1
                                        Score :+ Counter
                                End If
                        Next
                       
                        X = 5
                        Y =  - 1
                        N = Decide()
                EndIf
               
                Y :+ 1
        End If
Until KeyHit( KEY_ESCAPE )

Function CheckPosition:Int( X:Int, Y:Int, N:Int, R:Int )
        For Local I:Int = 0 To 3
                For Local J:Int = 0 To 3
                        If Figure[ N, R, I, J ] * World[ I + X, J + Y ] Then Return True
                Next
        Next
EndFunction

Function Decide:Int()
        Local CurrentScore:Int = 0
        Local CurrentN:Int = 0
        For Local N:Int = 0 To 6
                Local Score:Int = 999
                For Local R:Int = 0 To Phases[ N ]
                        For Local X:Int = 2 To 11
                                For Local Y:Int = 4 To 19
                                        If Not World[ X, Y ] And World[ X, Y + 1 ] Then
                                                Local XX:Int = X - XShift[ N ][ R ]
                                                Local YY:Int = Y + 1 - YShift[ N ][ R ]
                                                If CheckPosition( XX, YY, N, R ) Then Continue
                                                Score = Min( Score, Calculate( XX, YY, N, R ) )
                                        End If
                                Next
                        Next
                Next
               
                If Score >= CurrentScore Then
                        If Score = CurrentScore Then If Rand( 0, 1 ) Then Continue
                        CurrentScore = Score
                        CurrentN = N
                End If
        Next
       
        Return CurrentN
End Function



Function Calculate:Int( X:Int, Y:Int, N:Int, R:Int )
        For Local X:Int = 2 To 11
                For Local Y:Int = 0 To 20
                        TempWorld[ X, Y ] = World[ X, Y ]
                Next
        Next
       
        For Local I:Int = 0 To 3
                For Local J:Int = 0 To 3
                        If Figure[ N, R, I, J ] Then TempWorld[ X + I, Y + J ] = True
                Next
        Next

        Local Score:Int = 0
       
        Local CurrentHeight:Int
        For Local I:Int = 2 To 11
                For Local J:Int = 0 To 20
                        If TempWorld[ I, J ] Then
                                If I > 2 Then Score :+ Abs( J - 1 - CurrentHeight )
                                CurrentHeight = J - 1
                                Exit
                        End If
                Next
               
                For Local J:Int = 1 To 19
                        If Not TempWorld[ I, J ] And TempWorld[ I, J - 1 ] Then Score :+ 16
                Next
        Next
       
        Return Score
End Function


Жека 08.08.2012 06:59

Ответ: Гнусный Тетрис
 
Ты злодей. :)

ARA 08.08.2012 07:31

Ответ: Гнусный Тетрис
 
Рекорд - 6.
Тетрис и правда злобный.

St_AnGer 08.08.2012 10:23

Ответ: Гнусный Тетрис
 
рекорд - 9 :crazy: с 8-й попытки :)

Жека 08.08.2012 11:27

Ответ: Гнусный Тетрис
 
И ещё - мне до такой лаконичности кода далековато (хоть и не стремлюсь к ней), склоняюсь перед профессионализмом автора.

Matt Merkulov 08.08.2012 11:33

Ответ: Гнусный Тетрис
 
это частично потому что я переписал свой старый код тетриса-тысячесимвольника
там были использованы всякие извраты чтобы сократить объем кода

dimanche13 08.08.2012 12:20

Ответ: Гнусный Тетрис
 
6
вот я лох-то ))))))) в тетрис играть не умею

HolyDel 08.08.2012 12:21

Ответ: Гнусный Тетрис
 
1...

SBJoker 08.08.2012 12:56

Ответ: Гнусный Тетрис
 
а почему вращение на такие экзотические клавиши, а не на православное "вверх"?

Matt Merkulov 08.08.2012 13:08

Ответ: Гнусный Тетрис
 
вращать надо уметь в обе стороны, чтобы клавиши были рядом
хотя сейчас пальцы автоматом ставятся на WASD, так что мб A/D было бы лучше, согласен

(укрупнил поле, перезалил экзешник)

HolyDel 08.08.2012 13:13

Ответ: Гнусный Тетрис
 
кстати, работает в убунте под вайном.

в новой версии набрал 5.

dimanche13 08.08.2012 14:39

Ответ: Гнусный Тетрис
 
Цитата:

Сообщение от HolyDel (Сообщение 235620)
кстати, работает в убунте под вайном.

этож БМ. можно скомпилить для линукса нативный бинарник и никакой вайн будет не нужен.
7

HolyDel 08.08.2012 14:42

Ответ: Гнусный Тетрис
 
а можно запустить под вайном и никакой нативный бинарник будет не нужен


Часовой пояс GMT +4, время: 10:00.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot