專題:連連看-戊-核心算法(三)

本文深入探讨连连看游戏的核心算法实现,详细介绍了棋盘结构、卡片摆放与清除的实现方法,以及寻找可消元项的递归算法,并提供了一个简单的测试示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

經過前面兩篇的討論,理論的東西也差不多了,如果你还不明其中机理,可参看專題:連連看-戊-核心算法(一)及專題:連連看-戊-核心算法(二) 。本篇關注程序實現,基本上就直接放代碼了。

先看看定義的頭文件把。

LKK.h  //連連看(遊戲本身)全域性的頭文件
#ifndef __LLK_H__
#define  __LLK_H__

#define  __DEBUG__

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

// 棋盤最大尺寸
// 0~127
#define  CHESSBOARD_X_MAX 128
#define  CHESSBOARD_Y_MAX 128

// 棋盤尺寸
#define  CHESSBOARD_X 10
#define  CHESSBOARD_Y 6

#define  EMPTY 0
#define  REDBALL 1
#define  BLUEBALL 2
#define  YELLOWBALL 3

// 牌面值
typedef unsigned  char  CARDVALUE;

// 坐標結構
typedef  struct
{
    
char X;
    
char Y;
}
Locator,  * pLocator;

// 卡片結構
typedef  struct
{
    Locator MyLocator;
    CARDVALUE Value;
}
Card,  * pCard;

// 棋盤規格
typedef  struct
{
    unsigned 
char X;
    unsigned 
char Y;
}
ChessboardScope;

// 控制字
typedef  struct
{
    ChessboardScope MyChessboardScope;
    unsigned 
char MaxInflexions;
}
Control,  * pControl;

// 棋盤結構
typedef  struct
{
    
//棋盤尺寸結構
    ChessboardScope Scope;

    
//卡片數組
    Card CardArray[CHESSBOARD_X][CHESSBOARD_Y];
}
Chessboard,  *  pChessboard;


// 棋盤初始化函數
void  ChessboardInit(Chessboard  *   const  pChessboard);

// 擺放卡片
BOOL SetCard( const   char  X,  const   char  Y,  const  CARDVALUE CardValue, Chessboard  *   const  pChessboard);
BOOL SetCard(
const  Locator,  const  CARDVALUE CardValue, Chessboard  *   const  pChessboard);
BOOL SetCard(
const  Locator,  const  CARDVALUE CardValue, Chessboard  *   const  pChessboard);

// 清除卡片
BOOL ClearCard( const   char  X,  const   char  Y, Chessboard  *   const  pChessboard);
BOOL ClearCard(
const  Locator, Chessboard  *   const  pChessboard);
BOOL ClearCard(
const  Locator  *   const  pLocator, Chessboard  *   const  pChessboard);

#endif

 

functions.h//功能函數頭文件,主要是跟外掛有關的東西

#ifndef __FUNCTIONS_H__
#define  __FUNCTIONS_H__

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

#include 
" LLK.h "

// 坐標
#define  NA -1
#define  LOCATOR_OUTSIDE -1

//
#define  UP 1
#define  DOWN 2
#define  LEFT 3
#define  RIGHT 4
#define  AUTO 5
#define  DIRECTION_ERROR 0


// 方向
typedef unsigned  char  DIRECTION;


// 下一個點支座標(三個)
typedef  struct
{
    Locator ForwardLocator;
    Locator LeftLocator;
    Locator RightLocator;
}
NextLocators;

// 依來源方向,取得下一個點(三种)的坐標
BOOL GetNextLocators(
                    
const  Locator  *   const  pCurrentLocation,  // 當前點位
                    NextLocators  *   const  pNextLocator,  // 存放下一點(三种)坐標結構
                    DIRECTION SourceDirection,  // 來源方向
                     const  Chessboard  *   const  pChessboard  // 棋盤結構指針
                    );

// 設置下一個(三种)點位
void  SetNextLocators(NextLocators  *   const  pNextLocator, unsigned  char  Flag);


// 坐標是否越界判斷函數
BOOL IsOverScope( const  Locator  *   const  pTheLocator,  const  Control  *   const  pTheControl);

