123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157 |
- /*
- * Seven Kingdoms: Ancient Adversaries
- *
- * Copyright 1997,1998 Enlight Software Ltd.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- //Filename : OSPATHS2.CPP
- //Description : Object SeekPathS2
- //Owner : Alex
- #include <math.h>
- #include <stdlib.h>
- #include <ALL.h>
- #include <OWORLD.h>
- #include <OSPATHS2.h>
- #include <OUNIT.h>
- #include <OFIRM.h>
- #include <OTOWN.h>
- #include <OSYS.h>
- //----------- Define static variables -----------//
- static Location* world_loc_matrix;
- static int cur_stack_pos_s2 = 0;
- static NodeS2* stack_array[MAX_STACK_NUM];
- static DWORD group_id_s2;
- static short search_mode_s2;
- static char mobile_type_s2;
- static short target_recno_s2;
- static short building_id_s2; // used in search_mode = SEARCH_MODE_TO_FIRM or SEARCH_MODE_TO_TOWN, get from miscNo
- static int building_x1_s2, building_y1_s2, building_x2_s2, building_y2_s2;
- // the building upper-left to lower-right positions
- // if search_mode = SEARCH_MODE_TO_FIRM or SEARCH_MODE_TO_TOWN
- static FirmInfo *searchFirmInfo_s2;
- static short x_shift_array[8] = { 1, 1, 0, -1, -1, -1, 0, 1};
- static short y_shift_array[8] = { 0, -1, -1, -1, 0, 1, 1, 1};
- //---- used in determining the return nodes in the starting node -----//
- static char source_blocked_exit_direction[8]; // indicate which exit direction of starting node is impossible
- static char source_locate_type; // indicate the upper left position of the unit located in the 2x2 node
- //---- used to decide which path is return in a node -------//
- static short prefer_upper_s2; // if upper and lower paths are available, true if the upper path is preferred
- static short prefer_lower_s2; // if upper and lower paths are available, true if the lower path is preferred
- static short prefer_left_s2; // if left and right paths are available, true if the left path is preferred
- static short prefer_right_s2; // if left and right paths are available, true if the right path is preferred
- //--- show whether shift-map method is used the direction shifted ---//
- static short use_shift_map_method_s2;// is 0 or 1, 1 for using this method
- static short shift_map_x_offset_s2; // useful only as shift-map-method is applied
- static short shift_map_y_offset_s2; // useful only as shift-map-method is applied
- //static short reverse_direction_result_node;
- //-- store the orginal and the finalized starting and destination location --//
- static short source_x_s2; // starting x location in 2x2 node format
- static short source_y_s2; // starting y location in 2x2 node format
- static int vir_start_x_s2; // store the start x loc after applying shift-map-method
- static int vir_start_y_s2; // store the start y loc after applying shift-map-method
- static int final_dest_x_s2; // store the finalize x loc after applying shift-map-method, path-reuse, and etc
- static int final_dest_y_s2; // store the finalize y loc after applying shift-map-method, path-reuse, and etc
- //------------------- used in path-reuse -----------------------//
- static int max_node_num_s2;
- static short *reuse_node_matrix_ptr_s2;
- static NodeS2 *reuse_result_node_ptr_s2;
- static int final_dx;
- static int final_dy;
- //------- aliasing class member vars for fast access ------//
- static SeekPathS2* cur_seek_path_s2;
- static short cur_dest_x_s2, cur_dest_y_s2;
- static short* cur_node_matrix_s2;
- static NodeS2* cur_node_array_s2;
- static short cur_border_x1_s2, cur_border_y1_s2, cur_border_x2_s2, cur_border_y2_s2;
- #ifdef DEBUG
- static ResultNode *debugPtr1, *debugPtr2;
- static short debugVX, debugVY;
- static int debugCount;
- void debug_checks2(ResultNode *nodeArray, int count)
- {
- debugPtr1 = nodeArray;
- debugPtr2 = nodeArray+1;
-
- for(debugCount=1; debugCount<count; debugCount++, debugPtr1++, debugPtr2++)
- {
- err_when(debugPtr1->node_x<0 || debugPtr1->node_x>=MAX_WORLD_X_LOC-1 ||
- debugPtr1->node_y<0 || debugPtr1->node_y>=MAX_WORLD_Y_LOC-1);
- debugVX = debugPtr1->node_x - debugPtr2->node_x;
- debugVY = debugPtr1->node_y - debugPtr2->node_y;
- err_when(debugVX!=0 && debugVY!=0 && (abs(debugVX)!=abs(debugVY)));
- }
- err_when(debugPtr1->node_x<0 || debugPtr1->node_x>=MAX_WORLD_X_LOC-1 ||
- debugPtr1->node_y<0 || debugPtr1->node_y>=MAX_WORLD_Y_LOC-1);
- }
- #endif
- #ifdef DEBUG
- #define debug_check_paths2(nodeArray, count) debug_checks2((nodeArray), (count))
- #else
- #define debug_check_paths2(nodeArray, count)
- #endif
- //----------- Define static functions -----------//
- static void stack_push(NodeS2 *nodePtr);
- static NodeS2* stack_pop();
- //------- Begin of static function sys_yield ----------//
- static void sys_yield()
- {
- //sys.yield();
- }
- //------- End of static function sys_yield ----------//
- //------- Begin of static function can_move_to ----------//
- static int can_move_to(int xLoc, int yLoc) // xLoc, yLoc is location after applying shift-map-method
- {
- //-------------------------------------------------------//
- // note : return value should be 0 (false) or 1 (true)
- //-------------------------------------------------------//
- int x, y;
- //-------------------- boundary checking -----------------//
- if(shift_map_x_offset_s2==0)
- {
- if(xLoc<0 || xLoc>=MAX_WORLD_X_LOC)
- return 0;
- else
- x = xLoc;
- }
- else // shifted
- {
- if(xLoc<1 || xLoc>MAX_WORLD_X_LOC)
- return 0;
- else
- x = xLoc+shift_map_x_offset_s2;
- }
- if(shift_map_y_offset_s2==0)
- {
- if(yLoc<0 || yLoc>=MAX_WORLD_Y_LOC)
- return 0;
- else
- y = yLoc;
- }
- else // shifted
- {
- if(yLoc<1 || yLoc>MAX_WORLD_Y_LOC)
- return 0;
- else
- y = yLoc+shift_map_y_offset_s2;
- }
- Location* locPtr = world_loc_matrix+y*MAX_WORLD_X_LOC+x;
- Unit* unitPtr;
- //---------- checking whether the location is walkable ----------//
- switch(mobile_type_s2)
- {
- case UNIT_LAND:
- if(!locPtr->walkable() && search_mode_s2<SEARCH_MODE_TO_FIRM) // be careful for the search_mode>=SEARCH_MODE_TO_FIRM
- return 0;
-
- switch(search_mode_s2)
- {
- case SEARCH_MODE_IN_A_GROUP: // group move
- case SEARCH_MODE_REUSE: // path-reuse
- if(!locPtr->cargo_recno)
- return 1;
- else
- {
- unitPtr = unit_array[locPtr->cargo_recno];
- return (unitPtr->unit_group_id==group_id_s2 && unitPtr->cur_action!=SPRITE_ATTACK) ||
- unitPtr->cur_action==SPRITE_MOVE;
- }
- case SEARCH_MODE_A_UNIT_IN_GROUP: // a unit in a group
- return locPtr->cargo_recno==0 || unit_array[locPtr->cargo_recno]->cur_action==SPRITE_MOVE;
- case SEARCH_MODE_TO_ATTACK: // to attack target
- if(!locPtr->cargo_recno)
- return 1;
- else
- {
- unitPtr = unit_array[locPtr->cargo_recno];
- return (unitPtr->unit_group_id==group_id_s2 && unitPtr->cur_action!=SPRITE_ATTACK) ||
- locPtr->cargo_recno==target_recno_s2 || unitPtr->cur_action==SPRITE_MOVE;
- }
- case SEARCH_MODE_BLOCKING: // 2x2 unit blocking
- if(locPtr->cargo_recno)
- unitPtr = unit_array[locPtr->cargo_recno];
- return locPtr->cargo_recno==0 ||
- (unitPtr->unit_group_id==group_id_s2 && (unitPtr->cur_action==SPRITE_MOVE || unitPtr->cur_action==SPRITE_READY_TO_MOVE));
- case SEARCH_MODE_TO_VEHICLE:
- err_here(); //** error
- return 0;
- //-----------------------------------------------------------------------//
- // for the following search_mode, location may be treated as walkable
- // although it is not.
- //-----------------------------------------------------------------------//
- case SEARCH_MODE_TO_FIRM: // move to a firm, (location may be not walkable)
- case SEARCH_MODE_TO_TOWN: // move to a town zone, (location may be not walkable)
- return (locPtr->walkable() && (locPtr->cargo_recno==0 ||
- (unit_array[locPtr->cargo_recno]->unit_group_id==group_id_s2 &&
- unit_array[locPtr->cargo_recno]->cur_action!=SPRITE_ATTACK) )) ||
- (xLoc>=building_x1_s2 && xLoc<=building_x2_s2 && yLoc>=building_y1_s2 && yLoc<=building_y2_s2);
- case SEARCH_MODE_TO_WALL_FOR_GROUP: // move to wall for a group, (location may be not walkable)
- return (locPtr->walkable() && (locPtr->cargo_recno==0 ||
- (unit_array[locPtr->cargo_recno]->unit_group_id==group_id_s2 &&
- unit_array[locPtr->cargo_recno]->cur_action!=SPRITE_ATTACK) )) ||
- (xLoc==final_dest_x_s2 && yLoc==final_dest_y_s2);
- case SEARCH_MODE_TO_WALL_FOR_UNIT: // move to wall for a unit only, (location may be not walkable)
- return (locPtr->walkable() && locPtr->cargo_recno==0) ||
- (xLoc==final_dest_x_s2 && yLoc==final_dest_y_s2);
- }
- break;
- case UNIT_SEA:
- if( !locPtr->sailable() )
- return 0;
- if( search_mode_s2== SEARCH_MODE_A_UNIT_IN_GROUP)
- return locPtr->cargo_recno==0;
- else
- return locPtr->cargo_recno==0 || unit_array[locPtr->cargo_recno]->unit_group_id==group_id_s2 ||
- (search_mode_s2==SEARCH_MODE_TO_ATTACK && locPtr->cargo_recno==target_recno_s2);
- break;
- case UNIT_AIR:
- if( search_mode_s2== SEARCH_MODE_A_UNIT_IN_GROUP)
- return locPtr->air_cargo_recno==0;
- else
- return locPtr->air_cargo_recno==0 || unit_array[locPtr->air_cargo_recno]->unit_group_id==group_id_s2 ||
- (search_mode_s2==SEARCH_MODE_TO_ATTACK && locPtr->air_cargo_recno==target_recno_s2);
- break;
- default:
- err_here();
- break;
- }
- return 0;
- }
- //------- End of static function can_move_to ----------//
- //------- Begin of static function can_move_to_s2 ----------//
- static int can_move_to_s2(int xLoc, int yLoc) // xLoc, yLoc is location after applying shift-map-method
- {
- //------------------------------------------------//
- // note: return value should be 0 or 1
- //------------------------------------------------//
- if(can_move_to(xLoc,yLoc) && can_move_to(xLoc+1,yLoc) &&
- can_move_to(xLoc,yLoc+1) && can_move_to(xLoc+1,yLoc+1))
- return 1; // is walkable
- else
- return 0; // is not walkable as one point is not walkable
- }
- //------- End of static function can_move_to_s2 ----------//
- //-------- Begin of function SeekPathS2::init ---------//
- void SeekPathS2::init(int maxNode)
- {
- max_node = maxNode;
- node_array = (NodeS2*) mem_add( max_node * sizeof(NodeS2) );
- node_matrix = (short*) mem_add(sizeof(short)*(MAX_WORLD_X_LOC/2+1)*(MAX_WORLD_Y_LOC/2+1));
- path_status = PATH_WAIT;
- open_node_list = NULL;
- closed_node_list = NULL;
- }
- //--------- End of function SeekPathS2::init ---------//
- //-------- Begin of function SeekPathS2::deinit ---------//
- void SeekPathS2::deinit()
- {
- if( node_array )
- {
- mem_del(node_array);
- node_array = NULL;
- }
- if( node_matrix )
- {
- mem_del(node_matrix);
- node_matrix = NULL;
- }
- }
- //--------- End of function SeekPathS2::deinit ---------//
- //-------- Begin of function SeekPathS2::set_node_matrix ---------//
- void SeekPathS2::set_node_matrix(short reuseNodeMatrix[])
- {
- reuse_node_matrix_ptr_s2 = reuseNodeMatrix;
- }
- //--------- End of function SeekPathS2::set_node_matrix ---------//
- //-------- Begin of function SeekPathS2::reset ---------//
- void SeekPathS2::reset()
- {
- path_status=PATH_WAIT;
- open_node_list=NULL;
- closed_node_list=NULL;
- }
- //--------- End of function SeekPathS2::reset ---------//
- //-------- Begin of function SeekPathS2::add_result_node ---------//
- inline void SeekPathS2::add_result_node(ResultNode** curPtr, ResultNode** prePtr, int& count)
- {
- err_when(abs((*curPtr)->node_x-(*prePtr)->node_x)>1 || abs((*curPtr)->node_y-(*prePtr)->node_y)>1);
- *prePtr = *curPtr;
- (*curPtr)++;
- count++;
- }
- //--------- End of function SeekPathS2::add_result_node ---------//
- //-------- Begin of function SeekPathS2::seek ---------//
- //
- // <int> sx, sy - the starting world location.
- // <int> dx, dy - the destination world location.
- // <DWORD> groupId - unit group id.
- // <char> mobileType - mobile type, can be UNIT_AIR, UNIT_LAND or UNIT_SEA
- //
- // [int] searchMode - 1, SEARCH_MODE_IN_A_GROUP for one group with an unique group id (default)
- // 2, SEARCH_MODE_A_UNIT_IN_GROUP for one sprite in a group
- // 3, SEARCH_MODE_TO_ATTACK for attacking
- // 4, SEARCH_MODE_REUSE for path reuse
- // 5, SEARCH_MODE_BLOCKING for 2x2 unit blocked searching
- // 6, SEARCH_MODE_TO_FIRM for moving to a firm
- // 7, SEARCH_MODE_TO_TOWN for moving to a town zone
- // 8, SEARCH_MODE_TO_VEHICLE for moving to a vehicle
- // (default : 1)
- //
- // [int] miscNo - target record no if searchMode=SEARCH_MODE_TO_ATTACK
- // - firm ID if searchMode=SEARCH_MODE_TO_FIRM
- //
- // [int] maxTries - maximum no. of tries in the first seek action.
- // this refer to the maximum no. of nodes created.
- // (default : max_node)
- //
- // [int] borderX1, borderY1, - borders of the seek area in the world map
- // borderX2, borderY2 (default: the whole map)
- //
- // Note: if maxTries==max_node, incremental seek (PATH_SEEKING) won't happen.
- //
- // return : <int> seekStatus - PATH_FOUND, PATH_SEEKING, PATH_NODE_USED_UP, or PATH_IMPOSSIBLE
- // if PATH_FOUND, or PATH_NODE_USED_UP, can call get_result() to retrieve the result.
- //
- int SeekPathS2::seek(int sx,int sy,int dx,int dy,DWORD groupId,char mobileType,short searchMode,short miscNo,
- int maxTries,int borderX1,int borderY1,int borderX2,int borderY2)
- {
- //-------- initialize vars --------------//
- path_status = PATH_SEEKING;
- world_loc_matrix = world.loc_matrix; // alias for fast access
- open_node_list = NULL;
- closed_node_list = NULL;
- search_mode_s2 = searchMode;
- group_id_s2 = groupId;
- mobile_type_s2 = mobileType;
-
- //------------------------------------------------------------------------------//
- // extract informaton from the parameter "miscNo"
- //------------------------------------------------------------------------------//
- target_recno_s2 = building_id_s2 = 0;
- building_x1_s2 = building_y1_s2 = building_x2_s2 = building_y2_s2 = -1;
- err_when(search_mode_s2==SEARCH_MODE_TO_VEHICLE);
-
- if(search_mode_s2==SEARCH_MODE_TO_ATTACK)
- target_recno_s2 = miscNo;
- else
- {
- building_id_s2 = miscNo;
- building_x1_s2 = dx; // upper left corner location
- building_y1_s2 = dy;
- //------- calculate the lower right corner location -------//
- if(search_mode_s2==SEARCH_MODE_TO_FIRM)
- {
- searchFirmInfo_s2 = firm_res[building_id_s2];
- building_x2_s2 = dx+searchFirmInfo_s2->loc_width-1;
- building_y2_s2 = dy+searchFirmInfo_s2->loc_height-1;
- }
- else if(search_mode_s2==SEARCH_MODE_TO_TOWN)
- {
- if(miscNo != -1)
- {
- Location* buildPtr = world.get_loc(dx, dy);
- Town* targetTown = town_array[buildPtr->town_recno()];
- building_x2_s2 = targetTown->loc_x2;
- building_y2_s2 = targetTown->loc_y2;
- }
- else // searching to settle. Detail explained in function set_move_to_surround()
- {
- building_x2_s2 = building_x1_s2+STD_TOWN_LOC_WIDTH-1;
- building_y2_s2 = building_y1_s2+STD_TOWN_LOC_HEIGHT-1;
- }
- }
- }
- //------------------------------------------------------------------------------//
- // set start location and destination location
- //------------------------------------------------------------------------------//
- real_sour_x = sx;
- real_sour_y = sy;
- //---------- adjust destination for some kind of searching ------------//
- if(search_mode_s2==SEARCH_MODE_TO_FIRM || search_mode_s2==SEARCH_MODE_TO_TOWN)
- {
- final_dx = (building_x1_s2+building_x2_s2)/2; // the destination is set to be the middle of the building
- final_dy = (building_y1_s2+building_y2_s2)/2;
- }
- else
- {
- //---------- no adjustment --------//
- final_dx = real_dest_x = dx;
- final_dy = real_dest_y = dy;
- }
- //------------------------------------------------------------------------------//
- // check whether applying shift-map-method
- //------------------------------------------------------------------------------//
- if(final_dx%2) // perform x-shift
- {
- use_shift_map_method_s2 = 1;
- shift_map_x_offset_s2 = -1;
- vir_start_x_s2 = sx+1;
- final_dest_x_s2 = final_dx+1;
- }
- else
- {
- use_shift_map_method_s2 = 0;
- shift_map_x_offset_s2 = 0;
- vir_start_x_s2 = sx;
- final_dest_x_s2 = final_dx;
- }
- if(final_dy%2) // perform y-shift
- {
- use_shift_map_method_s2 = 1;
- shift_map_y_offset_s2 = -1;
- vir_start_y_s2 = sy+1;
- final_dest_y_s2 = final_dy+1;
- }
- else
- {
- //use_shift_map_method_s2 = 0; // have been set to zero in the previous check
- shift_map_y_offset_s2 = 0;
- vir_start_y_s2 = sy;
- final_dest_y_s2 = final_dy;
- }
- //--------------------------------------------------------------//
- // change to 2x2 node format
- //--------------------------------------------------------------//
- border_x1 = short(borderX1/2); // change to 2x2 node format
- border_y1 = short(borderY1/2);
- border_x2 = short(borderX2/2);
- border_y2 = short(borderY2/2);
- if(shift_map_x_offset_s2!=0) // adjust if shift-map is used
- border_x2++;
- if(shift_map_y_offset_s2!=0)
- border_y2++;
- //-------------- initialize the array -----------------//
- memset(source_blocked_exit_direction, 0, sizeof(char)*8);
- //----- determine the blocked exit direction in starting point----------//
- // there are four cases the real source located in the 2x2 node
- //
- // -- -- the number in the 2x2 node representing where the
- // | 1| 2| upper_left location of the unit is
- // -- --
- // | 3| 4|
- // -- --
- if(vir_start_y_s2%2 != 1)
- {
- if(vir_start_x_s2%2 != 1) // case 1
- source_locate_type = 1;
- else // case 2
- {
- source_locate_type = 2;
- if(!can_move_to(vir_start_x_s2-1, vir_start_y_s2+1) && !can_move_to(vir_start_x_s2, vir_start_y_s2-1))
- source_blocked_exit_direction[7] = 1; // direction 8
- if(!can_move_to(vir_start_x_s2-1, vir_start_y_s2) && !can_move_to(vir_start_x_s2, vir_start_y_s2+2))
- source_blocked_exit_direction[1] = 1; // direction 2
- // other cases will not be checked as these cases do not crack the search
- }
- }
- else
- {
- if(vir_start_x_s2%2 != 1) // case 3
- {
- source_locate_type = 3;
- if(!can_move_to(vir_start_x_s2, vir_start_y_s2-1) && !can_move_to(vir_start_x_s2+2, vir_start_y_s2))
- source_blocked_exit_direction[5] = 1; // direction 6
- if(!can_move_to(vir_start_x_s2-1, vir_start_y_s2) && !can_move_to(vir_start_x_s2+1, vir_start_y_s2-1))
- source_blocked_exit_direction[7] = 1; // direction 8
- // other cases will not be checked as these cases do not crack the search
- }
- else // case 4
- {
- source_locate_type = 4;
- if(!can_move_to(vir_start_x_s2, vir_start_y_s2-1) || !can_move_to(vir_start_x_s2-1, vir_start_y_s2))
- source_blocked_exit_direction[7] = 1; // direction 8
- if(!can_move_to(vir_start_x_s2-1, vir_start_y_s2+1) && !can_move_to(vir_start_x_s2, vir_start_y_s2-1))
- source_blocked_exit_direction[0] = 1; // direction 1
- if(!can_move_to(vir_start_x_s2-1, vir_start_y_s2) && !can_move_to(vir_start_x_s2+1, vir_start_y_s2-1))
- source_blocked_exit_direction[6] = 1; // direction 7
- // other cases will not be checked as these cases do not crack the search
- }
- }
- source_x_s2 = short(vir_start_x_s2/2); // the upper left corner is used
- source_y_s2 = short(vir_start_y_s2/2);
- err_when(final_dest_x_s2%2 || final_dest_y_s2%2);
- dest_x = short(final_dest_x_s2/2);
- dest_y = short(final_dest_y_s2/2);
- if(search_mode_s2!=SEARCH_MODE_REUSE)
- {
- max_node_num_s2 = 0xFFFF;
- memset(node_matrix, 0, sizeof(short)*((MAX_WORLD_X_LOC/2+1)*(MAX_WORLD_Y_LOC/2+1)));
- }
- else
- {
- max_node_num_s2 = max_node;
- memcpy(node_matrix, reuse_node_matrix_ptr_s2, sizeof(short)*((MAX_WORLD_X_LOC/2+1)*(MAX_WORLD_Y_LOC/2+1)));
- }
-
- //--------- create the first node --------//
- node_count = 0;
- result_node_ptr = NULL;
- NodeS2 *nodePtr = node_array + node_count++;
- memset(nodePtr, 0, sizeof(NodeS2));
- //-------- store the upper left coordinate of the node ----------//
- upper_left_x = source_x_s2<<1;
- upper_left_y = source_y_s2<<1;
- //---------- calculate the node type -----------//
- switch(source_locate_type)
- {
- case 1: nodePtr->node_type = 15;
- break;
- case 2: nodePtr->node_type = 10+can_move_to(vir_start_x_s2-1,vir_start_y_s2)+
- can_move_to(vir_start_x_s2-1,vir_start_y_s2+1)*4;
- break;
- case 3: nodePtr->node_type = 12+can_move_to(vir_start_x_s2,vir_start_y_s2-1)+
- can_move_to(vir_start_x_s2+1,vir_start_y_s2-1)*2;
- break;
- case 4: nodePtr->node_type = 8+can_move_to(vir_start_x_s2-1,vir_start_y_s2-1)+
- can_move_to(vir_start_x_s2,vir_start_y_s2-1)*2+
- can_move_to(vir_start_x_s2-1,vir_start_y_s2)*4;
- break;
- default: err_here();
- break;
- }
- err_when(nodePtr->node_type>15 || nodePtr->node_type <0);
- is_dest_blocked = !can_move_to_s2(final_dest_x_s2, final_dest_y_s2);
- // whether the destination is blocked, if so, only search till the destination's neighbor locations
- nodePtr->node_g = 0;
- nodePtr->node_h = (source_x_s2-dest_x)*(source_x_s2-dest_x)+(source_y_s2-dest_y)*(source_y_s2-dest_y); // should really use sqrt().
- nodePtr->node_f = nodePtr->node_g + nodePtr->node_h;
- nodePtr->node_x = source_x_s2;
- nodePtr->node_y = source_y_s2;
- nodePtr->enter_direction = 0;
- open_node_list=nodePtr; // make Open List point to first node
- //--- if the destination is the current postion or next to it & the dest is occupied ---//
- if(source_x_s2==dest_x && source_y_s2==dest_y)
- {
- path_status = PATH_FOUND;
- result_node_ptr = nodePtr;
- return path_status;
- }
- //------------ seek now ------------------//
- if( !maxTries )
- maxTries = max_node;
- return continue_seek( maxTries, 1); // 1-first seek session of the current seek order
- }
- //-------- End of function SeekPathS2::seek ---------//
- //---- Begin of function SeekPathS2::continue_seek ---------//
- //
- // If the last seek operation does not find the whole path,
- // continue the search.
- //
- // <int> maxTries - maximum path seeking tries
- // [char] firstSeek - whether it's the first seek session of the seek order.
- // (default: 0)
- //
- // return : <int> seekStatus - PATH_FOUND, PATH_SEEKING, PATH_NODE_USED_UP,
- // or PATH_IMPOSSIBLE
- //
- // You can call get_result() to retrieve the result.
- //
- int SeekPathS2::continue_seek(int maxTries, char firstSeek)
- {
- if( path_status != PATH_SEEKING )
- return path_status;
- //------- aliasing class member vars for fast access ------//
- cur_seek_path_s2 = this;
- cur_dest_x_s2 = dest_x;
- cur_dest_y_s2 = dest_y;
- cur_node_matrix_s2 = node_matrix;
- cur_node_array_s2 = node_array;
- cur_border_x1_s2 = border_x1;
- cur_border_y1_s2 = border_y1;
- cur_border_x2_s2 = border_x2;
- cur_border_y2_s2 = border_y2;
- //------ seek the path using the A star algorithm -----//
- NodeS2 *bestNodePtr;
- int maxNode = max_node-MAX_CHILD_NODE; // generate_successors() can generate a max of MAX_CHILD_NODE new nodes per call
- if(maxTries < maxNode)
- maxNode = maxTries-MAX_CHILD_NODE; // limit the nodes used in shortest path searching
- for(int i=0; i<maxTries ; i++ )
- {
- bestNodePtr = return_best_node();
-
- if(i%20==0)
- sys_yield(); // update cursor position
- //---- even if the path is impossible, get the closest path ----//
- if( !bestNodePtr )
- {
- path_status = PATH_IMPOSSIBLE;
- break;
- }
- //----- exceed the object's max's node limitation, return the closest path ----//
- if( node_count >= maxNode )
- {
- path_status = PATH_NODE_USED_UP;
- break;
- }
- //------------------------------------------//
- // If the path is found OR
- //
- // If the destination is blocked,
- // consider it done when we are next to it.
- //------------------------------------------//
- if((bestNodePtr->node_x==dest_x && bestNodePtr->node_y==dest_y) ||
- (is_dest_blocked && abs(bestNodePtr->node_x-dest_x)<=0 && abs(bestNodePtr->node_y-dest_y)<=0))
- {
- path_status = PATH_FOUND;
- result_node_ptr = bestNodePtr;
- break;
- }
- //--------- generate successors -------//
- if(bestNodePtr->generate_successors(bestNodePtr->enter_direction))
- {
- path_status = PATH_REUSE_FOUND;
- result_node_ptr = reuse_result_node_ptr_s2;
- return path_status;
- }
- }
- err_when( cur_stack_pos_s2!=0 ); // it should be zero all the times, all pushes should have been poped
- return path_status;
- }
- //------ End of function SeekPathS2::continue_seek ---------//
- //---- Begin of function SeekPathS2::get_result ---------//
- //
- // Compile the seek result nodes using results processed by
- // seek() and continue_seek() and store the results in
- // an array of ResultNode.
- //
- // <int&> resultNodeCount - a reference var for returning the no. of result nodes.
- //
- // return : <ResultNode*> an array of ResultNode.
- // the caller function is responsible for
- // freeing the memory of the array.
- //
- ResultNode* SeekPathS2::get_result(int& resultNodeCount, short& pathDist)
- {
- resultNodeCount = pathDist = 0;
- short useClosestNode = 0;// indicate whether closest node is return instead of the actual node
- if( !result_node_ptr ) // if PATH_IMPOSSIBLE or PATH_NODE_USED_UP, result_node_ptr is NULL, we need to call get_closest_node() to get the closest node.
- {
- result_node_ptr = return_closest_node();
- useClosestNode = 1;
- if( !result_node_ptr )
- return NULL;
- }
- //--------------------------------------------------//
- // Trace backwards to the starting node, and rationalize
- // nodes (i.e. group nodes of the same direction into
- // single nodes.)
- //--------------------------------------------------//
- NodeS2* nodePtr = result_node_ptr; // the node current being processed
- NodeS2* baseNodePtr = result_node_ptr; // the first end node for connecting the other end node for the path in that direction.
- NodeS2* parentNode = nodePtr->parent_node; // the parent node of nodePtr
- NodeS2* childNodePtr = nodePtr; // it should point to the children node of nodePtr
- //------------------------------------------------------------------------
- // there are only one node, source & destination within the same 2x2 node
- //------------------------------------------------------------------------
- if( !parentNode ) // parentNode==0 when the source location is the desination already
- {
- if( (vir_start_x_s2!=final_dest_x_s2 || vir_start_y_s2!=final_dest_y_s2) &&
- abs(vir_start_x_s2-final_dest_x_s2)<=1 && abs(vir_start_y_s2-final_dest_y_s2)<=1 &&
- can_move_to_s2(vir_start_x_s2,vir_start_y_s2) && // for source
- can_move_to_s2(final_dest_x_s2,final_dest_y_s2)) // for destination
- {
- pathDist = 1;
- ResultNode* resultNodeArray1 = (ResultNode*) mem_add(sizeof(ResultNode)*2);
- ResultNode* resultNodePtr1 = resultNodeArray1;
- resultNodeCount=2;
- resultNodePtr1->node_x = vir_start_x_s2 + shift_map_x_offset_s2;
- resultNodePtr1->node_y = vir_start_y_s2 + shift_map_y_offset_s2;
- resultNodePtr1++;
- resultNodePtr1->node_x = final_dest_x_s2 + shift_map_x_offset_s2;
- resultNodePtr1->node_y = final_dest_y_s2 + shift_map_y_offset_s2;
- #ifdef DEBUG
- debugPtr1 = resultNodeArray1;
- debugPtr2 = resultNodeArray1+1;
- err_when(debugPtr1->node_x==debugPtr2->node_x && debugPtr1->node_y==debugPtr2->node_y);
- #endif
- return resultNodeArray1;
- }
- else
- return NULL;
- }
- resultNodeCount = 1;
- //-----------------------------------
- // count the number of 2x2 node
- //-----------------------------------
- int numOfNode=0;
- NodeS2* curPtr = result_node_ptr;
- while(curPtr != NULL)
- {
- curPtr = curPtr->parent_node;
- numOfNode++;
- }
- sys_yield(); // update cursor position
- //-----------------------------------------
- // otherwise, there are more than one node
- //-----------------------------------------
- ResultNode* maxSizeResultNodeArray; // store all the result node in the reverse order, the turning point will be extracted later
- int nodeAllocated, nodeCount=0;
- int preNodeCount = nodeCount;
- nodeAllocated = numOfNode*2+2;
- maxSizeResultNodeArray = (ResultNode*) mem_add(nodeAllocated*sizeof(ResultNode));
- max_size_result_node_ptr = maxSizeResultNodeArray;
- parent_result_node_ptr = maxSizeResultNodeArray;
- //----------------------------------
- // start from the destination
- //----------------------------------
- memset(max_size_result_node_ptr, 0, sizeof(ResultNode)*nodeAllocated);
- int upper_left_x = nodePtr->node_x<<1;
- int upper_left_y = nodePtr->node_y<<1;
-
- if(!useClosestNode && (search_mode_s2==SEARCH_MODE_TO_ATTACK || can_move_to_s2(final_dest_x_s2, final_dest_y_s2)))
- {
- max_size_result_node_ptr->node_x = final_dest_x_s2;
- max_size_result_node_ptr->node_y = final_dest_y_s2;
- max_size_result_node_ptr++; // note: parent_result_node_ptr don't change here
- nodeCount++;
- //---------------------------------------------------
- // process the end node, may pass through two points
- //---------------------------------------------------
- if(search_mode_s2==SEARCH_MODE_REUSE)
- process_end_node(upper_left_x, upper_left_y, nodePtr->node_type, nodePtr->enter_direction, nodeCount);
- }
- else // closest node is used
- {
- //------------------------------------------------------------------------//
- // may generate duplicated node for the destination if closet node is used.
- //------------------------------------------------------------------------//
- switch(nodePtr->enter_direction)
- {
- case 1: max_size_result_node_ptr->node_x = upper_left_x-1;
- max_size_result_node_ptr->node_y = upper_left_y;
- break;
- case 2: max_size_result_node_ptr->node_x = upper_left_x-1;
- max_size_result_node_ptr->node_y = upper_left_y+1;
- break;
- case 3: max_size_result_node_ptr->node_x = upper_left_x;
- max_size_result_node_ptr->node_y = upper_left_y+1;
- break;
- case 4: max_size_result_node_ptr->node_x = upper_left_x+1;
- max_size_result_node_ptr->node_y = upper_left_y+1;
- break;
- case 5: max_size_result_node_ptr->node_x = upper_left_x+1;
- max_size_result_node_ptr->node_y = upper_left_y;
- break;
- case 6: max_size_result_node_ptr->node_x = upper_left_x+1;
- max_size_result_node_ptr->node_y = upper_left_y-1;
- break;
- case 7: max_size_result_node_ptr->node_x = upper_left_x;
- max_size_result_node_ptr->node_y = upper_left_y-1;
- break;
- case 8: max_size_result_node_ptr->node_x = upper_left_x-1;
- max_size_result_node_ptr->node_y = upper_left_y-1;
- break;
- default: err_here();
- break;
- }
- max_size_result_node_ptr++; // note: parent_result_node_ptr don't change here
- nodeCount++;
- }
- nodePtr = nodePtr->parent_node; // next 2x2 node
- //--------------------------------------------------
- // get the actual path, process from the second node
- //--------------------------------------------------
- int yieldCount = 0;
- while( (parentNode=nodePtr->parent_node) != NULL )
- {
- upper_left_x = nodePtr->node_x<<1;
- upper_left_y = nodePtr->node_y<<1;
- err_when(nodePtr->enter_direction==(childNodePtr->enter_direction+3)%8+1);
- get_real_result_node(nodeCount, nodePtr->enter_direction, (childNodePtr->enter_direction+3)%8+1,
- nodePtr->node_type, upper_left_x, upper_left_y);
- childNodePtr = nodePtr;
- nodePtr = parentNode;
- //err_when(nodeCount+nodePtr->node_g+2 > nodeAllocated);
- yieldCount++;
- if(yieldCount%20==0)
- sys_yield(); // update cursor position
- }
- sys_yield(); // update cursor position
- debug_check_paths2(maxSizeResultNodeArray, nodeCount);
- /*#ifdef DEBUG
- debugPtr1 = maxSizeResultNodeArray;
- debugPtr2 = maxSizeResultNodeArray+1;
- for(debugCount=1; debugCount<nodeCount-1; debugCount++)
- {
- debugVX = debugPtr2->node_x - debugPtr1->node_x;
- debugVY = debugPtr2->node_y - debugPtr1->node_y;
- err_when(debugVX!=0 && debugVY!=0 && abs(debugVX)!=abs(debugVY));
- debugPtr1++;
- debugPtr2++;
- }
- #endif*/
- //----------------------------------------------------
- // process the starting node
- // nodePtr points at the starting node now
- //----------------------------------------------------
- err_when(nodePtr->enter_direction); // it should be zero
- upper_left_x = nodePtr->node_x<<1;
- upper_left_y = nodePtr->node_y<<1;
- //------------------------------------------------------------------------------------------//
- // process the starting node
- //------------------------------------------------------------------------------------------//
- process_start_node(upper_left_x, upper_left_y, nodePtr->node_type, (childNodePtr->enter_direction+3)%8+1, nodeCount);
- max_size_result_node_ptr->node_x = vir_start_x_s2;
- max_size_result_node_ptr->node_y = vir_start_y_s2;
- err_when((abs(max_size_result_node_ptr->node_x-parent_result_node_ptr->node_x)>1) ||
- (abs(max_size_result_node_ptr->node_y-parent_result_node_ptr->node_y)>1));
- nodeCount++;
- sys_yield(); // update cursor position
- debug_check_paths2(maxSizeResultNodeArray, nodeCount);
- /*#ifdef DEBUG
- debugPtr1 = maxSizeResultNodeArray;
- debugPtr2 = maxSizeResultNodeArray+1;
-
- for(debugCount=1; debugCount<nodeCount; debugCount++)
- {
- debugVX = debugPtr2->node_x - debugPtr1->node_x;
- debugVY = debugPtr2->node_y - debugPtr1->node_y;
-
- err_when(debugVX!=0 && debugVY!=0 && (abs(debugVX)!=abs(debugVY)));
- debugPtr1++;
- debugPtr2++;
- }
- #endif*/
-
- //--------------------------------------------------//
- // smooth the path
- //--------------------------------------------------//
- maxSizeResultNodeArray = smooth_the_path(maxSizeResultNodeArray, nodeCount);
- sys_yield(); // update cursor position
- parent_result_node_ptr = maxSizeResultNodeArray;
- max_size_result_node_ptr = maxSizeResultNodeArray+1;
- ResultNode* result_node_pointer = max_size_result_node_ptr;
- //----------------------------------
- // get the turning point
- //----------------------------------
- short vectorX = max_size_result_node_ptr->node_x - parent_result_node_ptr->node_x;
- short vectorY = max_size_result_node_ptr->node_y - parent_result_node_ptr->node_y;
- short newVectorX, newVectorY;
- for(int i=1; i<nodeCount-1; i++)
- {
- parent_result_node_ptr = max_size_result_node_ptr; // don't use parent_result_node_ptr++, if the above code of removing duplication is used.
- max_size_result_node_ptr++;
- newVectorX=(max_size_result_node_ptr->node_x-parent_result_node_ptr->node_x);
- newVectorY=(max_size_result_node_ptr->node_y-parent_result_node_ptr->node_y);
- err_when(newVectorY!=0 && newVectorX!=0 && abs(newVectorX)!=abs(newVectorY));
- //------ turning to another direction at this point ------//
- if(vectorX!=newVectorX || vectorY!=newVectorY)
- {
- if(newVectorX!=0 || newVectorY!=0)
- {
- result_node_pointer->node_x = parent_result_node_ptr->node_x;
- result_node_pointer->node_y = parent_result_node_ptr->node_y;
- result_node_pointer++;
- resultNodeCount++;
- vectorX = newVectorX;
- vectorY = newVectorY;
- }
- }
-
- if(i%20==0)
- sys_yield(); // update cursor position
- }
- result_node_pointer->node_x = vir_start_x_s2;
- result_node_pointer->node_y = vir_start_y_s2;
- result_node_pointer++;
- resultNodeCount++;
- //------------------------------------------------//
- // After the above process, here we will have a
- // link of rationalize nodes. Retrieve them in the
- // backwards order
- //------------------------------------------------//
- ResultNode *resultNodeArray = (ResultNode*) mem_add( sizeof(ResultNode) * resultNodeCount );
- ResultNode *resultNodePtr = resultNodeArray+resultNodeCount-1;
- int processCount = 1;
-
- ResultNode *preNodePtr = maxSizeResultNodeArray;
- resultNodePtr->node_x = preNodePtr->node_x;
- resultNodePtr->node_y = preNodePtr->node_y;
- resultNodePtr--;
- result_node_pointer = maxSizeResultNodeArray+1;
- err_when(pathDist!=0);
- int xDist, yDist;
- while(processCount++ < resultNodeCount)
- {
- err_when(result_node_pointer->node_x<0 || result_node_pointer->node_x>=MAX_WORLD_X_LOC ||
- result_node_pointer->node_y<0 || result_node_pointer->node_y>=MAX_WORLD_Y_LOC);
- resultNodePtr->node_x = result_node_pointer->node_x;
- resultNodePtr->node_y = result_node_pointer->node_y;
- resultNodePtr--;
-
- xDist = abs(result_node_pointer->node_x-preNodePtr->node_x);
- yDist = abs(result_node_pointer->node_y-preNodePtr->node_y);
- err_when((!xDist && !yDist) || (xDist && yDist && xDist!=yDist));
- pathDist += (xDist) ? xDist : yDist;
- preNodePtr = result_node_pointer;
- result_node_pointer++;
- if(processCount%20==0)
- sys_yield(); // update cursor position
- }
- err_when(nodeAllocated<nodeCount);
- mem_del(maxSizeResultNodeArray);
- //-------- adjust/shift the path if shift-map-method is use --------//
- ResultNode* adjustNode = resultNodeArray;
- if(use_shift_map_method_s2)
- {
- for(int ii=0; ii<resultNodeCount; ii++)
- {
- adjustNode->node_x += shift_map_x_offset_s2;
- adjustNode->node_y += shift_map_y_offset_s2;
- adjustNode++;
- }
- }
- debug_check_paths2(resultNodeArray, resultNodeCount);
- /*#ifdef DEBUG
- debugPtr1 = resultNodeArray;
- debugPtr2 = resultNodeArray+1;
-
- for(debugCount=1; debugCount<resultNodeCount; debugCount++)
- {
- debugVX = debugPtr2->node_x - debugPtr1->node_x;
- debugVY = debugPtr2->node_y - debugPtr1->node_y;
-
- err_when(debugVX!=0 && debugVY!=0 && (abs(debugVX)!=abs(debugVY)));
- debugPtr1++;
- debugPtr2++;
- }
- #endif*/
- //--------------------------------------------------//
- // return NULL if there are only two nodes and these
- // nodes are equal
- //--------------------------------------------------//
- if(resultNodeCount == 2)
- {
- ResultNode *curTestNode1 = resultNodeArray;
- ResultNode *curTestNode2 = resultNodeArray+1;
- if(curTestNode1->node_x==curTestNode2->node_x &&
- curTestNode1->node_y==curTestNode2->node_y)
- {
- mem_del(resultNodeArray);
- resultNodeCount = 0;
- pathDist = 0;
- return NULL;
- }
- }
- #ifdef DEBUG
- if(resultNodeCount==2)
- {
- debugPtr1 = resultNodeArray;
- debugPtr2 = resultNodeArray+1;
- err_when(debugPtr1->node_x==debugPtr2->node_x && debugPtr1->node_y==debugPtr2->node_y);
- }
- #endif
- sys_yield(); // update cursor position
- return resultNodeArray;
- }
- //------ End of function SeekPathS2::get_result ---------//
- //---- Begin of function SeekPathS2::process_end_node ---------//
- void SeekPathS2::process_end_node(int xLoc, int yLoc, char nodeType, char enterDirection, int &nodeCount)
- {
- short usePathSuccess = 0; // if failure, use the last path in the checking
- short destType = 1 + (final_dest_x_s2%2) + 2*(final_dest_y_s2%2);
-
- switch(destType)
- {
- case 1:
- break;
- case 2:
- switch(enterDirection)
- {
- case 1:
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 2:
- err_when(!(nodeType&0x1) && !can_move_to(xLoc+1,yLoc+2));
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc+!(nodeType&0x1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 3: case 4: case 6: case 7:
- break;
- case 5:
- break;
- case 8:
- err_when(!(nodeType&0x4) && !can_move_to(xLoc+1,yLoc-1));
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc-!(nodeType&0x4);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- default: err_here();
- break;
- }
- break;
- case 3:
- switch(enterDirection)
- {
- case 1: case 2: case 4: case 5:
- break;
- case 3:
- break;
- case 6:
- err_when(!(nodeType&0x1) && !can_move_to(xLoc+2,yLoc+1));
- max_size_result_node_ptr->node_x = xLoc+!(nodeType&0x1);
- max_size_result_node_ptr->node_y = yLoc;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 7:
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 8:
- err_when(!(nodeType&0x2) && !can_move_to(xLoc-1,yLoc+1));
- max_size_result_node_ptr->node_x = xLoc-!(nodeType&0x2);
- max_size_result_node_ptr->node_y = yLoc;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- default: err_here();
- break;
- }
- break;
- case 4:
- switch(enterDirection)
- {
- case 1:
- err_when(!(nodeType&0x2) && !can_move_to(xLoc,yLoc+2));
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc+can_move_to(xLoc,yLoc+2);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 2:
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc+1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 3: case 4: case 5:
- break;
- case 6:
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 7:
- err_when(!(nodeType&0x4) && !can_move_to(xLoc+2,yLoc));
- max_size_result_node_ptr->node_x = xLoc+can_move_to(xLoc+2,yLoc);
- max_size_result_node_ptr->node_y = yLoc;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 8:
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- default: err_here();
- break;
- }
- break;
- default: err_here();
- break;
- }
- }
- //------ End of function SeekPathS2::process_end_node ---------//
- //---- Begin of function SeekPathS2::process_start_node ---------//
- void SeekPathS2::process_start_node(int xLoc, int yLoc, char nodeType, char exitDirection, int &nodeCount)
- {
- short usePathSuccess = 0; // if failure, use the last path in the checking
- switch(source_locate_type)
- {
- case 1:
- switch(exitDirection)
- {
- case 1: // 3 possible paths
- if(parent_result_node_ptr->node_y<yLoc && can_move_to(xLoc-1,yLoc-1) &&
- can_move_to(xLoc,yLoc-1))
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc-1;
- usePathSuccess++;
- }
- if(!usePathSuccess && parent_result_node_ptr->node_y>yLoc &&
- can_move_to(xLoc-1,yLoc+2) && can_move_to(xLoc,yLoc+2))
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc+1;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc;
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 2: // 3 possible paths
- if(parent_result_node_ptr->node_x==xLoc && //can_move_to(xLoc+1,yLoc+1) &&
- can_move_to(xLoc+1,yLoc+2))
- {
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc+1;
- usePathSuccess++;
- }
- if(!usePathSuccess && parent_result_node_ptr->node_y==yLoc &&
- can_move_to(xLoc-1,yLoc))
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc+1;
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 3:
- if(parent_result_node_ptr->node_x>xLoc && can_move_to(xLoc+2,yLoc+1) &&
- can_move_to(xLoc+2,yLoc+2))
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc+1;
- usePathSuccess++;
- }
- if(!usePathSuccess && parent_result_node_ptr->node_x<xLoc &&
- can_move_to(xLoc-1,yLoc+1) && can_move_to(xLoc-1,yLoc+2))
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc+1;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc+1;
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 4:
- if(parent_result_node_ptr->node_x==xLoc && //can_move_to(xLoc,yLoc+1) &&
- can_move_to(xLoc,yLoc+2))
- {
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc+1;
- usePathSuccess++;
- }
- if(!usePathSuccess && parent_result_node_ptr->node_y==yLoc && //can_move_to(xLoc+1,yLoc) &&
- can_move_to(xLoc+2,yLoc))
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc+1;
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 5:
- if(parent_result_node_ptr->node_y<yLoc && can_move_to(xLoc+1,yLoc-1) &&
- can_move_to(xLoc+2,yLoc-1))
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc-1;
- usePathSuccess++;
- }
- if(!usePathSuccess && parent_result_node_ptr->node_y>yLoc &&
- can_move_to(xLoc+1,yLoc+2) && can_move_to(xLoc+2,yLoc+2))
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc+1;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc;
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 6:
- if(parent_result_node_ptr->node_y==yLoc && //can_move_to(xLoc+1,yLoc+1) &&
- can_move_to(xLoc+2,yLoc+1))
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc;
- usePathSuccess++;
- }
- if(!usePathSuccess && parent_result_node_ptr->node_x==xLoc && can_move_to(xLoc,yLoc-1))
- {
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc-1;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc-1;
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 7:
- if(parent_result_node_ptr->node_x>xLoc && can_move_to(xLoc+2,yLoc-1) &&
- can_move_to(xLoc+2,yLoc))
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc-1;
- usePathSuccess++;
- }
- if(!usePathSuccess && parent_result_node_ptr->node_x<xLoc &&
- can_move_to(xLoc-1,yLoc-1) && can_move_to(xLoc-1,yLoc))
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc-1;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc-1;
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 8:
- if(parent_result_node_ptr->node_x==xLoc && can_move_to(xLoc+1,yLoc-1))
- {
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc-1;
- usePathSuccess++;
- }
- if(!usePathSuccess && parent_result_node_ptr->node_y==yLoc && can_move_to(xLoc-1,yLoc+1))
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc-1;
- }
-
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- default: err_here();
- break;
- }
- break;
- case 2:
- switch(exitDirection)
- {
- case 1:
- if(parent_result_node_ptr->node_y<yLoc && can_move_to(xLoc-1,yLoc-1) &&
- can_move_to(xLoc,yLoc-1) && can_move_to(xLoc+1,yLoc-1))
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc-1;
- usePathSuccess++;
- }
- if(!usePathSuccess && parent_result_node_ptr->node_y>yLoc && can_move_to(xLoc-1,yLoc+2) &&
- can_move_to(xLoc,yLoc+2) && can_move_to(xLoc+1,yLoc+2))
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc+1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc+1;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc;
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 2:
- if(parent_result_node_ptr->node_y==yLoc+1 && can_move_to(xLoc+1,yLoc+2))
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc+1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc+1;
- usePathSuccess++;
- }
-
- if(!usePathSuccess && can_move_to(xLoc+1,yLoc+2) &&
- ( (vir_start_x_s2-parent_result_node_ptr->node_x==parent_result_node_ptr->node_y-vir_start_y_s2) ||
- (parent_result_node_ptr->node_x==xLoc) ) )
- {
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc+1;
- usePathSuccess++;
- }
-
- if(!usePathSuccess && parent_result_node_ptr->node_y==yLoc &&
- can_move_to(xLoc-1,yLoc) && can_move_to(xLoc,yLoc))
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc+1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- err_when(!(nodeType&0x1) && !can_move_to(xLoc+1,yLoc+2));
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc+(!(nodeType&0x1));
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 3:
- if(parent_result_node_ptr->node_x>xLoc && //can_move_to(xLoc+2,yLoc+1) &&
- can_move_to(xLoc+2,yLoc+2))
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc+1;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc+1;
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 4:
- if(parent_result_node_ptr->node_x==xLoc && can_move_to(xLoc,yLoc+1) &&
- can_move_to(xLoc,yLoc+2))
- {
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc+1;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- if(abs(parent_result_node_ptr->node_x-vir_start_x_s2)>1 ||
- abs(parent_result_node_ptr->node_y-vir_start_y_s2)>1)
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc+1;
- }
- else
- break;
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 5:
- break;
- case 6:
- if(parent_result_node_ptr->node_x==xLoc && can_move_to(xLoc,yLoc-1) &&
- can_move_to(xLoc,yLoc))
- {
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc-1;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- if(abs(parent_result_node_ptr->node_x-vir_start_x_s2)>1 ||
- abs(parent_result_node_ptr->node_y-vir_start_y_s2)>1)
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc-1;
- }
- else
- break;
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 7:
- if(parent_result_node_ptr->node_x>xLoc && can_move_to(xLoc+2,yLoc-1) &&
- can_move_to(xLoc+2,yLoc))
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc-1;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc-1;
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 8:
- if(parent_result_node_ptr->node_y==yLoc-1 && can_move_to(xLoc+1,yLoc-1))
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc-1;
- usePathSuccess++;
- }
-
- if(!usePathSuccess && can_move_to(xLoc+1,yLoc-1) &&
- ( (vir_start_x_s2-parent_result_node_ptr->node_x==vir_start_y_s2-parent_result_node_ptr->node_y) ||
- (parent_result_node_ptr->node_x==xLoc) ) )
- {
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc-1;
- usePathSuccess++;
- }
-
- if(!usePathSuccess && parent_result_node_ptr->node_y==yLoc &&
- can_move_to(xLoc-1,yLoc+1) && can_move_to(xLoc,yLoc+1))
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- err_when(!(nodeType&0x4) && !can_move_to(xLoc+1,yLoc-1));
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc-(!(nodeType&0x4));
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- default: err_here();
- break;
- }
- break;
- case 3:
- switch(exitDirection)
- {
- case 1:
- if(parent_result_node_ptr->node_y>yLoc && can_move_to(xLoc-1,yLoc+2))
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc+1;
- usePathSuccess++;
- }
-
- if(!usePathSuccess)
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc;
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 2:
- if(abs(parent_result_node_ptr->node_x-vir_start_x_s2)>1 ||
- abs(parent_result_node_ptr->node_y-vir_start_y_s2)>1)
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc+1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- }
- break;
- case 3:
- break;
- case 4:
- if(abs(parent_result_node_ptr->node_x-vir_start_x_s2)>1 ||
- abs(parent_result_node_ptr->node_y-vir_start_y_s2)>1)
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc+1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- }
- break;
- case 5:
- if(parent_result_node_ptr->node_y>yLoc && can_move_to(xLoc+2,yLoc+2))
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc+1;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc;
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 6:
- if(parent_result_node_ptr->node_y==yLoc && can_move_to(xLoc+2,yLoc+1))
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc;
- usePathSuccess++;
- }
- if(!usePathSuccess && parent_result_node_ptr->node_x==xLoc &&
- can_move_to(xLoc,yLoc-1) && can_move_to(xLoc,yLoc))
- {
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- err_when(!(nodeType&0x1) && !can_move_to(xLoc+2, yLoc+1));
- max_size_result_node_ptr->node_x = xLoc+!(nodeType&0x1);
- max_size_result_node_ptr->node_y = yLoc;
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 7:
- if(parent_result_node_ptr->node_x>xLoc && can_move_to(xLoc+2,yLoc-1) &&
- can_move_to(xLoc+2,yLoc))
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc;
- usePathSuccess++;
- }
- if(!usePathSuccess && parent_result_node_ptr->node_x<xLoc &&
- can_move_to(xLoc-1,yLoc-1) && can_move_to(xLoc-1,yLoc))
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc;
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 8:
- if(can_move_to(xLoc-1,yLoc+1) &&
- ( (vir_start_x_s2-parent_result_node_ptr->node_x==vir_start_y_s2-parent_result_node_ptr->node_y)||
- (parent_result_node_ptr->node_y==yLoc) ) )
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc;
- usePathSuccess++;
- }
- if(!usePathSuccess && parent_result_node_ptr->node_x==xLoc &&
- can_move_to(xLoc+1,yLoc-1) && can_move_to(xLoc+1,yLoc))
- {
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
-
- err_when(!(nodeType&0x2) && !can_move_to(xLoc-1, yLoc+1));
- max_size_result_node_ptr->node_x = xLoc-!(nodeType&0x2);
- max_size_result_node_ptr->node_y = yLoc;
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- default: err_here();
- break;
- }
- break;
- case 4:
- switch(exitDirection)
- {
- case 1:
- if(parent_result_node_ptr->node_y>yLoc && can_move_to(xLoc-1,yLoc+2) &&
- can_move_to(xLoc,yLoc+2))
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc+1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc+1;
- usePathSuccess++;
- }
- if(!usePathSuccess && can_move_to(xLoc,yLoc+2) && parent_result_node_ptr->node_y==yLoc-1)
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc+1;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- err_when(!(nodeType&0x2) && !can_move_to(xLoc, yLoc+2));
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc+!(nodeType&0x2);
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 2:
- if(vir_start_x_s2-parent_result_node_ptr->node_x==parent_result_node_ptr->node_y+1-vir_start_y_s2)
- {
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc+1;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- if(abs(parent_result_node_ptr->node_x-vir_start_x_s2)>1 ||
- abs(parent_result_node_ptr->node_y-vir_start_y_s2)>1)
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc+1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc+1;
- }
- else
- break;
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 3:
- if(abs(parent_result_node_ptr->node_x-vir_start_x_s2)>1 ||
- abs(parent_result_node_ptr->node_y-vir_start_y_s2)>1)
- {
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc+1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- }
- break;
- case 4:
- break;
- case 5:
- if(abs(parent_result_node_ptr->node_x-vir_start_x_s2)>1 ||
- abs(parent_result_node_ptr->node_y-vir_start_y_s2)>1)
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- }
- break;
- case 6:
- if(parent_result_node_ptr->node_x+1-vir_start_x_s2==vir_start_y_s2-parent_result_node_ptr->node_y)
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- if(abs(parent_result_node_ptr->node_x-vir_start_x_s2)>1 ||
- abs(parent_result_node_ptr->node_y-vir_start_y_s2)>1)
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc;
- }
- else
- break;
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 7:
- if(parent_result_node_ptr->node_x>xLoc && can_move_to(xLoc+2,yLoc-1) &&
- can_move_to(xLoc+2,yLoc))
- {
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc;
- usePathSuccess++;
- }
- if(!usePathSuccess && parent_result_node_ptr->node_x<xLoc &&
- can_move_to(xLoc+2,yLoc))
- {
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- max_size_result_node_ptr->node_x = xLoc+1;
- max_size_result_node_ptr->node_y = yLoc;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- err_when(!(nodeType&0x4) && !can_move_to(xLoc+2, yLoc));
- max_size_result_node_ptr->node_x = xLoc+!(nodeType&0x4);
- max_size_result_node_ptr->node_y = yLoc;
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- case 8:
- if(parent_result_node_ptr->node_x==xLoc && can_move_to(xLoc+1,yLoc-1))
- {
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc-1;
- usePathSuccess++;
- }
- if(!usePathSuccess && parent_result_node_ptr->node_y==yLoc && can_move_to(xLoc-1,yLoc+1))
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc;
- usePathSuccess++;
- }
- if(!usePathSuccess)
- {
- max_size_result_node_ptr->node_x = xLoc-1;
- max_size_result_node_ptr->node_y = yLoc-1;
- }
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- err_when(!can_move_to(xLoc+1, yLoc) || !can_move_to(xLoc, yLoc+1));
- max_size_result_node_ptr->node_x = xLoc;
- max_size_result_node_ptr->node_y = yLoc;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, nodeCount);
- break;
- default: err_here();
- break;
- }
- break;
- default: err_here();
- break;
- }
- }
- //------ End of function SeekPathS2::process_start_node ---------//
- //---- Begin of function SeekPathS2::get_real_result_node ---------//
- //
- // called by get_result to extract the point in a 2x2 node that is
- // used in the shortest path
- //
- // <int&> count - a reference var for counting number of node in
- // max_size_result_node_ptr
- //
- void SeekPathS2::get_real_result_node(int &count, short enterDirection, short exitDirection,
- short nodeType, short xCoord, short yCoord)
- {
- prefer_upper_s2 = prefer_lower_s2 = prefer_left_s2 = prefer_right_s2 = 0;
- switch(enterDirection)
- {
- case 0: err_here();
- break;
-
- case 1:
- switch(exitDirection)
- {
- case 2: // 2 possible paths
- if(parent_result_node_ptr->node_x<xCoord)
- prefer_left_s2 = 1;
- else
- {
- if(!can_move_to(xCoord+1,yCoord+1) || !can_move_to(xCoord+1,yCoord+2))
- prefer_left_s2 = 1;
- else
- prefer_right_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord-prefer_left_s2;
- max_size_result_node_ptr->node_y = yCoord+1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 3: // 2 possible paths
- if(parent_result_node_ptr->node_x>=xCoord)
- prefer_right_s2 = 1;
- else
- {
- if(can_move_to(xCoord-1,yCoord+2))
- prefer_left_s2 = 1;
- else
- prefer_right_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord-prefer_left_s2;
- max_size_result_node_ptr->node_y = yCoord+1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 4: // 2 points, 2 paths
- max_size_result_node_ptr->node_x = xCoord+1;
- max_size_result_node_ptr->node_y = yCoord+1;
- //----------- process path selection ---------------//
- if( (parent_result_node_ptr->node_x-max_size_result_node_ptr->node_x==0) ||
- (parent_result_node_ptr->node_y-max_size_result_node_ptr->node_y==0) )
- prefer_lower_s2 = 1;
- else
- prefer_upper_s2 = 1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- err_when(!(nodeType&0x2) && !can_move_to(xCoord, yCoord+2));
-
- max_size_result_node_ptr->node_x = xCoord;
- if(prefer_upper_s2)
- max_size_result_node_ptr->node_y = yCoord + !(nodeType&0x2);
- else // prefer_lower_s2
- max_size_result_node_ptr->node_y = yCoord + can_move_to(xCoord, yCoord+2);
- err_when(max_size_result_node_ptr->node_y!=yCoord && max_size_result_node_ptr->node_y!=yCoord+1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 5: // 2 points, 2 paths
- //----------- process path selection ---------------//
- if(parent_result_node_ptr->node_y<=yCoord)
- prefer_upper_s2 = 1;
- else
- {
- if(!can_move_to(xCoord,yCoord+2) || !can_move_to(xCoord+1,yCoord+2) ||
- !can_move_to(xCoord+2,yCoord+2))
- prefer_upper_s2 = 1;
- else
- prefer_lower_s2 = 1;
- }
-
- max_size_result_node_ptr->node_x = xCoord+1;
- max_size_result_node_ptr->node_y = yCoord+prefer_lower_s2;
- err_when(max_size_result_node_ptr->node_y!=yCoord && max_size_result_node_ptr->node_y!=yCoord+1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- max_size_result_node_ptr->node_x = xCoord;
- max_size_result_node_ptr->node_y = yCoord+prefer_lower_s2;
- err_when(max_size_result_node_ptr->node_y!=yCoord && max_size_result_node_ptr->node_y!=yCoord+1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 6: // 2 points, 2 paths
- max_size_result_node_ptr->node_x = xCoord+1;
- max_size_result_node_ptr->node_y = yCoord-1;
- //----------- process path selection ---------------//
- if( (parent_result_node_ptr->node_x-max_size_result_node_ptr->node_x==0) ||
- (parent_result_node_ptr->node_y-max_size_result_node_ptr->node_y==0) )
- prefer_upper_s2 = 1;
- else
- prefer_lower_s2 = 1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
-
- err_when(!(nodeType&0x8) && !can_move_to(xCoord, yCoord-1));
- max_size_result_node_ptr->node_x = xCoord;
- if(prefer_upper_s2)
- max_size_result_node_ptr->node_y = yCoord-can_move_to(xCoord, yCoord-1);
- else // prefer_lower_s2
- max_size_result_node_ptr->node_y = yCoord-!(nodeType&0x8);
- err_when(max_size_result_node_ptr->node_y!=yCoord && max_size_result_node_ptr->node_y!=yCoord-1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 7: // 2 possible paths
- if(parent_result_node_ptr->node_x>=xCoord)
- prefer_right_s2 = 1;
- else
- {
- if(can_move_to(xCoord-1,yCoord-1))
- prefer_left_s2 = 1;
- else
- prefer_right_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord-prefer_left_s2;
- max_size_result_node_ptr->node_y = yCoord-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 8: // 2 possible paths
- if(parent_result_node_ptr->node_x<xCoord)
- prefer_left_s2 = 1;
- else
- {
- if(!can_move_to(xCoord+1,yCoord-1) || !can_move_to(xCoord+1,yCoord))
- prefer_left_s2 = 1;
- else
- prefer_right_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord-prefer_left_s2;
- max_size_result_node_ptr->node_y = yCoord-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- default: err_here();
- break;
- }
- break;
- case 2:
- switch(exitDirection)
- {
- case 1:
- max_size_result_node_ptr->node_x = xCoord-1;
- max_size_result_node_ptr->node_y = yCoord;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 3:
- max_size_result_node_ptr->node_x = xCoord;
- max_size_result_node_ptr->node_y = yCoord+1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 4: // 2 points, 2 possible paths
- if(parent_result_node_ptr->node_y<=yCoord+1)
- prefer_upper_s2 = 1;
- else
- {
- if(!can_move_to(xCoord, yCoord+3) || !can_move_to(xCoord+1, yCoord+3) ||
- !can_move_to(xCoord+2, yCoord+3))
- prefer_upper_s2 = 1;
- else
- prefer_lower_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord+1;
- max_size_result_node_ptr->node_y = yCoord+1+prefer_lower_s2;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- max_size_result_node_ptr->node_x = xCoord;
- max_size_result_node_ptr->node_y = yCoord+1+prefer_lower_s2;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 5: // 2 points, 2 paths
- if(parent_result_node_ptr->node_y<=yCoord)
- prefer_upper_s2 = 1;
- else
- {
- if(!can_move_to(xCoord+2,yCoord+2) || !can_move_to(xCoord+1,yCoord+2))
- prefer_upper_s2 = 1;
- else
- prefer_lower_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord+1;
- max_size_result_node_ptr->node_y = yCoord+prefer_lower_s2;
- err_when(max_size_result_node_ptr->node_y!=yCoord && max_size_result_node_ptr->node_y!=yCoord+1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- err_when(!(nodeType&0x1) && !can_move_to(xCoord+1, yCoord+2));
- max_size_result_node_ptr->node_x = xCoord;
- max_size_result_node_ptr->node_y = yCoord+(prefer_lower_s2 || !(nodeType&0x1));
- err_when(max_size_result_node_ptr->node_y!=yCoord && max_size_result_node_ptr->node_y!=yCoord+1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 6: // 2 points
- max_size_result_node_ptr->node_x = xCoord+1;
- max_size_result_node_ptr->node_y = yCoord-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- err_when(nodeType != 15);
- max_size_result_node_ptr->node_x = xCoord;
- max_size_result_node_ptr->node_y = yCoord;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 7: // 2 points, 2 paths
- max_size_result_node_ptr->node_x = xCoord;
- max_size_result_node_ptr->node_y = yCoord-1;
- //----------- process path selection ---------------//
- if( (parent_result_node_ptr->node_x-max_size_result_node_ptr->node_x==0) ||
- (parent_result_node_ptr->node_y-max_size_result_node_ptr->node_y==0) )
- prefer_right_s2 = 1;
- else
- prefer_left_s2 = 1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- err_when(!can_move_to(xCoord-1,yCoord) && !(nodeType&0x8));
- max_size_result_node_ptr->node_y = yCoord;
- if(prefer_left_s2)
- max_size_result_node_ptr->node_x = xCoord-can_move_to(xCoord-1,yCoord);
- else
- max_size_result_node_ptr->node_x = xCoord-!(nodeType&0x8);
-
- err_when(max_size_result_node_ptr->node_x!=xCoord && max_size_result_node_ptr->node_x!=xCoord-1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 8: // 2 points, 2 possible paths
- if(parent_result_node_ptr->node_x>=xCoord-1)
- prefer_right_s2 = 1;
- else
- {
- if(!can_move_to(xCoord-2,yCoord-1) || !can_move_to(xCoord-2,yCoord) ||
- !can_move_to(xCoord-2,yCoord+1)) // must check for all 3 points to avoid problems in dummy node generated in path-reuse
- prefer_right_s2 = 1;
- else
- prefer_left_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord-1-prefer_left_s2;
- max_size_result_node_ptr->node_y = yCoord-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- max_size_result_node_ptr->node_x = xCoord-1-prefer_left_s2;
- max_size_result_node_ptr->node_y = yCoord;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- default: err_here();
- break;
- }
- break;
-
- case 3: switch(exitDirection)
- {
- case 1: // 2 possible paths
- if(parent_result_node_ptr->node_y<=yCoord)
- prefer_upper_s2 = 1;
- else
- {
- if(can_move_to(xCoord-1,yCoord+2))
- prefer_lower_s2 = 1;
- else
- prefer_upper_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord-1;
- max_size_result_node_ptr->node_y = yCoord+prefer_lower_s2;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 2: // 2 possible paths
- if(parent_result_node_ptr->node_y>yCoord)
- prefer_lower_s2 = 1;
- else
- {
- if(!can_move_to(xCoord, yCoord) || !can_move_to(xCoord-1,yCoord))
- prefer_lower_s2 = 1;
- else
- prefer_upper_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord-1;
- max_size_result_node_ptr->node_y = yCoord+prefer_lower_s2;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 4: // 2 possible paths
- if(parent_result_node_ptr->node_y>yCoord)
- prefer_lower_s2 = 1;
- else
- {
- if(!can_move_to(xCoord+1,yCoord) || !can_move_to(xCoord+2,yCoord))
- prefer_lower_s2 = 1;
- else
- prefer_upper_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord+1;
- max_size_result_node_ptr->node_y = yCoord+prefer_lower_s2;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 5: // 2 possible paths
- if(parent_result_node_ptr->node_y<=yCoord)
- prefer_upper_s2 = 1;
- else
- {
- if(can_move_to(xCoord+2,yCoord+2))
- prefer_lower_s2 = 1;
- else
- prefer_upper_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord+1;
- max_size_result_node_ptr->node_y = yCoord+prefer_lower_s2;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 6: // 2 points. 2 paths
- max_size_result_node_ptr->node_x = xCoord+1;
- max_size_result_node_ptr->node_y = yCoord-1;
- //----------- process path selection ---------------//
- if( (parent_result_node_ptr->node_x-max_size_result_node_ptr->node_x==0) ||
- (parent_result_node_ptr->node_y-max_size_result_node_ptr->node_y==0) )
- prefer_right_s2 = 1;
- else
- prefer_left_s2 = 1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- err_when(!(nodeType&0x1) && !can_move_to(xCoord+2, yCoord+1));
- max_size_result_node_ptr->node_y = yCoord;
- if(prefer_left_s2)
- max_size_result_node_ptr->node_x = xCoord + !(nodeType&0x1);
- else // prefer_right_s2
- max_size_result_node_ptr->node_x = xCoord + can_move_to(xCoord+2, yCoord+1);
- err_when(max_size_result_node_ptr->node_x!=xCoord && max_size_result_node_ptr->node_x!=xCoord+1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 7: // 2 points, 2 paths
- max_size_result_node_ptr->node_y = yCoord-1;
- //----------- process path selection ---------------//
- if(parent_result_node_ptr->node_x<=xCoord)
- prefer_left_s2 = 1;
- else
- {
- if(!can_move_to(xCoord+2,yCoord-1) || !can_move_to(xCoord+2,yCoord) ||
- !can_move_to(xCoord+2,yCoord+1))
- prefer_left_s2 = 1;
- else
- prefer_right_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord+prefer_right_s2;
- err_when(max_size_result_node_ptr->node_x!=xCoord && max_size_result_node_ptr->node_x!=xCoord+1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- max_size_result_node_ptr->node_x = xCoord+prefer_right_s2;
- max_size_result_node_ptr->node_y = yCoord;
- err_when(max_size_result_node_ptr->node_x!=xCoord && max_size_result_node_ptr->node_x!=xCoord+1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 8: // 2 points, 2 paths
- max_size_result_node_ptr->node_x = xCoord-1;
- max_size_result_node_ptr->node_y = yCoord-1;
- //----------- process path selection ---------------//
- if( (parent_result_node_ptr->node_x-max_size_result_node_ptr->node_x==0) ||
- (parent_result_node_ptr->node_y-max_size_result_node_ptr->node_y==0) )
- prefer_left_s2 = 1;
- else
- prefer_right_s2 = 1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- err_when(!(nodeType&0x2) && !can_move_to(xCoord-1, yCoord+1));
- max_size_result_node_ptr->node_y = yCoord;
- if(prefer_left_s2)
- max_size_result_node_ptr->node_x = xCoord - can_move_to(xCoord-1, yCoord+1);
- else // prefer_right_s2
- max_size_result_node_ptr->node_x = xCoord - !(nodeType&0x2);
-
- err_when(max_size_result_node_ptr->node_x!=xCoord && max_size_result_node_ptr->node_x!=xCoord-1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- default: err_here();
- break;
- }
- break;
- case 4: switch(exitDirection)
- {
- case 1: // 2 points, 2 paths
- max_size_result_node_ptr->node_x = xCoord-1;
- //----------- process path selection ---------------//
- if(parent_result_node_ptr->node_y<=yCoord)
- prefer_upper_s2 = 1;
- else
- {
- if(!can_move_to(xCoord-1,yCoord+2) || !can_move_to(xCoord,yCoord+2))
- prefer_upper_s2 = 1;
- else
- prefer_lower_s2 = 1;
- }
- max_size_result_node_ptr->node_y = yCoord+prefer_lower_s2;
- err_when(max_size_result_node_ptr->node_y!=yCoord && max_size_result_node_ptr->node_y!=yCoord+1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- err_when(!(nodeType&0x2) && !can_move_to(xCoord, yCoord+2));
- max_size_result_node_ptr->node_x = xCoord;
- max_size_result_node_ptr->node_y = yCoord+(prefer_lower_s2 || !(nodeType&0x2));
- err_when(max_size_result_node_ptr->node_y!=yCoord && max_size_result_node_ptr->node_y!=yCoord+1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 2: // 2 points, 2 possible paths
- if(parent_result_node_ptr->node_y<=yCoord+1)
- prefer_upper_s2 = 1;
- else
- {
- if(!can_move_to(xCoord-1, yCoord+3) || !can_move_to(xCoord, yCoord+3) ||
- !can_move_to(xCoord+1, yCoord+3))
- prefer_upper_s2 = 1;
- else
- prefer_lower_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord-1;
- max_size_result_node_ptr->node_y = yCoord+1+prefer_lower_s2;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- max_size_result_node_ptr->node_x = xCoord;
- max_size_result_node_ptr->node_y = yCoord+1+prefer_lower_s2;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 3:
- max_size_result_node_ptr->node_x = xCoord;
- max_size_result_node_ptr->node_y = yCoord+1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 5:
- max_size_result_node_ptr->node_x = xCoord+1;
- max_size_result_node_ptr->node_y = yCoord;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 6: // 2 points, 2 possible paths
- if(parent_result_node_ptr->node_x<=xCoord+1)
- prefer_left_s2 = 1;
- else
- {
- if(!can_move_to(xCoord+3,yCoord-1) || !can_move_to(xCoord+3,yCoord) ||
- !can_move_to(xCoord+3,yCoord+1))
- prefer_left_s2 = 1;
- else
- prefer_right_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord+1+prefer_right_s2;
- max_size_result_node_ptr->node_y = yCoord-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- max_size_result_node_ptr->node_x = xCoord+1+prefer_right_s2;
- max_size_result_node_ptr->node_y = yCoord;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 7: // 2 points, 2 paths
- max_size_result_node_ptr->node_y = yCoord-1;
- //----------- process path selection ---------------//
- if(parent_result_node_ptr->node_x<=xCoord)
- prefer_left_s2 = 1;
- else
- {
- if(!can_move_to(xCoord+2,yCoord-1) || !can_move_to(xCoord+2,yCoord))
- prefer_left_s2 = 1;
- else
- prefer_right_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord+prefer_right_s2;
- err_when(max_size_result_node_ptr->node_x!=xCoord && max_size_result_node_ptr->node_x!=xCoord+1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- err_when(!(nodeType&0x4) && !can_move_to(xCoord+2, yCoord));
- max_size_result_node_ptr->node_x = xCoord+(prefer_right_s2 || !(nodeType&0x4));
- max_size_result_node_ptr->node_y = yCoord;
- err_when(max_size_result_node_ptr->node_x!=xCoord && max_size_result_node_ptr->node_x!=xCoord+1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 8: // 2 points
- max_size_result_node_ptr->node_x = xCoord-1;
- max_size_result_node_ptr->node_y = yCoord-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- err_when(nodeType!=15);
- max_size_result_node_ptr->node_x = xCoord;
- max_size_result_node_ptr->node_y = yCoord;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- default: err_here();
- break;
- }
- break;
- case 5: switch(exitDirection)
- {
- case 1: // 2 points, 2 paths
- max_size_result_node_ptr->node_x = xCoord-1;
- //----------- process path selection ---------------//
- if(parent_result_node_ptr->node_y<=yCoord)
- prefer_upper_s2 = 1;
- else
- {
- if(!can_move_to(xCoord-1,yCoord+2) || !can_move_to(xCoord,yCoord+2) ||
- !can_move_to(xCoord+1,yCoord+2))
- prefer_upper_s2 = 1;
- else
- prefer_lower_s2 = 1;
- }
- max_size_result_node_ptr->node_y = yCoord+prefer_lower_s2;
- err_when(max_size_result_node_ptr->node_y!=yCoord && max_size_result_node_ptr->node_y!=yCoord+1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- max_size_result_node_ptr->node_x = xCoord;
- max_size_result_node_ptr->node_y = yCoord+prefer_lower_s2;
- err_when(max_size_result_node_ptr->node_y!=yCoord && max_size_result_node_ptr->node_y!=yCoord+1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 2: // 2 points, 2 paths
- max_size_result_node_ptr->node_x = xCoord-1;
- max_size_result_node_ptr->node_y = yCoord+1;
- //----------- process path selection ---------------//
- if( (parent_result_node_ptr->node_x-max_size_result_node_ptr->node_x==0) ||
- (parent_result_node_ptr->node_y-max_size_result_node_ptr->node_y==0) )
- prefer_lower_s2 = 1;
- else
- prefer_upper_s2 = 1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- err_when(!(nodeType&0x1) && !can_move_to(xCoord+1, yCoord+2));
- max_size_result_node_ptr->node_x = xCoord;
- if(prefer_upper_s2)
- max_size_result_node_ptr->node_y = yCoord + !(nodeType&0x1);
- else // prefer_lower_s2
- max_size_result_node_ptr->node_y = yCoord + can_move_to(xCoord+1, yCoord+2);
- err_when(max_size_result_node_ptr->node_y!=yCoord && max_size_result_node_ptr->node_y!=yCoord+1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 3: // 2 possible paths
- if(parent_result_node_ptr->node_x<=xCoord)
- prefer_left_s2 = 1;
- else
- {
- if(can_move_to(xCoord+2,yCoord+2))
- prefer_right_s2 = 1;
- else
- prefer_left_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord+prefer_right_s2;
- max_size_result_node_ptr->node_y = yCoord+1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 4: // 2 possible paths
- if(parent_result_node_ptr->node_x>xCoord)
- prefer_right_s2 = 1;
- else
- {
- if(!can_move_to(xCoord,yCoord+1) || !can_move_to(xCoord,yCoord+2))
- prefer_right_s2 = 1;
- else
- prefer_left_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord+prefer_right_s2;
- max_size_result_node_ptr->node_y = yCoord+1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 6: // 2 possible paths
- if(parent_result_node_ptr->node_x>xCoord)
- prefer_right_s2 = 1;
- else
- {
- if(!can_move_to(xCoord,yCoord-1) || !can_move_to(xCoord,yCoord))
- prefer_right_s2 = 1;
- else
- prefer_left_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord+prefer_right_s2;
- max_size_result_node_ptr->node_y = yCoord-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 7: // 2 possible paths
- if(parent_result_node_ptr->node_x<=xCoord)
- prefer_left_s2 = 1;
- else
- {
- if(can_move_to(xCoord+2,yCoord-1))
- prefer_right_s2 = 1;
- else
- prefer_left_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord+prefer_right_s2;
- max_size_result_node_ptr->node_y = yCoord-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 8: // 2 points
- max_size_result_node_ptr->node_x = xCoord-1;
- max_size_result_node_ptr->node_y = yCoord-1;
- //----------- process path selection ---------------//
- if( (parent_result_node_ptr->node_x-max_size_result_node_ptr->node_x==0) ||
- (parent_result_node_ptr->node_y-max_size_result_node_ptr->node_y==0) )
- prefer_upper_s2 = 1;
- else
- prefer_lower_s2 = 1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- err_when(!(nodeType&0x4) && !can_move_to(xCoord+1, yCoord-1));
- max_size_result_node_ptr->node_x = xCoord;
- if(prefer_upper_s2)
- max_size_result_node_ptr->node_y = yCoord - can_move_to(xCoord+1, yCoord-1);
- else // prefer_lower_s2
- max_size_result_node_ptr->node_y = yCoord - !(nodeType&0x4);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- default: err_here();
- break;
- }
- break;
- case 6: switch(exitDirection)
- {
- case 1: // 2 points, 2 paths
- max_size_result_node_ptr->node_x = xCoord-1;
- max_size_result_node_ptr->node_y = yCoord;
- //----------- process path selection ---------------//
- if( (parent_result_node_ptr->node_x-max_size_result_node_ptr->node_x==0) ||
- (parent_result_node_ptr->node_y-max_size_result_node_ptr->node_y==0) )
- prefer_lower_s2 = 1;
- else
- prefer_upper_s2 = 1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- err_when(!(nodeType&0x8) && !can_move_to(xCoord, yCoord-1));
- max_size_result_node_ptr->node_x = xCoord;
- if(prefer_upper_s2)
- max_size_result_node_ptr->node_y = yCoord - can_move_to(xCoord, yCoord-1);
- else // prefer_lower_s2
- max_size_result_node_ptr->node_y = yCoord - !(nodeType&0x8);
- err_when(max_size_result_node_ptr->node_y!=yCoord && max_size_result_node_ptr->node_y!=yCoord-1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 2: // 2 points
- max_size_result_node_ptr->node_x = xCoord-1;
- max_size_result_node_ptr->node_y = yCoord+1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- err_when(nodeType != 15);
- max_size_result_node_ptr->node_x = xCoord;
- max_size_result_node_ptr->node_y = yCoord;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 3: // 2 points, 2 paths
- max_size_result_node_ptr->node_x = xCoord;
- max_size_result_node_ptr->node_y = yCoord+1;
- //----------- process path selection ---------------//
- if( (parent_result_node_ptr->node_x-max_size_result_node_ptr->node_x==0) ||
- (parent_result_node_ptr->node_y-max_size_result_node_ptr->node_y==0) )
- prefer_left_s2 = 1;
- else
- prefer_right_s2 = 1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- err_when(!(nodeType&0x1) && !can_move_to(xCoord+2, yCoord+1));
- max_size_result_node_ptr->node_y = yCoord;
- if(prefer_left_s2)
- max_size_result_node_ptr->node_x = xCoord + !(nodeType&0x1);
- else // prefer_right_s2
- max_size_result_node_ptr->node_x = xCoord + can_move_to(xCoord+2, yCoord+1);
- err_when(max_size_result_node_ptr->node_y!=yCoord && max_size_result_node_ptr->node_y!=yCoord-1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 4: // 2 points, 2 possible paths
- if(parent_result_node_ptr->node_x<=xCoord+1)
- prefer_left_s2 = 1;
- else
- {
- if(!can_move_to(xCoord+3,yCoord) || !can_move_to(xCoord+3,yCoord+1) ||
- !can_move_to(xCoord+3,yCoord+2))
- prefer_left_s2 = 1;
- else
- prefer_right_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord+1+prefer_right_s2;
- max_size_result_node_ptr->node_y = yCoord+1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- max_size_result_node_ptr->node_x = xCoord+1+prefer_right_s2;
- max_size_result_node_ptr->node_y = yCoord;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 5:
- max_size_result_node_ptr->node_x = xCoord+1;
- max_size_result_node_ptr->node_y = yCoord;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 7:
- max_size_result_node_ptr->node_x = xCoord;
- max_size_result_node_ptr->node_y = yCoord-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 8: // 2 points, 2 possible paths
- if(parent_result_node_ptr->node_y>=yCoord-1)
- prefer_lower_s2 = 1;
- else
- {
- if(!can_move_to(xCoord-1,yCoord-2) || !can_move_to(xCoord,yCoord-2) ||
- !can_move_to(xCoord+1,yCoord-2)) // must check for all 3 points to avoid problems in dummy node generated in path-reuse
- prefer_lower_s2 = 1;
- else
- prefer_upper_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord-1;
- max_size_result_node_ptr->node_y = yCoord-1-prefer_upper_s2;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- max_size_result_node_ptr->node_x = xCoord;
- max_size_result_node_ptr->node_y = yCoord-1-prefer_upper_s2;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
-
- default: err_here();
- break;
- }
- break;
- case 7: switch(exitDirection)
- {
- case 1: // 2 possible paths
- if(parent_result_node_ptr->node_y>=yCoord)
- prefer_lower_s2 = 1;
- else
- {
- if(can_move_to(xCoord-1,yCoord-1))
- prefer_upper_s2 = 1;
- else
- prefer_lower_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord-1;
- max_size_result_node_ptr->node_y = yCoord-prefer_upper_s2;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 2: // 2 points, 2 paths
- max_size_result_node_ptr->node_x = xCoord-1;
- max_size_result_node_ptr->node_y = yCoord+1;
- //----------- process path selection ---------------//
- if( (parent_result_node_ptr->node_x-max_size_result_node_ptr->node_x==0) ||
- (parent_result_node_ptr->node_y-max_size_result_node_ptr->node_y==0) )
- prefer_left_s2 = 1;
- else
- prefer_right_s2 = 1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- err_when(!(nodeType&0x8) && !can_move_to(xCoord-1, yCoord));
- max_size_result_node_ptr->node_y = yCoord;
- if(prefer_left_s2)
- max_size_result_node_ptr->node_x = xCoord - can_move_to(xCoord-1, yCoord);
- else // prefer_right_s2
- max_size_result_node_ptr->node_x = xCoord - !(nodeType&0x8);
- err_when(max_size_result_node_ptr->node_x!=xCoord && max_size_result_node_ptr->node_x!=xCoord-1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 3: // 2 points, 2 paths
- max_size_result_node_ptr->node_y = yCoord+1;
- //----------- process path selection ---------------//
- if(parent_result_node_ptr->node_x<=xCoord)
- prefer_left_s2 = 1;
- else
- {
- if(!can_move_to(xCoord+2,yCoord) || !can_move_to(xCoord+2,yCoord+1) ||
- !can_move_to(xCoord+2,yCoord+2))
- prefer_left_s2 = 1;
- else
- prefer_right_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord+prefer_right_s2;
- err_when(max_size_result_node_ptr->node_x!=xCoord && max_size_result_node_ptr->node_x!=xCoord+1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- max_size_result_node_ptr->node_x = xCoord+prefer_right_s2;
- max_size_result_node_ptr->node_y = yCoord;
- err_when(max_size_result_node_ptr->node_x!=xCoord && max_size_result_node_ptr->node_x!=xCoord+1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 4: // 2 points, 2 paths
- max_size_result_node_ptr->node_x = xCoord+1;
- max_size_result_node_ptr->node_y = yCoord+1;
- //----------- process path selection ---------------//
- if( (parent_result_node_ptr->node_x-max_size_result_node_ptr->node_x==0) ||
- (parent_result_node_ptr->node_y-max_size_result_node_ptr->node_y==0) )
- prefer_right_s2 = 1;
- else
- prefer_left_s2 = 1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- err_when(!(nodeType&0x4) && !can_move_to(xCoord+2, yCoord));
- max_size_result_node_ptr->node_y = yCoord;
- if(prefer_left_s2)
- max_size_result_node_ptr->node_x = xCoord + !(nodeType&0x4);
- else // prefer_right_s2
- max_size_result_node_ptr->node_x = xCoord + can_move_to(xCoord+2, yCoord);
- err_when(max_size_result_node_ptr->node_x!=xCoord && max_size_result_node_ptr->node_x!=xCoord+1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 5: // 2 possible paths
- if(parent_result_node_ptr->node_y>=yCoord)
- prefer_lower_s2 = 1;
- else
- {
- if(can_move_to(xCoord+1,yCoord-1))
- prefer_upper_s2 = 1;
- else
- prefer_lower_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord+1;
- max_size_result_node_ptr->node_y = yCoord-prefer_upper_s2;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 6: // 2 possible paths
- if(parent_result_node_ptr->node_y<yCoord)
- prefer_upper_s2 = 1;
- else
- {
- if(!can_move_to(xCoord+1,yCoord+1) || !can_move_to(xCoord+2,yCoord+1))
- prefer_upper_s2 = 1;
- else
- prefer_lower_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord+1;
- max_size_result_node_ptr->node_y = yCoord-prefer_upper_s2;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 8: // 2 possible paths
- if(parent_result_node_ptr->node_y<yCoord)
- prefer_upper_s2 = 1;
- else
- {
- if(!can_move_to(xCoord-1,yCoord+1) || !can_move_to(xCoord,yCoord+1))
- prefer_lower_s2 = 1;
- else
- prefer_upper_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord-1;
- max_size_result_node_ptr->node_y = yCoord-prefer_upper_s2;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- default: err_here();
- break;
- }
- break;
- case 8: switch(exitDirection)
- {
- case 1:
- max_size_result_node_ptr->node_x = xCoord-1;
- max_size_result_node_ptr->node_y = yCoord;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 2: // 2 points, 2 possible paths
- if(parent_result_node_ptr->node_x>=xCoord-1)
- prefer_right_s2 = 1;
- else
- {
- if(!can_move_to(xCoord-2,yCoord) || !can_move_to(xCoord-2,yCoord+1) ||
- !can_move_to(xCoord-2,yCoord+2))
- prefer_right_s2 = 1;
- else
- prefer_left_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord-1-prefer_left_s2;
- max_size_result_node_ptr->node_y = yCoord+1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- max_size_result_node_ptr->node_x = xCoord-1-prefer_left_s2;
- max_size_result_node_ptr->node_y = yCoord;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 3: // 2 points, 2 paths
- max_size_result_node_ptr->node_x = xCoord;
- max_size_result_node_ptr->node_y = yCoord+1;
- //----------- process path selection ---------------//
- if( (parent_result_node_ptr->node_x-max_size_result_node_ptr->node_x==0) ||
- (parent_result_node_ptr->node_y-max_size_result_node_ptr->node_y==0) )
- prefer_right_s2 = 1;
- else
- prefer_left_s2 = 1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- err_when(!(nodeType&0x2) && !can_move_to(xCoord-1, yCoord+1));
- max_size_result_node_ptr->node_y = yCoord;
- if(prefer_left_s2)
- max_size_result_node_ptr->node_x = xCoord - can_move_to(xCoord-1, yCoord+1);
- else // prefer_right_s2
- max_size_result_node_ptr->node_x = xCoord - !(nodeType&0x2);
- err_when(max_size_result_node_ptr->node_x!=xCoord && max_size_result_node_ptr->node_x!=xCoord-1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 4: // 2 points
- max_size_result_node_ptr->node_x = xCoord+1;
- max_size_result_node_ptr->node_y = yCoord+1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- err_when(nodeType!=15);
- max_size_result_node_ptr->node_x = xCoord;
- max_size_result_node_ptr->node_y = yCoord;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 5: // 2 points, 2 paths
- max_size_result_node_ptr->node_x = xCoord+1;
- max_size_result_node_ptr->node_y = yCoord;
- //----------- process path selection ---------------//
- if( (parent_result_node_ptr->node_x-max_size_result_node_ptr->node_x==0) ||
- (parent_result_node_ptr->node_y-max_size_result_node_ptr->node_y==0) )
- prefer_lower_s2 = 1;
- else
- prefer_upper_s2 = 1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- err_when(!(nodeType&0x4) && !can_move_to(xCoord+1, yCoord-1));
- max_size_result_node_ptr->node_x = xCoord;
- if(prefer_upper_s2)
- max_size_result_node_ptr->node_y = yCoord - can_move_to(xCoord+1, yCoord-1);
- else // prefer_lower_s2
- max_size_result_node_ptr->node_y = yCoord - !(nodeType&0x4);
- err_when(max_size_result_node_ptr->node_y!=yCoord && max_size_result_node_ptr->node_y!=yCoord-1);
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 6: // 2 points, 2 possible paths
- if(parent_result_node_ptr->node_y>=yCoord-1)
- prefer_lower_s2 = 1;
- else
- {
- if(!can_move_to(xCoord,yCoord-2) || !can_move_to(xCoord+1,yCoord-2) ||
- !can_move_to(xCoord+2,yCoord-2))
- prefer_lower_s2 = 1;
- else
- prefer_upper_s2 = 1;
- }
- max_size_result_node_ptr->node_x = xCoord+1;
- max_size_result_node_ptr->node_y = yCoord-1-prefer_upper_s2;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- max_size_result_node_ptr->node_x = xCoord;
- max_size_result_node_ptr->node_y = yCoord-1-prefer_upper_s2;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- case 7:
- max_size_result_node_ptr->node_x = xCoord;
- max_size_result_node_ptr->node_y = yCoord-1;
- add_result_node(&max_size_result_node_ptr, &parent_result_node_ptr, count);
- break;
- default: err_here();
- break;
- }
- break;
- default: err_here();
- break;
- }
- }
- //------ End of function SeekPathS2::get_real_result_node ---------//
- //-------- Begin of function SeekPathS2::return_best_node -------//
- //
- // return : <NodeS2*> the best node.
- // NULL if no more node on the open node list. There is no
- // possible path between the starting and destination points.
- //
- NodeS2* SeekPathS2::return_best_node()
- {
- NodeS2 *tempNode;
- if( !open_node_list )
- return NULL;
- //------------------------------------------------------------------//
- // Pick Node with lowest f, in this case it's the first node in list
- // Because we sort the open_node_list list wrt lowest f. Call it BESTNode.
- //------------------------------------------------------------------//
- tempNode=open_node_list; // point to first node on open_node_list
- open_node_list=tempNode->next_node; // Make open_node_list point to nextnode or NULL.
- //------------------------------------------------------------------//
- // Next take BESTNode (or temp in this case) and put it on closed_node_list
- //------------------------------------------------------------------//
- tempNode->next_node=closed_node_list;
- closed_node_list=tempNode;
- return tempNode;
- }
- //-------- End of function SeekPathS2::return_best_node ---------//
- //----- Begin of function SeekPathS2::return_closest_node -------//
- //
- // Return the node that is closest to the destination.
- //
- NodeS2* SeekPathS2::return_closest_node()
- {
- NodeS2* nodePtr;
- NodeS2* shortestNode=NULL;
- int nodeDistance, shortestDistance=0x7FFF;
- int disX, disY;
- //------------ search open_node_list ----------//
- nodePtr = open_node_list;
- int yieldCount = 0;
- while(nodePtr)
- {
- //--- the distance between this node and the destination node ----//
- nodeDistance = (disX=cur_dest_x_s2-nodePtr->node_x)*disX + (disY=cur_dest_y_s2-nodePtr->node_y)*disY;
- //--- if the distance is shorter than the current shortest distance ---//
- if( nodeDistance < shortestDistance )
- {
- shortestDistance = nodeDistance;
- shortestNode = nodePtr;
- }
- nodePtr=nodePtr->next_node;
- yieldCount++;
- if(yieldCount%25==0)
- sys_yield();
- }
- //------------ search closed_node_list ----------//
- nodePtr = closed_node_list;
- yieldCount = 0;
- while(nodePtr)
- {
- //--- the distance between this node and the destination node ----//
- nodeDistance = (disX=cur_dest_x_s2-nodePtr->node_x)*disX + (disY=cur_dest_y_s2-nodePtr->node_y)*disY;
- //--- if the distance is shorter than the current shortest distance ---//
- if( nodeDistance < shortestDistance )
- {
- shortestDistance = nodeDistance;
- shortestNode = nodePtr;
- }
- nodePtr=nodePtr->next_node;
- yieldCount++;
- if(yieldCount%25==0)
- sys_yield();
- }
- //------------------------------------------------------//
- // there may be some nodes with the same shortest Distance
- // from the destination node. However, one should be closer
- // to the starting node. The following is used to find
- // out the closer node.
- //------------------------------------------------------//
- nodePtr = shortestNode->parent_node;
- yieldCount = 0;
- while(nodePtr)
- {
- //--- the distance between the parent node and the destination node ----//
- nodeDistance = (disX=cur_dest_x_s2-nodePtr->node_x)*disX + (disY=cur_dest_y_s2-nodePtr->node_y)*disY;
- //--- if the distance is shorter than the current shortest distance ---//
- if( nodeDistance <= shortestDistance )
- {
- shortestDistance = nodeDistance;
- shortestNode = nodePtr;
- }
- else
- break;
- nodePtr=nodePtr->parent_node;
- yieldCount++;
- if(yieldCount%25==0)
- sys_yield();
- }
- return shortestNode;
- }
- //----- End of function SeekPathS2::return_closest_node -------//
- //----- Begin of function SeekPathS2::insert_open_node -------//
- void SeekPathS2::insert_open_node(NodeS2 *succNode)
- {
- if (open_node_list == NULL)
- {
- open_node_list=succNode;
- return;
- }
- //---- insert into open_node_list successor wrt f ----//
- register int f=succNode->node_f;
- if( open_node_list && open_node_list->node_f < f )
- {
- NodeS2 *tempNode1, *tempNode2;
- tempNode1=open_node_list;
- tempNode2=tempNode1->next_node;
- int yieldCount = 0;
- while( tempNode2 && tempNode2->node_f < f )
- {
- tempNode1=tempNode2;
- tempNode2=tempNode2->next_node;
- yieldCount++;
- if(yieldCount%200==0)
- sys_yield();
- }
- err_when(succNode!=NULL && tempNode2!=NULL && succNode->node_x==tempNode2->node_x &&
- succNode->node_y==tempNode2->node_y); // avoid pointer pointing back to itself
- succNode->next_node = tempNode2;
- tempNode1->next_node = succNode;
- }
- else
- {
- succNode->next_node = open_node_list;
- open_node_list = succNode;
- }
- }
- //----- End of function SeekPathS2::insert_open_node -------//
- //-------- Begin of function SeekPath::smooth_the_path ---------//
- ResultNode* SeekPathS2::smooth_the_path(ResultNode* nodeArray, int& nodeCount)
- {
- //--------------------------------------------------//
- // to remove duplicate or useless node
- //--------------------------------------------------//
- int i, j, curNodeCount = 1;
- parent_result_node_ptr = nodeArray;
- max_size_result_node_ptr = nodeArray+1;
-
- for(i=0; i<nodeCount-1; i++)
- {
- if(parent_result_node_ptr->node_x!=max_size_result_node_ptr->node_x ||
- parent_result_node_ptr->node_y!=max_size_result_node_ptr->node_y)
- {
- parent_result_node_ptr++;
- parent_result_node_ptr->node_x = max_size_result_node_ptr->node_x;
- parent_result_node_ptr->node_y = max_size_result_node_ptr->node_y;
- curNodeCount++;
- }
- max_size_result_node_ptr++;
- if(i%50==0)
- sys_yield();
- }
- nodeCount = curNodeCount;
- //return nodeArray;
-
- //---------- declare variables ---------------//
- int checkedNodeCount;
- short vectorX, vectorY, newVectorX, newVectorY, newVectorX2, newVectorY2;
- short changed, caseNum, processed;
- ResultNode *curUsefulNodePtr = nodeArray+1;
- ResultNode *ptr1;
- ResultNode *ptr2;
- ResultNode *ptr3;
- ResultNode *ptr4;
-
- //--------------------------------------------------//
- // smooth the path
- //--------------------------------------------------//
- parent_result_node_ptr = nodeArray;
- max_size_result_node_ptr = nodeArray+1;
- changed = 1;
- checkedNodeCount = 1;
- curNodeCount = nodeCount;
- ptr1 = parent_result_node_ptr;
- ptr2 = max_size_result_node_ptr;
- ptr3 = max_size_result_node_ptr+1;
- int yieldCount = 1;
- while(changed && curNodeCount>=3)
- {
- yieldCount++;
- if(yieldCount%20==0)
- sys_yield();
- vectorX = ptr2->node_x - ptr1->node_x;
- vectorY = ptr2->node_y - ptr1->node_y;
- changed = 0;
-
- for(j=1; j<curNodeCount-1; j++)
- {
- processed = 0;
- newVectorX= ptr3->node_x - ptr2->node_x;
- newVectorY= ptr3->node_y - ptr2->node_y;
-
- //----------------------------------------------------------//
- // reverse direction
- //----------------------------------------------------------//
- if(vectorX==-newVectorX && vectorY==-newVectorY)
- {
- if(j+2<curNodeCount) //------ not the end of the array ------//
- {
- ptr2 = ptr3+1;
- ptr3 = ptr2+1;
- vectorX = ptr2->node_x - ptr1->node_x;
- vectorY = ptr2->node_y - ptr1->node_y;
- processed = 1;
- j++;
- continue;
- }
- else //-------- already the end of the array ----------//
- {
- ptr3++;
- changed++;
- break; // break the for loop
- }
- }
- //----------------------------------------------------------//
- // turning 45 degree angle
- //----------------------------------------------------------//
- if(abs(vectorX+newVectorX)<=1 && abs(vectorY+newVectorY)<=1 && // if so, turning 45 or 90 degree
- vectorX*newVectorX+vectorY*newVectorY!=0) // reject turning 90 degree
- {
- ptr2=ptr3;
- ptr3++;
- vectorX = ptr2->node_x - ptr1->node_x;
- vectorY = ptr2->node_y - ptr1->node_y;
- processed = 1;
- continue;
- }
- //----------------------------------------------------------//
- // turning at 90 degree clockwise / anti-clockwise
- //----------------------------------------------------------//
- if((vectorX==0 && vectorY!=0 && newVectorX!=0 && newVectorY==0) || // + case
- (vectorX!=0 && vectorY==0 && newVectorX==0 && newVectorY!=0))
- {
- ptr2=ptr3;
- ptr3++;
- vectorX = ptr2->node_x - ptr1->node_x;
- vectorY = ptr2->node_y - ptr1->node_y;
- processed = 1;
- continue;
- }
- if((vectorX!=0 && vectorY!=0 && newVectorX!=0 && newVectorY!=0) && // x case
- ((vectorX==newVectorX && vectorY==-newVectorY) || (vectorX==-newVectorX && vectorY==newVectorY)))
- {
- ptr2->node_x = (ptr1->node_x+ptr3->node_x)/2;
- ptr2->node_y = (ptr1->node_y+ptr3->node_y)/2;
- curUsefulNodePtr->node_x = ptr2->node_x;
- curUsefulNodePtr->node_y = ptr2->node_y;
- curUsefulNodePtr++;
- checkedNodeCount++;
- ptr1 = ptr2;
- ptr2 = ptr3;
- ptr3++;
- vectorX = ptr2->node_x - ptr1->node_x;
- vectorY = ptr2->node_y - ptr1->node_y;
- processed = 1;
- continue;
- }
- //----------------------------------------------------------//
- // check for the 4-point case
- //----------------------------------------------------------//
- if(j<curNodeCount-2)
- {
- ptr4 = ptr3+1;
- newVectorX2 = ptr4->node_x - ptr3->node_x;
- newVectorY2 = ptr4->node_y - ptr3->node_y;
- caseNum = 0;
- if(!caseNum && vectorX==-1 && vectorY==0 && newVectorX==-1 && newVectorX2==0)
- {
- if(newVectorY==1 && newVectorY2==1 && can_move_to(ptr1->node_x, ptr4->node_y))
- caseNum = 1;
- if(!caseNum && newVectorY==-1 && newVectorY2==-1 && can_move_to(ptr1->node_x, ptr4->node_y-1))
- caseNum = 5;
- }
- if(!caseNum && vectorX==1 && vectorY==0 && newVectorX==1 && newVectorX2==0)
- {
- if(newVectorY==1 && newVectorY2==1 && can_move_to(ptr1->node_x+1, ptr4->node_y))
- caseNum = 3;
- if(!caseNum && newVectorY==-1 && newVectorY2==-1 && can_move_to(ptr1->node_x+1, ptr4->node_y-1))
- caseNum = 7;
- }
- if(!caseNum && vectorX==0 && vectorY==-1 && newVectorY==-1 && newVectorY2==0)
- {
- if(newVectorX==1 && newVectorX2==1 && can_move_to(ptr4->node_x, ptr1->node_y))
- caseNum = 2;
- if(!caseNum && newVectorX==-1 && newVectorX2==-1 && can_move_to(ptr4->node_x+1, ptr1->node_y))
- caseNum = 4;
- }
- if(!caseNum && vectorX==0 && vectorY==1 && newVectorY==1 && newVectorY2==0)
- {
- if(newVectorX==1 && newVectorX2==1 && can_move_to(ptr4->node_x, ptr1->node_y+1))
- caseNum = 6;
- if(!caseNum && newVectorX==-1 && newVectorX2==-1 && can_move_to(ptr4->node_x+1, ptr1->node_y+1))
- caseNum = 8;
- }
- if(caseNum)
- {
- switch(caseNum)
- {
- case 1:
- if(can_move_to(ptr1->node_x, ptr4->node_y))
- {
- //ptr2->node_x = ptr2->node_x;
- ptr2->node_y++; //ptr2->node_y = ptr3->node_y;
- processed = 1;
- }
- break;
- case 2:
- if(can_move_to(ptr4->node_x, ptr1->node_y))
- {
- ptr2->node_x++; //ptr2->node_x = ptr3->node_x;
- //ptr2->node_y = ptr2->node_y;
- processed = 1;
- }
- break;
- case 3:
- if(can_move_to(ptr2->node_x, ptr4->node_y))
- {
- //ptr2->node_x = ptr2->node_x;
- ptr2->node_y++; //ptr2->node_y = ptr3->node_y;
- processed = 1;
- }
- break;
- case 4:
- if(can_move_to(ptr3->node_x, ptr1->node_y))
- {
- ptr2->node_x--; //ptr2->node_x = ptr3->node_x;
- //ptr2->node_y = ptr2->node_y;
- processed = 1;
- }
- break;
- case 5:
- if(can_move_to(ptr1->node_x, ptr3->node_y))
- {
- //ptr2->node_x = ptr2->node_x;
- ptr2->node_y--; //ptr2->node_y = ptr3->node_y;
- processed = 1;
- }
- break;
- case 6:
- if(can_move_to(ptr4->node_x, ptr2->node_y))
- {
- ptr2->node_x++; //ptr2->node_x = ptr3->node_x;
- //ptr2->node_y = ptr2->node_y;
- processed = 1;
- }
- break;
- case 7:
- if(can_move_to(ptr2->node_x, ptr3->node_y))
- {
- //ptr2->node_x = ptr2->node_x;
- ptr2->node_y--; //ptr2->node_y = ptr3->node_y;
- processed = 1;
- }
- break;
- case 8:
- if(can_move_to(ptr3->node_x, ptr2->node_y))
- {
- ptr2->node_x--; //ptr2->node_x = ptr3->node_x;
- //ptr2->node_y = ptr2->node_y;
- processed = 1;
- }
- break;
- default:
- err_here();
- break;
- }
- if(processed)
- {
- ptr3 = ptr4;
- curUsefulNodePtr->node_x = ptr2->node_x;
- curUsefulNodePtr->node_y = ptr2->node_y;
- curUsefulNodePtr++;
- checkedNodeCount++;
- ptr1 = ptr2;
- ptr2 = ptr3;
- ptr3++;
- j++;
- vectorX = ptr2->node_x - ptr1->node_x;
- vectorY = ptr2->node_y - ptr1->node_y;
- continue;
- }
- }
- }
- //------ none of the above case ---------//
- if(!processed)
- {
- curUsefulNodePtr->node_x = ptr2->node_x;
- curUsefulNodePtr->node_y = ptr2->node_y;
- curUsefulNodePtr++;
- checkedNodeCount++;
- }
- else
- changed = 1;
- ptr1 = ptr2;
- ptr2 = ptr3;
- ptr3++;
- vectorX = ptr2->node_x - ptr1->node_x;
- vectorY = ptr2->node_y - ptr1->node_y;
- }
- //---- end checking and then reset parameters----//
- curUsefulNodePtr->node_x = ptr2->node_x;
- curUsefulNodePtr->node_y = ptr2->node_y;
- curUsefulNodePtr++;
- checkedNodeCount++;
-
- curNodeCount = checkedNodeCount;
- checkedNodeCount = 1;
- ptr1 = parent_result_node_ptr;
- ptr2 = ptr1+1;
- ptr3 = ptr2+1;
- }
- nodeCount = curNodeCount;
- return nodeArray;
- }
- //------- End of function SeekPathS2::smooth_the_path -------//
- //-------- Begin of function NodeS2::generate_successors ---------//
- // Note: In fact, the cost of the starting node should be 0 or 1
- // and the parentEnterDirection is 0. Now the cost in this
- // case is set to 2. The difference can be ignored as it will
- // not affect the search after generating the second level
- // children.
- // The advantage to ignore this case is that less comparsion
- // effort in checking parentEnterDirection.
- //
- short NodeS2::generate_successors(short parentEnterDirection)
- {
- int hasLeft = node_x > cur_border_x1_s2;
- int hasRight = node_x < cur_border_x2_s2;
- int hasUp = node_y > cur_border_y1_s2;
- int hasDown = node_y < cur_border_y2_s2;
- int upperLeftX,upperLeftY;
- short cost;
- upperLeftX = node_x<<1;
- upperLeftY = node_y<<1;
- err_when(upperLeftX != node_x+node_x || upperLeftY != node_y+node_y);
- //-------------------------------------------
- // enter_direction = (exit_direction+3)%8+1
- //-------------------------------------------
- if( hasLeft )
- {
- //--------- Left, exit_direction=1 --------//
- if(can_move_to(upperLeftX-1, upperLeftY) && node_type&0x1 &&
- can_move_to(upperLeftX-1, upperLeftY+1) && node_type&0x4 )
- {
- if(parentEnterDirection==2 || parentEnterDirection==3 || parentEnterDirection==7 || parentEnterDirection==8)
- cost = 1;
- else
- {
- if((parentEnterDirection==4 && (node_type&0x2 || can_move_to(upperLeftX,upperLeftY+2))) ||
- parentEnterDirection==5 ||
- (parentEnterDirection==6 && (node_type&0x8 || can_move_to(upperLeftX,upperLeftY-1))))
- cost = 2;
- else
- {
- if(parentEnterDirection==0 && !source_blocked_exit_direction[0]) // direction 1
- {
- if(source_locate_type==1 || source_locate_type==3)
- cost = 1;
- else
- cost = 2;
- }
- else
- cost = 0;
- }
- }
- if(cost)
- {
- err_when(parentEnterDirection==1);
- if(generate_succ(node_x-1,node_y,5,cost))
- return 1;
- }
- }
-
- if( hasUp )
- {
- //------- Upper-Left, exit_direction=8 ---------//
- if(can_move_to(upperLeftX-1, upperLeftY-1) && can_move_to(upperLeftX, upperLeftY-1) &&
- can_move_to(upperLeftX-1, upperLeftY) && node_type&0x1)
- {
- if(parentEnterDirection==1 || parentEnterDirection==2 || parentEnterDirection==6 || parentEnterDirection==7)
- cost = 1;
- else
- {
- if((parentEnterDirection==3 && (node_type&0x2 || can_move_to(upperLeftX-1, upperLeftY+1))) ||
- (parentEnterDirection==4 && node_type==15) ||
- (parentEnterDirection==5 && (node_type&0x4 || can_move_to(upperLeftX+1, upperLeftY-1))))
- cost = 2;
- else
- {
- if(parentEnterDirection==0 && !source_blocked_exit_direction[7]) // direction 8
- {
- if(source_locate_type==1)
- cost = 1;
- else
- cost = 2;
- }
- else
- cost = 0;
- }
- }
- if(cost)
- {
- err_when(parentEnterDirection==8);
- if(generate_succ(node_x-1,node_y-1,4,cost))
- return 1;
- }
- }
- }
- if( hasDown )
- {
- //--------- Lower-Left, exit_direction=2 ----------//
- if(can_move_to(upperLeftX-1,upperLeftY+1) && node_type&0x4 &&
- can_move_to(upperLeftX-1,upperLeftY+2) && can_move_to(upperLeftX,upperLeftY+2))
- {
- if(parentEnterDirection==1 || parentEnterDirection==3 || parentEnterDirection==4 || parentEnterDirection==8)
- cost = 1;
- else
- {
- if((parentEnterDirection==5 && (node_type&0x1 || can_move_to(upperLeftX+1,upperLeftY+2))) ||
- (parentEnterDirection==6 && node_type==15) ||
- (parentEnterDirection==7 && (node_type&0x8 || can_move_to(upperLeftX-1,upperLeftY))))
- cost = 2;
- else
- {
- if(parentEnterDirection==0 && !source_blocked_exit_direction[1]) // direction 2
- {
- if(source_locate_type==1||source_locate_type==3)
- cost = 1;
- else
- cost = 2;
- }
- else
- cost = 0;
- }
- }
- if(cost || (parentEnterDirection==0 && source_locate_type==3 && !source_blocked_exit_direction[1]))
- {
- err_when(parentEnterDirection==2);
- if(generate_succ(node_x-1,node_y+1,6,cost))
- return 1;
- }
- }
- }
- }
- if( hasRight )
- {
- //----------- Right, exit_direction=5 -----------//
- if(node_type&0x2 && can_move_to(upperLeftX+2,upperLeftY) &&
- node_type&0x8 && can_move_to(upperLeftX+2,upperLeftY+1))
- {
- if(parentEnterDirection==3 || parentEnterDirection==4 || parentEnterDirection==6 || parentEnterDirection==7)
- cost = 1;
- else
- {
- if(parentEnterDirection==1 ||
- (parentEnterDirection==2 && (node_type&0x1 || can_move_to(upperLeftX+1,upperLeftY+2))) ||
- (parentEnterDirection==8 && (node_type&0x4 || can_move_to(upperLeftX+1,upperLeftY-1))))
- cost = 2;
- else
- {
- if(parentEnterDirection==0 && !source_blocked_exit_direction[4] && //direction 5
- (source_locate_type==1||source_locate_type==3))
- cost = 1;
- else
- cost = 0;
- }
- }
- if(cost||(parentEnterDirection==0&&!source_blocked_exit_direction[4]&&(source_locate_type==2||source_locate_type==4)))
- {
- err_when(parentEnterDirection==5);
- if(generate_succ(node_x+1,node_y,1,cost))
- return 1;
- }
- }
-
- if( hasUp )
- {
- //-------- Upper-Right, exit_direction=6 ---------//
- if(can_move_to(upperLeftX+1,upperLeftY-1) && can_move_to(upperLeftX+2,upperLeftY-1) &&
- node_type&0x2 && can_move_to(upperLeftX+2,upperLeftY))
- {
- if(parentEnterDirection==4 || parentEnterDirection==5 || parentEnterDirection==7 || parentEnterDirection==8)
- cost = 1;
- else
- {
- if((parentEnterDirection==1 && (node_type&0x8 || can_move_to(upperLeftX,upperLeftY-1))) ||
- (parentEnterDirection==2 && node_type==15) ||
- (parentEnterDirection==3 && (node_type&0x1 || can_move_to(upperLeftX+2,upperLeftY+1))))
- cost = 2;
- else
- {
- if(parentEnterDirection==0 && !source_blocked_exit_direction[5]) // direction 6
- {
- if(source_locate_type==1||source_locate_type==2)
- cost = 1;
- else
- cost = 2;
- }
- else
- cost = 0;
- }
- }
- if(cost)
- {
- err_when(parentEnterDirection==6);
- if(generate_succ(node_x+1,node_y-1,2,cost))
- return 1;
- }
- }
- }
- if( hasDown )
- {
- //--------- Lower-Right, exit_direction=4 ---------//
- if(node_type&0x8 && can_move_to(upperLeftX+2,upperLeftY+1) &&
- can_move_to(upperLeftX+1,upperLeftY+2) && can_move_to(upperLeftX+2,upperLeftY+2))
- {
- if(parentEnterDirection==2 || parentEnterDirection==3 || parentEnterDirection==5 || parentEnterDirection==6)
- cost = 1;
- else
- {
- if((parentEnterDirection==1 && (node_type&0x2 || can_move_to(upperLeftX,upperLeftY+2))) ||
- (parentEnterDirection==8 && node_type==15) ||
- (parentEnterDirection==7 && (node_type&0x4 || can_move_to(upperLeftX+2,upperLeftY))))
- cost = 2;
- else
- {
- if(parentEnterDirection==0&&source_locate_type!=4&&!source_blocked_exit_direction[3]) // direction 4
- cost = 1;
- else
- cost = 0;
- }
- }
- if(cost||(parentEnterDirection==0&&source_locate_type==4&&!source_blocked_exit_direction[3]))
- {
- err_when(parentEnterDirection==4);
- if(generate_succ(node_x+1,node_y+1,8,cost))
- return 1;
- }
- }
- }
- }
- if( hasUp )
- {
- //---------- Upper, exit_direction=7 -----------//
- if(can_move_to(upperLeftX,upperLeftY-1) && can_move_to(upperLeftX+1,upperLeftY-1) &&
- node_type&0x1 && node_type&0x2)
- {
- if(parentEnterDirection==1 || parentEnterDirection==5 || parentEnterDirection==6 || parentEnterDirection==8)
- cost = 1;
- else
- {
- if((parentEnterDirection==2 && (node_type&0x8 || can_move_to(upperLeftX-1,upperLeftY))) ||
- parentEnterDirection==3 ||
- (parentEnterDirection==4 && (node_type&0x4 || can_move_to(upperLeftX+2,upperLeftY))))
- cost = 2;
- else
- {
- if(parentEnterDirection==0 && !source_blocked_exit_direction[6]) // direction 7
- {
- if(source_locate_type==1||source_locate_type==2)
- cost = 1;
- else
- cost = 2;
- }
- else
- cost = 0;
- }
- }
- if(cost)
- {
- err_when(parentEnterDirection==7);
- if(generate_succ(node_x,node_y-1,3,cost))
- return 1;
- }
- }
- }
-
- if( hasDown )
- {
- //---------- Lower, exit_direction=3 -----------//
- if(node_type&0x4 && node_type&0x8 &&
- can_move_to(upperLeftX,upperLeftY+2) && can_move_to(upperLeftX+1,upperLeftY+2))
- {
- if(parentEnterDirection==1 || parentEnterDirection==2 || parentEnterDirection==4 || parentEnterDirection==5)
- cost = 1;
- else
- {
- if((parentEnterDirection==6 && (node_type&0x1 || can_move_to(upperLeftX+2,upperLeftY+1))) ||
- parentEnterDirection==7 ||
- (parentEnterDirection==8 && (node_type&0x2 || can_move_to(upperLeftX-1,upperLeftY+1))))
- cost = 2;
- else
- {
- if(parentEnterDirection==0&&(source_locate_type==1||source_locate_type==2)&&!source_blocked_exit_direction[2]) // direction 3
- cost = 1;
- else
- cost = 0;
- }
- }
- if(cost||(parentEnterDirection==0&&(source_locate_type==3||source_locate_type==4)&&!source_blocked_exit_direction[2]))
- {
- err_when(parentEnterDirection==3);
- if(generate_succ(node_x,node_y+1,7,cost))
- return 1;
- }
- }
- }
- return 0;
- }
- //------- End of function NodeS2::generate_successors -------//
- //-------- Begin of function NodeS2::generate_succ ---------//
- short NodeS2::generate_succ(short x, short y, short enter_direct,short cost)
- {
- int upperLeftX, upperLeftY;
- upperLeftX = x<<1;
- upperLeftY = y<<1;
- //----- if it points back to this node's parent ----//
- if( parent_node )
- {
- if( parent_node->node_x==x && parent_node->node_y==y )
- return 0;
- }
- //----- if there is an existing node at the given position ----//
- short c, g = node_g+cost; // g(Successor)=g(BestNode)+cost of getting from BestNode to Successor
- short nodeRecno;
- //if( (nodeRecno=cur_node_matrix_s2[y*(MAX_WORLD_X_LOC/2+1)+x]) > 0 )
- if( (nodeRecno=cur_node_matrix_s2[y*(MAX_WORLD_X_LOC/2+1)+x]) > 0 &&
- nodeRecno<max_node_num_s2)
- {
- NodeS2* oldNode = cur_node_array_s2+nodeRecno-1;
- //------ Add oldNode to the list of BestNode's child_noderen (or Successors).
- for(c=0 ; c<MAX_CHILD_NODE && child_node[c] ; c++);
- child_node[c]=oldNode;
- //---- if our new g value is < oldNode's then reset oldNode's parent to point to BestNode
- if (g < oldNode->node_g)
- {
- //-------------check whether the oldNode can process propagate down -----------//
- char canPropagateDown=1;
- if(oldNode->node_type!=15 && enter_direct%2==0)
- {
- NodeS2* oldChildNode;
- short xShift1 = x_shift_array[enter_direct-1];
- short yShift1 = y_shift_array[enter_direct-1];
- short xShift2, yShift2, xShift3, yShift3;
- if(enter_direct>1)
- {
- xShift2 = x_shift_array[enter_direct-2];
- yShift2 = y_shift_array[enter_direct-2];
- }
- else
- {
- xShift2 = x_shift_array[7];
- yShift2 = y_shift_array[7];
- }
- if(enter_direct<8)
- {
- xShift3 = x_shift_array[enter_direct];
- yShift3 = y_shift_array[enter_direct];
- }
- else
- {
- xShift3 = x_shift_array[0];
- yShift3 = y_shift_array[0];
- }
- for(c=0; c<MAX_CHILD_NODE && oldNode->child_node[c]; c++) // for each child of oldNode
- {
- oldChildNode = oldNode->child_node[c];
- if(oldNode->parent_node != oldChildNode)
- {
- switch(enter_direct) // for entering at corner
- {
- case 2:
- if(oldChildNode->enter_direction==enter_direct &&
- oldChildNode->node_x-oldNode->node_x==xShift1 &&
- oldChildNode->node_y-oldNode->node_y==yShift1 &&
- (!can_move_to(upperLeftX, upperLeftY) ||
- !can_move_to(upperLeftX+1, upperLeftY+1)))
- canPropagateDown = 0;
- if(oldChildNode->enter_direction==enter_direct-1 &&
- oldChildNode->node_x-oldNode->node_x==xShift2 &&
- oldChildNode->node_x-oldNode->node_y==yShift2 &&
- !can_move_to(upperLeftX,upperLeftY) &&
- !can_move_to(upperLeftX+1,upperLeftY+2))
- canPropagateDown = 0;
- if(oldChildNode->enter_direction==enter_direct+1 &&
- oldChildNode->node_x-oldNode->node_x==xShift2 &&
- oldChildNode->node_x-oldNode->node_y==yShift2 &&
- !can_move_to(upperLeftX+1,upperLeftY+1) &&
- !can_move_to(upperLeftX-1,upperLeftY))
- canPropagateDown = 0;
- break;
- case 4:
- if(oldChildNode->enter_direction==enter_direct &&
- oldChildNode->node_x-oldNode->node_x==xShift1 &&
- oldChildNode->node_y-oldNode->node_y==yShift1 &&
- (!can_move_to(upperLeftX+1, upperLeftY) ||
- !can_move_to(upperLeftX, upperLeftY+1)))
- canPropagateDown = 0;
- if(oldChildNode->enter_direction==enter_direct-1 &&
- oldChildNode->node_x-oldNode->node_x==xShift2 &&
- oldChildNode->node_x-oldNode->node_y==yShift2 &&
- !can_move_to(upperLeftX,upperLeftY+1)&&
- !can_move_to(upperLeftX+2,upperLeftY))
- canPropagateDown = 0;
- if(oldChildNode->enter_direction==enter_direct+1 &&
- oldChildNode->node_x-oldNode->node_x==xShift2 &&
- oldChildNode->node_x-oldNode->node_y==yShift2 &&
- !can_move_to(upperLeftX,upperLeftY+2) &&
- !can_move_to(upperLeftX+1,upperLeftY))
- canPropagateDown = 0;
- break;
- case 6:
- if(oldChildNode->enter_direction==enter_direct &&
- oldChildNode->node_x-oldNode->node_x==xShift1 &&
- oldChildNode->node_y-oldNode->node_y==yShift1 &&
- (!can_move_to(upperLeftX, upperLeftY) ||
- !can_move_to(upperLeftX+1, upperLeftY+1)))
- canPropagateDown = 0;
- if(oldChildNode->enter_direction==enter_direct-1 &&
- oldChildNode->node_x-oldNode->node_x==xShift2 &&
- oldChildNode->node_x-oldNode->node_y==yShift2 &&
- !can_move_to(upperLeftX,upperLeftY-1)&&
- !can_move_to(upperLeftX+1,upperLeftY+1))
- canPropagateDown = 0;
- if(oldChildNode->enter_direction==enter_direct+1 &&
- oldChildNode->node_x-oldNode->node_x==xShift2 &&
- oldChildNode->node_x-oldNode->node_y==yShift2 &&
- !can_move_to(upperLeftX,upperLeftY) &&
- !can_move_to(upperLeftX+2,upperLeftY+1))
- canPropagateDown = 0;
- break;
- case 8:
- if(oldChildNode->enter_direction==enter_direct &&
- oldChildNode->node_x-oldNode->node_x==xShift1 &&
- oldChildNode->node_y-oldNode->node_y==yShift1 &&
- (!can_move_to(upperLeftX+1, upperLeftY) ||
- !can_move_to(upperLeftX, upperLeftY+1)))
- canPropagateDown = 0;
- if(oldChildNode->enter_direction==enter_direct-1 &&
- oldChildNode->node_x-oldNode->node_x==xShift2 &&
- oldChildNode->node_x-oldNode->node_y==yShift2 &&
- !can_move_to(upperLeftX-1,upperLeftY+1)&&
- !can_move_to(upperLeftX+1,upperLeftY))
- canPropagateDown = 0;
- if(oldChildNode->enter_direction==(enter_direct%8+1) &&
- oldChildNode->node_x-oldNode->node_x==xShift2 &&
- oldChildNode->node_x-oldNode->node_y==yShift2 &&
- !can_move_to(upperLeftX+1,upperLeftY-1) &&
- !can_move_to(upperLeftX,upperLeftY+1))
- canPropagateDown = 0;
- break;
- default: err_here();
- break;
- }
- }
- }
- }
-
- if(canPropagateDown)
- {
- oldNode->parent_node = this;
- oldNode->node_g = g;
- oldNode->node_f = g+oldNode->node_h;
- oldNode->enter_direction = (char)enter_direct;
- //-------- if it's a closed node ---------//
- if( oldNode->child_node[0] )
- {
- //-------------------------------------------------//
- // Since we changed the g value of oldNode, we need
- // to propagate this new value downwards, i.e.
- // do a Depth-First traversal of the tree!
- //-------------------------------------------------//
- oldNode->propagate_down();
- sys_yield();
- }
- }
- }
- }
- else //------------ add a new node -----------//
- {
- NodeS2* succNode = cur_node_array_s2 + cur_seek_path_s2->node_count++;
- memset(succNode, 0, sizeof(NodeS2));
- succNode->parent_node = this;
- succNode->node_g = g;
- succNode->node_h = (x-cur_dest_x_s2)*(x-cur_dest_x_s2)+(y-cur_dest_y_s2)*(y-cur_dest_y_s2); // should do sqrt(), but since we don't really
- succNode->node_f = g+succNode->node_h; // care about the distance but just which branch looks
- succNode->node_x = x; // better this should suffice. Anyayz it's faster.
- succNode->node_y = y;
- succNode->enter_direction = (char)enter_direct;
- succNode->node_type =can_move_to(upperLeftX,upperLeftY)+(can_move_to(upperLeftX+1,upperLeftY)<<1)+
- (can_move_to(upperLeftX,upperLeftY+1)<<2)+(can_move_to(upperLeftX+1,upperLeftY+1)<<3);
- /*if(search_mode_s2==4 && nodeRecno>max_node_num_s2)
- {
- reuse_connect_node_exit_direction = nodeRecno - max_node_num_s2;
- reuse_result_node_ptr_s2 = succNode;
- return 1;
- }*/
-
- if(search_mode_s2==SEARCH_MODE_REUSE && nodeRecno>max_node_num_s2) // path-reuse node found, but checking of can_walk(final_dest_?) is requested
- {
- int destIndex = nodeRecno - max_node_num_s2;
- int addNode = 1;
- switch(destIndex)
- {
- case 1:
- final_dest_x_s2 = x<<1;
- final_dest_y_s2 = y<<1;
- break;
- case 2:
- if(enter_direct==2 && (!succNode->node_type&0x1 || !can_move_to((x<<1)+1,(y<<1)+2) ) )
- addNode = 0;
- if(addNode && enter_direct==8 && (!succNode->node_type&0x4 || !can_move_to((x<<1)+1,(y<<1)-1) ) )
- addNode = 0;
- if(addNode) // not the two blocked cases
- {
- final_dest_x_s2 = (x<<1) + 1;
- final_dest_y_s2 = y<<1;
- }
- break;
- case 3:
- if(enter_direct==6 && (!succNode->node_type&0x1 || !can_move_to((x<<1)+2,(y<<1)+1) ) )
- addNode = 0;
- if(addNode && enter_direct==8 && (!succNode->node_type&0x2 || !can_move_to((x<<1)-1,(y<<1)+1) ) )
- addNode = 0;
- if(addNode) // not the two blocked cases
- {
- final_dest_x_s2 = x<<1;
- final_dest_y_s2 = (y<<1)+1;
- }
- break;
- case 4:
- if(enter_direct==1 && (!succNode->node_type&0x2 || !can_move_to(x<<1,(y<<1)+2) ) )
- addNode = 0;
- if(addNode && enter_direct==7 && (!succNode->node_type&0x4 || !can_move_to((x<<1)+2,y<<1) ) )
- addNode = 0;
- if(addNode && enter_direct==8 && (!succNode->node_type&0x2 || !succNode->node_type&0x4) )
- addNode = 0;
- if(addNode) // not the two blocked cases
- {
- final_dest_x_s2 = (x<<1)+1;
- final_dest_y_s2 = (y<<1)+1;
- }
- break;
- default: err_here();
- break;
- }
- if(addNode)
- {
- reuse_result_node_ptr_s2 = succNode;
- err_when(!can_move_to_s2(final_dest_x_s2, final_dest_y_s2));
- return 1; // PATH_REUSE_FOUND
- }
- else // add nothing
- {
- memset(succNode, 0, sizeof(NodeS2));
- cur_seek_path_s2->node_count--;
- return 0;
- }
- }
-
- cur_node_matrix_s2[y*(MAX_WORLD_X_LOC/2+1)+x] = cur_seek_path_s2->node_count;
- cur_seek_path_s2->insert_open_node(succNode); // insert succNode on open_node_list list wrt f
- for(c=0 ; c<MAX_CHILD_NODE && child_node[c] ; c++); // Add oldNode to the list of BestNode's child_noderen (or succNodes).
- child_node[c]=succNode;
- }
- return 0;
- }
- //------- End of function NodeS2::generate_succ -------//
- //-------- Begin of function NodeS2::propagate_down ---------//
- void NodeS2::propagate_down()
- {
- NodeS2 *childNode, *fatherNode;
- int c, g=node_g; // alias.
- short cost;
- char xShift, yShift; // the x, y difference between parent and child nodes
- char childEnterDirection;
- char exitDirection;
- char testResult;
-
- for(c=0;c<8;c++)
- {
- if ((childNode=child_node[c])==NULL) // create alias for faster access.
- break;
- if(childNode->parent_node==this)
- break;
- cost = 2; // in fact, may be 1 or 2
- if (g+cost <= childNode->node_g) // first checking
- {
- char canMove = 0;
- int childUpperLeftX = childNode->node_x<<1;
- int childUpperLeftY = childNode->node_y<<1;
- xShift = childNode->node_x-node_x;
- yShift = childNode->node_y-node_y;
- err_when(abs(xShift)>1 || abs(yShift)>1);
- //---------- calulate the new enter direction ------------//
- switch(yShift)
- {
- case -1:
- childEnterDirection = char(3-xShift);
- break;
- case 0:
- childEnterDirection = char(3-(xShift<<1));
- break;
- case 1:
- childEnterDirection = char(7+xShift);
- break;
- }
- //---------- decide can move or not and use special case or not --------//
- switch(childEnterDirection)
- {
- case 1:
- err_when(node_x!=childNode->node_x-1 || node_y!=childNode->node_y);
- if(can_move_to(childUpperLeftX-1,childUpperLeftY) && childNode->node_type&0x1 &&
- can_move_to(childUpperLeftX-1,childUpperLeftY+1) && childNode->node_type&0x4) //if the entering location is walkable
- {
- switch(enter_direction)
- {
- case 5: canMove = 0; //reverse direction
- break;
-
- case 1:case 3:case 4:case 6:case 7: // obviously
- canMove = 1;
- break;
- case 2: if(node_type&0x1 || can_move_to(childUpperLeftX-1, childUpperLeftY+2))
- canMove = 1;
- break;
- case 8: if(node_type&0x4 || can_move_to(childUpperLeftX-1, childUpperLeftY-1))
- canMove = 1;
- break;
- default: err_here();
- break;
- }
- }
- break;
- case 2:
- err_when(node_x!=childNode->node_x-1 || node_y!=childNode->node_y+1);
- if(can_move_to(childUpperLeftX-1,childUpperLeftY+1) && childNode->node_type&0x4 &&
- can_move_to(childUpperLeftX-1,childUpperLeftY+2) && can_move_to(childUpperLeftX,childUpperLeftY+2))
- {
- switch(enter_direction)
- {
- case 6: canMove = 0; //reverse direction
- break;
- case 4:case 5:case 7:case 8:
- canMove = 1;
- break;
- case 1: if(node_type&0x8 || can_move_to(childUpperLeftX-2, childUpperLeftY+1))
- canMove = 1;
- break;
- case 2: if(node_type==15)
- canMove = 1;
- else
- canMove = 0;
- break;
- case 3: if(node_type&0x1 || can_move_to(childUpperLeftX, childUpperLeftY+3))
- canMove = 1;
- break;
- default: err_here();
- break;
- }
- }
- break;
- case 3:
- err_when(node_x!=childNode->node_x || node_y!=childNode->node_y+1);
- if(childNode->node_type&0x4 && childNode->node_type&0x8 &&
- can_move_to(childUpperLeftX,childUpperLeftY+2) && can_move_to(childUpperLeftX+1,childUpperLeftY+2))
- {
- switch(enter_direction)
- {
- case 7: canMove = 0; //reverse direction
- break;
- case 1:case 3:case 5:case 6:case 8:
- canMove = 1;
- break;
- case 2: if(node_type&0x8 || can_move_to(childUpperLeftX-1, childUpperLeftY+2))
- canMove = 1;
- break;
- case 4: if(node_type&0x4 || can_move_to(childUpperLeftX+2, childUpperLeftY+2))
- canMove = 1;
- break;
- default: err_here();
- break;
- }
- }
- break;
- case 4:
- err_when(node_x!=childNode->node_x+1 || node_y!=childNode->node_y+1);
- if(childNode->node_type&0x8 && can_move_to(childUpperLeftX+2,childUpperLeftY+1) &&
- can_move_to(childUpperLeftX+1,childUpperLeftY+2) && can_move_to(childUpperLeftX+2,childUpperLeftY+2))
- {
- switch(enter_direction)
- {
- case 8: canMove = 0; //reverse direction
- break;
- case 1:case 2:case 6:case 7:
- canMove = 1;
- break;
- case 3: if(node_type&0x2 || can_move_to(childUpperLeftX+1, childUpperLeftY+3))
- canMove = 1;
- break;
- case 4: if(node_type==15)
- canMove = 1;
- else
- canMove = 0;
- break;
- case 5: if(node_type&0x4 || can_move_to(childUpperLeftX+3, childUpperLeftY+1))
- canMove = 1;
- break;
- default: err_here();
- break;
- }
- }
- break;
- case 5:
- err_when(node_x!=childNode->node_x+1 || node_y!=childNode->node_y);
- if(childNode->node_type&0x2 && can_move_to(childUpperLeftX+2,childUpperLeftY) &&
- childNode->node_type&0x8 && can_move_to(childUpperLeftX+2,childUpperLeftY+1))
- {
- switch(enter_direction)
- {
- case 1: canMove = 0; //reverse direction
- break;
- case 2:case 3:case 5:case 7:case 8:
- canMove = 1;
- break;
- case 4: if(node_type&0x2 || can_move_to(childUpperLeftX+2, childUpperLeftY+2))
- canMove = 1;
- break;
- case 6: if(node_type&0x8 || can_move_to(childUpperLeftX+2, childUpperLeftY-1))
- canMove = 1;
- break;
- default: err_here();
- break;
- }
- }
- break;
- case 6:
- err_when(node_x!=childNode->node_x+1 || node_y!=childNode->node_y-1);
- if(can_move_to(childUpperLeftX+1,childUpperLeftY-1) && can_move_to(childUpperLeftX+2,childUpperLeftY-1) &&
- childNode->node_type&0x2 && can_move_to(childUpperLeftX+2,childUpperLeftY))
- {
- switch(enter_direction)
- {
- case 2: canMove = 0; //reverse direction
- break;
- case 1:case 3:case 4:case 8:
- canMove = 1;
- break;
- case 5: if(node_type&0x1 || can_move_to(childUpperLeftX+3, childUpperLeftY))
- canMove = 1;
- break;
- case 6: if(node_type==15)
- canMove = 1;
- else
- canMove = 0;
- break;
- case 7: if(node_type&0x8 || can_move_to(childUpperLeftX+1, childUpperLeftY-2))
- canMove = 1;
- break;
- default: err_here();
- break;
- }
- }
- break;
- case 7:
- err_when(node_x!=childNode->node_x || node_y!=childNode->node_y-1);
- if(can_move_to(childUpperLeftX,childUpperLeftY-1) && can_move_to(childUpperLeftX+1,childUpperLeftY-1) &&
- childNode->node_type&0x1 && childNode->node_type&0x2)
- {
- switch(enter_direction)
- {
- case 3: canMove = 0; //reverse direction
- break;
- case 1:case 2:case 4:case 5:case 7:
- canMove = 1;
- break;
- case 6: if(node_type&0x1 || can_move_to(childUpperLeftX+2, childUpperLeftY-1))
- canMove = 1;
- break;
- case 8: if(node_type&0x2 || can_move_to(childUpperLeftX-1, childUpperLeftY-1))
- canMove = 1;
- break;
- default: err_here();
- break;
- }
- }
- break;
- case 8:
- err_when(node_x!=childNode->node_x-1 || node_y!=childNode->node_y-1);
- if(can_move_to(childUpperLeftX-1,childUpperLeftY-1) && can_move_to(childUpperLeftX,childUpperLeftY-1) &&
- can_move_to(childUpperLeftX-1,childUpperLeftY) && childNode->node_type&0x1)//can_move_to(childUpperLeftX,childUpperLeftY))
- {
- switch(enter_direction)
- {
- case 4: canMove = 0; //reverse direction
- break;
- case 2:case 3:case 5:case 6:
- canMove = 1;
- break;
- case 1: if(node_type&0x2 || can_move_to(childUpperLeftX-2, childUpperLeftY))
- canMove = 1;
- break;
- case 7: if(node_type&0x4 || can_move_to(childUpperLeftX, childUpperLeftY-2))
- canMove = 1;
- break;
- case 8: if(node_type==15)
- canMove = 1;
- else
- canMove = 0;
- break;
- default: err_here();
- break;
- }
- }
- break;
- default: err_here();
- break;
- }
- if(canMove) // can move in the child node
- {
- exitDirection = (childEnterDirection+3)%8+1;
-
- if(enter_direction > exitDirection)
- {
- if((enter_direction==8 && (exitDirection==1 || exitDirection==2)) ||
- (enter_direction==7 && exitDirection==1))
- testResult = exitDirection + 8 - enter_direction;
- else
- testResult = enter_direction - exitDirection;
- }
- else
- {
- if((exitDirection==8 && (enter_direction==1 || enter_direction==2)) ||
- (exitDirection==7 && enter_direction==1))
- testResult = enter_direction + 8 - exitDirection;
- else
- testResult = exitDirection - enter_direction;
- }
- if((exitDirection%2 && testResult<=2) || (!exitDirection%2 && testResult<=1))
- cost = 1;
- else
- cost = 2;
-
- err_when(cost>2 || cost<1);
- if(g+cost < childNode->node_g) // second checking, mainly for cost = 2;
- {
- char canPropagateDown=1;
- if(childNode->node_type!=15 && childEnterDirection%2==0)
- {
- NodeS2* oldChildNode;
- short xShift1 = x_shift_array[childEnterDirection-1];
- short yShift1 = y_shift_array[childEnterDirection-1];
- short xShift2, yShift2, xShift3, yShift3;
- if(childEnterDirection>1)
- {
- xShift2 = x_shift_array[childEnterDirection-2];
- yShift2 = y_shift_array[childEnterDirection-2];
- }
- else
- {
- xShift2 = x_shift_array[7];
- yShift2 = y_shift_array[7];
- }
- if(childEnterDirection<8)
- {
- xShift3 = x_shift_array[childEnterDirection];
- yShift3 = y_shift_array[childEnterDirection];
- }
- else
- {
- xShift3 = x_shift_array[0];
- yShift3 = y_shift_array[0];
- }
- for(c=0; c<MAX_CHILD_NODE && childNode->child_node[c]; c++) // for each child of oldNode
- {
- oldChildNode = childNode->child_node[c];
- if(childNode->parent_node != oldChildNode)
- {
- switch(childEnterDirection)
- {
- case 2:
- if(oldChildNode->enter_direction==childEnterDirection &&
- oldChildNode->node_x-childNode->node_x==xShift1 &&
- oldChildNode->node_y-childNode->node_y==yShift1)
- canPropagateDown = 0;
- if(oldChildNode->enter_direction==childEnterDirection-1 &&
- oldChildNode->node_x-childNode->node_x==xShift2 &&
- oldChildNode->node_x-childNode->node_y==yShift2 &&
- !can_move_to(childUpperLeftX,childUpperLeftY)&&
- !can_move_to(childUpperLeftX+1,childUpperLeftY+2))
- canPropagateDown = 0;
-
- if(oldChildNode->enter_direction==childEnterDirection+1 &&
- oldChildNode->node_x-childNode->node_x==xShift2 &&
- oldChildNode->node_x-childNode->node_y==yShift2 &&
- !can_move_to(childUpperLeftX+1,childUpperLeftY+1) &&
- !can_move_to(childUpperLeftX-1,childUpperLeftY))
- canPropagateDown = 0;
- break;
- case 4:
- if(oldChildNode->enter_direction==childEnterDirection &&
- oldChildNode->node_x-childNode->node_x==xShift1 &&
- oldChildNode->node_y-childNode->node_y==yShift1)
- canPropagateDown = 0;
- if(oldChildNode->enter_direction==childEnterDirection-1 &&
- oldChildNode->node_x-childNode->node_x==xShift2 &&
- oldChildNode->node_x-childNode->node_y==yShift2 &&
- !can_move_to(childUpperLeftX,childUpperLeftY+1)&&
- !can_move_to(childUpperLeftX+2,childUpperLeftY))
- canPropagateDown = 0;
- if(oldChildNode->enter_direction==childEnterDirection+1 &&
- oldChildNode->node_x-childNode->node_x==xShift2 &&
- oldChildNode->node_x-childNode->node_y==yShift2 &&
- !can_move_to(childUpperLeftX,childUpperLeftY+2) &&
- !can_move_to(childUpperLeftX+1,childUpperLeftY))
- canPropagateDown = 0;
- break;
- case 6:
- if(oldChildNode->enter_direction==childEnterDirection &&
- oldChildNode->node_x-childNode->node_x==xShift1 &&
- oldChildNode->node_y-childNode->node_y==yShift1)
- canPropagateDown = 0;
-
- if(oldChildNode->enter_direction==childEnterDirection-1 &&
- oldChildNode->node_x-childNode->node_x==xShift2 &&
- oldChildNode->node_x-childNode->node_y==yShift2 &&
- !can_move_to(childUpperLeftX,childUpperLeftY-1)&&
- !can_move_to(childUpperLeftX+1,childUpperLeftY+1))
- canPropagateDown = 0;
- if(oldChildNode->enter_direction==childEnterDirection+1 &&
- oldChildNode->node_x-childNode->node_x==xShift2 &&
- oldChildNode->node_x-childNode->node_y==yShift2 &&
- !can_move_to(childUpperLeftX,childUpperLeftY) &&
- !can_move_to(childUpperLeftX+2,childUpperLeftY+1))
- canPropagateDown = 0;
- break;
- case 8:
- if(oldChildNode->enter_direction==childEnterDirection &&
- oldChildNode->node_x-childNode->node_x==xShift1 &&
- oldChildNode->node_y-childNode->node_y==yShift1)
- canPropagateDown = 0;
- if(oldChildNode->enter_direction==childEnterDirection-1 &&
- oldChildNode->node_x-childNode->node_x==xShift2 &&
- oldChildNode->node_x-childNode->node_y==yShift2 &&
- !can_move_to(childUpperLeftX-1,childUpperLeftY+1)&&
- !can_move_to(childUpperLeftX+1,childUpperLeftY))
- canPropagateDown = 0;
- if(oldChildNode->enter_direction==childEnterDirection+1 &&
- oldChildNode->node_x-childNode->node_x==xShift2 &&
- oldChildNode->node_x-childNode->node_y==yShift2 &&
- !can_move_to(childUpperLeftX+1,childUpperLeftY-1) &&
- !can_move_to(childUpperLeftX,childUpperLeftY+1))
- canPropagateDown = 0;
- break;
- default: err_here();
- break;
- }
- }
- }
- }
-
- if(canPropagateDown)
- {
- childNode->node_g = g+cost;
- childNode->node_f = childNode->node_g+childNode->node_h;
- childNode->parent_node = this;// reset parent to new path.
- childNode->enter_direction = childEnterDirection;
- stack_push(childNode); // Now the childNode's branch need to be checked out. Remember the new cost must be propagated down.
- }
- }
- }
- }
- }
- while( cur_stack_pos_s2>0 )
- {
- fatherNode=stack_pop();
- g = fatherNode->node_g;
- for(c=0;c<8;c++)
- {
- if ((childNode=fatherNode->child_node[c])==NULL) // we may stop the propagation 2 ways: either
- break;
- if(childNode->parent_node==fatherNode)
- break;
- cost = 2; // in fact, may be 1 or 2
- if (g+cost <= childNode->node_g) // first checking
- // there are no children, or that the g value of the child is equal or better than the cost we're propagating
- {
- char canMove = 0;
- int childUpperLeftX = childNode->node_x<<1;
- int childUpperLeftY = childNode->node_y<<1;
-
- xShift = childNode->node_x-fatherNode->node_x;
- yShift = childNode->node_y-fatherNode->node_y;
- err_when(abs(xShift)>1 || abs(yShift)>1);
- //---------- calulate the new enter direction ------------//
- switch(yShift)
- {
- case -1:
- childEnterDirection = char(3-xShift);
- break;
- case 0:
- childEnterDirection = char(3-(xShift<<1));
- break;
- case 1:
- childEnterDirection = char(7+xShift);
- break;
- }
- switch(childEnterDirection)
- {
- case 1:
- err_when(fatherNode->node_x!=childNode->node_x-1 || fatherNode->node_y!=childNode->node_y);
- if(can_move_to(childUpperLeftX-1,childUpperLeftY) && childNode->node_type&0x1 && //can_move_to(childUpperLeftX,childUpperLeftY) &&
- can_move_to(childUpperLeftX-1,childUpperLeftY+1) && childNode->node_type&0x4)//can_move_to(childUpperLeftX,childUpperLeftY+1))
- {
- switch(fatherNode->enter_direction)
- {
- case 5: canMove = 0; //reverse direction
- break;
- case 1:case 3:case 4:case 6:case 7:
- canMove = 1;
- break;
- case 2: if(fatherNode->node_type&0x1 || can_move_to(childUpperLeftX-1, childUpperLeftY+2))
- canMove = 1;
- break;
- case 8: if(fatherNode->node_type&0x4 || can_move_to(childUpperLeftX-1, childUpperLeftY-1))
- canMove = 1;
- break;
- default: err_here();
- break;
- }
- }
- break;
- case 2:
- err_when(fatherNode->node_x!=childNode->node_x-1 || fatherNode->node_y!=childNode->node_y+1);
- if(can_move_to(childUpperLeftX-1,childUpperLeftY+1) && childNode->node_type&0x4 &&//can_move_to(childUpperLeftX,childUpperLeftY+1) &&
- can_move_to(childUpperLeftX-1,childUpperLeftY+2) && can_move_to(childUpperLeftX,childUpperLeftY+2))
- {
- switch(fatherNode->enter_direction)
- {
- case 6: canMove = 0; //reverse direction
- break;
- case 4:case 5:case 7:case 8:
- canMove = 1;
- break;
- case 1: if(fatherNode->node_type&0x8 || can_move_to(childUpperLeftX-2,childUpperLeftY+1))
- canMove = 1;
- break;
- case 2: if(fatherNode->node_type==15)
- canMove = 1;
- else
- canMove = 0;
- break;
- case 3: if(fatherNode->node_type&0x1 || can_move_to(childUpperLeftX,childUpperLeftY+3))
- canMove = 1;
- break;
- default: err_here();
- break;
- }
- canMove = 1;
- }
- break;
- case 3:
- err_when(fatherNode->node_x!=childNode->node_x || fatherNode->node_y!=childNode->node_y+1);
- if(childNode->node_type&0x4 && childNode->node_type&0x8 &&
- can_move_to(childUpperLeftX,childUpperLeftY+2) && can_move_to(childUpperLeftX+1,childUpperLeftY+2))
- {
- switch(fatherNode->enter_direction)
- {
- case 7: canMove = 0; //reverse direction
- break;
- case 1:case 3:case 5:case 6:case 8:
- canMove = 1;
- break;
- case 2: if(fatherNode->node_type&0x8 || can_move_to(childUpperLeftX-1,childUpperLeftY+2))
- canMove = 1;
- break;
- case 4: if(fatherNode->node_type&0x4 || can_move_to(childUpperLeftX+2,childUpperLeftY+2))
- canMove = 1;
- break;
- default: err_here();
- break;
- }
- }
- break;
- case 4:
- err_when(fatherNode->node_x!=childNode->node_x+1 || fatherNode->node_y!=childNode->node_y+1);
- if(childNode->node_type&0x8 && can_move_to(childUpperLeftX+2,childUpperLeftY+1) &&
- can_move_to(childUpperLeftX+1,childUpperLeftY+2) && can_move_to(childUpperLeftX+2,childUpperLeftY+2))
- {
- switch(fatherNode->enter_direction)
- {
- case 8: canMove = 0; //reverse direction
- break;
- case 1:case 2:case 6:case 7:
- canMove = 1;
- break;
- case 3: if(fatherNode->node_type&0x2 || can_move_to(childUpperLeftX+1,childUpperLeftY+3))
- canMove = 1;
- break;
- case 4: if(fatherNode->node_type==15)
- canMove = 1;
- else
- canMove = 0;
- break;
- case 5: if(fatherNode->node_type&0x4 && can_move_to(childUpperLeftX+3,childUpperLeftY+1))
- canMove = 1;
- break;
- default: err_here();
- break;
- }
- }
- break;
- case 5:
- err_when(fatherNode->node_x!=childNode->node_x+1 || fatherNode->node_y!=childNode->node_y);
- if(childNode->node_type&0x2 && can_move_to(childUpperLeftX+2,childUpperLeftY) &&
- childNode->node_type&0x8 && can_move_to(childUpperLeftX+2,childUpperLeftY+1))
- {
- switch(fatherNode->enter_direction)
- {
- case 1: canMove = 0; //reverse direction
- break;
-
- case 2:case 3:case 5:case 7:case 8:
- canMove = 1;
- break;
- case 4: if(fatherNode->node_type&0x2 || can_move_to(childUpperLeftX+2,childUpperLeftY+2))
- canMove = 1;
- break;
- case 6: if(fatherNode->node_type&0x8 || can_move_to(childUpperLeftX+2,childUpperLeftY-1))
- canMove = 1;
- break;
- default: err_here();
- break;
- }
- }
- break;
-
- case 6:
- err_when(fatherNode->node_x!=childNode->node_x+1 || fatherNode->node_y!=childNode->node_y-1);
- if(can_move_to(childUpperLeftX+1,childUpperLeftY-1) && can_move_to(childUpperLeftX+2,childUpperLeftY-1) &&
- childNode->node_type&0x2 && can_move_to(childUpperLeftX+2,childUpperLeftY))
- {
- switch(fatherNode->enter_direction)
- {
- case 2: canMove = 0; //reverse direction
- break;
-
- case 1:case 3:case 4:case 8:
- canMove = 1;
- break;
- case 5: if(fatherNode->node_type&0x1 || can_move_to(childUpperLeftX+3,childUpperLeftY))
- canMove = 1;
- break;
- case 6: if(fatherNode->node_type==15)
- canMove = 1;
- else
- canMove = 0;
- break;
- case 7: if(fatherNode->node_type&0x8 || can_move_to(childUpperLeftX+1,childUpperLeftY-2))
- canMove = 1;
- break;
- default: err_here();
- break;
- }
- }
- break;
- case 7:
- err_when(fatherNode->node_x!=childNode->node_x || fatherNode->node_y!=childNode->node_y-1);
- if(can_move_to(childUpperLeftX,childUpperLeftY-1) && can_move_to(childUpperLeftX+1,childUpperLeftY-1) &&
- childNode->node_type&0x1 && childNode->node_type&0x2)
- {
- switch(fatherNode->enter_direction)
- {
- case 3: canMove = 0; //reverse direction
- break;
-
- case 1:case 2:case 4:case 5:case 7:
- canMove = 1;
- break;
- case 6: if(fatherNode->node_type&0x1 || can_move_to(childUpperLeftX+2,childUpperLeftY-1))
- canMove = 1;
- break;
- case 8: if(fatherNode->node_type&0x2 || can_move_to(childUpperLeftX-1,childUpperLeftY-1))
- canMove = 1;
- break;
- default: err_here();
- break;
- }
- }
- break;
- case 8:
- err_when(fatherNode->node_x!=childNode->node_x-1 || fatherNode->node_y!=childNode->node_y-1);
- if(can_move_to(childUpperLeftX-1,childUpperLeftY-1) && can_move_to(childUpperLeftX,childUpperLeftY-1) &&
- can_move_to(childUpperLeftX-1,childUpperLeftY) && childNode->node_type&0x1)//can_move_to(childUpperLeftX,childUpperLeftY))
- {
- switch(fatherNode->enter_direction)
- {
- case 4: canMove = 0; //reverse direction
- break;
- case 2:case 3:case 5:case 6:
- canMove = 1;
- break;
- case 1: if(fatherNode->node_type&0x2 || can_move_to(childUpperLeftX-2,childUpperLeftY))
- canMove = 1;
- break;
- case 8: if(fatherNode->node_type==15)
- canMove = 1;
- else
- canMove = 0;
- break;
- case 7: if(fatherNode->node_type&0x4 || can_move_to(childUpperLeftX,childUpperLeftY-2))
- canMove = 1;
- break;
- default: err_here();
- break;
- }
- }
- break;
-
- default: err_here();
- break;
- }
- if(canMove)
- {
- exitDirection = (childEnterDirection+3)%8+1;
- if(fatherNode->enter_direction > exitDirection)
- {
- if((fatherNode->enter_direction==8 && (exitDirection==1 || exitDirection==2)) ||
- (fatherNode->enter_direction==7 && exitDirection==1))
- testResult = exitDirection + 8 - fatherNode->enter_direction;
- else
- testResult = fatherNode->enter_direction - exitDirection;
- }
- else
- {
- if((exitDirection==8 && (fatherNode->enter_direction==1 || fatherNode->enter_direction==2)) ||
- (exitDirection==7 && fatherNode->enter_direction==1))
- testResult = fatherNode->enter_direction + 8 - exitDirection;
- else
- testResult = exitDirection - fatherNode->enter_direction;
- }
- if((exitDirection%2 && testResult<=2) || (!exitDirection%2 && testResult<=1))
- cost = 1;
- else
- cost = 2;
-
- err_when(cost>2 || cost<1);
- if(g+cost < childNode->node_g) // second checking, mainly for cost = 2;
- {
- char canPropagateDown=1;
- if(childNode->node_type!=15 && childEnterDirection%2==0)
- {
- NodeS2* oldChildNode;
- short xShift1 = x_shift_array[childEnterDirection-1];
- short yShift1 = y_shift_array[childEnterDirection-1];
- short xShift2, yShift2, xShift3, yShift3;
- if(childEnterDirection>1)
- {
- xShift2 = x_shift_array[childEnterDirection-2];
- yShift2 = y_shift_array[childEnterDirection-2];
- }
- else
- {
- xShift2 = x_shift_array[7];
- yShift2 = y_shift_array[7];
- }
- if(childEnterDirection<8)
- {
- xShift3 = x_shift_array[childEnterDirection];
- yShift3 = y_shift_array[childEnterDirection];
- }
- else
- {
- xShift3 = x_shift_array[0];
- yShift3 = y_shift_array[0];
- }
- for(c=0; c<MAX_CHILD_NODE && childNode->child_node[c]; c++) // for each child of oldNode
- {
- oldChildNode = childNode->child_node[c];
- if(childNode->parent_node != oldChildNode)
- {
- switch(childEnterDirection)
- {
- case 2:
- if(oldChildNode->enter_direction==childEnterDirection &&
- oldChildNode->node_x-childNode->node_x==xShift1 &&
- oldChildNode->node_y-childNode->node_y==yShift1)
- canPropagateDown = 0;
- if(oldChildNode->enter_direction==childEnterDirection-1 &&
- oldChildNode->node_x-childNode->node_x==xShift2 &&
- oldChildNode->node_x-childNode->node_y==yShift2 &&
- !can_move_to(childUpperLeftX,childUpperLeftY)&&
- !can_move_to(childUpperLeftX+1,childUpperLeftY+2))
- canPropagateDown = 0;
-
- if(oldChildNode->enter_direction==childEnterDirection+1 &&
- oldChildNode->node_x-childNode->node_x==xShift2 &&
- oldChildNode->node_x-childNode->node_y==yShift2 &&
- !can_move_to(childUpperLeftX+1,childUpperLeftY+1) &&
- !can_move_to(childUpperLeftX-1,childUpperLeftY))
- canPropagateDown = 0;
- break;
- case 4:
- if(oldChildNode->enter_direction==childEnterDirection &&
- oldChildNode->node_x-childNode->node_x==xShift1 &&
- oldChildNode->node_y-childNode->node_y==yShift1)
- canPropagateDown = 0;
-
- if(oldChildNode->enter_direction==childEnterDirection-1 &&
- oldChildNode->node_x-childNode->node_x==xShift2 &&
- oldChildNode->node_x-childNode->node_y==yShift2 &&
- !can_move_to(childUpperLeftX,childUpperLeftY+1)&&
- !can_move_to(childUpperLeftX+2,childUpperLeftY))
- canPropagateDown = 0;
- if(oldChildNode->enter_direction==childEnterDirection+1 &&
- oldChildNode->node_x-childNode->node_x==xShift2 &&
- oldChildNode->node_x-childNode->node_y==yShift2 &&
- !can_move_to(childUpperLeftX,childUpperLeftY+2) &&
- !can_move_to(childUpperLeftX+1,childUpperLeftY))
- canPropagateDown = 0;
- break;
- case 6:
- if(oldChildNode->enter_direction==childEnterDirection &&
- oldChildNode->node_x-childNode->node_x==xShift1 &&
- oldChildNode->node_y-childNode->node_y==yShift1)
- canPropagateDown = 0;
-
- if(oldChildNode->enter_direction==childEnterDirection-1 &&
- oldChildNode->node_x-childNode->node_x==xShift2 &&
- oldChildNode->node_x-childNode->node_y==yShift2 &&
- !can_move_to(childUpperLeftX,childUpperLeftY-1)&&
- !can_move_to(childUpperLeftX+1,childUpperLeftY+1))
- canPropagateDown = 0;
- if(oldChildNode->enter_direction==childEnterDirection+1 &&
- oldChildNode->node_x-childNode->node_x==xShift2 &&
- oldChildNode->node_x-childNode->node_y==yShift2 &&
- !can_move_to(childUpperLeftX,childUpperLeftY) &&
- !can_move_to(childUpperLeftX+2,childUpperLeftY+1))
- canPropagateDown = 0;
- break;
- case 8:
- if(oldChildNode->enter_direction==childEnterDirection &&
- oldChildNode->node_x-childNode->node_x==xShift1 &&
- oldChildNode->node_y-childNode->node_y==yShift1)
- canPropagateDown = 0;
-
- if(oldChildNode->enter_direction==childEnterDirection-1 &&
- oldChildNode->node_x-childNode->node_x==xShift2 &&
- oldChildNode->node_x-childNode->node_y==yShift2 &&
- !can_move_to(childUpperLeftX-1,childUpperLeftY+1)&&
- !can_move_to(childUpperLeftX+1,childUpperLeftY))
- canPropagateDown = 0;
- if(oldChildNode->enter_direction==childEnterDirection+1 &&
- oldChildNode->node_x-childNode->node_x==xShift2 &&
- oldChildNode->node_x-childNode->node_y==yShift2 &&
- !can_move_to(childUpperLeftX+1,childUpperLeftY-1) &&
- !can_move_to(childUpperLeftX,childUpperLeftY+1))
- canPropagateDown = 0;
- break;
- default: err_here();
- break;
- }
- }
- }
- }
-
- if(canPropagateDown)
- {
- childNode->node_g = g+cost;
- childNode->node_f = childNode->node_g+childNode->node_h;
- childNode->parent_node = fatherNode;
- childNode->enter_direction = childEnterDirection;
- stack_push(childNode);
- }
- }
- }
- }
- }
- }
- }
- //------- End of function NodeS2::propagate_down -------//
- //-------- Begin of static function stack_push ---------//
- static void stack_push(NodeS2 *nodePtr)
- {
- stack_array[cur_stack_pos_s2++] = nodePtr;
- err_when( cur_stack_pos_s2 >= MAX_STACK_NUM );
- }
- //--------- End of static function stack_push ---------//
- //-------- Begin of static function stack_pop ---------//
- static NodeS2* stack_pop()
- {
- return stack_array[--cur_stack_pos_s2];
- }
- //--------- End of static function stack_pop ---------//
|