1. 程式人生 > 實用技巧 >陣列2與推箱子·遊戲

陣列2與推箱子·遊戲

陣列2==推箱子

include<conio.h>===>getch()//獲取鍵盤上的輸入

氣泡排序:

給陣列排序

1. 演算法步驟

比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。

對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。這步做完後,最後的元素會是最大的數。

針對所有的元素重複以上的步驟,除了最後一個。

持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要

例子:

時長={20,60,30,50,10}

要讓時長從長到短:

第一輪 第二輪

1.20<60》60,20,30,50,10 1.60>30

》不交換

2.20<30》60,30,20,50,10 2.30<50》60,50,30,20,10

3.20<50==》60,30,50,20,10 冒泡結束

結果完成排序

時長=={60,50,30,20,10}

程式設計實現:

通過兩層迴圈巢狀使用

外層迴圈執行一次,一趟

內層迴圈執行一次,一次==》需要通過外層迴圈控制內層迴圈的次數,從而減少不必要的比較次數,提高效率

注意

1.每多排好一個元素,內層迴圈可以減少一次

2.總共n個元素,只需要比較n-1趟

程式碼示例:


int time[5] = { 20,60,30,50,10 };  int t;
		for (int k = 0; k < 4; k++) //外層迴圈控制排序次數
		{                        
			for (int i = 0; i < 4 - k; i++)//內層迴圈控制每次比較的次數
			{
				if (time[i] < time[i + 1])
				{
					t = time[i];                  //將兩個數交換,大的在前,小的在後
					time[i] = time[i + 1];
					time[i + 1] = t;
                    /*
                    用異或交換兩個數的大小
                    time[i]=time[i]^time[i+1];
                    time[i+1]=time[i]^time[i+1];
                    time[i]time[i]^time[i+1];
				}
			}
		}
		for (int i = 0; i < 5; i++)     // 最後輸出交換後的時間排序
		{
			printf("%d ", time[i]);
		}
		while (1);
		return 0;

二維陣列

int str[3][4];
//表示定義了一個二維陣列
//3行4列
1.記憶體

1.二維陣列的記憶體也是連續的

2.總記憶體=單個元素記憶體 * (元素個數) 元素個數=行數 * 列數

3.二維陣列的每一行可以理解為一個一維陣列

4.二維陣列可以理解為元素型別為一維陣列的一維陣列

2.初始化與賦值
//按行初始化
//賦值
    int str1[3][4]={
    {0,1,2,3},
    {5,6,4,8},
    {8,6,3,4}
    };
//把值給滿
int str2[3][4]={
    {5,2},
    {6,3,4},
    {5,6,9,7}
};
//沒有給值的,預設為0

//連續初始化
int arr1[3][4]={2,5,8,6,3,5,4,5,2,3,12,5};
//從前往後給值

//不給行數,只給列數==》必須初始化
int arr1[][4]={2,5,8,6,3,5,4,5,2,3,12};
//11個元素,每行4列,行數:11/4=2...2===>3行

int str1[][4]={
    {0,1,2,3},
    {5,6,4,8},
    {8,6,3,4},
    {}
    };
//有幾個大括號就有幾行
3.訪問
//二維陣列,陣列名[行下標][列下標]
//注意都是從0行0列開始的
int str1[3][4]={
    {0,1,2,3},
    {5,6,4,8},
    {8,6,3,4}
    };
cout << str1[0][0] << endl;
cout << str1[2][3] << endl;
cout << str1[0][4] << endl;//列印的是5
cout << str1[1][-2] << endl;//列印的是2


遍歷二維陣列

使用迴圈巢狀,控制行列下標,實現遍歷

實現遍歷後,可以進行賦值,列印等操作

注意:不要越界

int str1[3][4]={
    {0,1,2,3},
    {5,6,4,8},
    {8,6,3,4}
    };
for(int i=0;i<3;i++)
{
    for(int k=0;k<4;k++)
    {
       // printf("%3d",str1[i][k]);
       // cout << str1[i][k] << " ";
    }
    //printf("\n");
    //cout << endl;
}

推箱子游戲

#include<stdio.h>
#include<conio.h>
#include<windows.h>

#define LAND 0
#define WALL 1
#define HERO 2
#define BOX_ 3
#define WIN_ 4


int main()
{

	int Map[10][10] = {
{1,1,1,1,1,1,1,1,1,1 },
{1,0,0,0,1,0,0,0,0,1 },
{1,0,0,0,1,0,0,0,0,1 },
{1,0,0,0,1,0,0,0,0,1 },
{1,0,0,0,1,4,0,0,0,1 },
{1,0,0,0,0,0,0,0,0,1 },
{1,1,1,0,0,3,0,0,0,1 },
{1,0,0,0,0,0,0,0,0,1 },
{1,0,0,0,0,2,0,0,0,1 },
{1,1,1,1,1,1,1,1,1,1 }
	};

	

	bool isBOX_ = false;
	while (1)
	{
		isBOX_ = false;
		for (int i = 0; i < sizeof(Map) / sizeof(Map[0]); i++)
		{
			for (int j = 0; j < sizeof(Map[0]) / sizeof(int); j++)
			{
				if (BOX_ == Map[i][j])
				{
					isBOX_ = true;
				}
			}
		}
		if (!isBOX_)
		{
			printf("win");
			break;
		}
		system("cls");
	
		//遍歷陣列 列印地圖
		for (int i = 0; i < sizeof(Map) / sizeof(Map[0]); i++)
		{
			for (int j = 0; j < sizeof(Map[0]) / sizeof(int); j++)
			{
				//printf("%2d", Map[i][j]);
				switch (Map[i][j])
				{
				case 0:
					printf("  ");
					break;
				case 1:
					printf("■");
					break;
				case 2:
					printf("♀");
					break;
				case 3:
					printf("●");
					break;
				case 4:
					printf("☆");
					break;
				case BOX_+WIN_://箱子在成功上
					printf("★");
					break;
				case HERO+WIN_://人在成功點上
					printf("♀");
				default:
					break;


				}



			}
			printf("\n");
		}


		//確定人物位置
		int posX = 0, posY = 0;
		for (int i = 0; i < sizeof(Map) / sizeof(Map[0]); i++)
		{
			for (int j = 0; j < sizeof(Map) / sizeof(int); j++)
			{
				if (HERO == Map[i][j]||
					HERO+WIN_==Map[i][j])
				{
					posX = i;
					posY = j;
				}
			}
		}

		switch (_getch())
		{

		case 'w':
		case 'W':
			/*向上的邏輯
			人的上面可能是 空地 箱子 牆壁 成功點*/
			if (LAND == Map[posX - 1][posY] ||
				WIN_ == Map[posX - 1][posY])//成功點 空地,直接走過去
			{
				//當前位置人離開
				Map[posX][posY] -=HERO;//人走後變成了空地
				//上一格人過來
				Map[posX - 1][posY] += HERO;
				//Map[posX-1][posY]=Map[posX-1][posY]+HERO
				//Map[posX-1][posY]就是上一格

			}
			else if (BOX_ == Map[posX - 1][posY])//如果是箱子
			{
				if (LAND == Map[posX - 2][posY] ||
					WIN_ == Map[posX - 2][posY])//箱子前如果是 空地 成功點 直接推過去
				{
					//當前位置人離開
					Map[posX][posY] -= HERO;//人走後變成了空地

					//上一格箱子離開
					Map[posX - 1][posY] -= BOX_;

					//上一格人過來
					Map[posX - 1][posY] += HERO;
					//Map[posX-1][posY]=Map[posX-1][posY]+HERO
					//Map[posX-1][posY]就是上一格

					
					//上上格箱子過來
					Map[posX - 2][posY] += BOX_;
				}



			}
			break;

			/*case 's':
			case 'S':

				;break;
			case 'a':
			case 'A':

				;break;
			case 'd':
			case 'D':

				;break;*/

		}










		
	}
	
	return 0;
}