2048

今天上午寫了個2048,直接在cmd運行...

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <conio.h>
#include <windows.h> 
#include <ctime>
#include <cassert>
using namespace std;

struct Game
{
	int ht,wd;
	int d[10][10],empty[17];
	int ptline[5],ptcross[5];
	long long sum; 
	inline void init(void)
	{
		ht=25,wd=80,sum=0;
		memset(d,0,sizeof d); 
		ptline[1]=4,ptline[2]=9,ptline[3]=14,ptline[4]=19;
		ptcross[1]=26,ptcross[2]=34,ptcross[3]=42,ptcross[4]=50;
		empty[0]=0; for (int i=1;i<=16;i++) empty[i]=1,empty[0]++;
	}
	inline int len(int i)
	{
		if (!i) return 1;
		int cnt=0;
		for (;i;i/=10) cnt++;
		return cnt;
	}
	void print(void)
	{
		system("cls");
		printf("\n現在的得分:%I64d\n\n",sum);
		int num=1,x=1,y=1;
		for (int i=4;i<=ht-4;i++)
		{
			for (int j=1;j<wd;j++)
				if (x<=4&&ptline[x]==i&&ptcross[y]==j)
				{
					if (!d[x][y]) printf("*"); else printf("%d",d[x][y]);
					num++;
					j+=len(d[x][y])-1;
					if (y==4)
						x++,y=1;
					else y++;
				}
				else printf(" ");
			printf("\n");
		}
		printf("________________________________________________________________________________\n");
		printf("操作說明:如果要終止這次遊戲,請輸入6\n");
	}
	inline void wait(int sec)
	{
		Sleep(sec);
	}
	inline int getid(int i,int j)
	{
		return (i-1)*4+j;
	}
	void make(void)
	{
		int num=0,x,y,rank,found=0;
		srand(time(0));
		rank=rand()%empty[0]+1;
		for (int i=1;i<=4&&!found;i++)
			for (int j=1;j<=4&&!found;j++)
			if (empty[getid(i,j)])
			{
				num++;
				if (num==rank)
				{
					x=i,y=j;
					found=1;
				}
			}
		assert(x>0&&x<5&&y>0&&y<5);
		d[x][y]=(rand()%4?2:4);
		empty[getid(x,y)]=0,empty[0]--;
	}
	int tmp[6][6],tmp2[6][6];
	inline void rotate_right(void)
	{
		for (int i=1;i<=4;i++)
			for (int j=1;j<=4;j++)
				tmp2[i][j]=d[i][j];
		memset(d,0,sizeof d);
		for (int i=1;i<=4;i++)
			for (int j=1;j<=4;j++)
				d[5-j][i]=tmp2[i][j];
	}
	int update(int dir,int changetag)
	{
		for (int i=1;i<=4;i++)
			for (int j=1;j<=4;j++) 
				tmp[i][j]=d[i][j];
		for (int i=1;i<=dir;i++) rotate_right();
		int k;
		for (int j=1;j<=4;j++)
		{
			for (int i=1;i<=4;i++)
				if (!d[i][j])
				{
					for (k=i+1;k<=4;k++)
						if (d[k][j]) break;
					if (k==5) break;
					for (int p=k;p<=4;p++)
						if (p^1) d[i+p-k][j]=d[p][j],d[p][j]=0;
				}
			for (int i=1;i<4;i++)
			{
				if (!d[i][j]) break;
				if (d[i][j]==d[i+1][j]) 
				{
					if (changetag) sum+=d[i][j];
					d[i][j]<<=1,d[i+1][j]=0,i++;
				}
			}
			for (int i=1;i<=4;i++)
				if (!d[i][j])
				{
					for (k=i+1;k<=4;k++)
						if (d[k][j]) break;
					if (k==5) break;
					for (int p=k;p<=4;p++)
						if (p^1) d[i+p-k][j]=d[p][j],d[p][j]=0;
				}
		}
		for (int i=1;i<=4-dir;i++) rotate_right();
		int changed=0;
		for (int i=1;i<=4;i++)
			for (int j=1;j<=4;j++)
				if (tmp[i][j]&&!d[i][j])
				{
					changed=1;
					if (changetag)
					{
						empty[0]++;
						empty[getid(i,j)]=1;
					}
				}
				else
				if (!tmp[i][j]&&d[i][j])
				{
					changed=1;
					if (changetag)
					{
						empty[0]--;
						empty[getid(i,j)]=0;
					}
				}
		return changed; 
	}
	int check_okay(void)
	{
		for (int i=1;i<=4;i++)
			for (int j=1;j<=4;j++) 
				tmp[i][j]=d[i][j];
		int can=0;
		for (int i=0;i<4;i++)
		{
			can|=update(i,0);
			for (int i=1;i<=4;i++)
				for (int j=1;j<=4;j++)
					d[i][j]=tmp[i][j];
			if (can) return 1;
		}
		return 0;
	}
	void start(void)
	{
		init(),make(),make(),print();
		char c; int done; 
		for (;;)
		{
			c=getch(),done=0;
			if (c==-32) continue;
			if (c=='6') return;
			if (c==72)
				done=update(0,1);
			else
			if (c==80)
				done=update(2,1);
			else
			if (c==75)
				done=update(3,1);
			else done=update(1,1);
			if (done)
			{
				make(); print();
				if (!check_okay())
				{
					wait(1000);
					printf("遊戲結束,你的得分爲:%I64d\n",sum);
					wait(5000);
					return;
				}
			}
			else
			{
				system("cls");
				printf("不能向%s\n",c==72?"上":c==80?"下":c==75?"左":"右");
				wait(1000);
				print();
			}
		}
	}
}game;

