#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>

void plus(int (*plate)[4], char *input) // ÀÌµ¿ ½Ã ¼­·Î ºÙ¾î ÀÖ´Â ¼ö°¡ ÀÖÀ¸¸é ¼­·Î ´õÇØÁÖ±â À§ÇÑ ÇÔ¼ö
{
	int i, j;
	
	if((*input=='w')||(*input=='W')) // À§·Î ¸ô¾Æ³ÖÀ¸¹Ç·Î, ¸Ç À§¿¡ ºÙ¾îÀÖ´Â ¼öµéºÎÅÍ Â÷·Ê´ë·Î ´õÇÑ´Ù.
	for(i=0; i<3; i++)
	{
		{
			for(j=0; j<4; j++)
			{
				if(plate[i][j]==plate[i+1][j])
				{
					plate[i][j]*=2;
					plate[i+1][j]=0;
				}
			}
		}
	}

	else if((*input=='s')||(*input=='S')) // ¾Æ·¡·Î ¸ô¾Æ³ÖÀ¸¹Ç·Î, ¸Ç ¾Æ·¡¿¡ ºÙ¾îÀÖ´Â ¼öµé³¢¸® Â÷·Ê´ë·Î ´õÇÑ´Ù.
	for(i=3; i>0; i--)
	{
		{
			for(j=3; j>=0; j--)
			{
				if(plate[i][j]==plate[i-1][j])
				{
					plate[i][j]*=2;
					plate[i-1][j]=0;
				}
			}
		}
	}

	else if((*input=='a')||(*input=='A')) // ¿ø¸®´Â °°´Ù.
	for(j=0; j<3; j++)
	{
		{
			for(i=0; i<4; i++)
			{
				if(plate[i][j]==plate[i][j+1])
				{
					plate[i][j]*=2;
					plate[i][j+1]=0;
				}
			}
		}
	}

    else if((*input=='d')||(*input=='D')) // ¿ø¸®´Â °°´Ù.
	for(j=3; j>0; j--)
	{
		{
			for(i=3; i>=0; i--)
			{
				if(plate[i][j]==plate[i][j-1])
				{
					plate[i][j]*=2;
					plate[i][j-1]=0;
				}
			}
		}
	}
}

void move(int (*plate)[4], char *input) // ÀÌµ¿ ¹æÇâÀ¸·Î ¼öµéÀ» ¸ðÁ¶¸® ¸ô¾Æ³Ö±â À§ÇÑ ÇÔ¼ö
{
	int i, j, k;

	if((*input=='w')||(*input=='W'))
	for(k=0; k<10; k++) // ÃæºÐÈ÷ ¿©·¯¹ø ¹Ýº¹ÇØ¼­ ¿ÏÀüÈ÷ ¸ô¾Æ³Ö°Ô ÇÏ±â À§ÇÔ
	for(i=0; i<3; i++)
	{
		{
			for(j=0; j<4; j++)
			{
				if(plate[i][j]==0)
				{
					plate[i][j]=plate[i+1][j];
					plate[i+1][j]=0;
				}
			}
		}
	}

	else if((*input=='s')||(*input=='S'))
	for(k=0; k<10; k++)
	for(i=3; i>0; i--)
	{
		{
			for(j=3; j>=0; j--)
			{
				if(plate[i][j]==0)
				{
					plate[i][j]=plate[i-1][j];
					plate[i-1][j]=0;
				}
			}
		}
	}

	else if((*input=='a')||(*input=='A'))
	for(k=0; k<10; k++)
	for(j=0; j<3; j++)
	{
		{
			for(i=0; i<4; i++)
			{
				if(plate[i][j]==0)
				{
					plate[i][j]=plate[i][j+1];
					plate[i][j+1]=0;
				}
			}
		}
	}

    else if((*input=='d')||(*input=='D'))
	for(k=0; k<10; k++)
	for(j=3; j>0; j--)
	{
		{
			for(i=3; i>=0; i--)
			{
				if(plate[i][j]==0)
				{
					plate[i][j]=plate[i][j-1];
					plate[i][j-1]=0;
				}
			}
		}
	}
}

