逝情是这样的:最近无意间找到了一个命令行版的2048,用C语言写的,然后自己编译自己玩就玩上瘾了。
后来我突然想起来之前玩过一个小程序,里面有各种2048的魔改版,其中有一个就是会生成数字0的(0只能跟0消并且不加分)
于是我突发奇想给这个2048.c魔改一下:

扔GayHub了:https://github.com/teddyxlandlee/2048-with-zero/
自己下载编译。上不了GayHub的也可以从这里复制:[spoiler]/*
============================================================================
Name : 2048.c
Author : Maurits van der Schee
Description : Console version of the game "2048" for GNU/Linux
============================================================================
*/
#define _XOPEN_SOURCE 500 // for: usleep
#include // defines: printf, puts, getchar
#include // defines: EXIT_SUCCESS
#include // defines: strcmp
#include // defines: STDIN_FILENO, usleep
#include // defines: termios, TCSANOW, ICANON, ECHO
#include // defines: true, false
#include // defines: uint8_t, uint32_t
#include // defines: time
#include // defines: signal, SIGINT
#define SIZE 4
// WithZero patch start: BLOCK_ZERO definition
#define BLOCK_ZERO (255)
// WithZero patch end
// this function receives 2 pointers (indicated by *) so it can set their values
void getColors(uint8_t value, uint8_t scheme, uint8_t *foreground, uint8_t *background)
{
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};
// modify the 'pointed to' variables (using a * on the left hand of the assignment)
*foreground = *(schemes[scheme] + (1 + value * 2) % sizeof(original));
*background = *(schemes[scheme] + (0 + value * 2) % sizeof(original));
// alternatively we could have returned a struct with two variables
}
uint8_t getDigitCount(uint32_t number)
{
uint8_t count = 0;
do
{
number /= 10;
count += 1;
} while (number);
return count;
}
void drawBoard(uint8_t board[SIZE][SIZE], uint8_t scheme, uint32_t score)
{
uint8_t x, y, fg, bg;
printf("\033[H"); // move cursor to 0,0
printf("2048.c %17d pts\n\n", score);
for (y = 0; y
{
for (x = 0; x
{
// send the addresses of the foreground and background variables,
// so that they can be modified by the getColors function
getColors(board[x][y], scheme, &fg, &bg);
printf("\033[38;5;%d;48;5;%dm", fg, bg); // set color
printf(" ");
printf("\033[m"); // reset all modes
}
printf("\n");
for (x = 0; x
{
getColors(board[x][y], scheme, &fg, &bg);
printf("\033[38;5;%d;48;5;%dm", fg, bg); // set color
if (board[x][y] != 0)
{
// WithZero patch start: render BLOCK_ZERO as 0
//uint32_t number = 1
uint32_t number = board[x][y] == BLOCK_ZERO ? 0 : 1
// WithZero patch end
uint8_t t = 7 - getDigitCount(number);
printf("%*s%u%*s", t - t / 2, "", number, t / 2, "");
}
else
{
printf(" · ");
}
printf("\033[m"); // reset all modes
}
printf("\n");
for (x = 0; x
{
getColors(board[x][y], scheme, &fg, &bg);
printf("\033[38;5;%d;48;5;%dm", fg, bg); // set color
printf(" ");
printf("\033[m"); // reset all modes
}
printf("\n");
}
printf("\n");
printf(" ←,↑,→,↓ 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 target
return x;
}
bool slideArray(uint8_t array[SIZE], uint32_t *score)
{
bool success = false;
uint8_t x, t, stop = 0;
for (x = 0; 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])
{
// WithZero patch starts: Adapt BLOCK_ZERO move
if (array[t] == BLOCK_ZERO) {
// Do nothing but slide
} else {
// WithZero patch ends
// merge (increase power of two)
array[t]++;
// increase score
*score += (uint32_t)1
// set stop to avoid double merge
} // WithZero patch
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
{
for (j = i; 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], uint32_t *score)
{
bool success = false;
uint8_t x;
for (x = 0; x
{
success |= slideArray(board[x], score);
}
return success;
}
bool moveLeft(uint8_t board[SIZE][SIZE], uint32_t *score)
{
bool success;
rotateBoard(board);
success = moveUp(board, score);
rotateBoard(board);
rotateBoard(board);
rotateBoard(board);
return success;
}
bool moveDown(uint8_t board[SIZE][SIZE], uint32_t *score)
{
bool success;
rotateBoard(board);
rotateBoard(board);
success = moveUp(board, score);
rotateBoard(board);
rotateBoard(board);
return success;
}
bool moveRight(uint8_t board[SIZE][SIZE], uint32_t *score)
{
bool success;
rotateBoard(board);
rotateBoard(board);
rotateBoard(board);
success = moveUp(board, score);
rotateBoard(board);
return success;
}
bool findPairDown(uint8_t board[SIZE][SIZE])
{
bool success = false;
uint8_t x, y;
for (x = 0; x
{
for (y = 0; 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
{
for (y = 0; y
{
if (board[x][y] == 0)
{
count++;
}
}
}
return count;
}
bool 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
{
for (y = 0; 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];
// WithZero patch start: rolls out zero, with the same chance of 4
//n = (rand() % 10) / 9 + 1;
n = (rand() % 11) / 9 + 1;
if (n == 2) {
n = (rand() % 2) ? 2 : BLOCK_ZERO;
}
// WithZero patch end
board[x][y] = n;
}
}
void initBoard(uint8_t board[SIZE][SIZE])
{
uint8_t x, y;
for (x = 0; x
{
for (y = 0; y
{
board[x][y] = 0;
}
}
addRandom(board);
addRandom(board);
}
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)
// data holds per line: 4x IN, 4x OUT, 1x POINTS
uint8_t data[] = {
0, 0, 0, 1, 1, 0, 0, 0, 0,
0, 0, 1, 1, 2, 0, 0, 0, 4,
0, 1, 0, 1, 2, 0, 0, 0, 4,
1, 0, 0, 1, 2, 0, 0, 0, 4,
1, 0, 1, 0, 2, 0, 0, 0, 4,
1, 1, 1, 0, 2, 1, 0, 0, 4,
1, 0, 1, 1, 2, 1, 0, 0, 4,
1, 1, 0, 1, 2, 1, 0, 0, 4,
1, 1, 1, 1, 2, 2, 0, 0, 8,
2, 2, 1, 1, 3, 2, 0, 0, 12,
1, 1, 2, 2, 2, 3, 0, 0, 12,
3, 0, 1, 1, 3, 2, 0, 0, 4,
2, 0, 1, 1, 2, 2, 0, 0, 4};
uint8_t *in, *out, *points;
uint8_t t, tests;
uint8_t i;
bool success = true;
uint32_t score;
tests = (sizeof(data) / sizeof(data[0])) / (2 * SIZE + 1);
for (t = 0; t
{
in = data + t * (2 * SIZE + 1);
out = in + SIZE;
points = in + 2 * SIZE;
for (i = 0; i
{
array[i] = in[i];
}
score = 0;
slideArray(array, &score);
for (i = 0; i
{
if (array[i] != out[i])
{
success = false;
}
}
if (score != *points)
{
success = false;
}
if (success == false)
{
for (i = 0; i
{
printf("%d ", in[i]);
}
printf("=> ");
for (i = 0; i
{
printf("%d ", array[i]);
}
printf("(%d points) expected ", score);
for (i = 0; i
{
printf("%d ", in[i]);
}
printf("=> ");
for (i = 0; i
{
printf("%d ", out[i]);
}
printf("(%d points)\n", *points);
break;
}
}
if (success)
{
printf("All %u tests executed successfully\n", tests);
}
return !success;
}
void signal_callback_handler(int signum)
{
printf(" TERMINATED \n");
setBufferedInput(true);
// make cursor visible, reset all modes
printf("\033[?25h\033[m");
exit(signum);
}
int main(int argc, char *argv[])
{
uint8_t board[SIZE][SIZE];
uint8_t scheme = 0;
uint32_t score = 0;
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;
}
// make cursor invisible, erase entire screen
printf("\033[?25l\033[2J");
// register signal handler for when ctrl-c is pressed
signal(SIGINT, signal_callback_handler);
initBoard(board);
setBufferedInput(false);
drawBoard(board, scheme, score);
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, &score);
break;
case 100: // 'd' key
case 108: // 'l' key
case 67: // right arrow
success = moveRight(board, &score);
break;
case 119: // 'w' key
case 107: // 'k' key
case 65: // up arrow
success = moveUp(board, &score);
break;
case 115: // 's' key
case 106: // 'j' key
case 66: // down arrow
success = moveDown(board, &score);
break;
default:
success = false;
}
if (success)
{
drawBoard(board, scheme, score);
usleep(150 * 1000); // 150 ms
addRandom(board);
drawBoard(board, scheme, score);
if (gameEnded(board))
{
printf(" GAME OVER \n");
break;
}
}
if (c == 'q')
{
printf(" QUIT? (y/n) \n");
c = getchar();
if (c == 'y')
{
break;
}
drawBoard(board, scheme, score);
}
if (c == 'r')
{
printf(" RESTART? (y/n) \n");
c = getchar();
if (c == 'y')
{
initBoard(board);
score = 0;
}
drawBoard(board, scheme, score);
}
}
setBufferedInput(true);
// make cursor visible, reset all modes
printf("\033[?25h\033[m");
return EXIT_SUCCESS;
}
复制代码
这个魔改版的规则如下:0+0=0别的数字不能跟0合0不会凭空消失,它只能和另一个0消失变成一个新的00跟0合不加分
由于在内存中,这些数字是按照以2为底的对数存储的(空位记0),所以我选择用255来表示“数字0”(不会有哪个闲人玩到2的255次方罢)
刷出0的几率跟4一样,都是1/11。
怎么说,不带0的时候我能打到将近15000,但是带0最多2k
md我被我自己写的游戏搞b溃了(虽然不完全是我写的)
不行不行我一定要恶心一下大家
另外谁能编译一个能在Windows环境下跑的版本,我不能只让Linux和OS X玩家难受啊啊啊啊啊
后来我突然想起来之前玩过一个小程序,里面有各种2048的魔改版,其中有一个就是会生成数字0的(0只能跟0消并且不加分)
于是我突发奇想给这个2048.c魔改一下:
扔GayHub了:https://github.com/teddyxlandlee/2048-with-zero/
自己下载编译。上不了GayHub的也可以从这里复制:[spoiler]/*
============================================================================
Name : 2048.c
Author : Maurits van der Schee
Description : Console version of the game "2048" for GNU/Linux
============================================================================
*/
#define _XOPEN_SOURCE 500 // for: usleep
#include // defines: printf, puts, getchar
#include // defines: EXIT_SUCCESS
#include // defines: strcmp
#include // defines: STDIN_FILENO, usleep
#include // defines: termios, TCSANOW, ICANON, ECHO
#include // defines: true, false
#include // defines: uint8_t, uint32_t
#include // defines: time
#include // defines: signal, SIGINT
#define SIZE 4
// WithZero patch start: BLOCK_ZERO definition
#define BLOCK_ZERO (255)
// WithZero patch end
// this function receives 2 pointers (indicated by *) so it can set their values
void getColors(uint8_t value, uint8_t scheme, uint8_t *foreground, uint8_t *background)
{
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};
// modify the 'pointed to' variables (using a * on the left hand of the assignment)
*foreground = *(schemes[scheme] + (1 + value * 2) % sizeof(original));
*background = *(schemes[scheme] + (0 + value * 2) % sizeof(original));
// alternatively we could have returned a struct with two variables
}
uint8_t getDigitCount(uint32_t number)
{
uint8_t count = 0;
do
{
number /= 10;
count += 1;
} while (number);
return count;
}
void drawBoard(uint8_t board[SIZE][SIZE], uint8_t scheme, uint32_t score)
{
uint8_t x, y, fg, bg;
printf("\033[H"); // move cursor to 0,0
printf("2048.c %17d pts\n\n", score);
for (y = 0; y
{
for (x = 0; x
{
// send the addresses of the foreground and background variables,
// so that they can be modified by the getColors function
getColors(board[x][y], scheme, &fg, &bg);
printf("\033[38;5;%d;48;5;%dm", fg, bg); // set color
printf(" ");
printf("\033[m"); // reset all modes
}
printf("\n");
for (x = 0; x
{
getColors(board[x][y], scheme, &fg, &bg);
printf("\033[38;5;%d;48;5;%dm", fg, bg); // set color
if (board[x][y] != 0)
{
// WithZero patch start: render BLOCK_ZERO as 0
//uint32_t number = 1
uint32_t number = board[x][y] == BLOCK_ZERO ? 0 : 1
// WithZero patch end
uint8_t t = 7 - getDigitCount(number);
printf("%*s%u%*s", t - t / 2, "", number, t / 2, "");
}
else
{
printf(" · ");
}
printf("\033[m"); // reset all modes
}
printf("\n");
for (x = 0; x
{
getColors(board[x][y], scheme, &fg, &bg);
printf("\033[38;5;%d;48;5;%dm", fg, bg); // set color
printf(" ");
printf("\033[m"); // reset all modes
}
printf("\n");
}
printf("\n");
printf(" ←,↑,→,↓ 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 target
return x;
}
bool slideArray(uint8_t array[SIZE], uint32_t *score)
{
bool success = false;
uint8_t x, t, stop = 0;
for (x = 0; 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])
{
// WithZero patch starts: Adapt BLOCK_ZERO move
if (array[t] == BLOCK_ZERO) {
// Do nothing but slide
} else {
// WithZero patch ends
// merge (increase power of two)
array[t]++;
// increase score
*score += (uint32_t)1
// set stop to avoid double merge
} // WithZero patch
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
{
for (j = i; 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], uint32_t *score)
{
bool success = false;
uint8_t x;
for (x = 0; x
{
success |= slideArray(board[x], score);
}
return success;
}
bool moveLeft(uint8_t board[SIZE][SIZE], uint32_t *score)
{
bool success;
rotateBoard(board);
success = moveUp(board, score);
rotateBoard(board);
rotateBoard(board);
rotateBoard(board);
return success;
}
bool moveDown(uint8_t board[SIZE][SIZE], uint32_t *score)
{
bool success;
rotateBoard(board);
rotateBoard(board);
success = moveUp(board, score);
rotateBoard(board);
rotateBoard(board);
return success;
}
bool moveRight(uint8_t board[SIZE][SIZE], uint32_t *score)
{
bool success;
rotateBoard(board);
rotateBoard(board);
rotateBoard(board);
success = moveUp(board, score);
rotateBoard(board);
return success;
}
bool findPairDown(uint8_t board[SIZE][SIZE])
{
bool success = false;
uint8_t x, y;
for (x = 0; x
{
for (y = 0; 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
{
for (y = 0; y
{
if (board[x][y] == 0)
{
count++;
}
}
}
return count;
}
bool 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
{
for (y = 0; 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];
// WithZero patch start: rolls out zero, with the same chance of 4
//n = (rand() % 10) / 9 + 1;
n = (rand() % 11) / 9 + 1;
if (n == 2) {
n = (rand() % 2) ? 2 : BLOCK_ZERO;
}
// WithZero patch end
board[x][y] = n;
}
}
void initBoard(uint8_t board[SIZE][SIZE])
{
uint8_t x, y;
for (x = 0; x
{
for (y = 0; y
{
board[x][y] = 0;
}
}
addRandom(board);
addRandom(board);
}
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)
// data holds per line: 4x IN, 4x OUT, 1x POINTS
uint8_t data[] = {
0, 0, 0, 1, 1, 0, 0, 0, 0,
0, 0, 1, 1, 2, 0, 0, 0, 4,
0, 1, 0, 1, 2, 0, 0, 0, 4,
1, 0, 0, 1, 2, 0, 0, 0, 4,
1, 0, 1, 0, 2, 0, 0, 0, 4,
1, 1, 1, 0, 2, 1, 0, 0, 4,
1, 0, 1, 1, 2, 1, 0, 0, 4,
1, 1, 0, 1, 2, 1, 0, 0, 4,
1, 1, 1, 1, 2, 2, 0, 0, 8,
2, 2, 1, 1, 3, 2, 0, 0, 12,
1, 1, 2, 2, 2, 3, 0, 0, 12,
3, 0, 1, 1, 3, 2, 0, 0, 4,
2, 0, 1, 1, 2, 2, 0, 0, 4};
uint8_t *in, *out, *points;
uint8_t t, tests;
uint8_t i;
bool success = true;
uint32_t score;
tests = (sizeof(data) / sizeof(data[0])) / (2 * SIZE + 1);
for (t = 0; t
{
in = data + t * (2 * SIZE + 1);
out = in + SIZE;
points = in + 2 * SIZE;
for (i = 0; i
{
array[i] = in[i];
}
score = 0;
slideArray(array, &score);
for (i = 0; i
{
if (array[i] != out[i])
{
success = false;
}
}
if (score != *points)
{
success = false;
}
if (success == false)
{
for (i = 0; i
{
printf("%d ", in[i]);
}
printf("=> ");
for (i = 0; i
{
printf("%d ", array[i]);
}
printf("(%d points) expected ", score);
for (i = 0; i
{
printf("%d ", in[i]);
}
printf("=> ");
for (i = 0; i
{
printf("%d ", out[i]);
}
printf("(%d points)\n", *points);
break;
}
}
if (success)
{
printf("All %u tests executed successfully\n", tests);
}
return !success;
}
void signal_callback_handler(int signum)
{
printf(" TERMINATED \n");
setBufferedInput(true);
// make cursor visible, reset all modes
printf("\033[?25h\033[m");
exit(signum);
}
int main(int argc, char *argv[])
{
uint8_t board[SIZE][SIZE];
uint8_t scheme = 0;
uint32_t score = 0;
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;
}
// make cursor invisible, erase entire screen
printf("\033[?25l\033[2J");
// register signal handler for when ctrl-c is pressed
signal(SIGINT, signal_callback_handler);
initBoard(board);
setBufferedInput(false);
drawBoard(board, scheme, score);
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, &score);
break;
case 100: // 'd' key
case 108: // 'l' key
case 67: // right arrow
success = moveRight(board, &score);
break;
case 119: // 'w' key
case 107: // 'k' key
case 65: // up arrow
success = moveUp(board, &score);
break;
case 115: // 's' key
case 106: // 'j' key
case 66: // down arrow
success = moveDown(board, &score);
break;
default:
success = false;
}
if (success)
{
drawBoard(board, scheme, score);
usleep(150 * 1000); // 150 ms
addRandom(board);
drawBoard(board, scheme, score);
if (gameEnded(board))
{
printf(" GAME OVER \n");
break;
}
}
if (c == 'q')
{
printf(" QUIT? (y/n) \n");
c = getchar();
if (c == 'y')
{
break;
}
drawBoard(board, scheme, score);
}
if (c == 'r')
{
printf(" RESTART? (y/n) \n");
c = getchar();
if (c == 'y')
{
initBoard(board);
score = 0;
}
drawBoard(board, scheme, score);
}
}
setBufferedInput(true);
// make cursor visible, reset all modes
printf("\033[?25h\033[m");
return EXIT_SUCCESS;
}
复制代码
这个魔改版的规则如下:0+0=0别的数字不能跟0合0不会凭空消失,它只能和另一个0消失变成一个新的00跟0合不加分
由于在内存中,这些数字是按照以2为底的对数存储的(空位记0),所以我选择用255来表示“数字0”(不会有哪个闲人玩到2的255次方罢)
刷出0的几率跟4一样,都是1/11。
怎么说,不带0的时候我能打到将近15000,但是带0最多2k
md我被我自己写的游戏搞b溃了(虽然不完全是我写的)
不行不行我一定要恶心一下大家
另外谁能编译一个能在Windows环境下跑的版本,我不能只让Linux和OS X玩家难受啊啊啊啊啊