struct Menu
{
	int ht,wd;		//25*80
	char s[30][90];
	int locflag,locsize;
	inline void init(void)
	{
		ht=25,wd=80,locflag=1,locsize=3;
		system("@echo off");
		system("color fc");
	}
	inline void print(void)
	{
		memset(s,0,sizeof s);
		strcpy(s[5],"                                    2048");
		if (locflag==1)
			strcpy(s[9],"                              →   新遊戲");
		else strcpy(s[9],"                                   新遊戲");
		if (locflag==2)
			strcpy(s[13],"                              →   遊戲介紹");
		else strcpy(s[13],"                                   遊戲介紹");
		if (locflag==3)
			strcpy(s[17],"                              →   退出");
		else strcpy(s[17],"                                   退出");
		strcpy(s[20],"                                                           By Sdchr");
		strcpy(s[23],"________________________________________________________________________________");
		strcpy(s[24],"操作說明:往上移動按↑,往下移動按↓,確認按Enter"); 
		system("cls");
		for (int i=1;i<=ht;i++) printf("%s\n",s[i]); 
	}
	inline void wait(int sec)
	{
		Sleep(sec);
	}
	void reflect(void)
	{
		if (locflag==2)
		{
			system("cls");
			printf("\n");
			printf("這款遊戲的玩法很簡單喲。\n");
			printf("\n");
			printf("對於給定的4*4棋盤,每次可以選擇上下左右滑動。\n");
			printf("\n");
			printf("每滑動一次,所有的數字方塊都會往滑動的方向靠攏,系統也會在空白的地方亂數出現一個數字方塊。\n");
			printf("\n");
			printf("相同數字的方塊在靠攏、相撞時會相加。\n");
			printf("\n");
			printf("不斷的疊加最終拼湊出2048這個數字就算成功。\n");
			printf("\n");
			//system("type 介紹.txt");
			printf("\n\n\n\n\n\n\n\n\n");
			system("pause");
			print();
		}
		if (locflag==1)
		{
			game.start();
			init();
			print();
		} 
	}
}menu;

int main(void)
{
	char c;
	menu.init();
	menu.print();
	for (;;)
	{
		c=getch();
		if (c==-32) continue;
		if (c==72)
		{
			menu.locflag=(menu.locflag+1)%3+1;
			menu.print();
		}
		else
		if (c==80)
		{
			menu.locflag=menu.locflag%3+1;
			menu.print();
		}
		else 
		if (c==13) 
		{
			menu.reflect();
			if (menu.locflag==3) break;
		}
	}
	return 0;
}


發佈了137 篇原創文章 · 獲贊 4 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章