Bump 2048 to newest remote master

This commit is contained in:
Kevin Lange 2014-04-06 13:24:44 -07:00
parent 058574d5a8
commit 489cc1221f

View File

@ -15,76 +15,109 @@
#include <stdbool.h>
#include <stdint.h>
#include <time.h>
#include <stdlib.h>
#include <signal.h>
#define SIZE 4
uint32_t score=0;
void getColor(uint16_t value, char *color, size_t length) {
uint16_t c = 40;
if (value > 0) while (value >>= 1) c++;
snprintf(color,length,"\033[0;41;%dm",c);
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 *scheme = original;
uint8_t *background = scheme+0;
uint8_t *foreground = scheme+1;
if (value > 0) while (value >>= 1) {
if (background+2<scheme+sizeof(original)) {
background+=2;
foreground+=2;
}
}
snprintf(color,length,"\033[38;5;%d;48;5;%dm",*foreground,*background);
}
void drawBoard(uint16_t board[SIZE][SIZE]) {
int8_t x,y;
char color[20], reset[] = "\033[0m";
printf("\033[2J");
char color[40], reset[] = "\033[m";
printf("\033[H");
printf("2048.c %17d pts\n\n",score);
for (x=0;x<SIZE;x++) {
printf(" ______");
}
printf(" \n");
for (y=0;y<SIZE;y++) {
for (x=0;x<SIZE;x++) {
getColor(board[x][y],color,20);
getColor(board[x][y],color,40);
printf("%s",color);
printf("| ");
printf(" ");
printf("%s",reset);
}
printf("|\n");
printf("\n");
for (x=0;x<SIZE;x++) {
getColor(board[x][y],color,20);
getColor(board[x][y],color,40);
printf("%s",color);
if (board[x][y]!=0) {
char s[7];
snprintf(s,7,"%u",board[x][y]);
int8_t t = 6-strlen(s);
printf("|%*s%s%*s",t-t/2,"",s,t/2,"");
char s[8];
snprintf(s,8,"%u",board[x][y]);
int8_t t = 7-strlen(s);
printf("%*s%s%*s",t-t/2,"",s,t/2,"");
} else {
printf("| ");
printf(" · ");
}
printf("%s",reset);
}
printf("|\n");
printf("\n");
for (x=0;x<SIZE;x++) {
getColor(board[x][y],color,20);
getColor(board[x][y],color,40);
printf("%s",color);
printf("|______");
printf(" ");
printf("%s",reset);
}
printf("|\n");
printf("\n");
}
printf("\nPress arrow keys or 'q' to quit\n\n");
printf("\n");
printf(" ←,↑,→,↓ or q \n");
printf("\033[A");
}
int8_t arrayLength(uint16_t array[SIZE]) {
int8_t len;
len = SIZE;
while (len>0 && array[len-1]==0) {
len--;
int8_t findTarget(uint16_t array[SIZE],int8_t x,int8_t stop) {
int8_t t;
// if the position is already on the first, don't evaluate
if (x==0) {
return x;
}
return len;
for(t=x-1;t>=0;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;
}
bool shiftArray(uint16_t array[SIZE],int8_t start,int8_t length) {
bool slideArray(uint16_t array[SIZE]) {
bool success = false;
int8_t x,i;
for (x=start;x<length-1;x++) {
while (array[x]==0) {
for (i=x;i<length-1;i++) {
array[i] = array[i+1];
array[i+1] = 0;
length = arrayLength(array);
int8_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 not zero, set stop to avoid double merge
if (array[t]!=0) {
score+=array[t]+array[x];
stop = t+1;
}
array[t]+=array[x];
array[x]=0;
success = true;
}
}
@ -92,29 +125,6 @@ bool shiftArray(uint16_t array[SIZE],int8_t start,int8_t length) {
return success;
}
bool collapseArray(uint16_t array[SIZE],int8_t x) {
bool success = false;
if (array[x] == array[x+1]) {
array[x] *= 2;
array[x+1] = 0;
success = true;
}
return success;
}
bool condenseArray(uint16_t array[SIZE]) {
bool success = false;
int8_t x,length;
length = arrayLength(array);
for (x=0;x<length-1;x++) {
length = arrayLength(array);
success |= shiftArray(array,x,length);
length = arrayLength(array);
success |= collapseArray(array,x);
}
return success;
}
void rotateBoard(uint16_t board[SIZE][SIZE]) {
int8_t i,j,n=SIZE;
uint16_t tmp;
@ -133,7 +143,7 @@ bool moveUp(uint16_t board[SIZE][SIZE]) {
bool success = false;
int8_t x;
for (x=0;x<SIZE;x++) {
success |= condenseArray(board[x]);
success |= slideArray(board[x]);
}
return success;
}
@ -195,13 +205,13 @@ int16_t countEmpty(uint16_t board[SIZE][SIZE]) {
bool gameEnded(uint16_t board[SIZE][SIZE]) {
bool ended = true;
if (countEmpty(board)>0) return false;
if (findPairDown(board)) return false;
if (findPairDown(board)) return false;
rotateBoard(board);
if (findPairDown(board)) ended = false;
rotateBoard(board);
rotateBoard(board);
rotateBoard(board);
return ended;
if (findPairDown(board)) ended = false;
rotateBoard(board);
rotateBoard(board);
rotateBoard(board);
return ended;
}
void addRandom(uint16_t board[SIZE][SIZE]) {
@ -229,7 +239,7 @@ void addRandom(uint16_t board[SIZE][SIZE]) {
r = rand()%len;
x = list[r][0];
y = list[r][1];
n = (rand()%2+1)*2;
n = ((rand()%10)/9+1)*2;
board[x][y]=n;
}
}
@ -258,24 +268,104 @@ void setBufferedInput(bool enable) {
}
}
int main(void) {
int test() {
uint16_t array[SIZE];
uint16_t data[] = {
0,0,0,2, 2,0,0,0,
0,0,2,2, 4,0,0,0,
0,2,0,2, 4,0,0,0,
2,0,0,2, 4,0,0,0,
2,0,2,0, 4,0,0,0,
2,2,2,0, 4,2,0,0,
2,0,2,2, 4,2,0,0,
2,2,0,2, 4,2,0,0,
2,2,2,2, 4,4,0,0,
4,4,2,2, 8,4,0,0,
2,2,4,4, 4,8,0,0,
8,0,2,2, 8,4,0,0,
4,0,2,2, 4,4,0,0
};
uint16_t *in,*out;
uint16_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");
exit(signum);
}
int main(int argc, char *argv[]) {
uint16_t board[SIZE][SIZE];
char c;
bool success;
if (argc == 2 && strcmp(argv[1],"test")==0) {
return test();
}
printf("\033[?25l\033[2J\033[H");
// register signal handler for when ctrl-c is pressed
signal(SIGINT, signal_callback_handler);
memset(board,0,sizeof(board));
addRandom(board);
addRandom(board);
drawBoard(board);
setBufferedInput(false);
do {
while (true) {
c=getchar();
switch(c) {
case 68: success = moveLeft(board); break;
case 67: success = moveRight(board); break;
case 65: success = moveUp(board); break;
case 66: success = moveDown(board); break;
case 68: // left arrow
success = moveLeft(board); break;
case 67: // right arrow
success = moveRight(board); break;
case 65: // up arrow
success = moveUp(board); break;
case 66: // down arrow
success = moveDown(board); break;
default: success = false;
}
if (success) {
@ -283,12 +373,19 @@ int main(void) {
usleep(150000);
addRandom(board);
drawBoard(board);
if (gameEnded(board)) break;
if (gameEnded(board)) {
printf(" GAME OVER \n");
break;
}
}
} while (c!='q');
if (c=='q') {
printf(" QUIT \n");
break;
}
}
setBufferedInput(true);
printf("GAME OVER\n");
printf("\033[?25h");
return EXIT_SUCCESS;
}