/[projet1]/users/barnsey123/HNEFATAFL/main.c
Defence Force logotype

Contents of /users/barnsey123/HNEFATAFL/main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1042 - (show annotations)
Wed Dec 18 18:24:12 2013 UTC (6 years, 3 months ago) by barnsey123
File MIME type: text/plain
File size: 97584 byte(s)
v0.101 more efficient text routines (press a key) saving 150 bytes.
Fixed problem of attackers moving out the way of the king to allow him to escape (well MOSTLY sorted).
Still some unusual behaviour related to BrokenArrow detection? Probably need to optimize pacman4...
1 // HNEFATAFL by Neil Barnes (a.k.a. Barnsey123)
2 // 24-08-2012 NB: Tided up source (removed "bracket hell")
3 // 27-08-2012 NB: v0.012 Minor changes to save memory
4 // 27-08-2012 NB: v0.013 Created Priority array and routine to populate it
5 // 28-08-2012 NB: v0.014 Add hightarget to pacman checkroute (when route to corners are empty)
6 // 30-08-2012 NB: V0.015 updated pacman routines - added brokenarrow
7 // 01-09-2012 NB: V0.016 Fixed brokenarrow
8 // 02-09-2012 NB: v0.017 Compressed - and fixed - checkroute()
9 // 03-09-2012 NB: v0.018 Rejigged pacman (do a while...to edge)
10 // 05-09-2012 NB: v0.019 pacman2
11 // 21-10-2012 NB: v0.020 Fixed bug in gspot
12 // 22-10-2012 NB: v0.021 Fixed bugs in following:
13 // pacman2 [not calculating hightarget in right place, not doing brokenarrow properly)
14 // sub [not calcing points properly]
15 // 23-10-2012 NB: v0.022 Removed some redundant code (enemytargetupdate)
16 // 24-04-2013 NB: v0.023 starting to add DEADPILE
17 // 25-04-2013 NB: v0.024 Font Changes for deadpile, endgame detection improvements, some memory reduction
18 // 27-04-2013 NB: v0.025 Some changes to make code clearer
19 // 29-04-2013 NB v0.026 some more cleary uppy stuff . fixed bug in endgame detection.broken arrow not working.
20 // 29-04-2013 NB v0.027 adding kingtracker (all the spaces where the king can get to
21 // 01-05-2013 NB v0.028 Brokenarrow fixed
22 // 01-05-2013 NB v0.029 Potential Broken Arrow Situation
23 // 02-05-2013 NB v0.030 Fixed central square "backbone" issue
24 // 02-05-2013 NB v0.031 Added TRIGGER weighting and changes to brokenarrow
25 // 04-05-2013 NB v0.032 Replecaed g variable in gspot with kingtargets array
26 // 04-05-2013 NB v0.033 Introduced pacman3 and some changes to subpacmanx
27 // 07-05-2013 NB v0.040 Skip 03x coz of different versions floating about
28 // 07-05-2013 NB v0.041 Fixed a few bugs, reduced footprint
29 // 08-05-2013 NB v0.042 resolving the vinegar strokes (trying)
30 // 08-05-2013 NB v0.043 SHAZAM! One major bug resolved (broken arrow issue)
31 // 09-05-2013 NB v0.044 Exploiting tzonemode
32 // 13-05-2013 NB v0.045 Introduction of RED FLAG (vinegar strokes issue 1 resolved) PROBLEM with illegal moves
33 // 13-05-2013 NB v0.046 released not tested
34 // 14-05-2013 NB v0.047 bugfix in enemy[][] array testing. Minor font change. Redflag disables full brokenarrow
35 // 15-05-2013 NB v0.048 Fixed illegal moves.
36 // 21-05-2013 NB v0.049 improving AI (RingOfSteel), added color to deadpile
37 // 03-06-2013 NB v0.050 Added color cursor (removed dotted type as got messy)
38 // 03-06-2013 NB v0.051 replace some draw and curset commands
39 // 04-06-2013 NB v0.052 minor change to brokenarrow
40 // 11-06-2013 NB v0.053 using asm instead of hchar/curset
41 // 12-06-2013 NB v0.054 add RowCountAtt and ColCountAtt to record number of attackers on any given row/col
42 // 15-07-2013 nb V0.060 (V0.055 IS PARKED)
43 // 17-07-2013 NB v0.061 Adding turncounters, turns remaining (huns, thor, odin variables)
44 // 17-07-2013 NB v0.062 removed "ring of steel"
45 // 17-07-2013 nb v0.063 Tidied up display, changed font, added SAGA, THOR, ODIN modes
46 // 18-07-2013 NB v0.064 REMOVE RowCountAtt and ColCountAtt
47 // 18-07-2013 NB v0.065 added "ring of steel" for THOR and ODIN levels
48 // 18-07-2013 NB v0.066 possible screw up with new ODINJUMP (though new calchightarget looks good)
49 // 18-07-2013 NB v0.067 FIRST BLOOD MODE
50 // 22-07-2013 NB v0.068 More efficient text display (for remaining turns)
51 // 22-07-2013 NB v0.069 Flashing TEXT for "PRESS A KEY" and FIRST BLOOD
52 // 06-09-2013 NB v0.070 Bug in calcantake2 WAS: (ew < 10) NOW: (ew < 9)
53 // 07-09-2013 NB v0.071 Adding flashing messages for multiple takes
54 // 04-11-2013 NB v0.072 To be called from VIKLOADER (this version has no font data loaded) and NO FLIPRUNE
55 // 05-11-2013 NB v0.073 Calling hires from CopyFont in Loader saving 3 bytes!
56 // Also adding border tiles for Trophy Display
57 // 06-11-2013 NB v0.074 Fixed Trophy Screen issues
58 // 07-11-2013 NB v0.075 New credits text
59 // 08-11-2013 NB v0.076 New Trophy Graphic, contents drawn
60 // 09-11-2013 NB v0.077 Draw Trophy Grid edges and Color Headings
61 // 24-11-2013 NB v0.078 Adds text to Trophy Screen...
62 // 26-11-2013 NB v0.079 changed some text messages
63 // 26-11-2013 NB v0.080 Changed RINGOFSTEEL behaviour (improves AI)
64 // 26-11-2013 NB v0.081 Variable TAKEWEIGHT to control agression
65 // 29-11-2013 NB v0.082 Changed kingtoedge to kingtargets
66 // 29-11-2013 NB v0.083 Fixed issue with REDFLAG (finally?)
67 // 01-12-2013 NB v0.084 The Sheldon Gambit part1 (left or right block?)
68 // 01-12-2013 NB v0.085 The Sheldon Gambit part2 (compressed, using sheldon array)
69 // 02-12-2013 NB v0.086 Added screen fade: CheckerBoard
70 // 03-12-2013 NB v0.087 Fixed bug in CheckerBoard
71 // 04-12-2013 NB v0.088 Reduced memory footprint (37222->36914)
72 // 05-12-2013 NB v0.089 More memory reductions. 36609.
73 // 05-12-2013 NB v0.090 Major change to possiblemoves (fixing bug in process)
74 // 06-12-2013 NB v0.091 Partially Fixed major bug (findpiece)
75 // 07-12-2013 NB v0.092 Fully fixed findpiece bug.
76 // 08-12-2013 NB v0.093 Now trying XENON (to occupy an unnocupied row if king can't be blocked otherwise), salvaged some more memory but XENON not working...
77 // 09-12-2013 NB v0.094 compressed XENON routines and got them working
78 // 10-12-2013 NB v0.095 introduction of XENON3
79 // 11-12-2013 NB v0.096 refined placement of Xenon3
80 // 12-12-2013 NB v0.097 Fixed the "Crucifix Conundrum"
81 // 13-12-2013 NB v0.098 removed cantakeadjust (superfluous?) added SPIKE to finally solve
82 // the "LookBackInAnger" issue...
83 // 14-12-2013 NB v0.099 forgot calchightarget after pacman4 (brokenarrow)
84 // 17-12-2013 NB v0.100 fixed bug in inccantake, brassed off.
85 // 18-12-2013 NB v0.101 solved the "don't move away from king if leaves path open" issue
86 // More efficient text routines (saving 150 bytes)
87 /****************************************/
88 // TODO:
89 // Fix the bloody thing
90 //
91 #include <lib.h>
92 #define NORTH 0
93 #define SOUTH 1
94 #define EAST 2
95 #define WEST 3
96 #define ENEMYWEIGHT 37
97 #define DEADPILEA 222
98 #define DEADPILED 234
99 #define SIDESTEP 3
100 #define ATTACKER 1
101 #define DEFENDER 2
102 #define KING 3
103 #define CASTLE 4
104 #define ENEMYBLOCK 3
105 #define LOWTAKEWEIGHT 3
106 #define TRIGGERHIGH 3
107 #define TRIGGERLOW 7
108 #define PARTIAL1 0
109 #define PARTIAL2 1
110 #define FULL 2
111 #define NO 0
112 #define YES 1
113 #define BLACK 0
114 #define RED 1
115 #define GREEN 2
116 #define YELLOW 3
117 #define BLUE 4
118 #define MAGENTA 5
119 #define CYAN 6
120 #define WHITE 7
121 #define SAGA 0
122 #define THOR 1
123 #define ODIN 2
124 #define TROPHY 10
125 #define FIRSTBLOOD 1
126 #define BLOODEAGLE 2
127 #define BERZERKER 3
128 #define ALGIZ 4
129 #define URUZ 5
130 #define RAIDO 6
131 #define RINGOFSTEEL 6
132 /*
133 FIRSTBLOOD = MAKE FIRST KILL
134 BLOODEAGLE = DOUBLE KILL
135 BERZERKER = TRIPLE KILL
136 ALGIZ = SURVIVAL - DONT LOSE A MAN - DEFENCE - SELF PRESERVATION
137 URUZ = SPEED - WIN WITH >= 5 TURNS REMAINING
138 RAIDO = A LONG JOURNEY - WIN ON LAST TURN
139 */
140 //#define VINEGAR 3
141 extern unsigned char ExplodeTiles[]; // extra graphics to "explode" a piece (animation)
142 extern unsigned char PictureTiles[]; // standard graphics for pieces and backgrounds
143 //extern unsigned char RunicTiles[]; // Runic alphabet
144 extern unsigned char TimerTiles[]; // display timer in central square when computer's turn
145 extern unsigned char BorderTiles2[]; // for Trophy Screen
146 /*
147 ; You simply replace the existing font from C doing this:
148 ;
149 ; extern unsigned char Font_6x8_FuturaFull[1024];
150 ;
151 ; Then to set the HIRES font:
152 ; memcpy((unsigned char*)0x9800+32*8,Font_6x8_FuturaFull,768);
153 ;
154 ; Or to set the TEXT font:
155 ; memcpy((unsigned char*)0xb400+32*8,Font_6x8_FuturaFull,768);
156 ;
157 */
158 //extern unsigned char Font_6x8_runic1_partial[520]; // runic oric chars (was [1024] 02/02/2012)
159
160 /* RUNIC Alphabet Tiles (NOT the runic1 font) ordered as follows :
161 Actually, the numbers here are not true anymore due to changes in the runes.png file
162 However, Have left the descriptions for educational purposes...
163 The Viking "alphabet" begins with "F" and is rEferred to as "FUTHAR" rather than "Alphabet"
164 0 F: Fehu Cattle/Gold/General Wealth
165 1 U: Uruz Strength/Speed/Good Health
166 2 TH: Thurisaz Norse Giants
167 3 A: Ansuz The Gods, mostly Odin
168 4 R: Raido A long Journey
169 5 K/C: Kenaz Torch/Light source
170 6 G: Gebo sACRIFICE/OFFERING TO THE gODS
171 7 W: Wunjo Comfort/Joy/Glory
172 8 H: Hagalaz Hail/Missile
173 9 N: Nauthiz Need/Necessity
174 10 I: Isa ICE
175 11 Y/J: Jera year/harvest
176 12 EI: Eithwaz Sacred Yew tree
177 13 P: Perth Unknown
178 14 Z: Algiz Defence/Protection/Self-Preservation
179 15 S: Sowilo The Sun
180 16 T: Tiwaz The War God, TYR
181 17 B: Berkano Birch Tree/LDUN(goddess of spring/fertility)
182 18 E: Ehwaz Horse
183 19 M: Mannaz Man/Mankind
184 20 L: Laguz Water
185 21 NG: Ingwaz the Danes (and danish hero ING)
186 22 D: Dagaz Day/Daylight
187 23 O: Othila Inheritance (of property or knowledge)
188 */
189 /******************* Function Declarations ************************/
190 //void brokenarrow();
191 //void deccounter(); // decrement counter
192 //void LookBackInAnger(); // runs subcanbetaken if the piece "behind" an attacker is defender/king and prospective target adjacent to defender/king
193 //void subLookBackInAnger(); // runs the various "lookbackinanger" checks
194 //void zoneupdate(); // Increment target positions on unnocupied rows/columns (especially the "zone")
195 unsigned char cantakepiece(); // returns 0=no, 1 yes
196 unsigned char checkroute(); // sets counter to be number of pieces on a given route
197 void blinkcursor(); // blinks the cursor to attract attention
198 void blinkcursorB(); // subroutine of blinkcursor()
199 //void calccantake(); // can take be made (how many)
200 void calchightarget(); // updates value of hightarget (the highest target so far)
201 //void calctakeweight(); // calculate the weight of "takeweight"
202 void canbetaken(); // can I be taken after moving here? returns value (take) 0=no 1=yes
203 void canpiecemove(); // can a selected piece move? 0=no, 1=yes
204 void CanPieceMoveB();
205 void cantakeadjust(); // decrement cantake if taken piece is on same plane as king
206 void cantakeadjust2(); // don't take a piece in zone if it is only piece on row/col
207 void checkbrokenarrow(); // check to see if brokenarrow can be incremented
208 void checkend(); // check for end game conditions
209 void checkincroute(); // check to see if OK to incroute
210 void computerturn(); // AI for computer
211 void computerturn2(); // subroutine of computerturn()
212 void cursormodevalid(); // sets modevalid to 1
213 void cursormodezero(); // set cursor mode to 0 if 1
214 void decpoints(); // decrement points variable
215 void decroute(); // decs route
216 void pointsplusten(); // ADDS 10 TO POINTS
217 void drawarrow(); // draws "arrow" (not any more 05/12/2013!)
218 void drawboard(); // kicks off drawgrid/drawtiles
219 void drawcursor(); // draws cursor
220 void drawpiece(); // draws piece
221 void drawplayers(); // draw playing pieces
222 void drawtile(); // draw a tile (subroutine of drawtiles)
223 void drawtiles(); // draws all tiles at board x,y boxsize z (uses draw*tile functions)
224 void enemyzero(); // set enemy value to zero when surrounded=3
225 void explodetile(); // explodes a piece (plays an animation)
226 void FindPiece(); // find a piece to move
227 void FindPieceNS(); // check for BAD moves NS (e.g. allowing king to escape)
228 void FindPieceEW(); // check for BAD moves EW (e.g. allowing king to escape)
229 void FindPieceB(); // subroutine of FindPieceNS/EW
230 void flashscreen(); // flashes screen in selected color for a second or so
231 //void fliprune(); // flip the rune tiles in title screen
232 void gspot(); // count no of targets from king to edge
233 //void incbrokenarrow(); // increments the value of brokenarrow
234 void inccantake(); // increments cantake
235 void inccounter(); // inc counter
236 void incdefatt(); // increments count of attacker/defenders round king (calls incking...)
237 void inckingattacker(); // increments count of attackers round king
238 void inckingdefender(); // increments count of defenders round king
239 void incmodeone(); // increment the modeonevalid variable (from 0 to 1)
240 void incpoints(); // increment points variable
241 void incroute(); // incs route
242 void incsurround(); // increment "surrounded" variable
243 void inctarget(); // inc target[xns][xew]
244 void inverse(); // inverse the color in the square
245 void movecursor2(); // move cursor routine
246 void movepiece(); // move a piece
247 void movepieceB(); // subroutine of movepiece()
248 void pacman2(); // update target positions around king (need to develop further)
249 void pacman2b(); // subroutine of pacman2
250 void pacman3();
251 void pacman4(); // aka FULL broken arrow
252 void pacman5();
253 //void pacman6(); // "vinegar strokes"
254 void pause(); // wait a certain period of time (pausetime)
255 void playerturn(); // takes user input to move cursor
256 void backbone(); // renamed from "printarrowsorblanks"
257 void printdestinations(); // print arrows on tiles where a piece can move
258 void printmessage(); // prints message to screen
259 void printpossiblemoves(); // Print possible moves
260 //void printtitles(); // print the title screen (used in titles/menus etc)
261 void PrintTrophyScreen(); // prints the trophy screen
262 void PrintTrophyScreen1(); // sub of PrintTrophyScreen
263 //void PrintTrophyScreen2(); // blank out right edge of board
264 void PrintTrophyScreen3(); // Draw the Trophy Grid
265 void PrintTrophyScreen4(); // Print the Trophy Titles
266 void PT5(); // subroutine of PrintTrophyScreen4()
267 void printturnprompt(); // prints "your turn" message
268 //void prioritycalc(); // updates priority array
269 void setpoints(); // set points to default value
270 void subarrows(); // subroutine of arrows or blanks
271 void subarrows2(); // subroutine of arrows or blanks (updates ENEMY with direction of enemy)
272 void subcanbetaken2(); // attempt to reduce memory footprint
273 //void subpaceastwest(); // subroutine of pacman
274 //unsigned char subpaccrosst(); // sub of pacman2
275 void subpacmanx(); // grand sub of pacman2
276 void subpacmany(); // apply points from the pacman routines
277 //void subpacnorthsouth(); // subroutine of pacman
278 //void subzoneupdate(); // subroutine of pacman
279 void surroundcheck(); // inc surrounded under various conditions
280 void surroundcount(); // counts the number of attackers surrounding KING (or edges, or central square)
281 void surroundpoints(); // increment points around king depending on "surrounded" figure
282 void takepiece(); // takes specified piece
283 void sidestep(); // add SIDESTEP to target (used in escape routine)
284 void targetselect(); // choose a target square
285 void tileloop(); // subfunction of explodetile and drawtile
286 void timertile(); // print timer
287 //void updateroutehightarget();// adds hightarget to targets on route
288 void updateroutetarget(); // increment targets on a given route
289 void updatetarget(); // updates target array
290 void zerocounter(); // set counter=0
291 //void zerofoundpiece(); // set foundpiece to 0 (PIECE NOT FOUND)
292 void deadpile(); // draw deadpile
293 void flashred(); // flash screen in red
294 //void gethightarget(); // without upsetting any other variables
295 void calccantake2(); // alternative calcantake
296 void calccantake3();
297 void calcturnvalue(); // calculate hundreds,tens,units (huns, thor and odin)
298 void printturnline(); // prints the turn counters
299 void takemessage(); // prints a message when multiple takes are made
300 void submessage(); // subroutine of takemessage
301 void ClearTrophies(); // Initialize the trophies array
302 void AlgizThorTrophyCalc(); // calculate awarding of the ALGIZ and THOR trophies
303 void DrawPictureTiles(); // called from lots of places so gets own function
304 //void cleartarget(); // set all targets to 1 (before adding redflag point values
305 void SubMoveCursor2(); // subroutine of movecursor2() to save memory
306 void SubMoveCursor2b(); // subroutine of movecursor2() to save memory
307 void CheckerBoard(); // Checkerboard screen wipe
308 void subCheckerBoard(); // subroutine of checkerboard
309 void subCheckerBoard2(); // subroutine 2 of checkerboard
310 void SheldonGambit(); // called from subpacmanx (block left or right?)
311 //void Xenon();
312 void Xenon2(); // replacement of pacman3 in pacman4
313 void Xenon3();
314 void Xenon4();
315 //void Xenon5();
316 /****************** GLOBAL VARIABLES *******************************/
317 /* Populate array with tile types
318 Tile types:
319 0=blank
320 1=attacker square
321 2=defender square
322 3=king square
323 */
324 extern unsigned char tiles[11][11]; // tile description on board
325 extern unsigned char target[11][11]; // uninitialized variable (will calc on fly) - target values of square
326 extern unsigned char TrophyText[6][11]; // Titles of Trophies
327 extern unsigned char sheldon[4][8]; // co-ords of corner squares (sheldon gambit)
328 //extern const unsigned char border[6][11]; // border (of title screens/menus etc)
329 //extern unsigned char presents[8]; // array of runic chars that spell "presents"
330 //extern unsigned char hnefatafl[9]; // array of runic chars that spell "hnefatafl"
331 /* populate array with places of players
332 Players:
333 0=vacant
334 1=attacker resident
335 2=defender resident
336 3=king resident
337 4=corner square // added 21/04/2011
338 */
339 //extern char baseplayers[11][11]; // BASEPLAYERS - the starting board positions. PLAYERS is the working COPY of BASEPLAYERS
340
341 // ARRAY ENEMY unititialized variable (will calc on fly) - can enemy reach a square?
342 // values:
343 // +1 Can be reached from NORTH
344 // +5 can be reached from SOUTH
345 // +10 can be reached from EAST
346 // +20 can be reached from WEST
347 extern unsigned char enemy[11][11]; // where the defenders can get to
348 extern unsigned char computer[11][11]; // where the attackers can get to
349 //extern unsigned char priority[11][11]; // holds the priority of a piece to move
350 extern unsigned char kingtracker[11][11]; // where the king can get to
351 //extern unsigned char RowCountAtt[11]; // count of attackers on a Row
352 //extern unsigned char ColCountAtt[11]; // count of attackers on a Column
353 unsigned char players[11][11]; // to be the working copy of baseplayers
354 unsigned char playertype,piecetype; // player 1=attacker, 2=defender
355 unsigned char ns,ew; // default north/south position of central square (0-10)
356 unsigned char cx,cy; // cursor x screen position (pixels across)
357 unsigned char fb=1; // foreground/background 0=background, 1=foreground, 2=opposite, 3=nothing
358 //unsigned char inversex; // x position of square to be inversed (to highlight a selected piece)
359 //unsigned char inversey; // y position of square to be inversed (to highlight a selected piece)
360 char mkey; // code of key pressed (plus loops)
361 unsigned char cursormode; // cursor movement mode 0=freeform 1=restricted
362 unsigned char ons,oew; // original north/south board pos
363 unsigned char ocx,ocy; // original xpos of piece
364 unsigned char orientation; // 0=north, 1=south 2=east 3=west
365 unsigned char tiletype; // type of tile under inspection (used in arrows)
366 unsigned char tpns,tpew; // north-south board location of taken piece (also used for 3) NB:no idea 20/10/2011
367 unsigned char flashcolor; // color of ink to flash in
368 unsigned char flashback; // color of ink to return to
369 char game; // *** MUST NOT BE UNSIGNED ***<=0 means endgame (see checkend for values), 1=GAMEON
370 unsigned char gamestyle; // 0=human vs human; 1=human king vs computer; ** NO!!! 2=human vs computer king**; 3=undefined
371 unsigned char kingns,kingew;// kings position North-South
372 unsigned char kingattacker[4]; // number of attackers in all four directions from king
373 unsigned char kingdefender[4]; // number of defenders in all four directions from king
374 unsigned char kingpieces[4]; // number of pieces in all four directions around king (saves calculating it all the time)
375 unsigned char surrounded; // status of king "surrounded" status //
376 unsigned char ctns=0; // Computer Turn north-south board position
377 unsigned char ctew=0; // Computer Turn east-west board position
378 extern char* playertext;
379 extern char* message;
380 unsigned char foundpiece; // has a piece been found (during computer move) that can move to the hightarget square? 0=no, 1=yes&ok, 9=yes!ok
381 //char xloop=0; // general purpose loop variable
382 unsigned char xns=0; // copy of ns (arrows or blanks, and subarrows)
383 unsigned char xew=0; // copy of ew (arrows or blanks, and subarrows)
384 unsigned char arrow=1; // used in arrowsorblanks(and subarrows)
385 unsigned char flag=0;
386 unsigned char cantake; // can I take? (for computer turn)
387 unsigned char route;
388 unsigned char row,col; // used in tile drawing routines and array navigation ( a row in 11x11 grid)
389 //unsigned char col; // used in tile drawing routines and array navigation ( a column in 11x11 grid)
390 unsigned char tiletodraw; // used in tile drawing routines 0-11 (as at 18-10-2011)
391 int pausetime; // amount of time to wait
392 //unsigned char* ptr_draw; // ptr to board starting position (e.g. 0xa002)
393 unsigned char* ptr_graph; // pointer to byte values of loaded picture
394 unsigned char points; // points around king
395 char counter; // general purpose counter (*** DO NOT set to UNSIGNED *** NB 24/10/2011)
396 char uncounter; // *** MUST BE SIGNED *** general purpose counter (can be negative)
397 //unsigned char lookcol,lookrow; // used in lookbackinanger
398 unsigned char origorient; // original orientation of a piece under test (which way he is heading)
399 unsigned char takerow,takecol; // can I be taken if I stop here?
400 unsigned char paclevel1,paclevel2; // used in pacman/subpacmanx either ns/ew
401 unsigned char surns,surew; // count of attackers surrounding king n/s used in surroundcount()
402 unsigned char takena,takenb,takenc,takend,takene; // used in canbetaken routines
403 unsigned char ezns1,ezew1; // used in surroundcount/enemyzero to reset enemy[][] to zero if surrounded=3
404 // WEIGHTS
405 //unsigned char enemyweight=37; // >36. weight of "enemy could get here but piece occupied by attacker"
406 //char defaulttakeweight=5; // default weight assigned to a TAKE
407 //unsigned char takeweight; // weight assigned to a TAKE (calculated in "calctakeweight")
408 //unsigned char cbtweight=4; // weight to be applied to escape position if can be taken
409 // End of Weights
410 //unsigned char pacpointsx,pacpointsy,pacpointsa,pacpointsb; // used to calculate points in subpacmanx
411 unsigned char pcheckns1,pcheckns2; // used in taking pieces and checking for takes
412 unsigned char pcheckew1,pcheckew2; // used in taking pieces and checking for takes
413 unsigned char startrow,startcol; // used in checkroute (returns no of pieces on a given path)
414 unsigned char destrow,destcol; // used in checkroute (returns no of pieces on a given path)
415 unsigned char canmovecursor; // controls wether screen cursor can be moved or not
416 unsigned char hightarget; // contains highest value target
417 unsigned char targetns,targetew; // used to calc takes
418 unsigned char w,x,y,z,a,b,c,d,e,f; // general purpose variables
419 /* below used for cursor move routine */
420 unsigned char multiple; // concerning central square (how much to multiply the coords to SKIP the square
421 unsigned char xptrns; // copy of NS
422 unsigned char xptrew; // copy of EW
423 unsigned char skipns; // skip to north/south
424 unsigned char skipew; // skip to east/west
425 unsigned char modeonevalid; // is OK for mode 1? 0=no, 1=yes
426 /* above variables used in cursor move routine */
427 unsigned char gameinput=0; // 0=undefined 1=play against computer, 2=human vs human
428 unsigned char take;
429 unsigned char p1; // piece type comparison (lower) - used for determining takes - default=attacker
430 unsigned char p2; // piece type comparison (upper) - used for determining takes - default=attacker
431 /* playerturn variables */
432 unsigned char xkey; // code of key pressed
433 unsigned char canselect; // 0=no, 1=yes (is the piece selectable?)
434 char cursormovetype; // -1=no, 0=yes (n,s,e,w) 1=(north/south only), 2=(east/west only)
435 unsigned char turn; // determines end of player turn 1=playerturn, 0=end of playerturn
436 unsigned char compass[4]; // used in cantake (if compass[NORTH]=1 then means canbetaken if i move here from NORTH
437 /* end of playerturn variables */
438 unsigned char xplayers;
439 unsigned char inkcolor; // screen color
440 unsigned char checkroutemode; // mode used for checkroute function
441 // 1= count number of pieces on route
442 // 2= increment target values on route (if no pieces on route)
443 // 3= amount of targets on route
444 // 4= Number of "enemy" targets on route (where enemies CAN go)
445 // 5= Emergency! Make target=255
446 unsigned char checkrouterow, checkroutecol, checkroutestart, checkroutedest; // used in checkroute routine
447 unsigned char subpacc,subpacd; // used in subpacman5
448 unsigned char turncount; // used to count the number of turns
449 //unsigned char enemytargetcount; // count of enemy targets on a route
450 unsigned char brokenarrow[4]; // NORTH/SOUTH/EAST/WEST: 0=OK, 1=BROKENARROW, 2=POTENTIAL BROKEN ARROW in that direction
451 unsigned char deadattackers, deaddefenders, deadplayers, deadtoggle; deadcurset; // count of dead attackers or defenders
452 //unsigned char deadchar;
453 unsigned char kingtargets[4]; // number of TARGETS from king to edge of board
454 unsigned char tzonemode; // 0=PARTIAL1, 1=PARTIAL2, 2=FULL
455 //unsigned char onlycheck; // restrict check to one route in certain situations
456 unsigned char redflag[4]; // raise the red flag to IGNORE "can I be taken"
457 unsigned char RedFlagX; // determine if ANY redflag is raised
458 //unsigned char deadcolor; // color of deadpiece
459 //unsigned int deadspace; // start of deadcolumn
460 unsigned char turnlimit; // limit the number of turns (compares to turncount)
461 unsigned char remaining; // number of turns remaining
462 unsigned char huns,thor,odin; // hundreds, tens and units...
463 unsigned char playerlevel; // player level (0=SAGA, 1=THOR, 2=ODIN)
464 unsigned char firstblood; // set to 0, gets changed on a take to signify who gets
465 // first blood award.
466 unsigned char erasetext; // how many lines to erase
467 unsigned char takecounter; // how many pieces were taken in one move
468 unsigned char bottompattern; // draw full line or blank
469 unsigned char Trophies[7][2]; // trophy array [trophytype][playertype]
470 unsigned char TurnsRemaining; // for awarding the RAIDO Trophy (win on last turn)
471 //unsigned char TrophyTitle[12]; // Titles of Trophies
472 unsigned char textchar; // Character of Trophy String
473 //unsigned char TextCursor; // Location of Text string
474 unsigned char TakeWeight;
475 unsigned char Checker=12;
476 unsigned char CanTakeDirection[4]; // the direction of a possible take [NORTH,SOUTH,EASt,WEST]
477 unsigned char DeadPiece;
478 unsigned char Spike; // used in canbetakes/subcanbetaken2
479 /****************** MAIN PROGRAM ***********************************/
480 main(){
481 //gameinput=0; // 0=undefined 1=play against computer, 2=human vs human
482 /*
483 CopyFont(); //memcpy((unsigned char*)0xb400+32*8,Font_6x8_runic1_full,768);
484 */
485 //printtitles();
486 CheckerBoard();
487 for(;;){ // endless loop
488 //playertype=0; // 1=attacker, 2=defender (set at zero as incremented within loop)
489 firstblood=1;
490 ClearTrophies(); // initialize trophy array
491 drawboard(); // draw the board
492 while (gamestyle==3){
493 message="PLAYERS:1-2"; // number of players
494 printmessage();
495 gameinput=getchar();
496 if ( gameinput == 49 ) {gamestyle=1;goto SKIPPY1;} // 1=human vs computer (as DEFENDERS)
497 if ( gameinput == 50 ) {gamestyle=0;goto SKIPPY2;} // 0=human vs human
498 flashback=CYAN;flashred();
499 }
500 SKIPPY1:
501 // set turnlimits
502 turnlimit=0; turncount=0;
503 while (turnlimit == 0){
504 message="1: 'SAGA' 255 TURNS\n2: 'THOR' 22 TURNS\n3: 'ODIN' 12 TURNS";
505 printmessage();
506 gameinput=getchar();
507 // playerlevel set here, 0=SAGA, 1=THOR, 2=ODIN
508 if ( gameinput == 49 ) {turnlimit=255; playerlevel=SAGA;goto SKIPPY2;} // 255 turns
509 if ( gameinput == 50 ) {turnlimit=22; playerlevel=THOR;goto SKIPPY2;} // 22 turns
510 if ( gameinput == 51 ) {turnlimit=12; playerlevel=ODIN;goto SKIPPY2;} // 12 turns
511 flashback=CYAN;flashred();
512 }
513 SKIPPY2:
514 message="\n\nTURN: REMAINING: ";
515 printmessage();
516 erasetext=80; // 40*2 (2 lines to erase)
517 while (game > 0){
518 ns=5; // default north/south position of central square
519 ew=5; // default east/west position of central square
520 cx=ew; // cursor x screen position
521 cy=ns; // cursor y screen position
522 playertype++; // playertype inited as 0 so ++ will make it 1 at start of game
523 if ( playertype == 3 ) {
524 playertype = ATTACKER; turncount++; // was defender, set to attacker player, inc turncount
525 if ( turncount > turnlimit ) gamestyle = 9; // signify end of game
526 }
527 if ( gamestyle != 9 ){ // if turns not exceeded
528 if (( gamestyle == 0 )||((gamestyle==1)&&(playertype==2))){
529 playerturn(); // player input
530 }else{
531 computerturn(); // computer has a go...
532 }
533 }
534 checkend(); // check for end of game conditions
535 }
536 /*
537 game=0 King Wins.
538 game=-1 Stalemate.
539 game=-2 Attacker wins.
540 */
541 message=" ATTACKER WINS"; // default (game=-2)
542 // king escapes or all attackers killed
543 if ( game == 0 ) message=" KING WINS";
544 // computer can't move
545 if ( game == -1 ) message="STALEMATE - OR TURN LIMIT EXCEEDED";
546 // Award RAIDO AND URUZ Trophies (RAIDO = win on last turn, URUZ >=5 turns remaining)
547 if ( game != -1 ){
548 if (TurnsRemaining == 0){
549 Trophies[RAIDO][playertype-1]=TROPHY;
550 }
551 if (TurnsRemaining >= 5){
552 Trophies[URUZ][playertype-1]=TROPHY;
553 }
554 }
555 printmessage();
556 //erasetext=80; // 40*3 (3 lines to erase)
557 //message="\n ()( PRESS A KEY )()";
558 //printline();
559 flashon();
560 printturnline();
561 getchar();
562 PrintTrophyScreen();
563 }
564 }
565
566 /********************* FUNCTION DEFINITIONS ************************/
567 void computerturn(){
568 message=" ()( I AM THINKING )()\n";
569 //if ( playertype == 1 ) { strcpy(playertext,"ATTACKER");}else{ strcpy(playertext,"KING");}
570 printmessage();
571 printturnline(); // print turn counters
572 // 1. initialize target, enemy and computer array to zeroes
573 ClearArrays(); // clear target, enemy, kingtracker and computer arrays
574 // 2. Calculate information about the board
575 fb=4; computerturn2(); // fb=4 means: don't print destinations, just update ENEMY
576 fb=5; computerturn2(); // fb=5 (+COMPUTER array)
577 fb=6; computerturn2(); // fb=6 if computer piece can get here update target values
578 fb=7; computerturn2(); // fb=7 (can I be taken)
579 fb=8; computerturn2(); // fb=8 update kingtracker
580
581 // 3. Increment target positions around King (PACMAN)
582 pacman2();
583 // 4. Find the highest value target (hightarget)
584 calchightarget(); // to get targetns/targetew values
585 // 5. BrokenArrow...
586 if ( RedFlagX == NO ) pacman4(); // check for full broken arrow (hightarget required)
587 //pacman4(); // check for full broken arrow (hightarget required)
588 // 5. if target is NOT on same row/column as king then check to see if
589 // there is a way open for the king to access an empty row/column (that can't
590 // be blocked by an attacker - really just the Level3 row/col).
591 // if so populate that blank/row column by making any target values upon it be
592 // a high value
593 //if ( targetns != kingns) {a=1;Xenon();} // a=1 means check rows
594 //if ( targetew != kingew) {a=0;Xenon();} // a=0 means check columns
595 //a=1;Xenon();
596 //a=0;Xenon();
597 //pacman6(); // "vinegar strokes"
598
599 calchightarget(); // re-calculate hightarget after all other points have been added
600 if (hightarget == 0) { // if can't move then stalemate
601 game=-1; // signify END of game: computer cannot move: stalemate
602 return;
603 }
604
605 // draw central square (overwriting timer)
606 tiletodraw=9; // KING ON A TILE
607 if (players[5][5] != KING) tiletodraw=3; // CASTLE TILE
608 row=5;col=5;
609 DrawPictureTiles();
610 // end of drawing central square
611 // For first turn have seperate starting positions for THOR and ODIN
612 if ((turncount==1)&&(playerlevel)){
613 target[8][7]=200;
614 if (playerlevel==ODIN) target[10][2]=210;
615 }
616 targetselect(); // Choose the highest value target and piece to move to it
617 ns=targetns;ew=targetew; // make computer move compatible with human move selection
618 movepiece(); // make the move
619
620 }
621 // xenon (secondary routine to run after pacman2(): check the "3rd level")
622 /*
623 void Xenon(){
624 points=20;
625 if (a){ // check ROWS
626 startrow=2; destrow=2; startcol=0; destcol=10;
627 Xenon2();
628 startrow=8; destrow=8;
629 Xenon2();
630 }else{ // check COLS
631 startrow=0; destrow=10; startcol=2; destcol=2;
632 Xenon2();
633 startcol=8; destcol=8;
634 Xenon2();
635 }
636 }*/
637 void Xenon2(){
638 setcheckmode1(); checkroute(); // is row/col empty (z)?
639 if ( z == 0 ){ // if row/col is empty...CAN KING GET TO IT?
640 checkroutemode=6; checkroute();
641 if (z) { // If he can...populate add points to target values
642 checkroutemode=5; checkroute();
643 }
644 }
645 }
646 void Xenon3(){
647 if ( orientation < EAST ){ // check rows (NORTH/SOUTH)
648 startrow=x; destrow=x; startcol=0;destcol=10;
649 if ((x==0)||(x==10)) {startcol=1;destcol=9;}
650 }else{ // check colums (EAST/WEST)
651 startrow=0; destrow=10; startcol=y; destcol=y;
652 if ((y==0)||(y==10)) {startrow=1;destrow=9;}
653 }
654 setcheckmode1(); checkroute(); // returns count of pieces on row/col (z)
655 }
656 void Xenon4(){
657 if (z==0){
658 checkroutemode=5; checkroute(); // if blank populate any targets with extra points
659 }
660 }
661 // end of computerturn()
662 void computerturn2(){
663 timertile();
664 for (ctns=0;ctns<11;ctns++){
665 for (ctew=0;ctew<11;ctew++){
666 ns=ctns;ew=ctew;
667 //if (( fb == 4 )&&(( players[ctns][ctew] == DEFENDER )||(players[ctns][ctew] == KING))) printdestinations();
668 //if (((fb == 5)||(fb == 7))&&( players[ctns][ctew] == ATTACKER)) printdestinations();
669 //if (( fb == 8)&&( players[ctns][ctew] == KING )) printdestinations();
670
671 if ((( fb == 4 )&&(( players[ctns][ctew] == DEFENDER )||(players[ctns][ctew] == KING))) || (((fb == 5)||(fb == 7))&&( players[ctns][ctew] == ATTACKER)) || (( fb == 8)&&( players[ctns][ctew] == KING ))) printdestinations();
672 if (( fb == 6)&&( computer[ctns][ctew] )) updatetarget();
673
674 }
675 }
676 }
677 void DrawPictureTiles(){
678 ptr_graph=PictureTiles;drawtile();
679
680 }
681
682 void FindPiece(){ // find a piece capable of moving to selected target
683
684 if ( foundpiece == 0 ){
685 if (players[a][b] == ATTACKER){ // a=row, b=column (ns,ew = target location)
686 // can computer take a piece (cantake)?
687 calccantake2();
688 // if cannot take can I be taken?
689 if (( cantake == NO )&&( surrounded < 3 )&&( RedFlagX == NO )) canbetaken();
690 if (compass[origorient] == 0){ // means this piece can't be taken
691 foundpiece=1;
692 /*
693 if ((( a<3 )&&(a<targetns)) || ((a>7)&&(a>targetns))){
694 startrow=a;destrow=a;startcol=0;destcol=10;
695 FindPieceB();// set foundpiece to 10 (don't leave ZONE unpopulated)
696 }
697 if ((( b<3 )&&(b<targetew)) || ((b>7)&&(b>targetew))){
698 startrow=0;destrow=10;startcol=b;destcol=b;
699 FindPieceB(); // set foundpiece to 10 (don't leave ZONE unpopulated)
700 }*/
701
702 }
703
704 // check NORTH and SOUTH
705 //if ( surrounded < 3 ){
706 if (foundpiece == 1){ // can't be taken so we've found a candidate && target is not on same row as candidate
707 if ( CanTakeDirection[NORTH] ) {
708 DeadPiece=targetns-1;
709 FindPieceNS();
710 }
711 if ( CanTakeDirection[SOUTH] ) {
712 DeadPiece=targetns+1;
713 FindPieceNS();
714 }
715 if (a == kingns){ // if candidate is on same row as king (don't move away if only one piece E/W)
716 if (((b > kingew)&&(kingpieces[EAST]==1)) || ((b < kingew)&&(kingpieces[WEST]==1))) setfoundpiece10();
717 }
718 }
719 // CHECK EAST AND WEST
720 if (foundpiece == 1){ // can't be taken so we've found a candidate && target is not on same column as candidate
721 if ( CanTakeDirection[EAST] ) {
722 DeadPiece=targetew+1;
723 FindPieceEW();
724 }
725 if ( CanTakeDirection[WEST] ) {
726 DeadPiece=targetew-1;
727 FindPieceEW();
728 }
729 if (b == kingew){ // if candidate is on same col as king (don't move away if only one piece N/S)
730 if (((a < kingns)&&(kingpieces[NORTH]==1)) || ((a > kingns)&&(kingpieces[SOUTH]==1))) setfoundpiece10();
731 }
732 }
733 //}
734 if (foundpiece == 1){
735 if (origorient < EAST){
736 ons = a;
737 }else{
738 oew = b;
739 }
740 }
741 }
742 if ((players[a][b] == DEFENDER)||(players[a][b] == KING)) foundpiece=9;
743 }
744 }
745 void FindPieceNS(){
746 if ((DeadPiece == kingns)&&((b < 2)||(b > 8))){
747 startrow=0;destrow=10;startcol=b;destcol=b;
748 FindPieceB();
749 }
750 }
751 void FindPieceEW(){
752 if ((DeadPiece == kingew)&&((a < 2)||(a > 8))){
753 startrow=a;destrow=a;startcol=0;destcol=10;
754 FindPieceB();
755 }
756 }
757 void FindPieceB(){
758 //see if by TAKING a piece we leave the way open for the king to escape
759 setcheckmode1(); // set checkroutemode=1 (checkroute will return count of pieces on row or column)
760 checkroute(); // returns z
761 if (z == 1) setfoundpiece10(); // don't TAKE piece
762 }
763 /*
764 CalcHighTarget used to be part of targetselect (and is still called from it) but
765 it is also now used in PACMAN so that the kings escape route can always be blocked
766 by adding the highest score (so far) onto the necessary targets...
767 It alters the values of ctns,ctew,targetns,targetew,ons,oew,ns,ew and of course,
768 hightarget
769 */
770 /*
771 void calchightarget(){
772 char nsloop=1;
773 char ewloop=1;
774 unsigned char nsstart=0;
775 unsigned char ewstart=0;
776 unsigned char nsend=10;
777 unsigned char ewend=10;
778 if ( playerlevel == THOR ){
779 nsloop=-1;
780 ewloop=-1;
781 nsstart=10;
782 ewstart=10;
783 nsend=0;
784 ewend=0;
785 }
786 if ( playerlevel == ODIN ){
787 //nsloop=1;
788 ewloop=-1;
789 //nstart=0;
790 //nsend=10;
791 ewstart=10;
792 ewend=0;
793 }
794 hightarget=0; // highest value target
795 for (ctns=nsstart;ctns != nsend; ctns+=nsloop){ // find the highest value for target
796 for (ctew=ewstart;ctew != ewend ;ctew+=ewloop){
797 if ( target[ctns][ctew] > hightarget ){
798 hightarget=target[ctns][ctew]; // make hightarget the highest value
799 targetns=ctns;
800 targetew=ctew;
801 ons=ctns; // target is accessible so make ons/oew the default piece position to move
802 oew=ctew; // the ACTUAL piece to move determined below (one of ons or oew will remain same)
803 ns=ctns;
804 ew=ctew;
805 }
806 }
807 }
808 }
809 */
810 void calchightarget(){
811 hightarget=0;
812 for (ctns=0;ctns<11;ctns++){ // find the highest value for target
813 for (ctew=0;ctew<11;ctew++){
814 if ( target[ctns][ctew] > hightarget ){
815 hightarget=target[ctns][ctew]; // make hightarget the highest value
816 targetns=ctns;
817 targetew=ctew;
818 ons=ctns;
819 oew=ctew;
820 ns=ctns;
821 ew=ctew;
822 }
823 }
824 }
825 }
826
827 /*
828 void gethightarget(){ // without upsetting anything else
829 hightarget=0;
830 for (ctns=0;ctns<11;ctns++){ // find the highest value for target
831 for (ctew=0;ctew<11;ctew++){
832 if ( target[ctns][ctew] > hightarget ){
833 hightarget=target[ctns][ctew]; // make hightarget the highest value
834 }
835 }
836 }
837 }
838 */
839 /*
840 void cleartarget(){ // nukes target array
841 for (ctns=0;ctns<11;ctns++){
842 for (ctew=0;ctew<11;ctew++){
843 if (target[ctns][ctew]) target[ctns][ctew]=1;
844 }
845 }
846 }
847 */
848 // TARGETSELECT - find the highest scoring TARGET and piece to move
849 void targetselect(){
850 unsigned char test=0;
851 zerofoundpiece();
852 NEWTARGET:
853 test++;
854 if (test==20){zap();return;} // catch endless loop
855 calchightarget(); // re-calculate hightarget
856 // having found target we need to select a piece to move
857 compass[NORTH]=0;compass[SOUTH]=0;compass[EAST]=0;compass[WEST]=0; // initialize compass array (can't be taken in any direction)
858 fb=9;
859 if ( playerlevel == ODIN ) goto ODINJUMP2;
860 ODINJUMP1:
861 // NORTH + SOUTH
862 // NORTH
863 origorient=NORTH;
864 if ( foundpiece != 1 ){
865 b=oew;
866 zerofoundpiece(); // set foundpiece to ZERO "piece not found"
867 for (mkey=ons-1; mkey>-1; mkey--){a=mkey;FindPiece();}
868 }
869 // SOUTH
870 if ( foundpiece != 1 ){
871 zerofoundpiece();
872 origorient=SOUTH;
873 for (mkey=ons+1; mkey<11; mkey++){a=mkey;FindPiece();}
874 }
875 if ( playerlevel == ODIN ) goto ODINJUMP3;
876 ODINJUMP2:
877 // EAST + WEST
878 // EAST
879 if ( foundpiece != 1 ){
880 a=ons;
881 zerofoundpiece();
882 origorient=EAST;
883 for (mkey=oew+1; mkey<11; mkey++){b=mkey;FindPiece();}
884 }
885 // WEST
886 if ( foundpiece != 1 ) {
887 zerofoundpiece();
888 origorient=WEST;
889 for (mkey=oew-1; mkey>-1; mkey--){b=mkey;FindPiece();}
890 }
891 if ( playerlevel == ODIN ) goto ODINJUMP1;
892 ODINJUMP3:
893 if ( foundpiece != 1 ) {target[targetns][targetew]=1;goto NEWTARGET;} // if can still be taken select new target, this may cause an ENDLESS LOOP if no target value found that is > 1
894 //if ( target[targetns][targetew]==2) {zoneupdate(); goto NEWTARGET;} // if nothing useful found update the zone
895 cx=oew; // piece x screen position
896 cy=ons; // piece y screen position
897 blinkcursor(); // draw cursor in foreground color at piece to move position cx,cy
898 fb=0;
899 cx=targetew; // target x screen position
900 cy=targetns; // target y screen position
901 blinkcursor(); // draw cursor in foreground color at target position cx,cy
902 ocx=oew; // piece to move x screen position
903 ocy=ons; // piece to move y screen position
904 }
905 // subroutine of pacman
906 void subpacmanx(){
907 setpoints(); // Set points to 10
908 surroundpoints(); // add 10 * surrounded
909 points+=brokenarrow[orientation]*10;
910 // "The Sheldon Gambit"
911 x=0; SheldonGambit();
912 x=2; SheldonGambit();
913 x=4; SheldonGambit();
914 x=6; SheldonGambit();
915 // REDFLAG detection
916 // if no pieces in orientation from KING but there ARE targets
917 if (( kingpieces[orientation] == 0 )&&(kingtargets[orientation])){
918 if (((orientation < EAST)&&((kingew<2)||(kingew>8))) || ((orientation > SOUTH)&&((kingns<2)||(kingns>8)))) { // NORTH/SOUTH OR EAST/WEST
919 redflag[orientation]=YES; // raise a red flag
920 RedFlagX=YES;
921 points=200;
922 //cleartarget(); // set all targets to 1
923 }
924 }
925 subpacmany(); // apply the points
926 }
927 void SheldonGambit(){ //called from subpacmanx
928 a=sheldon[orientation][x];
929 b=sheldon[orientation][x+1];
930 if ( enemy[a][b] ) pointsplusten();
931
932 }
933 void subpacmany(){ // apply the points generated in pacman2-6
934 // SET UNCOUNTER
935 pacman5(); // ensure correct paclevels are set
936 uncounter=paclevel2+1; // if south or east
937 if ((orientation == NORTH ) || ( orientation == WEST)){
938 uncounter=paclevel2-1;
939 }
940 // SET X & Y
941 x=paclevel1; // if EAST or WEST
942 y=uncounter;
943 if ( orientation < EAST ){ // IF NORTH OR SOUTH
944 x=uncounter;
945 y=paclevel1;
946 }
947
948 while (((players[x][y] == 0)||(tiles[x][y] == CASTLE)) && ((uncounter > -1)&&(uncounter < 11))){
949 if ( target[x][y] ){ // if accessible by attacker
950 //if (( target[x][y] > 1 )||(redflag[orientation])){
951 if ( target[x][y] > 1 ){
952 //printmessage();getchar();
953 target[x][y]+=points;
954 Xenon3(); // count number of pieces on row/column
955 if ( z==0) target[x][y]+=points; // add more points if empty row/col
956 }
957 if ( redflag[orientation] ) target[x][y]+=50;
958 decpoints();
959 //if (z){decpoints();} // only decrement points if route to edge is blocked
960 }else{
961 Xenon3(); Xenon4(); // update targets on blank rows
962 }
963 if ( (orientation == NORTH) || (orientation == WEST) ) {uncounter--;}else{uncounter++;}
964 if ( orientation < EAST ) {x=uncounter;}else{y=uncounter;}
965 }
966 /*
967 if (tzonemode==VINEGAR){
968 message="VINEGAR STROKES COMPLETE";
969 printmessage();
970 }*/
971 }
972 void checkbrokenarrow(){
973 // f= value of player piece at edge of board (if any)
974 // kingtargets[orientation]= count of targets from king to edge
975 // kingpieces[]= count of pieces from king in a given orientation
976 unsigned char test=0;
977 setcheckmode1(); c=checkroute(); // how many pieces on the route?
978 checkroutemode=6; d=checkroute();// can king get to a T-row 0-1
979 if (( c == 0 ) && ( d )) {
980 f=players[a][b]; // check for piece at edge of board
981 if (f == CASTLE) f=0; // check for corner square
982 if (( target[a][b] )&&(tzonemode==FULL)) kingtargets[orientation]--; // decrement kingtargets(so maybe kingtargets=zero) - to trigger brokenarrow
983 //if (( kingpieces[orientation] == 1) && (f) && (f != ATTACKER)) test=1;
984 if (( kingpieces[orientation] == 1) && (f)) test=1;
985 if ((kingpieces[orientation] == 0 )||( test )){
986 if ( kingtargets[orientation] == 0){ // no targets on route to edge
987 checkroutemode=5;checkroute(); // add points to t-zone targets (startrow, startcol,destrow, destcol)
988 }else{
989 brokenarrow[orientation]++; // POTENTIAL BROKEN ARROW
990 if (tzonemode){ // if tzonemode > PARTIAL1
991 brokenarrow[orientation]+=2; // will be at LEAST 3 if PARTIAL2
992 }
993 // if we have two PARTIAL1s (possible escape) then brokenarrow will be 2 so need to elevate
994 if (brokenarrow[orientation] == 2) brokenarrow[orientation]=4; // 4 beats one PARTIAL2
995 }
996 }
997 }
998 //if (( target[a][b] )&&(tzonemode==FULL)) kingtargets[orientation]++; // increment back
999
1000 }
1001
1002 /*
1003 // check the T zone (for broken arrow purposes)
1004 unsigned char subpaccrosst(){
1005 if ( orientation == NORTH ){
1006 a=0;b=kingew;startrow=1;destrow=1;startcol=0;destcol=10;
1007 }
1008 if ( orientation == SOUTH ){
1009 a=10;b=kingew;startrow=9;destrow=9;startcol=0;destcol=10;
1010 }
1011 if ( orientation == EAST ){
1012 a=kingns;b=10;startrow=0;destrow=10;startcol=9;destcol=9;
1013 }
1014 if ( orientation == WEST ){
1015 a=kingns;b=0;startrow=0;destrow=10;startcol=1;destcol=1;
1016 }
1017 return checkroute();
1018 }
1019 */
1020 void gspot(){
1021 setcheckmode3(); // count number of targets on route from king to edge
1022 // NORTH
1023 startrow=0;destrow=kingns;startcol=kingew;destcol=kingew;
1024 kingtargets[NORTH]=checkroute(); // count of targets from king to edge
1025 // SOUTH
1026 startrow=kingns;destrow=10;
1027 kingtargets[SOUTH]=checkroute(); // count of targets from king to edge
1028 // EAST
1029 destrow=kingns;destcol=10;
1030 kingtargets[EAST]=checkroute();
1031 // WEST
1032 startcol=0;destcol=kingew;
1033 kingtargets[WEST]=checkroute();
1034 }
1035 /*
1036 void gspot(){
1037 // default=NORTH
1038 if (( orientation == NORTH )&&(kingns > 1)) {
1039 startrow=0;destrow=kingns;startcol=kingew;destcol=kingew;
1040 }
1041 if (( orientation == SOUTH )&&(kingns < 9)){
1042 startrow=kingns;destrow=10;startcol=kingew;destcol=kingew;
1043 }
1044 if ((orientation == EAST )&&(kingew < 9)){
1045 startrow=kingns;destrow=kingns;startcol=kingew;destcol=10;
1046 }
1047 if ((orientation == WEST) && (kingew > 1)){
1048 startrow=kingns;destrow=kingns;startcol=0;destcol=kingew;
1049 }
1050 setcheckmode3(); g=checkroute(); // count of targets from king to edge
1051 }
1052 */
1053 /*
1054 void checkbrokenarrowhead(){
1055 // NORTH
1056 orientation=NORTH; brokenarrow[orientation]=0;
1057 a=0;b=kingew;startrow=0;destrow=0;startcol=0;destcol=kingew;
1058 checkbrokenarrow(); // PARTIAL LEVEL 1 "LEFT"
1059 startcol=kingew;destcol=10;
1060 checkbrokenarrow(); // PARTIAL LEVEL 1 "RIGHT"
1061 // SOUTH
1062 orientation=SOUTH; brokenarrow[orientation]=0;
1063 a=10;startrow=10;destrow=10;startcol=0;destcol=kingew;
1064 checkbrokenarrow(); // PARTIAL LEVEL 1 "LEFT"
1065 startcol=kingew;destcol=10;
1066 checkbrokenarrow(); // PARTIAL LEVEL 1 "RIGHT"
1067 // EAST
1068 orientation=EAST; brokenarrow[orientation]=0;
1069 a=kingns;b=10;startrow=0; destrow=kingns;startcol=10;
1070 checkbrokenarrow(); // PARTIAL LEVEL 1 "LEFT"
1071 startrow=kingns;destrow=10;
1072 checkbrokenarrow(); // PARTIAL LEVEL 1 "RIGHT"
1073 // WEST
1074 orientation=WEST; brokenarrow[orientation]=0;
1075 b=0; startrow=0;destrow=kingns;startcol=0; destcol=0;
1076 checkbrokenarrow(); // PARTIAL LEVEL 1 "LEFT"
1077 startrow=kingns;destrow=10;
1078 checkbrokenarrow(); // PARTIAL LEVEL 1 "RIGHT"
1079 }*/
1080
1081 void pacman2(){
1082 // improved version of pacman
1083 RedFlagX=NO; // at this point no red flag to be waived
1084 timertile();
1085 //calchightarget(); // calc highest target so far
1086 //if (hightarget == 0) return; // cannot move...
1087 gspot(); // sets kingtargets[orientation]=count of targets from king to edge (no of pieces is found in kingpieces[])
1088 //checkbrokenarrowhead();
1089 surroundcount(); // set surrounded value (used in subpacmanx - only have to calc once though)
1090 //for (orientation = 0; orientation < 4; orientation++){
1091 //if ( surrounded < 3 ){ // no need to add any more points
1092 orientation=NORTH; pacman2b();
1093 orientation=SOUTH; pacman2b();
1094 orientation=EAST; pacman2b();
1095 orientation=WEST; pacman2b();
1096 //}
1097 //}
1098 }
1099 void pacman2b(){
1100 brokenarrow[orientation]=0;
1101 redflag[orientation]=0;
1102 tzonemode=PARTIAL1;
1103 // count of pieces across the "T"
1104 // PARTIAL LEVEL 1 "LEFT"
1105 //points=50; // for level 1
1106 // *** IMPORTANT ***
1107 // It may look like you can save a few bytes by removing "redundant" statements
1108 // here, but you can't as these values are altered later in this routine
1109 a=0;b=kingew;startrow=0;destrow=0;startcol=0;destcol=kingew; // NORTH
1110 if ( orientation ){
1111 a=10;b=kingew;startrow=10;destrow=10;startcol=0;destcol=kingew; // SOUTH
1112 if ( orientation == EAST ){
1113 a=kingns;b=10;startrow=0; destrow=kingns;startcol=10;destcol=10;
1114 }
1115 if ( orientation == WEST ){
1116 a=kingns;b=0; startrow=0; destrow=kingns;startcol=0; destcol=0;
1117 }
1118 }
1119 pacman3();
1120 // PARTIAL LEVEL 1 "RIGHT"
1121 if (startrow == destrow){
1122 startcol=kingew;destcol=10;
1123 }else{
1124 startrow=kingns;destrow=10;
1125 }
1126 pacman3();
1127 // LEVEL 2
1128 // PARTIAL LEVEL 2 "LEFT"
1129 // a + b already set in PARTIAL LEVEL 1
1130 tzonemode=PARTIAL2;
1131 startrow=1;destrow=1;startcol=0;destcol=kingew; // NORTH
1132 if ( orientation ){
1133 startrow=9;destrow=9;startcol=0;destcol=kingew; // SOUTH
1134 if ( orientation == EAST ){
1135 startrow=0; destrow=kingns;startcol=9;destcol=9;
1136 }
1137 if ( orientation == WEST ){
1138 startrow=0; destrow=kingns;startcol=1; destcol=1;
1139 }
1140 }
1141 pacman3();
1142 // PARTIAL LEVEL 2 "RIGHT"
1143 if (startrow == destrow){
1144 startcol=kingew;destcol=10;
1145 }else{
1146 startrow=kingns;destrow=10;
1147 }
1148 pacman3();
1149 subpacmanx(); // add points to target in orientation from king
1150 }
1151 void pacman3(){
1152 //unsigned char test=0;
1153 unsigned char lower=0; // row/column lower bound
1154 unsigned char upper=10; // row/column upper bound
1155 pacman5(); // ensure correct paclevels are set
1156 if (tzonemode){ // if PARTIAL2 or FULL
1157 lower=1;
1158 upper=9;
1159 }
1160 //if ((( orientation == NORTH )||( orientation == WEST ))&&(paclevel2 > lower)) checkbrokenarrow();
1161 //if ((( orientation == SOUTH )||( orientation == EAST ))&&(paclevel2 < upper)) checkbrokenarrow();
1162 if (((( orientation == NORTH )||( orientation == WEST ))&&(paclevel2 > lower)) || ((( orientation == SOUTH )||( orientation == EAST ))&&(paclevel2 < upper))) checkbrokenarrow();
1163 }
1164 void pacman4(){
1165 // Cross the "T", see if a FULL broken arrow condition could exist (LEVEL 2)
1166 // FULL LEVEL 2
1167 //tzonemode=FULL;
1168 points=hightarget+1;
1169 orientation = NORTH; // NORTH
1170 startrow=1;destrow=1;startcol=0;destcol=10;
1171 Xenon2();
1172 orientation = SOUTH; // SOUTH
1173 startrow=9;destrow=9;startcol=0;destcol=10;
1174 Xenon2();
1175 orientation = EAST; // EAST
1176 startrow=0;destrow=10;startcol=9;destcol=9;
1177 Xenon2();
1178 orientation = WEST; // WEST
1179 startrow=0;destrow=10;startcol=1;destcol=1;
1180 Xenon2();
1181 }
1182 void pacman5(){
1183 if (orientation < EAST){ // NORTH AND SOUTH (for pacman3)
1184 paclevel1=kingew;
1185 paclevel2=kingns;
1186 }else{ // EAST AND WEST
1187 paclevel1=kingns;
1188 paclevel2=kingew;
1189 }
1190 }
1191 /*
1192 void Xenon5(){
1193 if (!redflag[orientation]){
1194 Xenon2();
1195 }
1196 }*/
1197 // check for endgame conditions
1198 void checkend() {
1199 /* END OF GAME CONDITIONS
1200 game=0 King Wins.
1201 game=-1 Stalemate. (or turnlimit exceeded)
1202 game=-2 Attacker wins.
1203 */
1204 // ns and ew contains new board co-ords of last piece moved
1205 if ((( players[ns][ew] == KING ) && ( tiles[ns][ew] == 4 ))||( deadattackers > 23)) game=0; // king has escaped
1206 // check to see if king is surrounded by attackers (first find king)
1207 if ( players[ns][ew] == ATTACKER ){ // if attacker was last to move
1208 if ((ns )&&(players[ns-1][ew] == KING )) surroundcount();
1209 if ((ns < 10 )&&(players[ns+1][ew] == KING )) surroundcount();
1210 if ((ew < 10 )&&(players[ns][ew+1] == KING )) surroundcount();
1211 if ((ew )&&(players[ns][ew-1] == KING )) surroundcount();
1212 if ( surrounded == 4 ) game=-2; // king is surrounded on all sides by attackers or king squares
1213 }
1214 if ( gamestyle == 9 ) game=-1; // turnlimit exceeded: stalemate
1215 }
1216
1217 void cursormodezero() {
1218 if ( cursormode == 0 ) canmovecursor=1;
1219 }
1220
1221
1222 // routine to move the cursor
1223 void movecursor2() {
1224 /*
1225 cursormode = [0 or 1] 0=unrestricted (move anywhere), 1= restricted (only move to possible destinations)
1226 */
1227 multiple=1; // concerning central square (how much to multiply the coords to SKIP the square
1228 xptrns=ns; // copy of NS
1229 xptrew=ew; // copy of EW
1230 skipns=ns; // skip to north/south
1231 skipew=ew; // skip to east/west
1232 modeonevalid=0; // is OK for mode 1? 0=no, 1=yes
1233 canmovecursor=0;
1234 piecetype=players[ons][oew]; // determines the piece type that is currently selected (used in mode 1)
1235 if ((mkey == 8 )&&( ew )){ // west
1236 //cursormodezero();
1237 xptrew--; // decrement copyew
1238 skipew-=2;
1239 SubMoveCursor2b();
1240 //incmodeone();
1241 }
1242 if ((mkey == 9 )&&( ew < 10)) { // east
1243 //cursormodezero();
1244 xptrew++;
1245 skipew+=2;
1246 SubMoveCursor2b();
1247
1248 //incmodeone();
1249 }
1250 if ((mkey == 10)&&( ns < 10)){ // south
1251 //cursormodezero();
1252 xptrns++;
1253 skipns+=2;
1254 SubMoveCursor2b();
1255
1256 //incmodeone();
1257 }
1258 if ((mkey == 11)&&( ns )){ // north
1259 //cursormodezero();
1260 xptrns--;
1261 skipns-=2;
1262 SubMoveCursor2b();
1263 //incmodeone();
1264 }
1265 if (( cursormode ) && ( modeonevalid )){ // if not at edge of board
1266 if ( tiles[xptrns][xptrew] == 4 ) canmovecursor=0; // !ok if corner
1267 if (( players[xptrns][xptrew] == 0 )||(( piecetype == KING )&&( tiles[xptrns][xptrew] > 2 ))||(( xptrns == ons )&&( xptrew == oew ))) canmovecursor=1;
1268
1269 // need to check that for non-king pieces wether the central square is vacant and can be skipped
1270 if (( piecetype < 3 )&&( tiles[xptrns][xptrew] == 3)&&(players[xptrns][xptrew] !=KING )){ // tiles=3(central), tiles=4(corner)
1271 if ( players[skipns][skipew] ) canmovecursor=0; // cannot skip if otherside occupied
1272 if ((( skipns == ons )&&( skipew == oew ))||( players[skipns][skipew] == 0)){ // ok to skip to self
1273 canmovecursor=1;
1274 multiple=2;
1275 }
1276 }
1277 }
1278 if (canmovecursor ){
1279 fb=0;a=cx;b=cy;
1280 SubMoveCursor2();
1281 cx=a;cy=b;
1282 fb=1;a=ew;b=ns;
1283 SubMoveCursor2();
1284 ew=a;ns=b;
1285 }else{
1286 flashback=CYAN;
1287 if ( cursormode ) flashback=GREEN;
1288 flashred();
1289 printturnline();
1290 }
1291 }
1292 void SubMoveCursor2(){
1293 inverse();
1294 if ( mkey == 8 ) a-=multiple; // left
1295 if ( mkey == 9 ) a+=multiple; // right
1296 if ( mkey == 10 )b+=multiple; // down
1297 if ( mkey == 11 )b-=multiple; // up
1298 }
1299 void SubMoveCursor2b(){
1300 cursormodezero();
1301 incmodeone();
1302 }
1303 // kicks off functions that highlights squares at all possible
1304 // destinations and blanks them out afterwards
1305 void printpossiblemoves(){
1306 char k; // key entered
1307 fb=1;
1308 printdestinations(); // print arrows on all destinations
1309 //message="\n )() PRESS A KEY ()(";
1310 erasetextarea();
1311 //printmessage(); // "PRESS A KEY"
1312 flashon(); // Make it FLASH RED
1313 printturnline();
1314 k=getchar();
1315 //fb=0;
1316 printdestinations(); // blank out arrows on all destinations
1317 }
1318
1319 // used in printdestinations
1320 void backbone() {
1321 origorient=orientation; // original orientation (for computer turn)
1322 xns=ns; // copy of ns
1323 xew=ew; // copy of ew
1324 arrow=1;
1325 // orientation 0,1,2,3 = N, S, E, W
1326 takerow=ns;takecol=ew; // will set below to be the opposite of the orientation
1327 if ( orientation == NORTH ) { xplayers=players[xns-1][xew];takerow=xns+1;} // check north
1328 if ( orientation == SOUTH ) { xplayers=players[xns+1][xew];takerow=xns-1;} // check south
1329 if ( orientation == EAST ) { xplayers=players[xns][xew+1];takecol=xew-1;} // check east
1330 if ( orientation == WEST ) { xplayers=players[xns][xew-1];takecol=xew+1;} // check west
1331 while (( arrow )&&(fb != 7)){ // keep checking until cannot move
1332 if (( orientation == NORTH ) && ( xns )){ // check north
1333 xns--; // decrement provisional north-south player position
1334 subarrows();
1335 }
1336 if (( orientation == SOUTH ) && ( xns < 10 )){ // check south
1337 xns++; // increment provisional north-south player position
1338 subarrows();
1339 }
1340 if ((orientation == EAST ) && ( xew < 10 )){ // check east
1341 xew++; // increment provisional east-west player position
1342 subarrows();
1343 }
1344 if ((orientation == WEST ) && ( xew )){ // check west
1345 xew--; // decrement provisional east-west player position
1346 subarrows();
1347 }
1348 tiletodraw=tiles[xns][xew]; // obtain type of tile
1349 if ( arrow ){ // if MODE is "draw an arrow" (aka: I can move here) arrow=1 or 2
1350 // NOTE: arrow=2 means piece can cross this square but not occupy it as in case with CASTLE squares
1351 row=xns;
1352 col=xew;
1353 if ( arrow == 1 ){ // don't draw the arrow or update any array if arrow=2
1354 if (fb == 1) drawarrow(); // draw arrow (or really, highlight square in red or blank it)
1355 if (fb == 4) subarrows2(); // enemy can get here, update enemy array (direction specific)
1356 if (fb == 5) computer[xns][xew]++;// computer can get here, increment computer array and set default target value
1357 //if (fb == 0) drawarrow(); // if MODE is "blank an arrow"
1358 if (fb == 8) kingtracker[xns][xew]=1; // king can get here...
1359 }
1360 }
1361 // have we reached the end of the board?
1362 //if (( orientation == NORTH ) && ( xns == 0 )) zeroarrow(); // check north
1363 //if (( orientation == SOUTH ) && ( xns == 10 )) zeroarrow(); // check south
1364 //if (( orientation == EAST ) && ( xew == 10 )) zeroarrow(); // check east
1365 //if (( orientation == WEST ) && ( xew == 0 )) zeroarrow(); // check west
1366
1367 if ((( orientation == NORTH ) && ( xns == 0 )) || (( orientation == SOUTH ) && ( xns == 10 )) || (( orientation == EAST ) && ( xew == 10 )) || (( orientation == WEST ) && ( xew == 0 ))) zeroarrow();
1368 }
1369 if ((fb == 7)&&(xplayers > ATTACKER)){ // check to see if an attacker can be caught if he stays where he is
1370 if ((players[takerow][takecol] == 0)&&(enemy[takerow][takecol] )) {
1371 a=takerow;b=takecol;sidestep();
1372 if (orientation < EAST){ // if heading north or south
1373 a=xns;
1374 if ( xew < 10 ) {b=xew+1;sidestep();}
1375 if ( xew ) {b=xew-1;sidestep();}
1376 }
1377 else{ // if heading east or west
1378 b=xew;
1379 if ( xns < 10 ) {a=xns+1;sidestep();}
1380 if ( xns ) {a=xns-1;sidestep();}
1381 }
1382 }
1383 }
1384 }
1385 // sidestep: take a step sideways (or backwards) if you can be caught
1386 // if you stay where you are...
1387 void sidestep(){
1388 if (target[a][b] > 1) {
1389 target[a][b]+=SIDESTEP;
1390 // add more points if step route on same row/col as king
1391 if ( ( a == kingns ) || ( b == kingew ) ) target[a][b]+=10;
1392 }
1393
1394 }
1395
1396 // Multi function depending on value of "fb"
1397 void printdestinations(){
1398 // check north
1399 if ( ns ) { orientation=NORTH;backbone();}
1400 // check south
1401 if ( ns < 10 ){ orientation=SOUTH;backbone();}
1402 // check east
1403 if ( ew < 10 ){ orientation=EAST;backbone();}
1404 // check west
1405 if ( ew ) { orientation=WEST;backbone();}
1406 }
1407
1408
1409 // CAN A SELECTED PIECE MOVE?
1410 void canpiecemove() {
1411 // returns 0 or 1 depending on wether a piece can move or not
1412 route=0;
1413 piecetype=players[ns][ew]; // determine TYPE of selected piece (1=attacker, 2=defendr, 3=king)
1414 /* for all piece types determine if adjacent square in any direction is blank or not
1415 it won't bother checking a particular direction if piece is at edge of board.
1416 */
1417 if ( ns ){ // check north
1418 a=ns-1;b=ew;checkincroute();
1419 }
1420 if ( ns < 10 ){ // check south
1421 a=ns+1;b=ew;checkincroute();
1422 }
1423 if ( ew < 10 ){ // check east
1424 a=ns;b=ew+1;checkincroute();
1425 }
1426 if ( ew ){ // check west
1427 a=ns;b=ew-1;checkincroute();
1428 }
1429 /* In the case that the central square is unnocupied and a piece is adjacent to that square then - for
1430 non-KING Pieces only - we need to check to see if the opposite square is occupied or not.
1431 ROUTE will be decremented if that piece is occupied (as no piece can occupy the central square except for
1432 the King but all pieces can traverse it */
1433 if (( piecetype < 3 ) && ( players[5][5] == 4 )){ // if not a king and central sqr unoccupied
1434 //c=ew;d=ns;f=0;
1435 //CanPieceMoveB();
1436 //if ( ns == 5 ) {
1437 //if (( ew == 4 )&&( players[5][6] )) decroute(); // check east +2 // east occupied, dec route
1438 //if (( ew == 6 )&&( players[5][4] )) decroute(); // check west +2 // west occupied, dec route
1439 //if (( ns == 5 )&& ((( ew == 4 )&&( players[5][6] )) || (( ew == 6 )&&( players[5][4] )))) decroute();
1440 //}
1441 //c=ns;d=ew;f=1;
1442 //CanPieceMoveB();
1443
1444 //if ( ew == 5 ){
1445 //if (( ns == 4 )&&( players[6][5] )) decroute(); // check south +2 // south occupied, dec route
1446 //if (( ns == 6 )&&( players[4][5] )) decroute(); // check north +2 // north occupied, dec route
1447 //if ((( ns == 4 )&&( players[6][5] )) || (( ns == 6 )&&( players[4][5] ))) decroute();
1448 //if (( ew == 5 ) && ((( ns == 4 )&&( players[6][5] )) || (( ns == 6 )&&( players[4][5] )))) decroute();
1449
1450 if ( (( ns == 5 )&& ((( ew == 4 )&&( players[5][6] )) || (( ew == 6 )&&( players[5][4] )))) || (( ew == 5 ) && ((( ns == 4 )&&( players[6][5] )) || (( ns == 6 )&&( players[4][5] )))) ) decroute();
1451
1452
1453
1454 //}
1455 }
1456 if ( route ) route=1;
1457 //return route;
1458 }
1459 /*
1460 void CanPieceMoveB(){
1461 w=5;x=6;y=5;z=4;
1462 if ( f ){
1463 w=6;x=5;y=4;z=5;
1464 }
1465 if ( d == 5 ){
1466 if (( c == 4 )&&( players[w][x] )) decroute();
1467 if (( c == 6 )&&( players[y][z] )) decroute();
1468 }
1469 }*/
1470
1471 void checkincroute(){
1472 if ( players[a][b] == 0 ) incroute();
1473 if ( (a == 5) && (b == 5) && (players[a][b] == 4)) incroute();
1474 if (( piecetype == 3 )&&(tiles[a][b] == 4 )) incroute(); // KING: corner square OK
1475 }
1476
1477
1478 // DRAW ALL THE PIECES ON THE BOARD
1479 void drawplayers() {
1480 for (row=0;row<11;row++){
1481 for (col=0;col<11;col++){
1482 if (( players[row][col] )&&(players[row][col] < 4)) drawpiece();
1483 }
1484 }
1485 }
1486 // update the deadpile
1487 void deadpile(){
1488 if (playertype == ATTACKER){ // IF ATTACKERS TURN THEN INC DEADEFENDERS
1489 if ( deadtoggle ) {
1490 deaddefenders++;
1491 textchar=40; // "("
1492 }
1493 deadplayers=deaddefenders;
1494 deadcurset=0xa027;
1495 }else{ // IF DEFENDERS TURN THEN INC DEADATTACKERS
1496 if ( deadtoggle ) {
1497 deadattackers++;
1498 textchar=41; // ")"
1499 }
1500 deadplayers=deadattackers;
1501 deadcurset=0xa025;
1502 }
1503 for (x=0;x<deadplayers;x++){
1504 chasm2();
1505 deadcurset+=(40*8); // 40*8
1506 }
1507 }
1508
1509 // DRAW THE BOARD
1510 void drawboard(){
1511 TakeWeight=5; // default TakeWeight - altered later
1512 inkcolor=6;inkasm();
1513 deadtoggle=0; textchar=32;// ensure deadpile char=space
1514 playertype=1;deadpile(); // clear the deadpile of defenders
1515 playertype=2;deadpile(); // clear the deadpile of attackers
1516 deadattackers=0;deaddefenders=0; // reset deadpile counts
1517 game=1; // game=1 means PLAY GAME
1518 gamestyle=3; // 0=play against human, 1=play as DEFENDERS, 2=play as ATTACKERS, 3=nobody
1519 kingns=5;kingew=5; // DEFAULT kings board position
1520 kingattacker[NORTH]=2; // count of attackers NORTH of king
1521 kingattacker[SOUTH]=2; // count of attackers SOUTH of king
1522 kingattacker[EAST]=2; // count of attackers EAST of king
1523 kingattacker[WEST]=2; // count of attackers WEST of king
1524 kingdefender[NORTH]=2; // count of defenders NORTH of king
1525 kingdefender[SOUTH]=2; // count of defenders SOUTH of king
1526 kingdefender[EAST]=2; // count of defenders EAST of king
1527 kingdefender[WEST]=2; // count of defenders WEST of king
1528 surrounded=0; // reset surrounded back to zero
1529 drawtiles(); // draw the background tiles
1530 //curset(12,198,1);
1531 //draw(198,0,1);
1532 bottompattern=63; drawbottom();
1533 drawedge(); // far right of board
1534 //draw(0,-198,1);
1535 drawplayers(); // draw the players
1536 deadatt(); // set dead colors attackers
1537 deaddef(); // set dead colors defenders
1538
1539 }
1540
1541
1542 // blinks the cursor a number of times to attract attention
1543 void blinkcursor() {
1544 //for (counter=0;counter<5;inccounter()){ // flash the cursor to draw attention to it
1545 blinkcursorB(); blinkcursorB(); blinkcursorB(); blinkcursorB(); blinkcursorB();
1546 //}
1547 if ((cx==5)&&(cy==5)) inverse();
1548 }
1549 void blinkcursorB(){
1550 fb=0;
1551 inverse();
1552 pausetime=500;pause();
1553 inverse();
1554 fb=1;
1555 pausetime=1000;pause();
1556 }
1557 // flashes the screen in the selected ink color
1558 void flashscreen() {
1559 inkcolor=flashcolor;inkasm();
1560 pausetime=1500;pause();
1561 inkcolor=flashback;inkasm();
1562 }
1563 // The human players turn : filter keyboard input
1564 void playerturn(){
1565 /*
1566 unsigned char key; // code of key pressed
1567 unsigned char canselect; // 0=no, 1=yes (is the piece selectable?)
1568 char cursormovetype=-1; // -1=no, 0=yes (n,s,e,w) 1=(north/south only), 2=(east/west only)
1569 char turn=1; // determines end of player turn 1=playerturn, 0=end of playerturn
1570 */
1571 cursormovetype=-1; // -1=no, 0=yes (n,s,e,w) 1=(north/south only), 2=(east/west only)
1572 turn=1; // determines end of player turn 1=playerturn, 0=end of playerturn
1573 ons=ns; // original ns board position
1574 oew=ew; // original ew board position
1575 ocx=cx; // original x screen position
1576 ocy=cy; // original y screen position
1577 flashback=CYAN;
1578 playertext="ATTACKER'S";
1579 if ( playertype == DEFENDER ) playertext="KING'S";
1580 /*
1581 if ( playertype == 2 ){
1582 playertext="KING'S";
1583 }
1584 else{
1585 playertext="ATTACKER";
1586 }
1587 */
1588 blinkcursor();
1589 printturnprompt(); // display instructions
1590 // print number of turns and remaining turns
1591 printturnline();
1592 while (turn){ // repeat until move is made
1593 xkey=getchar(); // get code of pressed key
1594 mkey=xkey;
1595 if (( xkey > 7 ) && ( xkey < 12 )){ // 8-11 = cursor keys
1596 cursormode=0; // freeform
1597 movecursor2();
1598 }
1599 /*******************************************************/
1600 /* determine if X or P is selected (to select a piece) */
1601 /*******************************************************/
1602 if (( xkey == 88) || ( xkey == 80)){ // if 'X' or 'P' is selected (88=X, 80=P)
1603 canselect=0; // set piece to NOT SELECTABLE
1604 if ((( playertype == ATTACKER )&&(players[ns][ew] == ATTACKER ))||(( playertype == DEFENDER )&&((players[ns][ew] == DEFENDER )||(players[ns][ew] == KING)))) { // piece is selectable
1605 canselect=1; // set piece is selectable
1606 canpiecemove();
1607 if (route ) {
1608 flashcolor=GREEN;flashscreen();
1609 if ( xkey == 80 ){ // if P is pressed
1610 printpossiblemoves(); // Print possible moves
1611 printturnprompt();
1612 printturnline();
1613 }
1614 }
1615 else {
1616 flashred();
1617 canselect=0; // unselectable, cannot move
1618 }
1619 }
1620 else {
1621 flashred();
1622 }
1623 if (( mkey == 88 )&&( canselect )){ // if piece is SELECTED and CAN move
1624 inkcolor=GREEN;inkasm(); // 2=green, 3=yellow to indicate piece is selected
1625 flashback=GREEN;
1626 inverse2();
1627 //printmessage();
1628 //strcpy(message,playertext);
1629 message="PLACE CURSOR ON DESTINATION\nX:SELECT SQUARE R:RESET";
1630 printmessage();
1631 printturnline();
1632 //printf("\n\n\n%s Turn X=Select R=Reset",playertext);
1633 //inversex=cx;
1634 //inversey=cy;
1635 //inverse(); // highlight selected square (inverse color)
1636 mkey=0; // ensure mkey at known value
1637 // set Original cursor and board position of selected square
1638 ocx=cx; ocy=cy; ons=ns; oew=ew;
1639 while (( mkey != 88 ) && ( mkey != 82)){ // move cursor until X or R selected
1640 if ( cursormovetype < 0 ){
1641 if ( ons == ns ) cursormovetype=1;
1642 if ( oew == ew ) cursormovetype=2;
1643 }
1644 if (( ons == ns )&& (oew == ew )) cursormovetype=0; // cursor can move
1645 if (( mkey >= 8 ) && ( mkey <= 11)){
1646 if ( cursormovetype > 0 ){
1647 if ((( cursormovetype == 2 )&&( mkey < 10 ))||((cursormovetype == 1)&&(mkey>9))) cursormovetype=-1;
1648 }else{ // cursormovetype is 0
1649 cursormovetype=1;
1650 if (( mkey == 10 )|| ( mkey == 11)) cursormovetype=2;
1651 }
1652 }
1653
1654 if ( cursormovetype > 0 ) {
1655 cursormode=1; // restricted
1656 movecursor2();
1657 }
1658 if ( cursormovetype < 0) { flashred();} // flashscreen red
1659 mkey=getchar();
1660 }
1661 if ( mkey == 82 ){ // R has been selected, Reset cursor to original positions
1662 fb=0;
1663 inverse();
1664 cx=ocx; // reset coords and board values to original positions
1665 cy=ocy;
1666 ns=ons;
1667 ew=oew;
1668 fb=1;
1669 inverse2(); inverse();
1670 }
1671 if ( mkey == 88 ){ // if X selected
1672 inverse(); // inverse original position
1673 // X is in original position so return to cursor movement
1674 if (( ons == ns )&&( oew == ew)){
1675 inverse2(); inverse();
1676 mkey=0; // piece de-selected
1677 }
1678 else{
1679 movepiece();// move selected piece
1680 turn=0; // player has ended turn
1681 }
1682
1683 }
1684 }
1685 inkcolor=CYAN;inkasm(); // back to cyan
1686 flashback=CYAN;
1687 printturnprompt();
1688 printturnline();
1689 } // key = X or P
1690 } // While player turn
1691 }
1692
1693
1694 // Moves selected piece to new location - updating board arrays and re-drawing tiles where necessary
1695 void movepiece(){
1696 p1=ATTACKER; // piece type comparison (lower) - used for determining takes - default=attacker
1697 p2=CASTLE; // piece type comparison (upper) - used for determining takes - default=attacker
1698 piecetype=players[ons][oew]; // obtain type of piece
1699 // move piece
1700 fb=0;
1701 //drawcursor(); // blank out cursor at new selected position
1702 row=ons;
1703 col=oew;
1704 tiletodraw=tiles[ons][oew];
1705 DrawPictureTiles(); //draw tile at original location (blank out square)
1706 players[ons][oew]=0; //set original location to zero (unnocupied)
1707 players[ns][ew]=piecetype; //update square with player info
1708 // row, col required for drawpiece function
1709 row=ns;
1710 col=ew;
1711 drawpiece(); // draw piece at new location - 18-10-2011
1712 if (piecetype == KING){ // update king position (used by AI)
1713 kingns=ns;kingew=ew;
1714 if ((kingns != 5)||(kingew != 5)) {
1715 players[5][5]=CASTLE; // set central square to be 4 so it can be used in takes
1716 tiletodraw=3; row=5;col=5;
1717 DrawPictureTiles(); // draw central square
1718 }
1719 }
1720 // having moved piece we now need to check for, and implement any TAKES
1721 if (piecetype > ATTACKER ){ // if defender/king
1722 p1=DEFENDER;
1723 p2=KING;
1724 }
1725 tpew=ew;
1726 takecounter=0; // set the take counter to zero (incremented in takepiece)
1727 if ( ns > 1 ){// check north
1728 orientation=NORTH; tpns=ns-1; movepieceB();
1729 }
1730 if ( ns < 9 ){ // check south
1731 orientation=SOUTH; tpns=ns+1; movepieceB();
1732 }
1733 tpns=ns;
1734 if ( ew < 9 ){ // check east
1735 orientation=EAST; tpew=ew+1; movepieceB();
1736 }
1737 if ( ew > 1 ){ // check west
1738 orientation=WEST; tpew=ew-1; movepieceB();
1739 }
1740
1741 // update count of attackers around king
1742 kingattacker[NORTH]=0; // count of attackers NORTH of king
1743 kingattacker[SOUTH]=0; // count of attackers SOUTH of king
1744 kingattacker[EAST]=0; // count of attackers EAST of king
1745 kingattacker[WEST]=0; // count of attackers WEST of king
1746 kingdefender[NORTH]=0; // count of defenders NORTH of king
1747 kingdefender[SOUTH]=0; // count of defenders SOUTH of king
1748 kingdefender[EAST]=0; // count of defenders EAST of king
1749 kingdefender[WEST]=0; // count of defenders WEST of king
1750 kingpieces[NORTH]=0;
1751 kingpieces[SOUTH]=0;
1752 kingpieces[EAST]=0;
1753 kingpieces[WEST]=0;
1754
1755 // perform NORTH/SOUTH checks
1756 cy=kingew;
1757 orientation=NORTH;
1758 for (counter=0;counter<kingns;inccounter()){
1759 cx=counter;incdefatt();
1760 }
1761 orientation=SOUTH; // SOUTH
1762 for (counter=kingns+1;counter<11;inccounter()){
1763 cx=counter; incdefatt();
1764 }
1765 // perform EASt/WEST check
1766 cx=kingns;
1767 orientation=EAST; // EAST
1768 for (counter=kingew+1;counter<11;inccounter()){
1769 cy=counter; incdefatt();
1770 }
1771
1772 orientation=WEST; // WEST
1773 for (counter=0;counter<kingew;inccounter()){
1774 cy=counter; incdefatt();
1775 }
1776
1777 if (takecounter > 1) takemessage(); // display a firstblood/multiple takes message
1778 }
1779
1780 void movepieceB(){
1781 if ( cantakepiece() ) takepiece();
1782 }
1783 void incdefatt(){
1784 if (players[cx][cy] == ATTACKER) inckingattacker();
1785 if (players[cx][cy] == DEFENDER) inckingdefender();
1786 }
1787
1788 void inckingdefender(){
1789 kingdefender[orientation]++;
1790 kingpieces[orientation]++;
1791 }
1792
1793 void inckingattacker(){
1794 kingattacker[orientation]++;
1795 kingpieces[orientation]++;
1796 }
1797
1798 /*void subcanbetaken(){
1799 target[targetns][targetew]=1;
1800 //if ((ns==kingns)||(ew==kingew)) { target[ns][ew]=3;} // means acceptable risk
1801 }
1802 */
1803 // can I be taken after moving here?
1804 void canbetaken() {
1805 if ((targetns )&&(targetns < 10)){
1806 Spike=NORTH;
1807 takena=targetns-1;takenb=targetew;takenc=targetns+1;takend=targetew;takene=1;
1808 subcanbetaken2();
1809 Spike=SOUTH;
1810 takena=targetns+1;takenb=targetew;takenc=targetns-1;takend=targetew;takene=5;
1811 subcanbetaken2();
1812 }
1813
1814 if ((targetew )&&(targetew < 10)){
1815 Spike=EAST;
1816 takena=targetns;takenb=targetew+1;takenc=targetns;takend=targetew-1;takene=10;
1817 subcanbetaken2();
1818 Spike=WEST;
1819 takena=targetns;takenb=targetew-1;takenc=targetns;takend=targetew+1;takene=20;
1820 subcanbetaken2();
1821 }
1822 }
1823
1824 // Will return a value (take) who's values will be: 0= no, 1=yes
1825 unsigned char cantakepiece(){
1826 take=0;
1827 p1=ATTACKER; // piece type comparison (lower) - used for determining takes - default=attacker
1828 p2=CASTLE; // piece type comparison (upper) - used for determining takes - default=attacker
1829 pcheckns1=ns-1; // defaults to north
1830 pcheckns2=ns-2;
1831 pcheckew1=ew;
1832 pcheckew2=ew;
1833 piecetype=players[ns][ew]; // obtain type of piece
1834 //if ( fb==3) { piecetype=players[ctns][ctew];} // if computer turn set piecetype to piece being checked
1835 if ((fb == 3)||(fb == 9)) piecetype=ATTACKER; // default = ATTACKER
1836 if (piecetype > ATTACKER ){ // if defender
1837 p1=DEFENDER;
1838 p2=KING;
1839 }
1840 if ( orientation == SOUTH){ // if south
1841 pcheckns1=ns+1;
1842 pcheckns2=ns+2;
1843 }
1844 if ( orientation > SOUTH){ // if east or west
1845 pcheckns1=ns;
1846 pcheckns2=ns;
1847 pcheckew1=ew+1;
1848 pcheckew2=ew+2;
1849 if ( orientation == WEST){ // if west
1850 pcheckew1=ew-1;
1851 pcheckew2=ew-2;
1852 }
1853 }
1854 // Ring Of Steel: when fb==6 update target if defender outside it's home zone
1855 if (( playerlevel )&&(turncount < RINGOFSTEEL)){ // if greater than SAGA and within 1st RINGOFSTEEL turns
1856 if ((fb == 6)&&(players[pcheckns1][pcheckew1] == DEFENDER)){
1857 if (( pcheckns1 < 3 ) || (pcheckns1 > 7) || (pcheckew1 < 3)||(pcheckew1 > 7)){
1858 target[ns][ew]+=10;
1859 }
1860 }
1861 }
1862 // if a take is possible increment the take counter - if values fall within bounds...
1863 if ((pcheckns2 > -1)&&(pcheckns2 < 11)&&(pcheckew2 > -1)&&(pcheckew2 < 11)){
1864 if (( players[pcheckns1][pcheckew1] )&&(players[pcheckns1][pcheckew1] != p1)&&(players[pcheckns1][pcheckew1] != p2 )&&(players[pcheckns1][pcheckew1] != CASTLE)){
1865 // if ((( players[pcheckns2][pcheckew2] == p1 )||(players[pcheckns2][pcheckew2] == p2 )||(players[pcheckns2][pcheckew2] == 4)&&(pcheckns2!=5)&&(pcheckew2!=5))) // the 5 is to EXCLUDE central square
1866 if (( players[pcheckns2][pcheckew2] == p1 )||(players[pcheckns2][pcheckew2] == p2 )||(players[pcheckns2][pcheckew2] == CASTLE)){
1867 take++;
1868 if (players[pcheckns1][pcheckew1]==KING) take--;// if possible take is a king
1869
1870 }
1871 if ( computer[pcheckns2][pcheckew2] ) inctarget(); // 31-10-2011 - can possibly take on next turn
1872 }
1873 }
1874 return take;
1875 }
1876
1877 // performs taking/removing a piece
1878 void takepiece(){
1879 players[tpns][tpew]=0; // clear board location
1880 row=tpns;
1881 col=tpew;
1882 inkcolor=6;inkasm();
1883 explodetile(); // plays animation to "kill" a tile
1884 tiletodraw=tiles[row][col]; // decide tile to draw
1885 DrawPictureTiles();// draw tile at location
1886 // update deadpile
1887 deadtoggle=1; // ensure deadpiece is drawn in foreground color on deadpile
1888 deadpile();
1889 inctakecounter(); // increment the take counter
1890 if (firstblood){
1891 TakeWeight=LOWTAKEWEIGHT; // reduce the takeweight figure
1892 Trophies[FIRSTBLOOD][playertype-1]=TROPHY; // update Trophies Array
1893 firstblood=0;
1894 //message=" ()( FIRST BLOOD TO ATTACKER )()\n )() PRESS A KEY ()(";
1895 message=" ()( FIRST BLOOD TO ATTACKER )()";
1896
1897 if ( playertype == DEFENDER ){
1898 //message=" ()( FIRST BLOOD TO KING )()\n )() PRESS A KEY ()(";
1899 message=" ()( FIRST BLOOD TO KING )()";
1900
1901 }
1902 submessage();
1903
1904 }
1905 }
1906 void takemessage(){ // displays a firstblood or multiple take message
1907 if ( takecounter == 2 ) {
1908 //message=" ()( BLOOD EAGLE )()\n )() PRESS A KEY ()(";
1909 message=" ()( BLOOD EAGLE )()";
1910 Trophies[BLOODEAGLE][playertype-1]=TROPHY;
1911 }
1912 if ( takecounter == 3 ) {
1913 //message=" ()( BERZERKER )()\n )() PRESS A KEY ()(";
1914 message=" ()( BERZERKER )()";
1915 Trophies[BERZERKER][playertype-1]=TROPHY;
1916 }
1917 submessage();
1918 }
1919 void submessage(){
1920 printmessage();
1921 flashon();
1922 printturnline();
1923 getchar();
1924 }
1925 void subarrows(){
1926 if ( tiles[xns][xew] == CASTLE ) arrow=2;
1927 if ((players[xns][xew])&&(players[xns][xew] < CASTLE)) {
1928 arrow=0; // !ok if piece occupied
1929 if ((fb == 4)&&(players[xns][xew] == ATTACKER)) enemy[xns][xew]+=ENEMYWEIGHT; // means enemy could get here if attacker moved elsewhere
1930 }
1931 if (( players[ns][ew] == KING )&&( tiles[xns][xew] == CASTLE )) arrow = 1; // CASTLE square ok if king
1932 }
1933
1934 void subarrows2(){
1935 if ( orientation == NORTH ) enemy[xns][xew]+=5; // means enemy can get here from SOUTH
1936 if ( orientation == SOUTH ) enemy[xns][xew]+=1; // means enemy can get here from NORTH
1937 if ( orientation == EAST ) enemy[xns][xew]+=20; // means enemy can get here from WEST
1938 if ( orientation == WEST ) enemy[xns][xew]+=10; // means enemy can get here from EAST
1939 }
1940
1941 void inccantake(){
1942 //z=cantakepiece(); // z=number of pieces that can be taken
1943 if (cantakepiece()){
1944 cantake+=take; // take is returned from cantakepiece()
1945 cantakeadjust(); // decrement take count if taken piece on same plane as king and taker isn't
1946 cantakeadjust2(); // dont take if only piece in zone rol/col
1947 }
1948 //cantake+=cantakepiece();
1949 }
1950
1951 // Explodes a tile
1952 void explodetile() {
1953 //unsigned char b;
1954 ptr_graph=ExplodeTiles; // pointer to byte values of loaded picture
1955 for (b=0;b<8;b++){
1956 tileloop();
1957 pausetime=900;
1958 if (b == 5) pausetime=3000; // pause longer on skull&crossbones
1959 pause(); // add a pause
1960 }
1961 }
1962
1963 void timertile(){
1964 unsigned char timer;
1965 ptr_graph=TimerTiles; // pointer to byte values of loaded picture (Timer)
1966 row=5;col=5;pausetime=250;
1967 for (timer=0;timer<8;timer++){
1968 tileloop();
1969 pause();
1970 }
1971 }
1972
1973 void drawpiece(){
1974 tiletodraw=players[row][col];
1975 if ( tiletodraw ) tiletodraw+=3;
1976 if ( tiles[row][col] ) tiletodraw+=3;
1977 DrawPictureTiles();
1978 }
1979
1980 void drawarrow(){ // not really an arrow any more...
1981 // The business with the c variable is a bit of finessing so that the central square is not highlighted if you can't actually land on it..
1982 a=cx;b=cy; // save contents of cx/cy to a/b
1983 c=1; // c means OK to print
1984 cx=col;cy=row; // copy row/col to cx/cy for inverse function
1985 if (((cx==5)&&(cy==5))&&(players[ns][ew] != KING)) c=0; // don't highlight central square...
1986 if (c) inverse(); // inverse the color at square cx/cy
1987 cx=a;cy=b; // restore contents of cx/cy from a/b
1988 /*
1989 if ( fb == 1 ){
1990 tiletodraw=10;
1991 if ( tiles[row][col] ) tiletodraw++; // add another 1 for arrow with background
1992 }
1993 else{
1994 tiletodraw=tiles[row][col]; // draw original tile (includes blank)
1995 }
1996 DrawPictureTiles();*/
1997 }
1998
1999 void surroundcount(){
2000 //unsigned char test;
2001 zerocounter();
2002 //setpoints();
2003 surrounded=0;
2004 if (( kingns == 0)||(kingns == 10)||(kingew == 0)||(kingew == 10)) incsurround(); // added 18/10/2011 (inc surround if at an edge)
2005 surew=kingew;
2006 if ( kingns ) {surns=kingns-1;surroundcheck();}
2007 if ( kingns < 10 ){surns=kingns+1;surroundcheck();}
2008 surns=kingns;
2009 if ( kingew ) {surew=kingew-1;surroundcheck();}
2010 if ( kingew < 10 ){surew=kingew+1;surroundcheck();}
2011 /*for (test=surrounded;test >0; test--){
2012 zap();
2013 }*/
2014 // unset any "enemy and target values" ONLY if blank square adjacent to king is accessible
2015 if (surrounded == 3){
2016 ezew1=kingew;
2017 if ( kingns ){ // NORTH
2018 ezns1=kingns-1;
2019 enemyzero();
2020 }
2021 if ( kingns < 10 ){ // SOUTH
2022 ezns1=kingns+1;
2023 enemyzero();
2024 }
2025 ezns1=kingns;
2026 if ( kingew < 10 ){ // EAST
2027 ezew1=kingew+1;
2028 enemyzero();
2029 }
2030 if ( kingew ){
2031 ezew1=kingew-1; // WEST
2032 enemyzero();
2033 }
2034 }
2035 }
2036
2037 void pause(){
2038 int p;
2039 for (p=0; p<pausetime;p++){};
2040 }
2041
2042
2043 /******************************/
2044
2045 void subcanbetaken2(){ // DO NOT MESS with this (NBARNES 10-01-2012)
2046 if (players[takena][takenb] > ATTACKER){
2047 if ((players[takenc][takend] == 0)||(enemy[takenc][takend] > ENEMYWEIGHT)){
2048 if ((enemy[takenc][takend]-takene)&&((enemy[takenc][takend] < ENEMYWEIGHT)||(enemy[takenc][takend]-ENEMYWEIGHT))){ // 23-12-2011
2049 compass[origorient]=1; // e.g. compass[NORTH]=1 means canbetaken here if moving from NORTH
2050 if ((Spike==origorient)&&(enemy[takenc][takend]-takene==0)) compass[origorient]=0;
2051 if (enemy[takenc][takend]>ENEMYWEIGHT){ // THIS is the business!!!
2052 if ((origorient < EAST)&&(mkey != takenc)&&(oew != takend)) compass[origorient]=0;
2053 if ((origorient > SOUTH)&&(ons != takenc)&&(mkey != takend))compass[origorient]=0;
2054 }
2055 }
2056 //if ((enemy[takenc][takend]-takene)==0) compass[origorient]=0;
2057 }
2058 }
2059 }
2060
2061
2062 void inctarget(){
2063 target[targetns][targetew]+=2;
2064 //target[targetns][targetew]++; // 28-04-2013
2065 }
2066
2067
2068 void surroundcheck(){
2069 // if attacker or kingsquare n/s/e/w then inc surrounded
2070 //if (players[surns][surew]==1) incsurround(); // is attacker n,s,e,w
2071 //if (tiles[surns][surew]>2) incsurround(); // is king square n,s,e,w
2072 if ((players[surns][surew] == ATTACKER)||(tiles[surns][surew] > 2)) {
2073 incsurround();
2074 }
2075 }
2076
2077
2078
2079
2080 // called from "surroundcount()"
2081 void enemyzero() {
2082 if (( players[ezns1][ezew1] == 0 )&&(target[ezns1][ezew1])){ // if adjacent square n/s/e/w is blank and accessible
2083 ClearArrays(); // set all arrays to zero (target, enemy, computer)
2084 target[ezns1][ezew1]=100; // set big target value to final space by king
2085 }
2086 }
2087 // Checkroute:
2088 // checkroutemode=1 Returns number of pieces on a given route
2089 // checkroutemode=2 Increments the target values on route
2090 // checkroutemode=3 Number of targets on route
2091 // checkroutemode=4 Number of "enemy" targets on route (where enemies CAN go)
2092 // checkroutemode=5 Emergency! Make target=hightarget+1
2093 unsigned char checkroute(){
2094 z=0;
2095 // a SINGLE COLUMN (North to South) so check each row on it
2096 checkroutestart=startrow;
2097 checkroutedest=destrow;
2098 checkrouterow=startrow;
2099 checkroutecol=startcol;
2100 if ( startrow == destrow ){ // ELSE a single ROW (WEST to EAST)
2101 checkroutestart=startcol;
2102 checkroutedest=destcol;
2103 }
2104 for (x=checkroutestart;x<=checkroutedest;x++){
2105 //if ( startrow==destrow ) {checkroutecol++;}else{checkrouterow++;}
2106 switch(checkroutemode){
2107 case 1: if ((players[checkrouterow][checkroutecol] == ATTACKER )||(players[checkrouterow][checkroutecol] == DEFENDER )) z++;break;
2108 case 2: if (target[checkrouterow][checkroutecol] ) target[checkrouterow][checkroutecol]+=2;break;
2109 case 3: if (target[checkrouterow][checkroutecol] > 1 ) z++;break;
2110 case 4: if (enemy[checkrouterow][checkroutecol] ) z+=ENEMYBLOCK;break;
2111 case 5: if (target[checkrouterow][checkroutecol]) target[checkrouterow][checkroutecol]+=points;break; // brokenarrow
2112 //case 6: if (players[checkrouterow][checkroutecol]) z++;break;
2113 case 6: if (kingtracker[checkrouterow][checkroutecol]) z++;break;
2114 //case 7: if (computer[checkrouterow][checkroutecol]) target[checkrouterow][checkroutecol]+=hightarget;break;
2115 }
2116 if ( startrow == destrow ) {checkroutecol++;}else{checkrouterow++;}
2117
2118 }
2119 return z;
2120 }
2121
2122 /*
2123 // ORIGINAL 02/09/2012
2124 unsigned char checkroute(){
2125 z=0;
2126 if (orientation<EAST){ // if checking ROWS (crossing the T) (used for NORTH SOUTH checks)
2127 for (x=startcol;x<=destcol;x++){ // check row
2128 switch(checkroutemode){
2129 case 1: if ((players[startrow][x]==1)||(players[startrow][x]==2)) {z++;}break;
2130 case 2: if (target[startrow][x]) {target[startrow][x]+=2;}break;
2131 case 3: if (target[startrow][x]) {z++;}break;
2132 case 4: if (enemy[startrow][x]) {z+=10;}break;
2133 case 5: if (target[startrow][x]) {target[startrow][x]=255;}
2134 }
2135 }
2136 }
2137 else { // EAST WEST checks (crossing the T)
2138 for (x=startrow;x<=destrow;x++){ // check accross
2139 switch(checkroutemode){
2140 case 1: if ((players[x][startcol]==1)||(players[x][startcol]==2)) {z++;}break;
2141 case 2: if (target[x][startcol]) {target[x][startcol]+=2;}break;
2142 case 3: if (target[x][startcol]) {z++;}break;
2143 case 4: if (enemy[x][startcol]) {z++;}break;
2144 case 5: if (target[x][startcol]) {target[x][startcol]==255;}
2145 }
2146 }
2147 }
2148 return z;
2149 }
2150 */
2151 // decrements cantake if taken piece is on same plane as king
2152 // and attacking piece isn't AND only one defender on plane
2153 void cantakeadjust(){
2154 flag=0;
2155 //if ((playertype == DEFENDER )&&(gamestyle == 1)){ // if COMPUTER playing as attacker and his turn
2156 if (pcheckns1 == kingns){
2157 flag=1;
2158 if (ctew < kingew){orientation=WEST;}else{orientation=EAST;}
2159 //if ((kingattacker[orientation]+kingdefender[orientation])<4){cantake--;}
2160 }
2161 if (pcheckew1 == kingew){
2162 flag=1;
2163 if (ctns < kingns){orientation=NORTH;}else{orientation=SOUTH;}
2164 //if ((kingattacker[orientation]+kingdefender[orientation])<4){cantake--;}
2165 }
2166 if (flag ) {
2167 //if ((kingattacker[orientation]+kingdefender[orientation])<4){cantake--;}
2168 if (kingpieces[orientation] < 4) cantake--; //10-05-2013 if no other pieces on plane
2169 }
2170 //}
2171 }
2172 void cantakeadjust2(){
2173 if (( pcheckns1 < 2 ) || ( pcheckns1 > 8 )){
2174 startrow=pcheckns1;destrow=pcheckns1;startcol=0;destcol=10;
2175 }
2176 if (( pcheckew1 < 2 ) || ( pcheckew1 > 8 )){
2177 startrow=0;destrow=10; startcol=pcheckew1; destcol=pcheckew1;
2178 }
2179 setcheckmode1();
2180 if (checkroute()==1) cantake--;
2181
2182 }
2183 void updatetarget(){
2184 targetns=ctns;targetew=ctew;
2185 target[targetns][targetew]=2; // set target to 2 (1=canbetaken if i go here)
2186 // set "illegal" squares to zero
2187 target[5][5]=0;
2188 target[0][10]=0;
2189 target[0][0]=0;
2190 target[10][0]=0;
2191 target[10][10]=0;
2192 if ( target[targetns][targetew] ){ // only if target is valid (i.e. not a king square)
2193 // increase target if blocking 1 enemy
2194 if ( enemy[targetns][targetew] ) inctarget();
2195 // increase target if blocking 2 enemies
2196 if (( enemy[targetns][targetew] == 6)||(enemy[targetns][targetew] == 11)||(enemy[targetns][targetew] == 21)||(enemy[targetns][targetew] == 15)||(enemy[targetns][targetew] == 25)||(enemy[targetns][targetew] == 30)) inctarget();
2197 // increase target if blocking 3 enemies
2198 if (( enemy[targetns][targetew] == 35)||(enemy[targetns][targetew] == 16)||(enemy[targetns][targetew] == 26) || (enemy[targetns][targetew] == 31)) inctarget();
2199 // calculates how many takes can be made in this position (cantake)
2200 calccantake2();
2201 target[targetns][targetew]+=(cantake*TakeWeight);
2202 // NOOSE: Favour takes in the zone (sketchy at present, needs refinement)
2203 /* if ((( targetns < 2 )||(targetns > 9))||((targetew < 2)||( targetew > 9))){
2204 target[targetns][targetew]+=(cantake*TakeWeight);
2205 }*/
2206 //if (cantake==0) {canbetaken();} // sets target to 1 if cannot take but can be taken
2207 }
2208 }
2209
2210
2211 // calculate how many takes can be made
2212 /*
2213 void calccantake() {
2214 //unsigned char x;
2215 //cantake=0;
2216 inccantake(); // inc cantake if can take in direction of travel
2217 //for (x=0;x<4;x++) {
2218 //if ( x<2 ){ // heading north/south
2219 if ( origorient < EAST ){ // HEADING NORTH/SOUTH
2220 if ( ew < 10 ) {orientation=EAST; inccantake();} // check EAST
2221 if ( ew > 1 ) {orientation=WEST; inccantake();} // check WEST
2222 }else{ // heading east/west
2223 if ( ns > 1 ) {orientation=NORTH; inccantake();} // check NORTH
2224 if ( ns < 9 ) {orientation=SOUTH; inccantake(); } // check SOUTH
2225 }
2226 }
2227 */
2228 void calccantake2(){
2229 // check all directions from a given target square...
2230 cantake=0;
2231 CanTakeDirection[NORTH]=0;
2232 CanTakeDirection[SOUTH]=0;
2233 CanTakeDirection[EAST]=0;
2234 CanTakeDirection[WEST]=0;
2235 if ( targetew < 9 ) {orientation=EAST; calccantake3();} // check EAST
2236 if ( targetew > 1 ) {orientation=WEST; calccantake3();} // check WEST
2237 if ( targetns > 1 ) {orientation=NORTH; calccantake3();} // check NORTH
2238 if ( targetns < 9 ) {orientation=SOUTH; calccantake3();} // check SOUTH
2239 }
2240 void calccantake3(){
2241 inccantake();
2242 CanTakeDirection[orientation]=z; // either 1 or 0 (TAKE or NOTAKE)
2243 }
2244 // print the title screen
2245 /*
2246 void printtitles() {
2247 unsigned char f=0;
2248 inkcolor=3;inkasm(); // yellow, erm...gold
2249 row=0;c=6;d=11;col=0;
2250 for (mkey=0;mkey<2;mkey++){
2251 for (a=row;a<c;a++){
2252 col=0;
2253 if (mkey ) {fliprune();col=1;} // flip the row
2254 for(b=col;b<d;b++){
2255 tiletodraw=border[a][b]; // get runic chars
2256 if (f == 1) tiletodraw++; // get western chars on 2nd pass
2257 if ( tiletodraw < 99){
2258 ptr_graph=RunicTiles; // pointer to Border Tiles graphics
2259 drawtile(); // draw tile
2260 }
2261 col++;
2262 }
2263 row++;
2264 }
2265 row=1;col=1;c=5;d=10;pausetime=26000;pause();
2266 f++;if (f==2) f=0;
2267 }
2268 }
2269 */
2270 void PrintTrophyScreen(){
2271 // Print text in text area
2272 Checker=11;CheckerBoard();
2273 erasetext=120; // all three lines
2274 erasetextarea();
2275 message=" ()( HNEFATAFL ()(\n )() VALHALLA AWARDS )()\n ()( PRESS A KEY ()(";
2276 //message=" ()( HNEFATAFL ()(\n )() VALHALLA AWARDS )()\nTURN: REMAINING:";
2277 printline();
2278 //printturnline();
2279 // set ink color for main screen
2280 inkcolor=3;inkasm(); // yellow, erm...gold
2281 row=0;a=0;b=4;c=1;
2282 PrintTrophyScreen1(); // print top row of border
2283 a=6;b=8;c=7;
2284 for (row=1;row<10;row++){
2285 PrintTrophyScreen1(); // print middle rows of border
2286 }
2287 row=10;a=2;b=5;c=3;
2288 PrintTrophyScreen1(); // print bottom row of border
2289 bottompattern=0;drawbottom(); // blank out line at bottom
2290 //PrintTrophyScreen2(); // blank out right edge before redrawing board
2291 AlgizThorTrophyCalc(); // Calculate the awarding of ALGIZ/THOR Trophies
2292 PrintTrophyScreen3(); // print the trophy grid (with trophies)
2293 cy=2;cx=7;inverse();cx=8;inverse(); // inverse the trophy head columns
2294 PrintTrophyScreen4(); // print text onto the hires part of screen
2295 getchar();
2296 Checker=11;CheckerBoard();
2297 }
2298 void PrintTrophyScreen1(){
2299 for (col=0; col<11; col++){
2300 tiletodraw=b;
2301 if (col==0) tiletodraw=a;
2302 if (col==10) tiletodraw=c;
2303 ptr_graph=BorderTiles2;
2304 drawtile();
2305 }
2306 }
2307 // CheckerBoard :screenwipe, x controls number of cols (different at start of game)
2308 void CheckerBoard(){
2309 tiletodraw=8;
2310 pausetime=25;
2311 a=0;subCheckerBoard2();
2312 a=1;subCheckerBoard2();
2313 }
2314 void subCheckerBoard(){
2315 for (col=b; col<Checker; col+=2){
2316 ptr_graph=BorderTiles2;
2317 drawtile();pause();
2318 }
2319 }
2320 void subCheckerBoard2(){
2321 for (row=0; row<11; row++){
2322 b=a;
2323 subCheckerBoard();
2324 if (row < 10 ) row++;
2325 b=0;
2326 if (a==0) b=1;
2327 subCheckerBoard();
2328 }
2329 }
2330 /*
2331 void PrintTrophyScreen2(){
2332 tiletodraw=8; // blank tile
2333 for (row=0;row<11;row++){
2334 for (col=11;col<13;col++){
2335 ptr_graph=BorderTiles2;
2336 drawtile();
2337 }
2338 }
2339 }
2340 */
2341 void PrintTrophyScreen3(){
2342 // draw grid header
2343 for (row=2;row<9;row++){
2344 for (col=7;col<9;col++){
2345 a=row-2;b=col-7; // adjust a,b to align with array values
2346 tiletodraw=Trophies[a][b];
2347 DrawPictureTiles();
2348 }
2349 }
2350 DrawTrophyEdge();
2351 DrawTrophyBottom();
2352 }
2353 // Print the trophy names
2354
2355 void PrintTrophyScreen4(){
2356 //deadtext=0xa5ae; //starting position of text on screen
2357 row=3;col=2;
2358 //for (x=0;x<6;x++){
2359 x=0; PT5();
2360 x=1; PT5();
2361 x=2; PT5();
2362 x=3; PT5();
2363 x=4; PT5();
2364 x=5; PT5();
2365 //}
2366 }
2367 void PT5(){
2368 deadcurset=0xa002+(40*18*row)+(40*6)+(col*3);
2369 for (y=0;y<11;y++){
2370 textchar=TrophyText[x][y];
2371 chasm2();
2372 deadcurset++;
2373 }
2374 row++;
2375 }
2376 void AlgizThorTrophyCalc(){ // Calculate if anyone should get the ALGIZ or THOR Trophies
2377 if (deadattackers==0) Trophies[ALGIZ][0]=TROPHY;
2378 if (deaddefenders==0) Trophies[ALGIZ][1]=TROPHY;
2379 if (deaddefenders>11) Trophies[THOR][0]=TROPHY;
2380 if (deadattackers==24)Trophies[THOR][1]=TROPHY;
2381 }
2382 void ClearTrophies(){
2383 Trophies[0][0]=7; // PictureTiles : attacker tile
2384 Trophies[0][1]=9; // PictureTiles : king tile
2385 Trophies[1][0]=0;
2386 Trophies[1][1]=0;
2387 Trophies[2][0]=0;
2388 Trophies[2][1]=0;
2389 Trophies[3][0]=0;
2390 Trophies[3][1]=0;
2391 Trophies[4][0]=0;
2392 Trophies[4][1]=0;
2393 Trophies[5][0]=0;
2394 Trophies[5][1]=0;
2395 Trophies[6][0]=0;
2396 Trophies[6][1]=0;
2397 }
2398 /*
2399 // performs the rune flipping sequence in title screen
2400 void fliprune() {
2401 for (tiletodraw=30;tiletodraw<35;tiletodraw++){
2402 for (col=1;col<10;col++){
2403 if (border[row][col] < 99){
2404 ptr_graph=RunicTiles; // pointer to Border Tiles graphics
2405 drawtile();pausetime=50;pause();
2406 }
2407 }
2408 }
2409 }
2410 */
2411 /*
2412 void subzoneupdate(){ // (updates border targets)
2413 message="BROKEN ARROW UPDATE";
2414 printline();
2415 message="\nPRESS A KEY";
2416 printline();
2417 getchar();
2418 checkroutemode=5;checkroute();
2419 }
2420 */
2421 void updateroutetarget(){
2422 //setcheckmode3(); // set the mode of checkroute to 3 (count how many TARGETS are on route)
2423 //pacpointsz=checkroute();
2424 //pacpointsz=25-pacpointsz; // 20 = max amount of targets on a given route to a corner
2425 setcheckmode2(); // set the mode of checkroute to 2 (update targets)
2426 checkroute();
2427 }
2428
2429 // flashes the screen red (goes back to whatever flashback is set to)
2430 void flashred(){
2431 flashcolor=RED;
2432 flashscreen();
2433 }
2434 // gets the turn values and splits into huns, thor, odin
2435 void calcturnvalue(){
2436 // calculate values
2437 huns=x/100;
2438 thor=(x-(huns*100))/10;
2439 odin=x-(huns*100)-(thor*10);
2440 // transform to ascii code (hundreds, tens and units)
2441 huns+=48;
2442 thor+=48;
2443 odin+=48;
2444 }
2445 // prints the turn counters (uses huns, thor, odin)
2446 void printturnline(){
2447 x=turncount;
2448 //x=kingns;
2449 //x=enemy[5][3];
2450 //x=target[8][4];
2451 calcturnvalue(); // for display purposes
2452 printturncount(); // print number of turns
2453 x=turnlimit-turncount;// x= turns remaining
2454 //x=kingew;
2455 //x=target[8][5];
2456 calcturnvalue(); // for display purposes
2457 TurnsRemaining=x; // for RAIDO Trophy Calculation
2458 printremaining(); // print turns remaining
2459 y=GREEN;
2460 if ( x < 10) y=YELLOW;
2461 if ( x < 5 ) y=RED;
2462 colorturn(); // set color for turn row
2463 }
2464 /*
2465 void prioritycalc(){ // calculates the priorities of moving a piece
2466 for(a=0;a<11;a++){
2467 for (b=0;b<11;b++){
2468 if (players[a][b]==1){
2469 // count attackers on row
2470 for (c=0;c<11;c++){
2471 if (players[c][b]==1) priority[a][b]++;
2472 }
2473 for (d=0;d<11;d++){
2474 if (players[a][d]==1) priority[a][b]++;
2475 }
2476 }
2477 }
2478 }
2479 }
2480 */

  ViewVC Help
Powered by ViewVC 1.1.26