I'm working on a tetris implementation.

Thread in 'Discussion' started by JoshuaD, 12 Jun 2007.

  1. It's not, what you have is essentially 16G, so if the well is empty then the block will be 1 frame late.
     
  2. 20G is the piece falling for the full height of the well in a single game-logic cycle. I imagine if you have the ghost piece implemented, you might be able to reuse the code for that?
     
  3. mat

    mat

    something seems to have gone wrong, that link is to the same version as you the one you posted before...? the filename has a .1 in it, but the archive seems to be the same... and thanks for the keyconfig file! although j should rotate left, k right, and l be the double as opposed to the way it is now--no worries, my beloved autohotkey saves the day once more.


    fix it so i can try it! hah.
     
  4. tepples

    tepples Lockjaw developer

    What you have is 16.7G. That's very close to 20G, which is 1200 cells per second.

    Needle is right: Firm or hard drops, the ghost piece, and 20G use essentially the same code. Whenever the tetromino enters, moves, or rotates, fake a hard drop and move the ghost piece to where it ended up. Then you can handle >1G by simply checking whether the tetromino fell past the ghost piece height, and you can change firm or hard drop to simply set the gravity to 20G for one cycle.

    If you go 30 lines per level (like Tengen Tetris on NES) and use lock delay, then it's not bad at all to put 20G at level 6. Specifically, the TGM games hit 20G at around 140 lines.
     
  5. JoshuaD

    JoshuaD Unregistered


    hahaha, my bad. The good one's up at the same link.


    As far as 20G's go:


    How does one define 20G exactly? Fall the entire height of the well in one Logical frame? If that's the case, I'm running at 1G; falling one row per frame at the pace of one frame per millisecond.


    If I'm wrong about that (hopefully I am), and I'm running at 16 or 16.7G like someone else said, is there ever going to be a need for 17, 18, or 19G? If not, I can just special case 20G out. However, if there's a theoretical demand for these in-between speeds I'll have to modify my game code so it can handle increments bigger than the block size, if not I can get 20G running pretty quickly.


    If that last paragraph doesn't make sense, let me rephrase: Would the level before the 20G level be 19G or 10G? 10G seems to make more sense to me.


    Keep any comments coming. If anyone has a link or opinions about how a delay system should work let me know. I am going to implement one similar to what I saw in LockJaw unless there's something better.
     
  6. JoshuaD

    JoshuaD Unregistered



    All of that is going to be really easy for the user to configure. At this point all I need to write for you guys to configure that stuff is the GUI giving you access to the variables.


    I envision user-made rule-sets with corresponding highscore files. If I'm playing on a ruleset that gives out 3000 points per block fallen and you are playing on one that gives none for block fallen, it doesn't make much sense to compare our scores. So each would have it's own highscore file to compare to it's own sorts of games.


    This idea is simple to extend to timed game fastest time/highest score and battle mode leader charts.


    Anyway, these are some of the exciting (well, exciting to me) ideas that I've got either in the works and already implemented. Once we get the gameplay to an acceptable level I can go back to implementing or writing a GUI for all this cool stuff. I would be very surprised if it took me even to this weekend to get the game play running well at 20G, but we'll see.
     
  7. JoshuaD

    JoshuaD Unregistered


    Hahah. The ghost piece was actually the sorest spot for me.


    I'm not sure if anyone's a coder, but I'm a big fan of only putting code in your program once, and of really separating the functionality of classes so they know the least about each other as possible and do what they're supposed to do and nothing else.


    For example the graph should be a dumb graph. It shouldn't know anything about game logic. The block generator should generate blocks on request.. The game logic should figure out what's going on in the game, it shouldn't be directly handling and parsing key input or rendering. etc.


    The ghost blocks just ruined all this for me.


    Like I said earlier, I have a GameLogic class that handles all of the moving and falling of blocks and a GameRenderer class that checks in on the Logic class, requests a few numbers, and then goes about it's buisiness of rendering the information in the game.


    When I add network play, that "requests a few numbers" step is going to be done over the network.


    Firstly, it should be obvious that the ghostblock's position is a derived variable, it's a function of the block position and the graph.


    So there's no reason for the GameLogic class to calculate, keep, or in any way know about the ghost block's position. It's really an entity that should be created during the rendering process; nothing interacts with it and the user doesn't directly control it. It's a visual element and nothing else.


    BUT the GameRenderer class had no framework in it for calculating block positions and the like. It gets a list of maybe 10 numbers and the graph, and goes about calling graphics functions.


    All the framework for calculating the ghost block's position was in the GameLogic.


    So either I could slow down my network play (unacceptable) or duplicate some code (Evil).


    Finally I decided to duplicate some code since it's the only thing that makes sense, but the process was pretty funny. I had a ghost block on the screen after literally a minute and then I sat there for an hour thinking about how to get a ghost block on the screen the correct way.


    Anyway, just venting. I hope you all enjoyed a peek at my incredibly anal-about-code mind. [​IMG]

    To tell you the truth, I'm still not entirely happy with my solution. Just typing this up brought to light what I think is the crux of the problem and the solution. I think the problem is that I haven't implemented the network yet, and the ghost-block code should go into a class I intend to write at that time. In fact, now I'm happy. That's how it should be.


    Thanks for listening! Time for (real) work.
     
  8. jujube

    jujube Unregistered

    the difference between 10G and 20G is substantial enough that it would be good to have at least 2 or 3 fall speeds in between. i did some testing on tetris DS with a 10x20 well, 12 Hz sideways speed, 183ms DAS, no initial piece movement. on level 13 (13G) an O piece can reach the wall at about the same time it touches the bottom of the well. at 17G a piece can still move over a column or two before it touches bottom. this is a small difference but gives the player a bit more freedom of movement compared to 20G. of course, if you were to implement ARE and initial movement/rotation a piece could land away from the center of the well, even at 20G.


    btw is there a readme file anywhere in your download that tells what to extract and how to run the game?
     
  9. JoshuaD

    JoshuaD Unregistered


    I'm running late to work, but I know that Java 1.5 associates with Jars and will make them executable. All you need for this to work is java installed. Then either double clicking on the jar, or if that doesn't work, typing "java -jar Tetris_v0.6.01.jar" at the command line.


    I've messed around with making .exe's to hide this process like Azureus or Eclipse, and that's something I'll certainly include in v1.0. If it's easy to do I'll try it tonight to make things a little easier for you guys.
     
  10. JoshuaD

    JoshuaD Unregistered

    Download Newest Version: Version 0.6.2


    Keys are currently setup like this, just something I quickly made for testing:


    Up: Firm Drop

    Down: Soft Drop

    Left: Shift Left

    Right: Shift Right

    Z: Counter clockwise

    C Clockwise

    X: Flip (180* rotation)

    V: Hold Block

    P: Pause

    End: Hard Drop


    (Sorry Matt, that key config I gave you may not work any longer)


    This version's gamplay should be much, much better than the previous versions. It currently has SRS, Wall Kicks, DAS, >20G speeds, hold block (no graphics for it yet, just the functionality), firm drops, hard drops, and probably some other stuff I've forgotten about.


    There are a few places where the kicks aren't doing what they should, here's one example:


    Code:
    []  [][][][][][]
    []() [][][][][][]
    []()  [][][][][]
    []()() [][][][][]
    
    []  [][][][][][]
    []  [][][][][][]
    []  ()[][][][][]
    []()()()[][][][][]
    
    I will implement these cases eventually. The problem is I need to be very specific with what rotations are ok otherwise there are some really silly ones allowed. Please let me know when you come across a rotation that you expect to work that doesn't.


    Sideways slides into small spots while free-falling isn't working perfectly either. I changed up some code to allow >16G gravity and I had to scrap the code that ensured these slides worked. I'll be fixing it soon.


    Level 3 is 1G, level 4 is 6G, Level 5 is 20G, level 6 is 334G.
     
  11. jujube

    jujube Unregistered

    very nice game, and it's interesting to combine a memoryless randomizer with 20G which makes for a good challenge. just a few thoughts:


    1. the sideways delay is pretty low (i'm guessing 100ms) and makes it hard for me to tap.


    2. it seems like my inputs control the current piece until i hard drop or the next piece is in the playing field. this causes double-hard dropping for me in higher levels. if i don't hard drop the current piece, i'll end up rotating or shifting it at the last moment, when these inputs are intended for the next piece.


    3. a keyboard shortcut to start a new game.


    the SRS rotations and kicks seem pretty accurate. i'll play some more and see if i spot anything that's off. fun game [​IMG]

    edit: auto-pause on task switch would be nice, also when i start a new game the first piece has landed and the second piece is falling.


    edit: it seems to freeze if i make it to level 7 (happened 3 times).
     
  12. jujube

    jujube Unregistered

    T wallkicks in SRS

    Code:
     () [][][][][][][]
    []()()[][][][][][][]
    []()  [][][][][][]
    
       [][][][][][][]
    [] ()[][][][][][][]
    []()()()[][][][][][]
    
    
     () [][][][][][][]
     ()()[][][][][][][]
    []()  [][][][][][]
    
     () [][][][][][][]
    ()()()[][][][][][][]
    []   [][][][][][]
    
     
  13. JoshuaD

    JoshuaD Unregistered

    Thanks Jujube.


    1)Damn. 100ms exactly. Nice guess! It will configurable by a slider, so don't sweat those details.


    2) This is a big deal. How do the other games work? Do they put a small delay on the beginning of the drop of a new piece?


    I know a fading animation on the dropped block with a flash at the end (for the lock timer) will help with this problem, but it won't solve it.


    3) You got it. I'll add a Ready... set....GO!" Countdown type timer too.


    Nice catch, thanks. I fixed it now. It was trying to go to level 7 when there's only 6 levels. It didn't like that. [​IMG]

    Just to give you an idea of what things are configurable and what aren't, here's the current game play config file. Anything in there can and probably will have an option in the GUI.


    Code:
    {
     int rows = 21;
     int columns = 10;
     
     boolean wallKicks = true;
     int floorKicks = 5;
     boolean infiniteFloorKicks = false;
     boolean randomInitialHoldBlock = false;
     
     boolean sideCollision = false;//TODO: Rename me
     
     int lockDelay = 500;
     
     int hardDropLockMinDelay = 60; //how long the user has to press a left or right key after a hard drop so it slides in.
             //it's a minimum because they always have at least the length of a frame to enter it in.
    
     int sideMoveSpeed = 16;
     int sideMoveDelay = 100; 
     
     boolean hardShiftsAllowed = false;
     boolean hardDropsAllowed = true;
     boolean firmDropsAllowed = true;
     boolean softDropsAllowed = true;
     boolean holdBlockAllowed = true;
     boolean flipAllowed = true;
     
    
     public boolean stopSoftDropEachFall = false;
     
     int initialLevel = 0;
     
     int[] scoreValues = new int[] {4, 50, 150, 400, 900 };//perpiece dropped, one line, two lines, three lines, four
     final int[] attackValues = new int[] {0, 0, 1, 2, 4 };
     
      public int startDropRow = 0;
     public int startDropCol = 4;
     
     //334G is (1, >=blockSize*20)
     //20G is {1, blockSize * 5/4}
     //16G is {1, blockSize}
     //12G is {1, blockSize * 3/4}
     //8G is {2, blockSize}
     //4G is {4, blockSize}
     //2G is {8, blockSize} 
     //1G is {16, blockSize)
     final int[] frameRate = new int[] { 15, 10, 5, 3, 1, 1 };
     final int[] incs = new int[]   { 1, 1, 1, 1, 20, 400 };
     
     
     public int softDropSpeed = 1;
     public int softDropInc = 4;
     
     public int linesPerLevel = 4;
       
     int trashRowMinBlocks = 3;
     int trashRowMaxBlocks = 7;
    }
    
     
  14. DIGITAL

    DIGITAL Unregistered

    Code:
     () [][][][][][][]
    []()()[][][][][][][]
    []()  [][][][][][]
    
       [][][][][][][]
    [] ()[][][][][][][]
    []()()()[][][][][][]
    
    
     () [][][][][][][]
     ()()[][][][][][][]
    []()  [][][][][][]
    
       [][][][][][][]
      ()[][][][][][][]
    []()()()[][][][][][]
    
    Long live ARS!
     
  15. JoshuaD

    JoshuaD Unregistered

    Hrm, that's another one of those "ceiling kicks". The block is actually pushed downward by the ceiling.

    Do you have any similar ones that SHOULDN'T work? I know if I allow shifting in all 8 or even 4 possible directions when trying rotations, some stuff breaks. Here' an example that looks bad to me.

    <> represents the "center" block; it's what's getting moved at most 1 square when doing wall kicks and floor kicks. (Except with I blocks who sometimes get two squares).
    Code:
       ()[][][][][]
      ()<>()[][][][]
    [][][][]  [][][]
    [][][]  [][][][]
    [][][][] [][][][]
    [][][][][][][][][]
    [][][][][][][][][]
    [][][][][][][][][]
    
    
    
        [][][][][]
        ()[][][][]
    [][][][]<>()[][][]
    [][][] ()[][][][]
    [][][][] [][][][]
    [][][][][][][][][]
    
    
        [][][][][]
         [][][][]
    [][][][]() [][][]
    [][][]()<>[][][][]
    [][][][]()[][][][]
    [][][][][][][][][]
    
     
  16. jujube

    jujube Unregistered

    i know the limitations of my finger speed and/or my keyboard [​IMG] and also Lockjaw is a good reference for timings like that.
    i'm not a programmer, but i can direct you to this:
    http://www.tetrisconcept.com/forum/viewtopic.php?t=576
    jagorochi did a frame-by-frame analysis of TAP Death at level 500 (where most players do not manually lock). it's a very different game but that might give you some idea of how it could work, maybe with some modification to fit your needs.
    the 2nd diagram shouldn't work. believe it or not though, in SRS a T piece will go from where it is in the 1st diagram to the 3rd with one rotation. see T-spin triple setups in the wiki.
     
  17. JoshuaD

    JoshuaD Unregistered

    Does this page look accurate? Some of those moves look funky as hell to me, but I don't have much experience with SRS.
     
  18. mat

    mat

    that's jago's page and it is completely accurate--enjoy that SRS.
     
  19. SRS definitely has it's fans and it's... not fans. I can live with the base rotation (so low gravity play), but the wallkicks drive me insane.


    The worst thing is that this is impossible in SRS:

    Code:
      ()[][][][][][][]
    []()()[][][][][][][]
    [] () [][][][][][]
    
       [][][][][][][]
    [] ()[][][][][][][]
    []()()()[][][][][][]
    
    This doesn't even use a wallkick in TGM. You could do it in the oldschool original arcade Sega Tetris. Any rotation system that has 4 kicks and doesn't allow this is designed by an idiot. Clearly nobody would ever want this to happen:

    Code:
      ()[][][][][][][]
    []()()[][][][][][][]
    [] () [][][][][][]
    
    
      ()
     ()()()
       [][][][][][][]
    []  [][][][][][][]
    []   [][][][][][]
    
    OH SNAP!
     
  20. JoshuaD

    JoshuaD Unregistered

    Does anyone have a page like Jago's on TGM?
     

Share This Page