丙-算法(一)
前文我們得到了棋盤矩陣M,M中同種元素的消元遵循連連看的原則:相鄰或者連綫彎折小於等於兩処。我們可以從矩陣的第一列第一行的那個元素分析起,如果不等于0就考慮消元。
對於消元,其過程稍顯複雜。我們需要做以下判別工作:
一、元素非0;
二、四周非全遮擋(封閉);
三、存在非己同類元素;
四、非己同類元素四周非全遮擋(封閉);
五、連綫彎折処不大于2。
五個條件同時滿足及消元。
把矩陣M再寫一遍:
1 2 3 0 1
M = [ 0 0 0 0 0 ]
0 1 0 3 1
0 2 1 2 0
這個東西用C語言的二位數組來描述。聲明一個二位數組Array[行數][列數],即Array[4][5],行數就是縱坐標,用y表示,列數是橫坐標,用x表示。
遍歷數組Array,如果Array[y][x]不等于0(滿足條件一)就進入下一步。
for
(y
=
0
; y
<=
3
; y
++
)
...
{

for(x = 0; x <= 4; x++)...{

if(Array[y][x] != 0)...{
//元素不等于0的處理代碼
}
}
}
注意0~3是4行,0~4是5列。
對於這樣一個複雜的問題我們需要對原始矩陣的每個元素掃描一道,得到它的相關訊息並將其存入一個重新構造的矩陣(二維數組)中,這些相關訊息包括:
1、牌面值(索引,無牌為“0”);
2、橫坐標;
3、縱坐標;
4、邊界狀況;
5、下一張同類牌指針。
於是定義結構card(中間體矩陣元素)
//
中間體矩陣元素

struct
card
{
int posx;
int posy;
char index;
char directions;
struct card * next;
}
;
typedef
struct
card CARD;
再聲明一個指針數組pCardArray:
CARD
*
pCardArray[
4
][
5
];
其每個元素指向CARD結構。
我們再來梳理一下思路:
先對原始矩陣掃描一遍,得到非“0”每個元素的相關訊息,將其存入另一個“中間體矩陣”pCardArray中,當然這是一個指針矩陣。如果發現相同的牌(索引值相同)便將其掛至上一個相同元素的next指針上去,這便形成了一個相同元素比如1(紅球)元素的鏈表。對於每個員素之鏈表頭必須予以記錄,於是再聲明:
TYPE IndexArray[TYPENUM]
=
{
0}
;
TYPE類型來源於聲明:
struct
type
...
{
// 在矩陣中的列坐標
int posx;
// 在矩陣中的行坐標
int posy;
//狀態,0-已消元,1-仍存在
char status;
}
;
typedef
struct
type TYPE;
IndexArray數組0號元素置空,從1號元素起分別與牌的Index值相對應,比如IndexArray[1]元素存放的是中間體矩陣中index == 1 的元素組成的鏈表的表頭,IndexArray[2]元素存放的是中間體矩陣中index == 2 的元素組成的鏈表的表頭,以此類推。如果 IndexArray[n].status == 0 則表示牌面為n的牌已經全部消除了,如果 == 1即表示這種牌仍存在。
以下是對原始矩陣處理的源程序,它了掃描原始矩陣Array由此生成中間體矩陣pCardArray及鏈表頭數組IndexArray並填充之。中間體矩陣中的directions相暫未填充,這個項目係標識牌四周相鄰位遮擋的情況,留作下一篇再講。
矩陣梳理(一)
#include
<
stdio.h
>
#include
<
stdlib.h
>

//
牌的種類
#define
TYPENUM 3

//
矩陣有5列
#define
XMAX 5

//
矩陣有4行
#define
YMAX 4

//
中間體矩陣元素

struct
card
...
{
int posx;
int posy;
char index;
char directions;
struct card * next;
}
;
typedef
struct
card CARD;

//
牌類別狀態、起始點數組元素

struct
type
...
{
int posx;
int posy;
char status;
}
;
typedef
struct
type TYPE;


