That corresponds to wfillrect() and main(). You never use the return value of wfillrect(), and main() doesn't really matter, but I suggest you return 0 from both of those. You could also make wfillrect() return void, but I'm guessting (sorry) that you wanted to match the ncurses style of prototypes and return int. (Assuming that's what it uses.)Code:$ gcc -W -Wall -ansi -pedantic -g block.c -o block -lcurses
block.c: In function ‘wfillrect’:
block.c:34: warning: control reaches end of non-void function
block.c: In function ‘main’:
block.c:211: warning: control reaches end of non-void function
$
The shadow is much nicer than I had envisioned! By "shadow", I just meant the way KSirtet does it. (See attached screenshot.) But yours is even nicer! :) Just one thing: the shadow of the T shape is black on my screen. I'm sure it's just my screen, though. I've attached a screenshot of the game after I've lost (intentionally), to show you the strange colours. (See other attached screenshot.)
Some more comments about the gameplay and such:
- If you keep pressing down, over and over again, the game sort of pauses. It could be considered a cheat, I suppose, since you can get an indefinite break from the game. I'd try to fix it if I were you. Actually, this works for any movement key. Press and hold right or left and watch the fireworks.
[edit] Never mind, I see this was intentional.
[/edit]Quote:
I did make it so when you dropped you were given a second more to position your piece, but that's about all I'll do for now.
- If you press down, you still have time to press left or right and shift the block before it is cemented into place. I'm pretty sure you don't really want this.
- The game always uses 100% of the CPU. I'm sure this isn't really necessary, though it might take another 4 AM programming spree for you to determine this for sure. :)
- You get a big advantage in a larger screen mode. You can see a lot more blocks that are to come. Is this what you wanted? . . . .
- You should consider making "down" move the blocks quickly, but not instantly. That way you could skip ahead if you need to slide a block in sideways or whatever. This is what I did in my tetris game. Note that you'll need to ignore down presses until you get a down keyup event or whatever for the next block, or they'll all come whizzing down, which isn't much fun.
Code comments:
- Your code isn't fully ctype.h'ized! What about that switch(in) statement in play()? . . . .
- You should really have a pause feature. Then I can play, report comments here, and then go back to playing again, and find more bugs and stuff. ;)
- I know you like ugly macros, but how hard is it to use functions instead? I guess you didn't want to pass seven arguments or something, but you could always use a structure or two. (5 AM.)
- I still think your rotation is a bit weird. For example, when a 'T' is flipped, the part that protruded down and now protrudes up has moved. In effect, the whole piece moves one unit to the right. It just feels counter-intuitive to me. (6 AM.)
- Why not make pieces keep their colours once they've fallen down? (You'll never get any sleep at this rate.) Actually, it's not too difficult. Just use ncurses's chtype to store the characters -- chtype stores colour information, as I'm sure you are aware.
From http://www.mkssoftware.com/docs/man3/curs_addch.3.aspQuote:
Video attributes can be combined with a character argument passed to addch() or related functions by logical-ORing them into the character. (Thus, text, including attributes, can be copied from one place to another using inch() and addch().). See the curs_attr() page for values of predefined video attribute constants that can be usefully OR'ed into characters.
- All those mvaddstr()'s in init() and mvprintw()'s in again() would be so much easier like this . . .
You could also make the messages a little more consistent. You have three different formats of specifying keys there. Most of those messages would fit onto one line, too, if you want to save space.Code:const char *message[] = {
" Use arrow",
"keys to play",
"UP = Rotate",
"'N' Next",
"'S' Shadow",
"'Q' to Quit"
};
size_t x;
for(x = 0; x < sizeof(message) / sizeof(*message); x ++) {
mvwaddstr (iwin, 5 + x, 2, message[x]);
}
- Speaking of saving space, I find your practise of putting two for loops on one line disturbing. :)
- In draw_piece():
It seems to me that you don't have to move if you're already in the right place. I'm not sure how efficient ncurses is with moving the cursor to where you already are. Probably very efficient. Forget I said anything. ;)Code:for (d = 0; d < 4; d++) for (c = 0; c < 4; c++)
if (blocks[rx(r, d, c)][p][rx((r + 1) % 4, d, c)] != '.')
mvwaddstr(w, d + y, (c + x - 1) * 2 - 1, " "); /* 2 spaces */
- The handlers for KEY_LEFT and KEY_RIGHT are the same except one uses +1 and the other, -1. Perhaps you could pass either +1 or -1 into a function that handled this . . . .

