/*
* File: main.c
* Author: z
*
* Created on January 30, 2015, 11:52 PM
*/
#define n 4 //Matrix of n*n
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <time.h>
#include<unistd.h>
static int a[n][n]; //game data matrix
static int steps=0; //number of steps
int mypow(int x)
{
if(x==0)return 1;
else return 2*mypow(x-1);
}
void initgame()
{
int i,j;
int k=rand()%(n*n);
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(k==(j*n+i))
{a[i][j]=mypow(rand()%5);}
else
{a[i][j]=0;}
}
}
}
void prtgame()
{
printf("\033[2J");//clear screen
printf("\033[0;0H");//move curse to left top
printf("\033[?25l");//hide curse
printf("\nSteps:\t%d\n",steps);
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("% *d",5,a[i][j]);
}
printf("\n");
}
}
void handarr(char ch)
{
int b[n][n];
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
b[i][j]=0;
}
if(ch=='a')
{
int c[n][n];
for(i=0;i<n;i++)
{
int l=0;
for(j=0;j<n;j++)
{
if(a[i][j]!=0)
{
b[i][l]=a[i][j];
l++;
}
int tmp;
for(tmp=l;tmp<n;tmp++)
{
b[i][tmp]=0;
}
}
}
for(i=0;i<n;i++)
{
int l=0;
for(j=0;j<n-1;j++)
{
if(b[i][j]==b[i][j+1])
{
c[i][l]=2*b[i][j];
j=j+1;
l++;
}
else
{
c[i][l]=b[i][j];
l++;
}
// printf("%d ",b[i][j]);
}
if(j==n-1)
{
c[i][l]=b[i][j];l++;
}
int tmp;
for(tmp=l;tmp<n;tmp++)
{
c[i][tmp]=0;
}
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
a[i][j]=c[i][j];
}
printf("\n");
}
}
if(ch=='d')
{
int b[n][n];
int c[n][n];
for(i=0;i<n;i++)
{
int l=0;
for(j=0;j<n;j++)
{
if(a[i][n-1-j]!=0)
{
b[i][l]=a[i][n-1-j];
l++;
}
int tmp;
for(tmp=l;tmp<n;tmp++)
{
b[i][tmp]=0;
}
}
}
for(i=0;i<n;i++)
{
int l=0;
for(j=0;j<n-1;j++)
{
if(b[i][j]==b[i][j+1])
{
c[i][l]=2*b[i][j];
j=j+1;
l++;
}
else
{
c[i][l]=b[i][j];
l++;
}
// printf("%d ",b[i][j]);
}
if(j==n-1)
{
c[i][l]=b[i][j];l++;
}
int tmp;
for(tmp=l;tmp<n;tmp++)
{
c[i][tmp]=0;
}
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
a[i][j]=c[i][n-1-j];
}
printf("\n");
}
}
if(ch=='s')
{
int b[n][n];
int c[n][n];
for(j=0;j<n;j++)
{
int l=0;
for(i=0;i<n;i++)
{
if(a[n-1-i][j]!=0)
{
b[j][l]=a[n-1-i][j];
l++;
}
int tmp;
for(tmp=l;tmp<n;tmp++)
{
b[j][tmp]=0;
}
}
}
for(i=0;i<n;i++)
{
int l=0;
for(j=0;j<n-1;j++)
{
if(b[i][j]==b[i][j+1])
{
c[i][l]=2*b[i][j];
j=j+1;
l++;
}
else
{
c[i][l]=b[i][j];
l++;
}
}
if(j==n-1)
{
c[i][l]=b[i][j];l++;
}
int tmp;
for(tmp=l;tmp<n;tmp++)
{
c[i][tmp]=0;
}
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
a[i][j]=c[j][n-1-i];
}
printf("\n");
}
}
if(ch=='w')
{
int b[n][n];
int c[n][n];
for(j=0;j<n;j++)
{
int l=0;
for(i=0;i<n;i++)
{
if(a[i][j]!=0)
{
b[j][l]=a[i][j];
l++;
}
int tmp;
for(tmp=l;tmp<n;tmp++)
{
b[j][tmp]=0;
}
}
}
for(i=0;i<n;i++)
{
int l=0;
for(j=0;j<n-1;j++)
{
if(b[i][j]==b[i][j+1])
{
c[i][l]=2*b[i][j];
j=j+1;
l++;
}
else
{
c[i][l]=b[i][j];
l++;
}
}
if(j==n-1)
{
c[i][l]=b[i][j];l++;
}
int tmp;
for(tmp=l;tmp<n;tmp++)
{
c[i][tmp]=0;
}
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
a[i][j]=c[j][i];
}
printf("\n");
}
}
}
/*read from stdin without blocking*/
int getkey()
{
int character;
struct termios orig_term_attr;
struct termios new_term_attr;
/* set the terminal to raw mode */
tcgetattr(fileno(stdin), &orig_term_attr);
memcpy(&new_term_attr, &orig_term_attr, sizeof(struct termios));
new_term_attr.c_lflag &= ~(ECHO|ICANON);
new_term_attr.c_cc[VTIME] = 0;
new_term_attr.c_cc[VMIN] = 0;
tcsetattr(fileno(stdin), TCSANOW, &new_term_attr);
/* read a character from the stdin stream without blocking */
/* returns EOF (-1) if no character is available */
character = fgetc(stdin);
/* restore the original terminal attributes */
tcsetattr(fileno(stdin), TCSANOW, &orig_term_attr);
return character;
}
void randadd()
{
int b[n*n];
int i,j,k=0;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
if(a[i][j]==0)
{
b[k]=i*n+j;//mark zero position
k++;
}
}
for(i=k;i<n*n;i++)
b[i]=-1;
if(k!=0)
{
int datainsert=mypow(rand()%5);
int destinsert=rand()%k;
i=b[destinsert]/n;j=b[destinsert]%n;
printf("\n%d\n",a[i][j]);
a[i][j]=datainsert;
}
}
int main()
{
char ch;
system("stty -echo");//turn echo
srand(time(NULL));
initgame();
prtgame();
while ((ch=getkey())!='q')
{
if(ch!=-1)
{
steps++;
handarr(ch);
randadd();
prtgame();
printf("%c",ch);
fflush(stdout);
}
}
system("stty echo");
return 0;
}