|
@@ -1,21 +1,15 @@
|
|
#define _XOPEN_SOURCE_EXTENDED
|
|
#define _XOPEN_SOURCE_EXTENDED
|
|
|
|
|
|
-#include <curses.h>
|
|
|
|
#include <locale.h>
|
|
#include <locale.h>
|
|
-#include <ncursesw/curses.h>
|
|
|
|
|
|
+#include <ncurses.h>
|
|
#include <stdio.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdlib.h>
|
|
-#include <sys/time.h>
|
|
|
|
#include <time.h>
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
#include <unistd.h>
|
|
-#include <wchar.h>
|
|
|
|
|
|
|
|
-static const wchar_t moving = L'\u2592';
|
|
|
|
-static const wchar_t still = L'\u2593';
|
|
|
|
-static const wchar_t wall = L'\u2588';
|
|
|
|
-static const wchar_t empty = L' ';
|
|
|
|
|
|
+typedef enum { MOVING, STILL, EMPTY, WALL } FieldState;
|
|
|
|
|
|
-static wchar_t** fields;
|
|
|
|
|
|
+static FieldState** fields;
|
|
static int width;
|
|
static int width;
|
|
static int height;
|
|
static int height;
|
|
|
|
|
|
@@ -27,10 +21,9 @@ static void (*rotateFunction)(void);
|
|
static uint32_t seed = 0;
|
|
static uint32_t seed = 0;
|
|
|
|
|
|
static void initRandom(void) {
|
|
static void initRandom(void) {
|
|
- struct timeval time;
|
|
|
|
- struct timezone zone = {.tz_dsttime = 0, .tz_minuteswest = 0};
|
|
|
|
- gettimeofday(&time, &zone);
|
|
|
|
- seed = (uint32_t)time.tv_usec;
|
|
|
|
|
|
+ struct timespec time;
|
|
|
|
+ timespec_get(&time, TIME_UTC);
|
|
|
|
+ seed = (uint32_t)time.tv_nsec;
|
|
}
|
|
}
|
|
|
|
|
|
static int nextRandom(int max) {
|
|
static int nextRandom(int max) {
|
|
@@ -40,39 +33,36 @@ static int nextRandom(int max) {
|
|
}
|
|
}
|
|
|
|
|
|
static void initGamefield(int w, int h) {
|
|
static void initGamefield(int w, int h) {
|
|
- width = w + 3;
|
|
|
|
- height = h + 2;
|
|
|
|
|
|
+ width = w;
|
|
|
|
+ height = h;
|
|
|
|
|
|
- fields = (wchar_t**)malloc(sizeof(wchar_t*) * (size_t)height);
|
|
|
|
|
|
+ fields = (FieldState**)malloc(sizeof(FieldState*) * (size_t)height);
|
|
for(int y = 0; y < height; y++) {
|
|
for(int y = 0; y < height; y++) {
|
|
- fields[y] = (wchar_t*)malloc(sizeof(wchar_t) * (size_t)width);
|
|
|
|
|
|
+ fields[y] = (FieldState*)malloc(sizeof(FieldState) * (size_t)width);
|
|
for(int x = 0; x < width; x++) {
|
|
for(int x = 0; x < width; x++) {
|
|
- fields[y][x] = empty;
|
|
|
|
|
|
+ fields[y][x] = EMPTY;
|
|
}
|
|
}
|
|
- fields[y][width - 1] = '\0';
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- for(int y = 0; y < height; y++) {
|
|
|
|
- fields[y][0] = wall;
|
|
|
|
- fields[y][width - 2] = wall;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- for(int x = 0; x < width - 1; x++) {
|
|
|
|
- fields[0][x] = wall;
|
|
|
|
- fields[height - 1][x] = wall;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void printGamefield(void) {
|
|
static void printGamefield(void) {
|
|
- wchar_t* line = malloc(sizeof(wchar_t) * (size_t)width * 2);
|
|
|
|
|
|
+ static const char* MAP[] = {"\u2592", "\u2593", " "};
|
|
|
|
+ static const char* wall = "\u2588";
|
|
|
|
+
|
|
|
|
+ for(int x = 0; x < width * 2 + 4; x++) {
|
|
|
|
+ mvaddstr(0, x, wall);
|
|
|
|
+ mvaddstr(height + 1, x, wall);
|
|
|
|
+ }
|
|
for(int y = 0; y < height; y++) {
|
|
for(int y = 0; y < height; y++) {
|
|
|
|
+ mvaddstr(y + 1, 0, wall);
|
|
|
|
+ addstr(wall);
|
|
for(int x = 0; x < width; x++) {
|
|
for(int x = 0; x < width; x++) {
|
|
- line[x * 2] = fields[y][x];
|
|
|
|
- line[x * 2 + 1] = fields[y][x];
|
|
|
|
|
|
+ addstr(MAP[fields[y][x]]);
|
|
|
|
+ addstr(MAP[fields[y][x]]);
|
|
}
|
|
}
|
|
- mvaddwstr(y, 0, line);
|
|
|
|
|
|
+ addstr(wall);
|
|
|
|
+ addstr(wall);
|
|
}
|
|
}
|
|
- free(line);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
static void deleteGamefield(void) {
|
|
static void deleteGamefield(void) {
|
|
@@ -82,22 +72,22 @@ static void deleteGamefield(void) {
|
|
free(fields);
|
|
free(fields);
|
|
}
|
|
}
|
|
|
|
|
|
-static void setField(int x, int y, wchar_t c) {
|
|
|
|
- if(x >= 0 && y >= 0 && x < width - 3 && y < height - 2) {
|
|
|
|
- fields[y + 1][x + 1] = c;
|
|
|
|
|
|
+static void setField(int x, int y, FieldState state) {
|
|
|
|
+ if(x >= 0 && y >= 0 && x < width && y < height) {
|
|
|
|
+ fields[y][x] = state;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-static wchar_t getField(int x, int y) {
|
|
|
|
- if(x >= 0 && y >= 0 && x < width - 3 && y < height - 2) {
|
|
|
|
- return fields[y + 1][x + 1];
|
|
|
|
|
|
+static FieldState getField(int x, int y) {
|
|
|
|
+ if(x >= 0 && y >= 0 && x < width && y < height) {
|
|
|
|
+ return fields[y][x];
|
|
}
|
|
}
|
|
- return 0;
|
|
|
|
|
|
+ return WALL;
|
|
}
|
|
}
|
|
|
|
|
|
static int canMove(int x, int y) {
|
|
static int canMove(int x, int y) {
|
|
- wchar_t t = getField(x, y);
|
|
|
|
- return t == empty || t == moving;
|
|
|
|
|
|
+ FieldState t = getField(x, y);
|
|
|
|
+ return t == EMPTY || t == MOVING;
|
|
}
|
|
}
|
|
|
|
|
|
static void rotate33(void) {
|
|
static void rotate33(void) {
|
|
@@ -111,12 +101,12 @@ static void rotate33(void) {
|
|
}
|
|
}
|
|
|
|
|
|
for(int i = 0; i < 8; i += 2) {
|
|
for(int i = 0; i < 8; i += 2) {
|
|
- setField(movingObject[i], movingObject[i + 1], empty);
|
|
|
|
|
|
+ setField(movingObject[i], movingObject[i + 1], EMPTY);
|
|
movingObject[i] = data[i];
|
|
movingObject[i] = data[i];
|
|
movingObject[i + 1] = data[i + 1];
|
|
movingObject[i + 1] = data[i + 1];
|
|
}
|
|
}
|
|
for(int i = 0; i < 8; i += 2) {
|
|
for(int i = 0; i < 8; i += 2) {
|
|
- setField(movingObject[i], movingObject[i + 1], moving);
|
|
|
|
|
|
+ setField(movingObject[i], movingObject[i + 1], MOVING);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -131,12 +121,12 @@ static void rotate41(void) {
|
|
}
|
|
}
|
|
|
|
|
|
for(int i = 0; i < 8; i += 2) {
|
|
for(int i = 0; i < 8; i += 2) {
|
|
- setField(movingObject[i], movingObject[i + 1], empty);
|
|
|
|
|
|
+ setField(movingObject[i], movingObject[i + 1], EMPTY);
|
|
movingObject[i] = data[i];
|
|
movingObject[i] = data[i];
|
|
movingObject[i + 1] = data[i + 1];
|
|
movingObject[i + 1] = data[i + 1];
|
|
}
|
|
}
|
|
for(int i = 0; i < 8; i += 2) {
|
|
for(int i = 0; i < 8; i += 2) {
|
|
- setField(movingObject[i], movingObject[i + 1], moving);
|
|
|
|
|
|
+ setField(movingObject[i], movingObject[i + 1], MOVING);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -253,7 +243,7 @@ static void spawnObject(int x, int y) {
|
|
}
|
|
}
|
|
|
|
|
|
for(int i = 0; i < 8; i += 2) {
|
|
for(int i = 0; i < 8; i += 2) {
|
|
- setField(movingObject[i], movingObject[i + 1], moving);
|
|
|
|
|
|
+ setField(movingObject[i], movingObject[i + 1], MOVING);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -267,25 +257,25 @@ static int moveObject(int x, int y) {
|
|
objectX += x;
|
|
objectX += x;
|
|
objectY += y;
|
|
objectY += y;
|
|
for(int i = 0; i < 8; i += 2) {
|
|
for(int i = 0; i < 8; i += 2) {
|
|
- setField(movingObject[i], movingObject[i + 1], empty);
|
|
|
|
|
|
+ setField(movingObject[i], movingObject[i + 1], EMPTY);
|
|
movingObject[i] += x;
|
|
movingObject[i] += x;
|
|
movingObject[i + 1] += y;
|
|
movingObject[i + 1] += y;
|
|
}
|
|
}
|
|
for(int i = 0; i < 8; i += 2) {
|
|
for(int i = 0; i < 8; i += 2) {
|
|
- setField(movingObject[i], movingObject[i + 1], moving);
|
|
|
|
|
|
+ setField(movingObject[i], movingObject[i + 1], MOVING);
|
|
}
|
|
}
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
static void removeRows(void) {
|
|
static void removeRows(void) {
|
|
- for(int y = 0; y < height - 2; y++) {
|
|
|
|
|
|
+ for(int y = 0; y < height; y++) {
|
|
int remove = 1;
|
|
int remove = 1;
|
|
- for(int x = 0; x < width - 3; x++) {
|
|
|
|
- remove = remove && getField(x, y) == still;
|
|
|
|
|
|
+ for(int x = 0; x < width; x++) {
|
|
|
|
+ remove = remove && getField(x, y) == STILL;
|
|
}
|
|
}
|
|
if(remove) {
|
|
if(remove) {
|
|
for(int ry = y; ry > 0; ry--) {
|
|
for(int ry = y; ry > 0; ry--) {
|
|
- for(int rx = 0; rx < width - 3; rx++) {
|
|
|
|
|
|
+ for(int rx = 0; rx < width; rx++) {
|
|
setField(rx, ry, getField(rx, ry - 1));
|
|
setField(rx, ry, getField(rx, ry - 1));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -296,7 +286,7 @@ static void removeRows(void) {
|
|
static void onObjectFall(void) {
|
|
static void onObjectFall(void) {
|
|
if(!moveObject(0, 1)) {
|
|
if(!moveObject(0, 1)) {
|
|
for(int i = 0; i < 8; i += 2) {
|
|
for(int i = 0; i < 8; i += 2) {
|
|
- setField(movingObject[i], movingObject[i + 1], still);
|
|
|
|
|
|
+ setField(movingObject[i], movingObject[i + 1], STILL);
|
|
}
|
|
}
|
|
removeRows();
|
|
removeRows();
|
|
spawnObject(0, 0);
|
|
spawnObject(0, 0);
|