-
-
Save anirudh-chhangani/9989292 to your computer and use it in GitHub Desktop.
M[16],X=16,W,k; | |
main(){ | |
T(system("stty cbreak")); | |
puts(W&1?"WIN":"LOSE"); | |
} | |
K[]={2,3,1}; | |
s(f,d,i,j,l,P){ | |
for(i=4;i--;) | |
for(j=k=l=0;k<4;) | |
j<4?P=M[w(d,i,j++)],W|=P>>11,l*P&&(f?M[w(d,i,k)]=l<<(l==P):0,k++),l=l?P?l-P?P:0:l:P:(f?M[w(d,i,k)]=l:0,++k,W|=2*!l,l=0); | |
} | |
w(d,i,j){ | |
return d?w(d-1,j,3-i):4*i+j; | |
} | |
T(i){ | |
for(i=X+rand()%X;M[i%X]*i;i--); | |
i?M[i%X]=2<<rand()%2:0; | |
for(W=i=0;i<4;)s(0,i++); | |
for(i=X,puts("\e[2J\e[H");i--;i%4||puts("")) | |
printf(M[i]?"%4d|":" |",M[i]); | |
W-2||read(0,&k,3)|T(s (1,K[(k>>X)%4])); | |
} | |
//[2048] reformated | |
Original Version : https://gist.github.com/justecorruptio/9967738 | |
by : Jay Chan |
This passes gcc and clang without a warning.
Simplified the three functions T(), w() and s(); the arguments weren't passed in from outside, but were later initialised.
Unrolled the for-loops, sticking to the "1 statement per line" rule.
Added random seed.
// Original file by Jay Chan:
// https://gist.github.com/justecorruptio/9967738
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#define GRID_LEN 16
int M[GRID_LEN];
int X = GRID_LEN;
int W;
int k;
int K[] = { 2, 3, 1 };
int
w (int d, int i, int j)
{
if (d <= 0) {
return 4 * i + j;
}
return w (d - 1, j, 3 - i);
}
void
s (int f, int d)
{
int i = 4, j, l, P;
for (; i--;) {
j = k = l = 0;
for (; k < 4;) {
if (j < 4) {
P = M[w (d, i, j++)];
W |= P >> 11;
l *P && (f ? M[w (d, i, k)] = l << (l == P) : 0, k++);
l = l ? (P ? (l - P ? P : 0) : l) : P;
}
else {
f ? M[w (d, i, k)] = l : 0;
++k;
W |= 2 * !l;
l = 0;
}
}
}
}
void
T ()
{
int i = X + rand () % X;
for (; M[i % X] * i; i--);
i ? M[i % X] = 2 << rand () % 2 : 0;
W = i = 0;
for (; i < 4; i++) {
s (0, i);
}
// Prints the tiles onto the terminal
i = X;
puts ("\e[2J\e[H");
for (; i--;) {
if (M[i]) {
printf ("%4d|", M[i]);
} else {
printf ("%s", " |");
}
// every 4th cell is followed by a line-break
if (0 == (i & 3)) {
putchar ('\n');
}
}
// read input from keyboard
if (!(W - 2)) {
read (0, &k, 3);
s (1, K[(k >> X) % 4]);
T ();
}
}
int
main (void)
{
// Uses stty to clear the screen in preparation for the game
system ("stty cbreak");
/* Intializes random number generator */
srand ((unsigned) time (NULL));
T ();
// Game has finished by this point
// If win, display "WIN". Otherwise, display "LOSE".
puts (W & 1 ? "WIN" : "LOSE");
return 0;
}
I don't understand, why read(0,&k,3), the arrow keys only need 2 bytes.
The reason why 3 characters are read is that arrow keys generate 3-byte sequences.
Key | bytes | Hex value |
---|---|---|
arrow left | 0x1b, '[', 'D' | 0x1b5b44 |
arrow right | 0x1b, '[', 'C' | 0x1b5b43 |
arrow up | 0x1b, '[', 'A' | 0x1b5b41 |
arrow down | 0x1b, '[', 'B' | 0x1b5b42 |
When the characters are read, the 3-byte sequence actually is reversed.
So for instance, in the last case ('arrow down'), k is assigned 0x425b1b.
k is then used to decide which of the K-array value to use.
k is right-shifted by 16 bits, reducing it to 0x42, so we have K [ 0x042 % 4 ], which is equivalent to K[2], the 3rd element of K[].
Thus, the statement after the read (0, &k, 3) evaluates to calling s (1, 1).
I wonder why K[] does not have 4 values, one for each arrow key.
What is this mate i dont understand this code can u pls help me? I think w,a,s,d doesnt work for example i put w but numbers doesnt went up why?
I've reformatted the code a bit more, and added a few comments to explain some of the code. Please correct me if I'm wrong. (Unfortunately I don't know much about gist, so for now I'll leave the code here)