// 是否有元素
BOOL IsCard( const  Locator  *   const  pTheLocator,  const  Chessboard  *   const  pTheChessboard);

// 依坐標,取得卡片面值
inline CARDVALUE GetCardValueByLocator( const  Locator  *   const  pTheLocator, 
                                       
const  Chessboard  *   const  pChessboard);

// 依坐標,取得卡片地址
Card  *  GetCardAddressByLocator( const  Locator  *   const  pTheLocator, 
                               
const  Chessboard  *   const  pTheChessboard);

// 取得新源方向
DIRECTION GetNewSourceDirection( const  Locator  *   const  pSourceLocator,  const  Locator  *   const  pNextLocator);

// 尋找消元函數
BOOL ClearFind(
               
const  Card  *   const  pSourceCard, 
               
const  Locator  *   const  pStepLocator, 
               Locator 
*   const  pClearLocator,
               
const  Chessboard  *   const  pChessboard,
               
const  Control  *   const  pControlReference, 
               
const  DIRECTION SourceDirection, 
               unsigned 
char  CurrentInflexionAmount
               );

#endif

 

LLK.cpp//遊戲相關的函數實現。

#include  " LLK.h "

#include 
" Functions.h "

// 棋盤初始化函數
void  ChessboardInit(Chessboard  *   const  pChessboard)
{
    
//
    pChessboard ->Scope.X = CHESSBOARD_X;
    pChessboard 
->Scope.Y = CHESSBOARD_Y;
    
    unsigned 
char i, j;
    
for(j = 0; j < CHESSBOARD_Y; j++)
    
{
        
for(i = 0; i < CHESSBOARD_X; i++)
        
{
            pChessboard 
->CardArray[i][j].MyLocator.X = i;
            pChessboard 
->CardArray[i][j].MyLocator.Y = j;
            pChessboard 
->CardArray[i][j].Value = EMPTY;
        }

    }

    
    
return;
}


// 擺放卡片
BOOL SetCard( const   char  X,  const   char  Y,  const  CARDVALUE CardValue, Chessboard  *   const  pChessboard)
{
    
if(X < 0 || X > pChessboard ->Scope.X || Y < 0 || Y > pChessboard ->Scope.Y || CardValue < 0)
    
{
        
return FALSE;
    }

    
    pChessboard 
->CardArray[X][Y].Value = CardValue;

    
return TRUE;  

}


// 清除卡片
BOOL ClearCard( const   char  X,  const   char  Y, Chessboard  *   const  pChessboard)
{
    
if(SetCard(X, Y, EMPTY, pChessboard))
    
{
        
return TRUE;
    }


    
return FALSE;
}

 


外掛有關的函數文件,主要的函數(包括找路函數)都在。

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

#include 
" Functions.h "
#include 
" LLK.h "

#ifdef __DEBUG__
extern  unsigned  short  count;
#endif

// 設置下一個(三种)點位
void  SetNextLocators(NextLocators  *   const  pNextLocator, unsigned  char  Flag)
{
    
switch(Flag)
    
{
    
case NA:
        pNextLocator 
->ForwardLocator.X = NA;
        pNextLocator 
->ForwardLocator.Y = NA;

        pNextLocator 
->LeftLocator.X = NA;
        pNextLocator 
->LeftLocator.Y = NA;

        pNextLocator 
->RightLocator.X = NA;
        pNextLocator 
->RightLocator.Y = NA;
        
        
break;

    
default:
        
break;
    }


    
return;
}


