用户:
噩絔y查看:0 回复:1 评论:0 创建时间:2023-02-11T11:46:09
【作品展示】

【作品介绍】
wt
【作品源代码】
#define _XOPEN_SOURCE 500
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define SIZE 4
uint32_t score = 0;
uint8_t scheme = 0;
void getColor(uint8_t value, char * color, size_t length) {
uint8_t original[] = {8, 255, 1, 255, 2, 255, 3, 255, 4, 255, 5, 255, 6, 255, 7, 255, 9, 0, 10, 0, 11, 0, 12, 0, 13, 0, 14, 0, 255, 0, 255, 0};
uint8_t blackwhite[] = {232, 255, 234, 255, 236, 255, 238, 255, 240, 255, 242, 255, 244, 255, 246, 0, 248, 0, 249, 0, 250, 0, 251, 0, 252, 0, 253, 0, 254, 0, 255, 0};
uint8_t bluered[] = {235, 255, 63, 255, 57, 255, 93, 255, 129, 255, 165, 255, 201, 255, 200, 255, 199, 255, 198, 255, 197, 255, 196, 255, 196, 255, 196, 255, 196, 255, 196, 255};
uint8_t * schemes[] = {original, blackwhite, bluered};
uint8_t * background = schemes[scheme]+0;
uint8_t * foreground = schemes[scheme]+1;
if (value > 0) while (value--) {
if (background+2 < schemes[scheme]+sizeof(original)) {
background += 2;
foreground += 2;}
}
snprintf(color, length, "\033[38;5;%d;48;5;%dm", *foreground, *background); }
void drawBoard(uint8_t board[SIZE][SIZE]) {
uint8_t x, y;
char color[40], reset[] = "\033[m";
printf("\033[H");
printf("2048.c %17d pts\n\n", score);
for (y=0; y < SIZE; y++) {
for (x=0; x < SIZE; x++) {
getColor(board[x][y], color, 40);
printf("%s", color);
printf(" ");
printf("%s", reset);}
printf("\n");
for (x=0; x < SIZE; x++) {
getColor(board[x][y], color, 40);
printf("%s", color);
if (board[x][y] != 0) {
char s[8];
snprintf(s, 8, "%u", (uint32_t)1 << board[x][y]);
uint8_t t = 7-strlen(s);
printf("%*s%s%*s", t-t/2, "", s, t/2, "");} else {
printf(" · "); }
printf("%s", reset);}
printf("\n");
for (x=0; x < SIZE; x++) {
getColor(board[x][y], color, 40);
printf("%s", color);
printf(" ");
printf("%s", reset);}
printf("\n"); }
printf("\n");
printf(" W,A,S,D or q \n");
printf("\033[A"); // one line up
}
uint8_t findTarget(uint8_t array[SIZE], uint8_t x, uint8_t stop) {
uint8_t t;
// if the position is already on the first, don't evaluate
if (x == 0) {
return x; }
for(t=x-1;; t--) {
if (array[t] != 0) {
if (array[t] != array[x]) {
// merge is not possible, take next position
return t+1; }
return t; } else {
// we should not slide further, return this one
if (t == stop) {
return t; }
}
}
// we did not find a
return x; }11: 4喵ool slideArray(uint8_t array[SIZE]) {
bool success = false;
uint8_t x, t, stop = 0;
for (x=0; x < SIZE; x++) {
if (array[x] != 0) {
t = findTarget(array, x, stop);
// if target is not original position, then move or merge
if (t != x) {
// if target is zero, this is a move
if (array[t] == 0) {
array[t] = array[x];} else if (array[t] == array[x]) {
// merge(increase power of two)
array[t]++;
// increase score
score += (uint32_t)1 << array[t];
// set stop to avoid double merge
stop = t+1; }
array[x] = 0;
success = true; }
}
}
return success; }
void rotateBoard(uint8_t board[SIZE][SIZE]) {
uint8_t i, j, n = SIZE;
uint8_t tmp;
for (i=0; i < n/2; i++) {
for (j=i; j < n-i-1; j++) {
tmp = board[i][j];
board[i][j] = board[j][n-i-1];
board[j][n-i-1] = board[n-i-1][n-j-1];
board[n-i-1][n-j-1] = board[n-j-1][i];
board[n-j-1][i] = tmp; }
}
}
bool moveUp(uint8_t board[SIZE][SIZE]) {
bool success = false;
uint8_t x;
for (x=0; x < SIZE; x++) {
success |= slideArray(board[x]); }
return success; }
bool moveLeft(uint8_t board[SIZE][SIZE]) {
bool success;
rotateBoard(board);
success = moveUp(board);
rotateBoard(board);
rotateBoard(board);
rotateBoard(board);
return success; }
bool moveDown(uint8_t board[SIZE][SIZE]) {
bool success;
rotateBoard(board);
rotateBoard(board);
success = moveUp(board);
rotateBoard(board);
rotateBoard(board);
return success; }
bool moveRight(uint8_t board[SIZE][SIZE]) {
bool success;
rotateBoard(board);
rotateBoard(board);
rotateBoard(board);
success = moveUp(board);
rotateBoard(board);
return success; }
bool findPairDown(uint8_t board[SIZE][SIZE]) {
bool success = false;
uint8_t x, y;
for (x=0; x < SIZE; x++) {
for (y=0; y < SIZE-1; y++) {
if (board[x][y] == board[x][y+1]) return true; }
}
return success; }
uint8_t countEmpty(uint8_t board[SIZE][SIZE]) {
uint8_t x, y;
uint8_t count = 0;
for (x=0; x < SIZE; x++) {
for (y=0; y < SIZE; y++) {
if (board[x][y] == 0) {
count++; }
}
}
return count; }11: 42bool gameEnded(uint8_t board[SIZE][SIZE]) {
bool ended = true;
if (countEmpty(board) > 0) return false;
if (findPairDown(board)) return false;
rotateBoard(board);
if (findPairDown(board)) ended = false;
rotateBoard(board);
rotateBoard(board);
rotateBoard(board);
return ended; }
void addRandom(uint8_t board[SIZE][SIZE]) {
static bool initialized = false;
uint8_t x, y;
uint8_t r, len = 0;
uint8_t n, list[SIZE*SIZE][2];
if (!initialized) {
srand(time(NULL));
initialized = true; }
for (x=0; x < SIZE; x++) {
for (y=0; y < SIZE; y++) {
if (board[x][y] == 0) {
list[len][0] = x;
list[len][1] = y;
len++; }
}
}
if (len > 0) {
r = rand() % len;
x = list[r][0];
y = list[r][1];
n = (rand() % 10)/9+1;
board[x][y] = n;}
}
void initBoard(uint8_t board[SIZE][SIZE]) {
uint8_t x, y;
for (x=0; x < SIZE; x++) {
for (y=0; y < SIZE; y++) {
board[x][y] = 0;}
}
addRandom(board);
addRandom(board);
drawBoard(board);
score = 0; }
void setBufferedInput(bool enable) {
static bool enabled = true;
static struct termios old;
struct termios new;
if (enable & & !enabled) {
// restore the former settings
tcsetattr(STDIN_FILENO, TCSANOW, & old);
// set the new state
enabled = true; } else if (!enable & & enabled) {
// get the terminal settings for standard input
tcgetattr(STDIN_FILENO, & new);
// we want to keep the old setting to restore them at the end
old = new;
// disable canonical mode(buffered i/o) and local echo
new.c_lflag &= (~ICANON & ~ECHO);
// set the new settings immediately
tcsetattr(STDIN_FILENO, TCSANOW, & new);
// set the new state
enabled = false; }
}
int test() {
uint8_t array[SIZE];
// these are exponents with base 2 (1=2 2=4 3=8)
uint8_t data[] = {
0, 0, 0, 1, 1, 0, 0, 0,
0, 0, 1, 1, 2, 0, 0, 0,
0, 1, 0, 1, 2, 0, 0, 0,
1, 0, 0, 1, 2, 0, 0, 0,
1, 0, 1, 0, 2, 0, 0, 0,
1, 1, 1, 0, 2, 1, 0, 0,
1, 0, 1, 1, 2, 1, 0, 0,
1, 1, 0, 1, 2, 1, 0, 0,
1, 1, 1, 1, 2, 2, 0, 0,
2, 2, 1, 1, 3, 2, 0, 0,
1, 1, 2, 2, 2, 3, 0, 0,
3, 0, 1, 1, 3, 2, 0, 0,
2, 0, 1, 1, 2, 2, 0, 0
};
uint8_t * in, *out;
uint8_t t, tests;
uint8_t i;
bool success = true;
tests = (sizeof(data)/sizeof(data[0]))/(2*SIZE);
for (t=0; t < tests; t++) {
in = data+t*2*SIZE;
out = in + SIZE;
for (i=0; i < SIZE; i++) {
array[i] = in[i]; }
slideArray(array);
for (i=0; i < SIZE; i++) {
if (array[i] != out[i]) {
success = false; }
}
if (success == false) {
for (i=0; i < SIZE; i++) {
printf("%d ", in [i]); }
printf("=> ");
for (i=0; i < SIZE; i++) {
printf("%d ", array[i]);}
printf("expected ");
for (i=0; i < SIZE; i++) {
printf("%d ", in [i]); }
printf("=> ");
for (i=0; i < SIZE; i++) {
printf("%d ", out[i]);}
printf("\n");
break; }
}
if (success) {
printf("All %u tests executed successfully\n", tests);}
return !success; }
void signal_callback_handler(int signum) {
printf(" TERMINATED \n");
setBufferedInput(true);
printf("\033[?25h\033[m");
exit(signum); }
int main(int argc, char * argv[]) {
uint8_t board[SIZE][SIZE];
char c;
bool success;
if (argc == 2 & & strcmp(argv[1], "test") == 0) {
return test(); }
if (argc == 2 & & strcmp(argv[1], "blackwhite") == 0) {
scheme = 1; }
if (argc == 2 & & strcmp(argv[1], "bluered") == 0) {
scheme = 2; }
printf("\033[?25l\033[2J");
// register signal handler for when ctrl-c is pressed
signal(SIGINT, signal_callback_handler);
initBoard(board);
setBufferedInput(false);
while (true) {
c = getchar();
if (c == -1){
puts("\nError! Cannot read keyboard input!");
break; }
switch(c) {
case 97: // 'a' key
case 104: // 'h' key
case 68: // left arrow
success = moveLeft(board); break;
case 100: // 'd' key
case 108: // 'l' key
case 67: // right arrow
success = moveRight(board); break;
case 119: // 'w' key
case 107: // 'k' key
case 65: // up arrow
success = moveUp(board); break;
case 115: // 's' key
case 106: // 'j' key
case 66: // down arrow
success = moveDown(board); break;
default: success = false; }
if (success) {
drawBoard(board);
usleep(150000);
addRandom(board);
drawBoard(board);
if (gameEnded(board)) {
printf(" GAME OVER \n");
break; }
}
if (c == 'q') {
printf(" QUIT? (y/n) \n");
c = getchar();
if (c == 'y') {
break; }
drawBoard(board); }
if (c == 'r') {
printf(" RESTART? (y/n) \n");
c = getchar();
if (c == 'y') {
initBoard(board); }
drawBoard(board); }
}
setBufferedInput(true);
printf("\033[?25h\033[m");
return EXIT_SUCCESS;
}
【提示】
部分含有Python第三方库相关内容的作品,在海龟编辑器网页端无法运行哦!如遇到这种情况,可以打开下面的链接,下载海龟编辑器客户端:
https://python.codemao.cn