summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2019-03-04 19:31:19 -0500
committerAndrew Opalach <andrew@akon.city> 2019-03-04 19:31:19 -0500
commit3be83e5f03748a6e7d9db785e38346ec45c69a35 (patch)
tree15fc9f205ad10599fba17a93cc0e501b3b46b37b
parent7c737f4d1d21a8c666bc8b868f4f29cfe9a3cbab (diff)
downloadcetris-3be83e5f03748a6e7d9db785e38346ec45c69a35.tar.gz
cetris-3be83e5f03748a6e7d9db785e38346ec45c69a35.tar.bz2
cetris-3be83e5f03748a6e7d9db785e38346ec45c69a35.zip
add scoring and fix some timing
-rw-r--r--cetris.c110
-rw-r--r--frontend/ncurses/ncurses_ui.c50
2 files changed, 107 insertions, 53 deletions
diff --git a/cetris.c b/cetris.c
index b36efb0..adba440 100644
--- a/cetris.c
+++ b/cetris.c
@@ -18,10 +18,11 @@ static void shuffle_queue(struct cetris_game* g);
static void next_piece(struct cetris_game* g);
static void move_current(struct cetris_game* g, vec2 offset);
static int check_new_matrix(struct cetris_game* g, piece_matrix m);
-static void wipe_board(struct cetris_game* g);
+static void wipe_board(struct cetris_game* g, int did_move);
static void set_constants(struct cetris_game* g);
static void rotate_matrix(struct cetris_game* g, int clockwise);
static void clear_move_queue(struct cetris_game* g);
+static void overlay_current_matrix(struct cetris_game* g);
/* DEFAULT MATRIX FOR EACH POSSIBLE TETRIMINO */
@@ -126,16 +127,21 @@ void move_current(struct cetris_game* g, vec2 offset) {
void move_hard_drop(struct cetris_game* g) {
int drop = 0;
+ int drop_count = 0;
while (!drop) {
g->current.pos.y++;
+ drop_count++;
int check = check_new_matrix(g, g->current.mat);
if (check <= 0) {
g->current.pos.y--;
+ drop_count--;
drop = 1;
}
}
+
+ g->score += 2 * drop_count; // 2 score for each harddrop cell
- wipe_board(g);
+ wipe_board(g, 1);
next_piece(g);
}
@@ -303,11 +309,13 @@ void init_game(struct cetris_game* g) {
clear_move_queue(g);
g->lines = 0;
- g->level = 0;
+ g->level = 1;
g->tspin = 0;
g->mini_tspin = 0;
+ g->score = 0;
+
init_piece_queue(g);
shuffle_queue(g);
@@ -385,13 +393,15 @@ void update_game_tick(struct cetris_game* g) {
clear_move_queue(g);
}
}
-
+
+ int did_move = 0;
if (!delay || g->tick % delay == 0) {
- wipe_board(g);
if (current_move > 0) {
+ did_move = 1;
switch (current_move) {
case DOWN:
move_current(g, cardinal_movements[0]);
+ g->score++; // 1 score for each softdrop
break;
case LEFT:
move_current(g, cardinal_movements[3]);
@@ -399,10 +409,14 @@ void update_game_tick(struct cetris_game* g) {
case RIGHT:
move_current(g, cardinal_movements[2]);
break;
+ default:
+ did_move = 0;
+ break;
}
if (g->move_queue_count != 0) g->move_queue_pos++;
if (g->move_queue_pos >= 20) clear_move_queue(g);
}
+ wipe_board(g, did_move);
}
g->tick++;
@@ -430,11 +444,47 @@ void set_constants(struct cetris_game* g) {
}
}
-void wipe_board(struct cetris_game* g) {
- int lines_cleared = 0;
- for (int y = 0; y < BOARD_Y; y++) {
- int clear_line = 1;
+void add_score(struct cetris_game* g, int lines) {
+ if (!g->tspin && !g->mini_tspin) {
+ switch (lines) {
+ case 1: g->score += 100 * g->level; break;
+ case 2: g->score += 300 * g->level; break;
+ case 3: g->score += 500 * g->level; break;
+ case 4: g->score += 800 * g->level; break;
+ }
+ } else if (g->tspin) {
+ switch (lines) {
+ case 0: g->score += 400 * g->level; break;
+ case 1: g->score += 800 * g->level; break;
+ case 2: g->score += 1200 * g->level; break;
+ case 3: g->score += 1600 * g->level; break;
+ }
+ g->tspin = 0;
+ } else if (g->mini_tspin) {
+ switch (lines) {
+ case 0: g->score += 100 * g->level; break;
+ case 1: g->score += 200 * g->level; break;
+ case 2: g->score += 400 * g->level; break;
+ }
+ g->mini_tspin = 0;
+ }
+}
+
+void overlay_current_matrix(struct cetris_game* g) {
+ vec2 r;
+ for (int y = 0; y < 4; y++) {
+ for (int x = 0; x < 4; x++) {
+ r = (vec2){x + g->current.pos.x, y + g->current.pos.y};
+ if (g->current.mat[y][x]) {
+ g->board[r.x][r.y].occupied = 1;
+ g->board[r.x][r.y].c = g->current.c;
+ }
+ }
+ }
+}
+void wipe_board(struct cetris_game* g, int did_move) {
+ for (int y = 0; y < BOARD_Y; y++) {
for (int x = 0; x < BOARD_X; x++) {
if (!g->board[x][y].constant) {
memset(&g->board[x][y], 0, sizeof(slot));
@@ -445,36 +495,36 @@ void wipe_board(struct cetris_game* g) {
g->board[x][s + 1] = g->board[x][s];
}
}
- if (!g->board[x][y].occupied || g->board[x][y].remove_tick > 0) clear_line = 0;
}
+ }
- if (clear_line) {
- lines_cleared++;
-
+ int lines_cleared = 0;
+ if (did_move) {
+ for (int y = 0; y < BOARD_Y; y++) {
+ int clear_line = 1;
for (int x = 0; x < BOARD_X; x++) {
- g->board[x][y].remove_tick = g->tick + CETRIS_LINE_CLEAR_DELAY;
+ if (!g->board[x][y].occupied ||
+ g->board[x][y].remove_tick > 0 ||
+ !g->board[x][y].constant)
+ clear_line = 0;
}
- }
- }
-
- vec2 r;
- for (int y = 0; y < 4; y++) {
- for (int x = 0; x < 4; x++) {
- r = (vec2){x + g->current.pos.x, y + g->current.pos.y};
- if (g->current.mat[y][x]) {
- g->board[r.x][r.y].occupied = 1;
- g->board[r.x][r.y].c = g->current.c;
+ if (clear_line) {
+ lines_cleared++;
+ for (int x = 0; x < BOARD_X; x++) {
+ g->board[x][y].remove_tick = g->tick + CETRIS_LINE_CLEAR_DELAY;
+ }
}
}
}
+ overlay_current_matrix(g);
+
assert(lines_cleared <= 4);
- if (lines_cleared > 0) {
- if (g->tspin || g->mini_tspin) {
- g->tspin = 0;
- g->mini_tspin = 0;
+ if (did_move) {
+ add_score(g, lines_cleared);
+ if (lines_cleared > 0) {
+ g->lines += lines_cleared;
+ if (g->lines >= (g->level * 10) && g->level <= 20) g->level++;
}
- g->lines += lines_cleared;
- if (g->lines >= (g->level * 10) && g->level <= 20) g->level++;
}
}
diff --git a/frontend/ncurses/ncurses_ui.c b/frontend/ncurses/ncurses_ui.c
index 1ae07b2..71ef49f 100644
--- a/frontend/ncurses/ncurses_ui.c
+++ b/frontend/ncurses/ncurses_ui.c
@@ -1,31 +1,32 @@
#include <stdlib.h>
+#include <string.h>
#include <ncurses.h>
#include <locale.h>
#include "cetris.h"
#define BLOCK "[]"
-#define PLAY_FIELD_STR " /--------------------\\ /--------\\\n"\
- " | | | |\n"\
- " | | \\--------/\n"\
- " | | \n"\
- " | | \n"\
- " | | \n"\
- " | | \n"\
- " | | \n"\
- " | | \n"\
- " | | \n"\
- " | | \n"\
- " | | \n"\
- " | | \n"\
- " | | \n"\
- " | | \n"\
- " | | \n"\
- " | | \n"\
- " | | \n"\
- " | | \n"\
- " | | \n"\
- " | | \n"\
+#define PLAY_FIELD_STR " /--------------------\\ /----------------\\\n"\
+ " | | | |\n"\
+ " | | \\----------------/\n"\
+ " | | \n"\
+ " | | \n"\
+ " | | \n"\
+ " | | \n"\
+ " | | \n"\
+ " | | \n"\
+ " | | \n"\
+ " | | \n"\
+ " | | \n"\
+ " | | \n"\
+ " | | \n"\
+ " | | \n"\
+ " | | \n"\
+ " | | \n"\
+ " | | \n"\
+ " | | \n"\
+ " | | \n"\
+ " | | \n"\
" \\--------------------/"
#define X_OFFSET 8
@@ -56,7 +57,7 @@ void draw_board(struct cetris_game* g) {
for (int x = 0; x < BOARD_X; x++) {
for (int y = 0; y < BOARD_Y; y++) {
if (g->board[x][y].occupied) {
- attron(COLOR_PAIR(g->board[x][y].c));
+ attron(COLOR_PAIR(g->board[x][y].c));
if (g->board[x][y].remove_tick > 0) {
if (g->tick % 2 == 0) {
mvaddstr(y + 1, x * 2 + X_OFFSET, BLOCK);
@@ -64,9 +65,12 @@ void draw_board(struct cetris_game* g) {
} else {
mvaddstr(y + 1, x * 2 + X_OFFSET, BLOCK);
}
- attroff(COLOR_PAIR(g->board[x][y].c));
+ attroff(COLOR_PAIR(g->board[x][y].c));
}
}
+ char score[50];
+ sprintf(score, "%li", g->score);
+ mvaddstr(1, (41 + X_OFFSET) - strlen(score), score);
}
}