void main()
{
	int plate[4][4]={0};
	int before[4][4]={0};

    int i, j, width, vertical, count=0, first=0, finish=0;

    char input;

	srand((unsigned)time(NULL));

			width=rand()%4;
			vertical=rand()%4;


	printf("Welcome to the 2048 game.\n\n");
	printf("coded by ±è¼ºº¸\n\n");
	printf("w : up,   s : down,   a : left,   d : right,   b : back\n\n");
	printf("Please press any key to start\n\n\n");

	scanf("%c", &input);
	fflush(stdin);
	system("cls");

restart:


	for(i=0; i<4; i++)
		for(j=0; j<4; j++)
			plate[i][j] = 0;
	plate[width][vertical]=2; // ¸Ç Ã³À½ ½ÃÀÛÇÒ ¶§ ¾Æ¹« Ä­¿¡¼­³ª ·£´ýÇÏ°Ô 2°¡ »ý°Ü³ª°Ô ÇÏ±â À§ÇÔ

	while(1)
	{
		for(i=0; i<4; i++)
		{
			for(j=0; j<4; j++)
			{
				if(plate[i][j]!=0)
				{
						printf("[%5d]", plate[i][j]);
				}
			
				else
					printf("[     ]");
			}
			printf("\n\n\n\n\n");
		}

		input = getch();
		fflush(stdin);
		system("cls");

		for(i=0; i<3; i++)
		{
			for(j=0; j<=3; j++)
			{
				if(plate[i][j]==plate[i+1][j]) // ¼¼·Î·Î °°Àº ¼ýÀÚ°¡ ¼­·Î ºÙ¾îÀÖ´Â °æ¿ì°¡ ÇÏ³ª¶óµµ ÀÖÀ¸¸é finish=1
					finish=1;
			}
		}

		for(j=0; j<3; j++)
		{
			for(i=0; i<=3; i++)
			{
				if(plate[i][j]==plate[i][j+1]) // °¡·Î·Î °°Àº ¼ýÀÚ°¡ ¼­·Î ºÙ¾îÀÖ´Â °æ¿ì°¡ ÇÏ³ª¶óµµ ÀÖÀ¸¸é finish=1
					finish=1;
			}
		}

		for(i=0; i<4; i++)
		{
			for(j=0; j<4; j++)
			{
				if(plate[i][j]==0) // ÇÑ Ä­ÀÌ¶óµµ ºñ¾îÀÖÀ¸¸é finish=1
					finish=1;
			}
		}
	
		if(finish==0) // °°Àº ¼ýÀÚ°¡ ¼­·Î ºÙ¾îÀÖ´Â °æ¿ì°¡ ¾Æ¾ê ¾ø°Å³ª, ºñ¾îÀÖ´Â Ä­µµ ¾ø¾î¼­ ´õ ÀÌ»óÀÇ °ÔÀÓ ÁøÇàÀÌ ºÒ°¡´ÉÇÑ °æ¿ì
			break;

		finish=0;

		if(input=='w'||input=='W'||input=='a'||input=='A'||input=='s'||input=='S'||input=='d'||input=='D')
		{
			count=0;
			first=1;

			for(i=0; i<4; i++)
			{
				for(j=0; j<4; j++)
				{
					before[i][j]=plate[i][j];
				}
			}

			move(plate, &input);
			plus(plate, &input);
			move(plate, &input);


			for(i=0; i<4; i++)
			{
				for(j=0; j<4; j++)
				{
					if(before[i][j]!=plate[i][j]) // ¹Ù·Î ÀüÀÇ Ä­°ú ÇöÀçÀÇ Ä­ÀÌ ¿Ïº®È÷ °°ÀºÁö¸¦ ±¸º°ÇÏ±â À§ÇÔ
						count=1;
				}
			}

			if(count==0)
				goto end;

			
			width=rand()%4;
			vertical=rand()%4;

			for(i=0; i<4; i++)
						{
							for(j=0; j<4; j++)
							{
								if(plate[i][j]==0)
									count=1;
							}
						}

			if(count==1)
			while(1)
				{
					if(plate[width][vertical]==0)
					{
						plate[width][vertical]=2;
						break;
					}	

					width=rand()%4;
					vertical=rand()%4;
				}
end:
			count=0;
	}
		else if(input=='b'||input=='B')
		{
			if(first==0)
				printf("¸Ç Ã³À½¿¡´Â µÚ·Î °¥ ¼ö ¾ø½À´Ï´Ù!\n\n");

			else if(count!=1)
			for(i=0; i<4; i++)
			{
				for(j=0; j<4; j++)
				{
					plate[i][j]=before[i][j];
					before[i][j]=0;
				}
			}
			else
				printf("µÚ·Î°¡±â´Â ¹Ù·Î ÀüÀÇ »óÅÂ·Î¹Û¿¡ µ¹¾Æ°¥ ¼ö ¾ø½À´Ï´Ù.\n\n");

			count=1;
		}
	}

	system("cls");
	for(i=0; i<4; i++)
		{
			for(j=0; j<4; j++)
			{
				printf("[%5d]", plate[i][j]);
			}

			printf("\n\n\n\n\n");
		}

	printf("\n\nGAME OVER\n\n");
	printf("r : restart,   e : exit game");
	scanf("%c", &input);

	while(1)
	{
		if(input=='r'||input=='R')
		{
			system("cls");
			goto restart;
		}
		else if(input=='e'||input=='E')
		{
			system("cls");
			break;
		}
	}
}