// 依來源方向,取得下一個點(三种)的坐標
BOOL GetNextLocators(
                    
const  Locator  *   const  pCurrentLocation,  // 當前點位
                    NextLocators  *   const  pNextLocator,  // 存放下一個點位的結構指針
                     const  DIRECTION SourceDirection,  // 來源方向
                     const  Chessboard  *   const  pChessboard  // 棋盤結構指針
                    )
{
#ifdef __DEBUG__
    
if((pCurrentLocation ->== 8&& (pCurrentLocation ->== 5))
    
{
        printf(
" (8,5) ");
    }

#endif

    
switch(SourceDirection)
    
{
    
case UP:
        
//前端點
        
//判斷是否出界
        if((pCurrentLocation ->Y) == pChessboard ->Scope.Y - 1)
        
{
            pNextLocator 
->ForwardLocator.X = LOCATOR_OUTSIDE;
            pNextLocator 
->ForwardLocator.Y = LOCATOR_OUTSIDE;
        }

        
else
        
{
            pNextLocator 
->ForwardLocator.X = pCurrentLocation ->X;
            pNextLocator 
->ForwardLocator.Y = pCurrentLocation ->+ 1;
        }


        
//左點
        
//判斷是否出界
        if(pCurrentLocation ->== 0)
        
{
            pNextLocator 
->LeftLocator.X = LOCATOR_OUTSIDE;
            pNextLocator 
->LeftLocator.Y = LOCATOR_OUTSIDE;
        }

        
else
        
{
            pNextLocator 
->LeftLocator.X = pCurrentLocation ->- 1;
            pNextLocator 
->LeftLocator.Y = pCurrentLocation ->Y;
        }


        
//右點
        
//判斷是否出界
        if((pCurrentLocation ->X) == pChessboard ->Scope.X - 1)
        
{
            pNextLocator 
->RightLocator.X = LOCATOR_OUTSIDE;
            pNextLocator 
->RightLocator.Y = LOCATOR_OUTSIDE;
        }

        
else
        
{
            pNextLocator 
->RightLocator.X = pCurrentLocation ->+ 1;
            pNextLocator 
->RightLocator.Y = pCurrentLocation ->Y;
        }


        
break;

    
case DOWN:
        
//前端點
        
//判斷是否出界
        if(pCurrentLocation ->== 0)
        
{
            pNextLocator 
->ForwardLocator.X = LOCATOR_OUTSIDE;
            pNextLocator 
->ForwardLocator.Y = LOCATOR_OUTSIDE;
        }

        
else
        
{
            pNextLocator 
->ForwardLocator.X = pCurrentLocation ->X;
            pNextLocator 
->ForwardLocator.Y = pCurrentLocation ->- 1;
        }


        
//左點
        
//判斷是否出界
        if(pCurrentLocation ->== 0)
        
{
            pNextLocator 
->LeftLocator.X = LOCATOR_OUTSIDE;
            pNextLocator 
->LeftLocator.Y = LOCATOR_OUTSIDE;
        }

        
else
        
{
            pNextLocator 
->LeftLocator.X = pCurrentLocation ->- 1;
            pNextLocator 
->LeftLocator.Y = pCurrentLocation ->Y;
        }


        
//右點
        
//判斷是否出界
        if((pCurrentLocation ->X) == pChessboard ->Scope.X -1)
        
{
            pNextLocator 
->RightLocator.X = LOCATOR_OUTSIDE;
            pNextLocator 
->RightLocator.Y = LOCATOR_OUTSIDE;
        }

        
else
        
{
            pNextLocator 
->RightLocator.X = pCurrentLocation ->+ 1;
            pNextLocator 
->RightLocator.Y = pCurrentLocation ->Y;
        }


        
break;

    
case LEFT:
        
//前端點
        
//判斷是否出界
        if((pCurrentLocation ->X) == pChessboard ->Scope.X - 1)
        
{
            pNextLocator 
->ForwardLocator.X = LOCATOR_OUTSIDE;
            pNextLocator 
->ForwardLocator.Y = LOCATOR_OUTSIDE;
        }

        
else
        
{
            pNextLocator 
->ForwardLocator.X = pCurrentLocation ->+ 1;
            pNextLocator 
->ForwardLocator.Y = pCurrentLocation ->Y;
        }


        
//左點
        
//判斷是否出界
        if(pCurrentLocation ->== 0)
        
{
            pNextLocator 
->LeftLocator.X = LOCATOR_OUTSIDE;
            pNextLocator 
->LeftLocator.Y = LOCATOR_OUTSIDE;
        }

        
else
        
{
            pNextLocator 
->LeftLocator.X = pCurrentLocation ->X;
            pNextLocator 
->LeftLocator.Y = pCurrentLocation ->- 1;
        }


        
//右點
        
//判斷是否出界
        if((pCurrentLocation ->Y) == pChessboard ->Scope.Y - 1)
        
{
            pNextLocator 
->RightLocator.X = LOCATOR_OUTSIDE;
            pNextLocator 
->RightLocator.Y = LOCATOR_OUTSIDE;
        }

        
else
        
{
            pNextLocator 
->RightLocator.X = pCurrentLocation ->X;
            pNextLocator 
->RightLocator.Y = pCurrentLocation ->+ 1;
        }


        
break;

    
case RIGHT:
        
//前端點
        
//判斷是否出界
        if(pCurrentLocation ->== 0)
        
{
            pNextLocator 
->ForwardLocator.X = LOCATOR_OUTSIDE;
            pNextLocator 
->ForwardLocator.Y = LOCATOR_OUTSIDE;
        }

        
else
        
{
            pNextLocator 
->ForwardLocator.X = pCurrentLocation ->- 1;
            pNextLocator 
->ForwardLocator.Y = pCurrentLocation ->Y;
        }

                
        
//左點
        
//判斷是否出界
        if((pCurrentLocation ->Y) == pChessboard ->Scope.Y - 1)
        
{
            pNextLocator 
->LeftLocator.X = LOCATOR_OUTSIDE;
            pNextLocator 
->LeftLocator.Y = LOCATOR_OUTSIDE;
        }

        
else
        
{
            pNextLocator 
->LeftLocator.X = pCurrentLocation ->X;
            pNextLocator 
->LeftLocator.Y = pCurrentLocation ->+ 1;
        }


        
//右點
        
//判斷是否出界
        if(pCurrentLocation ->== 0)
        
{
            pNextLocator 
->RightLocator.X = LOCATOR_OUTSIDE;
            pNextLocator 
->RightLocator.Y = LOCATOR_OUTSIDE;
        }

        
else
        
{
            pNextLocator 
->RightLocator.X = pCurrentLocation ->X;
            pNextLocator 
->RightLocator.Y = pCurrentLocation ->- 1;
        }


        
break;

    
default:
        
return FALSE;
    }


    
return TRUE;
}


// 坐標是否越界判斷函數
BOOL IsOverScope( const  Locator  *   const  pTheLocator,  const  Control  *   const  pTheControl)
{
    
if(pTheLocator ->> pTheControl ->MyChessboardScope.X || 
        pTheLocator 
->> pTheControl ->MyChessboardScope.Y)
    
{
        
//越界
        return TRUE;
    }

    
    
//未越界
    return FALSE;
}


// 是否有元素
BOOL IsCard( const  Locator  *   const  pTheLocator,  const  Chessboard  *   const  pTheChessboard)
{
    
//
    if(GetCardValueByLocator(pTheLocator, pTheChessboard) != EMPTY)
    
{
        
return TRUE;
    }


    
return FALSE;
}


// 依坐標,取得卡片面值
// 此函數不檢查坐標值是否有效(如是否出界等)
inline CARDVALUE GetCardValueByLocator( const  Locator  *   const  pTheLocator, 
                                       
const  Chessboard  *   const  pTheChessboard)
{
    
return pTheChessboard ->CardArray[pTheLocator ->X][pTheLocator ->Y].Value;
}


// 能否消元
BOOL CanClear( const  Card  *   const  pSourceCard,  const  Card  *   const  pTargetCard)
{
    
//能够消元
    if(pTargetCard ->Value == pSourceCard ->Value)
    
{
        
return TRUE;
    }


    
return FALSE;
}


// 取得新源方向
DIRECTION GetNewSourceDirection( const  Locator  *   const  pSourceLocator,  const  Locator  *   const  pNextLocator)
{
    
//
    if(((pNextLocator ->- pSourceLocator ->Y) > 0&& (pNextLocator->== pSourceLocator ->X))
    
{
        
return UP;
    }


    
if(((pNextLocator->- pSourceLocator ->Y) < 0&& (pNextLocator->== pSourceLocator ->X))
    
{
        
return DOWN;
    }


    
if(((pNextLocator->- pSourceLocator ->X) > 0&& (pNextLocator->== pSourceLocator ->Y))
    
{
        
return LEFT;
    }


    
if(((pNextLocator->- pSourceLocator ->X) < 0&& (pNextLocator->== pSourceLocator ->Y))
    
{
        
return RIGHT;
    }


    
return DIRECTION_ERROR;
}


// 依坐標,取得卡片地址
Card  *  GetCardAddressByLocator( const  Locator  *   const  pTheLocator, 
                               
const  Chessboard  *   const  pTheChessboard)
{
    
return (Card *)&(pTheChessboard ->CardArray[pTheLocator ->X][pTheLocator ->Y]);
}


// 尋找消元函數
BOOL ClearFind(
               
const  Card  *   const  pSourceCard, 
               
const  Locator  *   const  pStepLocator, 
               Locator 
*   const  pClearLocator,
               
const  Chessboard  *   const  pChessboard,
               
const  Control  *   const  pControlReference, 
               DIRECTION SourceDirection, 
               unsigned 
char  CurrentInflexionAmount
               )
{

#ifdef __DEBUG__
    count
++;
    
    printf(
"S(%d,%d) ", pStepLocator ->X, pStepLocator ->Y);

    
if((pStepLocator ->== 8&& (pStepLocator ->== 5))
    
{
        printf(
"prblm! ");
    }

#endif

    
//拐點檢查
    if(CurrentInflexionAmount > pControlReference ->MaxInflexions)
    
{
        
return FALSE;
    }


    
//是否是第一次調用
    BOOL Init = FALSE;

    
//
    if(SourceDirection == AUTO)
    
{
        SourceDirection 
= LEFT;
        Init 
= TRUE;
    }

    
//下一個點坐標
    NextLocators NextLocator;
    
    
//取得下一個點的坐標
    if(!GetNextLocators(pStepLocator, &NextLocator, 
                        SourceDirection, 
                        pChessboard))
    
{
        
return FALSE;
    }



    
//直走探測
    
//如果此調用返回TRUE表示已經找到可消元之元素,故返回TRUE

    
//如果下一個點(前)未越界
    if(!IsOverScope(&(NextLocator.ForwardLocator), pControlReference))
    
{

        
//這裡的下一個點(前)未越界

        
//下一個點(前)有元素
        if(IsCard(&(NextLocator.ForwardLocator), pChessboard))
        
{
            
//能夠消元
            if(CanClear(pSourceCard, GetCardAddressByLocator(&(NextLocator.ForwardLocator), pChessboard)))
            
{
                
//保存其坐標
                pClearLocator ->= NextLocator.ForwardLocator.X;
                pClearLocator 
->= NextLocator.ForwardLocator.Y;

                
return TRUE;
            }


            
//有元素又不能消元,則無作爲,繼續下面的找路
            
//return FALSE;

        }
//下一個點(前)有元素閉合
        
        
//下一個點(前)無元素
        else
        
{
            
//進一步調用自己
            
//調用時要做一些改變,比如步進
            
//
            
//如果發現能夠消元之元素,則成功返回
            if(ClearFind(
                        pSourceCard, 
                        
&(GetCardAddressByLocator(&(NextLocator.ForwardLocator), pChessboard) ->MyLocator),  
                        pClearLocator, 
                        pChessboard, 
                        pControlReference, 
                        SourceDirection, 
                        CurrentInflexionAmount
                        ))
            
{
                
//
                return TRUE;
            }

            
            
//步進了返回不能消元,則無作爲,繼續下面的找路
        }

    }
//下一個(前)點無元素閉合

    
//1、有元素不能消元
    
//2、無元素步進未找到出路
    
//3、下一個點(前)越界
    
//則無作爲,繼續下面的找路

    
//需要預防當拐點數為2且已經走到盡頭需要左右拐之情況
    
//發生在多次遞歸調用之后
    if(CurrentInflexionAmount == pControlReference ->MaxInflexions)
    
{
        
return FALSE;
    }

    
    DIRECTION NewSourceDirection;
    
    
//左走探測
    
//如果下一個點(左)未越界
    if(!IsOverScope(&(NextLocator.LeftLocator), pControlReference))
    
{
        
//下一個點(左)有元素
        if(IsCard(&(NextLocator.LeftLocator), pChessboard))
        
{
            
//能夠消元
            if(CanClear(pSourceCard, GetCardAddressByLocator(&(NextLocator.LeftLocator), pChessboard)))
            
{
                
//保存其坐標??
                pClearLocator ->= NextLocator.LeftLocator.X;
                pClearLocator 
->= NextLocator.LeftLocator.Y;

                
return TRUE;
            }


            
//有元素又不能消元,則無作爲,繼續下面的找路

        }
//下一個點(左)有元素閉合
        
        
//下一個點(左)無元素
        else
        
{
            
//進一步調用自己
            
//調用時要做一些改變,比如步進
            NewSourceDirection = GetNewSourceDirection(pStepLocator, &(NextLocator.LeftLocator));
            
if(NewSourceDirection == DIRECTION_ERROR)
            
{
                
return FALSE;
            }


            
//如果是第一次調用,拐點不+1
            if(Init)
            
{
                
if(ClearFind(pSourceCard, 
                            
&(GetCardAddressByLocator(&(NextLocator.LeftLocator), 
                                                     pChessboard) 
->MyLocator), 
                            pClearLocator, 
                            pChessboard, 
                            pControlReference, 
                            NewSourceDirection, 
                            CurrentInflexionAmount))
                
{
                    
return TRUE;
                }

            }

            
else
            
{
                
if(ClearFind(pSourceCard, 
                            
&(GetCardAddressByLocator(&(NextLocator.LeftLocator), 
                                                     pChessboard) 
->MyLocator), 
                            pClearLocator, 
                            pChessboard, 
                            pControlReference, 
                            NewSourceDirection, 
                            CurrentInflexionAmount 
+ 1))
                
{
                    
return TRUE;
                }

            }


        }
//下一個點(左)無元素閉合
    }
//下一個點(左)未越界閉合

    
//1、有元素不能消元
    
//2、無元素步進未找到出路
    
//3、下一個點(左)越界
    
//則無作爲,繼續下面的找路


    
//右走探測
    
//如果下一個點(右)未越界
    if(!IsOverScope(&(NextLocator.RightLocator), pControlReference))
    
{
        
//下一個點(右)有元素
        if(IsCard(&(NextLocator.RightLocator), pChessboard))
        
{
            
//能夠消元
            if(CanClear(pSourceCard, GetCardAddressByLocator(&(NextLocator.RightLocator), pChessboard)))
            
{
                
//保存其坐標
                pClearLocator ->= NextLocator.RightLocator.X;
                pClearLocator 
->= NextLocator.RightLocator.Y;

                
return TRUE;
            }


            
//有元素又不能消元,則無作爲,繼續下面的找路

        }
//下一個點(右)有元素閉合
        
        
//下一個點(右)無元素
        else
        
{
            
//進一步調用自己
            
//調用時要做一些改變,比如步進
            NewSourceDirection = GetNewSourceDirection(pStepLocator, &(NextLocator.RightLocator));
            
if(NewSourceDirection == DIRECTION_ERROR)
            
{
                
return FALSE;
            }

            
            
//如果是第一次調用,則拐點不+1
            if(Init)
            
{
                
if(ClearFind(pSourceCard, 
                            
&(GetCardAddressByLocator(&(NextLocator.RightLocator), 
                                                     pChessboard) 
->MyLocator),
                            pClearLocator, 
                            pChessboard, 
                            pControlReference, 
                            NewSourceDirection, 
                            CurrentInflexionAmount))
                
{
                    
return TRUE;
                }

            }

            
else
            
{
                
if(ClearFind(pSourceCard, 
                            
&(GetCardAddressByLocator(&(NextLocator.RightLocator), 
                                                     pChessboard) 
->MyLocator),
                            pClearLocator, 
                            pChessboard, 
                            pControlReference, 
                            NewSourceDirection, 
                            CurrentInflexionAmount 
+ 1))
                
{
                    
return TRUE;
                }

            }

        }
//下一個點(右)無元素閉合
    }
//下一個點(右)未越界閉合

    
//如果運行到這里都還沒有返回TRUE,則返回FALSE
    return FALSE;
}


上面的就是算法了

上面的就是算法了,現在把最主要的ClearFind函數說明一下,這個函數就是尋找消元項的函數。

BOOL ClearFind(
               
const  Card  *   const  pSourceCard, 
               
const  Locator  *   const  pStepLocator, 
               Locator 
*   const  pClearLocator,
               
const  Chessboard  *   const  pChessboard,
               
const  Control  *   const  pControlReference, 
               
const  DIRECTION SourceDirection, 
               unsigned 
char  CurrentInflexionAmount
               );

 

const Card * const pSourceCard //源卡片的指針
const Locator * const pStepLocator //步進點位坐標指針
Locator * const pClearLocator //目標點位坐標結構指針
const Chessboard * const pChessboard //棋盤結構指針
const Control * const pControlReference //控制字結構指針
const DIRECTION SourceDirection //源方向
unsigned char CurrentInflexionAmount //當前拐點數

說明一下,控制字是整個連連看遊戲控制的參考,裡面定義了棋盤的規格和允許的最大拐點數(此值一般小於等於2才是連連看嘛!)。


源卡片就是連連看消元的發起的那一頭的卡片;


步進點位就是“下一個點”的坐標(是一個不是三個),它是給函數遞歸調用時使用的,我們調用時一般就填源卡片的坐標;


目標點位坐標結構指針就是找到的另一頭(能消元)卡片的坐標,要的就是它!


棋盤結構指針,用之前當然要先初始化好棋盤;


控制字剛才說了。


源方向,很重要!找路最先走的方向(當但是相對于發起方),向左走、向右走?可惜這個在程序員調用是沒啥用處,因為都是規定好自動讓程序走的,所以程序員調用時必須填AUTO。


當前拐點數,程序員調用時填0,因為都還沒開始走,當然沒有拐點!

下面給個例子,其實也就是個main函數,看看效果。

main.cpp

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

#include 
" Functions.h "
#include 
" LLK.h "



#ifdef __DEBUG__
unsigned 
short  count  =   0 ;
#endif

int  main( void )
{
    
//

    Chessboard LLKChessboard;
    
    ChessboardInit(
&LLKChessboard);
    LLKChessboard.CardArray[
0][5].Value = REDBALL;
    LLKChessboard.CardArray[
5][2].Value = BLUEBALL;

    LLKChessboard.CardArray[
4][2].Value = REDBALL;
    
//LLKChessboard.CardArray[9][4].Value = BLUEBALL;
    LLKChessboard.CardArray[8][3].Value = BLUEBALL;

    printf(
"Chessboard init done! ");

    Locator TargetLocator;
    TargetLocator.X 
= NA;
    TargetLocator.Y 
= NA;

    Control TheControl;
    TheControl.MaxInflexions 
= 2;
    TheControl.MyChessboardScope.X 
= CHESSBOARD_X;
    TheControl.MyChessboardScope.Y 
= CHESSBOARD_Y;
    
    
int i, j;
    
for(j = 0; j < CHESSBOARD_Y; j++)
    
{
        
for(i = 0; i < CHESSBOARD_X; i++)
        
{
            printf(
"%d(%d.%d) ", LLKChessboard.CardArray[i][j].Value, 
                LLKChessboard.CardArray[i][j].MyLocator.X, 
                LLKChessboard.CardArray[i][j].MyLocator.Y);
        }

        printf(
" ");
    }

    printf(
" ");

    
    
//LLKChessboard.CardArray[0][0].Value = ;

    
if(ClearFind(&(LLKChessboard.CardArray[4][2]), 
                 
&(LLKChessboard.CardArray[4][2].MyLocator), 
                 
&TargetLocator, 
                 
&LLKChessboard, 
                 
&TheControl, 
                 AUTO, 
                 
0))
    
{
        printf(
"Found! ");
        printf(
"TargetLocator.X=%d TargetLocator.Y=%d ", TargetLocator.X, TargetLocator.Y);
    }

    
else
    
{
        printf(
"No target found! ");
    }


#ifdef __DEBUG__
    printf(
"count=%d ", count);
#endif

    
return TRUE;
}

 

 

如果定義了__debug__宏,運行時它會自動把找路的路線打印出來(S(x, x)),Count變量記錄的是遞歸調用的次數,盤子稍微大一點就可能很恐怖!所以遞歸這種方式能不用就不要用;還有別的什麼調試訊息。


你可以改變main函數測測效果,興許能發現什麼缺陷也有可能,呵呵!

 

好了,找路部分可以收工!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值