int
main(
void
)
...
{
printf("開始... ");

char x, y, m, n, i, j, k, forM = 0;

char Array[4][5] = ...{...{1, 2, 3, 0, 1},

...{0},

...{2, 1, 0, 3, 1},

...{0, 0, 1, 2, 0}};

//中間體指針矩陣
CARD * pCardArray[4][5];

//類別狀態數組
//0:未完成,1:完成

TYPE IndexArray[TYPENUM] = ...{0};

printf("原始矩陣: ");

for(y = 0; y <= (YMAX - 1); y++)...{

for(x = 0; x <= (XMAX -1); x++)...{
printf("%d ", Array[y][x]);
}
printf(" ");
}

printf(" 開始分析... ");

for(y = 0; y <= (YMAX - 1); y++)...{

for(x = 0; x <= (XMAX -1); x++)...{
pCardArray[y][x] = (CARD *)malloc(sizeof(CARD));
pCardArray[y][x] -> index = Array[y][x];
}
}

printf("中間體矩陣: ");

for(y = 0; y <= (YMAX -1); y++)...{

for(x = 0; x <= (XMAX -1); x++)...{
printf("%d ", pCardArray[y][x] -> index);
}
printf(" ");
}

printf(" 開始查找... ");

//完整矩陣遍歷

for(y = 0; y <= (YMAX -1); y++)...{

for(x = 0; x <= (XMAX -1); x++)...{

//牌種類依次分析

for(k = 1; k <= TYPENUM; k++)...{

//如果此牌是當前要處理的排類別

if(pCardArray[y][x] -> index == k)...{

//如果此類牌未被處理過,則處理

if(IndexArray[k - 1].status == 0)...{

//i,j係存放前一個元素坐標之變量
//此時為某一類元素之第一個元素
pCardArray[y][x] -> posx = x;
pCardArray[y][x] -> posy = y;
IndexArray[k - 1].posx = x;
IndexArray[k - 1].posy = y;
i = x;
j = y;
//設置查找起始點
//如果還沒到最後一列

if(x < (XMAX - 1))...{
m = x + 1;
n = y;
}
//如果已處於最後一列,則進入下一行並從第一列開始

if(x == (XMAX -1))...{
m = 0;
n = y + 1;
}
//開始往後查找

for(n = n; n <= (YMAX - 1); n++)...{

if(forM == 1)...{
m = 0;
}//if閉合
//從那個元素的後一個元素開始

for(m = m; m <= (XMAX - 1); m++)...{
forM = 1;
//printf("[%d][%d] ", m, n);
//如果發現下一個元素之index值與之相同
//便追加至鏈表中
//即修改當前元素之next

if(pCardArray[n][m] -> index == k)...{
pCardArray[j][i] -> next = pCardArray[n][m];
pCardArray[n][m] -> next = NULL;
i = m;
j = n;
printf("Array[%d][%d] == %d ", m, n, k);
}//if(pCardArray[n][m] -> index == k)閉合


if(m == XMAX - 1 && n== YMAX - 1)...{
IndexArray[k - 1].status = 1;
//printf("Status ");
}//if(m&&n)閉合
}//for(m)閉合
}//for(n)閉合

}//if(IndexArray[k - 1] = 0)閉合
}//if(index == k)閉合
}//for(k)閉合

}//for(x)閉合
}//for(y)閉合
printf("查找完畢! ");

printf("相同牌: ");

/**//*for(k = 0; k <= TYPENUM; k++){
while(pCurrent != NULL){
}
}*/
printf("pCardArray[][] = %p ", pCardArray[0][1] -> next);
printf("pCardArray[][] = %p ", &pCardArray[2][0]);


for(k = 0; k <= TYPENUM - 1; k++)...{
printf("索引%d:%d[][] ", k, IndexArray[k].status);
printf("IndexArray[%d].posx = %d, posy = %d ", k,
IndexArray[k].posx, IndexArray[k].posy);
}
printf("完成! ");
return 0;
}