/[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 768 - (show annotations)
Thu Jan 5 17:34:47 2012 UTC (8 years, 4 months ago) by barnsey123
File MIME type: text/plain
File size: 68363 byte(s)
removed all local vars
1 // main.c by Neil Barnes (a.k.a. Barnsey123)
2 // 22-03-2011 prog to draw a grid (for viking game)
3 // 23-03-2011 create new drawgrid function
4 // 01-04-2011 create new drawtile functions and use compact code (char instead of int etc)
5 // 02-04-2011 routine to read keyboard
6 // 06-04-2011 cursor drawing correct
7 // 11-04-2011 request help from DBUG - bug in OSDK. Have banged head against wall for far too long!
8 // 14-04-2011 DBUG fixed OSDK bug! :-)
9 // 15-04-2011 tidied code up
10 // 15-04-2011 tiles as a global variable, (will be used everywhere)
11 // 16-04-2011 Changed numeric settings for board (0=blank, 1=attackers tile, 2=defenders tile, 3=kings tile)
12 // 16-04-2011 drawing players
13 // 17-04-2011 improving tile drawing (saving few bytes in each routine and having different styles)
14 // 19-04-2011 added flashscreen (to flash screen with desired color - e.g. GREEN for OK, RED for !OK)
15 // 19-04-2011 context sensitive piece selection
16 // 19-04-2011 canpiecemove function (can a selected piece MOVE or not?)
17 // 21-04-2011 numerous bug-fixes to do with x,y co-ords vs north-south/east-west array positions
18 // 21-04-2011 brilliant arrow printing function (hover over one of your pieces and press 'P')
19 // 25-04-2011 fixed bugs in arrow printing routine and reduced code required (TOTAL 817 lines versus 957)
20 // 27-04-2011 fixed some other (all?) bugs in arrow printing routines (new, neater routines)
21 // 29-04-2011 saved a whole bunch of code (789 lines)
22 // 29-04-2011 changed flashscreen so that color can be returned to previous color mode
23 // 29-04-2011 Using POINTERS Huzzah! (never thought that would happen!) 786 lines!
24 // 01-05-2011 Once a piece is selected restrict cursor movement to legal destinations
25 // 02-05-2011 handle "skipping" of central square (if square beyond it is available)
26 // 02-05-2011 900 lines of code (including comments) versus 917 (more efficient and more features)
27 // 02-05-2011 907 lines including refinements
28 // 02-05-2011 CAN now move pieces (taking turns between attacker/defender) 935 lines
29 // 04-05-2011 Can now TAKE pieces (but king squares can't yet take part...) 1012 lines
30 // 04-05-2011 Re-design to save memory/complexity (987 lines)
31 // 05-05-2011 re-design to save memory/complexity (966 lines)
32 // 05-05-2011 add the take rule (of King being able to take attackers with the aid of the king squares)
33 // 06-05-2011 saved a few bytes
34 // 07-05-2011 saved a few bytes (962 lines, 30311 bytes)
35 // 10-05-2011 fixed bug in central square Skipping (could not return to self if adjacent to square)
36 // 10-05-2011 fixed bug allowing defender to select corner square to move!
37 // 10-05-2011 Continuing glabalization (few bugs sorted)
38 // 11-05-2011 Finished Globalizing (23639 bytes)
39 // 13-05-2011 Bug Hunt (23504 bytes) - some tidying up (not 100% byte efficient I'm sure)
40 // 14-05-2011 Bug in printpossiblemoves resolved (arrow WILL print on corner square if piece is KING)
41 // 14-05-2011 checkend function to check if king escapes or is captured (not complete) (26815)
42 // 18-05-2011 developing attacker move (running out of memory! 31213!) hardly started
43 // 26-05-2011 1st attempt at computer moving piece (since Amiga days! 1990/1991?)
44 // 31-05-2011 fixed bug in board update position? (phantom attackers!)
45 // 06-06-2011 incorporated printdestinations into computerturn saving wedges of code
46 // 08-06-2011 fixed bug in computer targetselection (cantake wasn't resetting to 0)
47 // 13-06-2011 fixed bug in canbetaken (mostly fixed)
48 // 15-06-2011 fixed "blind spot"
49 // 15-06-2011 changed checkend to enable "king surrounded against board edge" facility (works)
50 // 15-06-2011 The AI will only be for ATTACKERS (for the moment)
51 // 16-06-2011 various improvements
52 // 17-06-2011-11-07-2011 various tomfoolery to reduce memory footprint
53 // 12-07-2011 New variables to check for pieces NSEW of King
54 // 31-08-2011 prevent attackers occupying corner squares
55 // 12-10-2011 using 18x18 squares (unfinished...needs LOTS of work!!!)
56 // 17-10-2011 using new routine to draw tiles
57 // 18-10-2011 tidied up graphic routines (reduced size of code/executable)
58 // 20-10-2011 Added expodetile function (playes animation to "kill" a piece) plus pause function (reduces executable size)
59 // 20-10-2011 made graphics drawing more efficient (saved 300bytes)
60 // 21-10-2011 added STEELDIAMOND function (create higher target values in a diamond shape around king)
61 // 24-10-2011 Fixed bug with crashes at south-east corner of board (counter must be SIGNED)
62 // 24-10-2011 Fixed a bug regarding counter - much stronger AI!
63 // 24-10-2011 Play again? (needs work)
64 // 27-10-2011 Fixing the "enemy one space away ENEMY UDATE issue" - set value=50
65 // 31-10-2011 Added the COMPUTER array (where the computers's pieces can get to)
66 // 02-11-2011 Added Select gamestyle (human vs computer or human vs human selection)
67 // 02-11-2011 GONZO! the -50 behaviour is interesting - still crashing though...
68 // 09-11-2011 LookBackInAnger routine (attackers to check behind their original position)
69 // 10-11-2011 Now checks to see if a piece can be taken if it stays where it is (needs some finessing)
70 // 14-11-2011 Improved the above routine
71 // 16-11-2011 compress routines more (free up some memory)
72 // 06-12-2011 fixed a couple of bugs (I think)
73 // 08-12-2011 got rid of baseplayers as unnecessary (it's just a copy of tiles)
74 // 08-12-2011 shrunk code still further - added calctakeweight routine
75 // 08-12-2011 shrunk code again (33524) - added enemyzero routine and simplified surrounded routines
76 // 08-12-2011 found/fixed bug in the previous surrounded routine during simplification
77 // 10-12-2011 subpacmanx(made smaller), added checkroute function
78 // 10-12-2011 enemyzero made more effective (and smaller) by zeroing entire enemy array
79 // 12-12-2011 lots of changes (seperated out "updatetarget" from "printarrowsorblanks"
80 // 14-12-2011 Test of replacing PACMAN with something else (see updatetarget)
81 // 20-12-2011 Oh Christ!
82 // 21-12-2011 Added nifty, don't take a defender if on same plane as king routine...
83 // 22-12-2011 above, wont take if LAST defender on plane (added inckingattacker etc)
84 // 22-12-2011 kingsouth/defsouth replaced by arrays (kingattacker, kingdefender)
85 // 23-12-2011 reduced code, fixed a couple of bugs
86 // 04-01-2012 introduced calcantake function (also beefed up the hightarget routines "findpiecens/findpieceew")
87 // 05-01-2012 reduced memory requirements - using unsigned char where possible (34457)
88 // 05-01-2012 removed all local variables (replaced with globals) (34338)
89 // 05-01-2012 got rid of LookBackInAnger (plus some other changes) (33670)
90 /* TODO LIST
91 *** PROBLEM: Not blocking king under certain circumstances - related to changes in target selection...
92 *** Continue with endgame function to return a value determining victory conditions etc
93 *** routine to detect if all attackers have been captured
94 *** routine to detect stalemate (a side cannot move)
95 *** Improve the hightarget routine to select the BEST piece to move (rather than the 1st it finds)
96 */
97 #include <lib.h>
98 //#include <math.h>
99 //#define CHAR_BIT 8
100 #define NORTH 0
101 #define SOUTH 1
102 #define EAST 2
103 #define WEST 3
104 extern unsigned char PictureTiles[]; // standard graphics for pieces and backgrounds
105 extern unsigned char ExplodeTiles[]; // extra graphics to "explode" a piece (animation)
106 /******************* Function Declarations ************************/
107 void drawcursor(); // draws cursor
108 void inverse(); // inverse the color in the square
109 void drawtiles(); // draws all tiles at board x,y boxsize z (uses draw*tile functions)
110 void drawboard(); // kicks off drawgrid/drawtiles
111 void playerturn(); // takes user input to move cursor
112 void drawplayers(); // draw playing pieces
113 void flashscreen(); // flashes screen in selected color for a second or so
114 void canpiecemove(); // can a selected piece move? 0=no, 1=yes
115 void printdestinations(); // print arrows on tiles where a piece can move
116 void printpossiblemoves(); // Print possible moves
117 void printarrowsorblanks(); // PRINT ARROWS/BLANK EM OUT
118 void movecursor2(); // move cursor routine
119 void movepiece(); // move a piece
120 char cantakepiece(); // returns 0=no, 1 yes
121 void takepiece(); // takes specified piece
122 void blinkcursor(); // blinks the cursor to attract attention
123 void checkend(); // check for end game conditions
124 void computerturn(); // AI for computer
125 void pacman(); // update target positions around king (need to develop further)
126 void targetselect(); // choose a target square
127 //void findpiece();
128 void findpiecens(); // findpiece north-south
129 void findpieceew(); // findpiece east-west
130 void canbetaken(); // can I be taken after moving here? returns value (take) 0=no 1=yes
131 void subarrows(); // subroutine of arrows or blanks
132 void subarrows2(); // subroutine of arrows or blanks (updates ENEMY with direction of enemy)
133 void subpacman(); // subroutine of pacman
134 void subpacman2(); // subroutine of pacman
135 void subpacman3(); // sub of subpacman
136 void subpacman4(); // sub of subpacman2
137 void subpacmanx(); // grand sub of pacman
138 //void subcanbetaken(); // sub of canbetaken
139 void inccantake(); // increments cantake
140 void incroute(); // incs route
141 void decroute(); // decs route
142 void drawtile(); // draw a tile (subroutine of drawtiles)
143 void drawpiece(); // draws piece
144 void drawarrow(); // draws "arrow"
145 void printmessage(); // prints message to screen
146 void printturnprompt(); // prints "your turn" message
147 void surroundcount(); // counts the number of attackers surrounding KING (or edges, or central square)
148 void incsurround(); // increment "surrounded" variable
149 void explodetile(); // explodes a piece (plays an animation)
150 void pause(); // wait a certain period of time (pausetime)
151 void tileloop(); // subdir of explodetile and drawtile
152 void surroundpoints(); // increment points around king depending on "surrounded" figure
153 void incpoints(); // increment points variable
154 void decpoints(); // decrement points variable
155 void setpoints(); // set points to default value
156 void zerocounter(); // set counter=0
157 void inccounter(); // inc counter
158 //void deccounter(); // decrement counter
159 void doublepoints(); // doubles points
160 //void LookBackInAnger(); // runs subcanbetaken if the piece "behind" an attacker is defender/king and prospective target adjacent to defender/king
161 //void subLookBackInAnger(); // runs the various "lookbackinanger" checks
162 void inctarget(); // inc target[xns][xew]
163 void subcanbetaken2(); // attempt to reduce memory footprint
164 void surroundcheck(); // inc surrounded under various conditions
165 void calctakeweight(); // calculate the weight of "takeweight"
166 void enemyzero(); // set enemy value to zero when surrounded=3
167 char checkroute(); // sets counter to be number of pieces on a given route
168 void updatetarget(); // updates target array
169 void cantakeadjust(); // decrement cantake if taken piece is on same plane as king
170 void inckingattacker(); // increments count of attackers round king
171 void inckingdefender(); // increments count of defenders round king
172 void incdefatt(); // increments count of attacker/defenders round king (calls incking...)
173 void cursormodezero(); // set cursor mode to 1 if 0
174 void cursormodevalid(); // sets modevalid to 1
175 void ischeckroutezero(); // is checkroute zero?
176 void calccantake(); // can take be made (how many)
177 /****************** GLOBAL VARIABLES *******************************/
178 /* Populate array with tile types
179 Tile types:
180 0=blank
181 1=attacker square
182 2=defender square
183 3=king square
184 */
185 extern const unsigned char tiles[11][11]; // tile description on board
186 extern unsigned char target[11][11]; // uninitialized variable (will calc on fly) - target values of square
187 /* populate array with places of players
188 Players:
189 0=vacant
190 1=attacker resident
191 2=defender resident
192 3=king resident
193 4=corner square // added 21/04/2011
194 */
195 //extern char baseplayers[11][11]; // BASEPLAYERS - the starting board positions. PLAYERS is the working COPY of BASEPLAYERS
196
197 // ARRAY ENEMY unititialized variable (will calc on fly) - can enemy reach a square?
198 // values:
199 // +1 Can be reached from NORTH
200 // +5 can be reached from SOUTH
201 // +10 can be reached from EAST
202 // +20 can be reached from WEST
203 extern char enemy[11][11]; // where the defenders can get to
204 extern char computer[11][11]; // where the attackers can get to
205 char players[11][11]; // to be the working copy of baseplayers
206 const unsigned char boardx=12; // starting x co-ord of board (for cursor drawing purposes)
207 const unsigned char boardy=0; // starting y co-ord of board (for cursor drawing purposes)
208 const char boxsize=18; // set boxsize (for cursor drawing purposes)
209 unsigned char playertype,piecetype; // player 1=attacker, 2=defender
210 unsigned char ns,ew; // default north/south position of central square (0-10)
211 unsigned char cx,cy; // cursor x screen position (pixels across)
212 unsigned char fb=1; // foreground/background 0=background, 1=foreground, 2=opposite, 3=nothing
213 unsigned char inversex; // x position of square to be inversed (to highlight a selected piece)
214 unsigned char inversey; // y position of square to be inversed (to highlight a selected piece)
215 char mkey; // code of key pressed (plus loops)
216 unsigned char cursormode; // cursor movement mode 0=freeform 1=restricted
217 unsigned char ons,oew; // original north/south board pos
218 unsigned char ocx,ocy; // original xpos of piece
219 unsigned char orientation; // for arrows - 0=north, 1=south 2=east 3=west
220 unsigned char tiletype; // type of tile under inspection (used in arrows)
221 unsigned char tpns,tpew; // north-south board location of taken piece (also used for 3) NB:no idea 20/10/2011
222 unsigned char flashcolor; // color of ink to flash in
223 unsigned char flashback; // color of ink to return to
224 unsigned char game; // <=0 means endgame (see checkend for values), 1=GAMEON
225 unsigned char gamestyle; // 0=human vs human; 1=human king vs computer; ** NO!!! 2=human vs computer king**; 3=undefined
226 unsigned char kingns,kingew; // kings position North-South
227 unsigned char kingattacker[4]; // number of attackers in all four directions from king
228 unsigned char kingdefender[4]; // number of defenders in all four directsions from king
229 unsigned char surrounded; // status of king "surrounded" status //
230 unsigned char ctns=0; // Computer Turn north-south board position
231 unsigned char ctew=0; // Computer Turn east-west board position
232 char playertext[]="Attacker";
233 char turntext[]=" Turn:Use cursor keys.\nX:Select Piece P:Possible Moves";
234 char message[]="*";
235 char foundpiece=0; // has a piece been found (during computer move) that can move to the hightarget square? 0=no, 1=yes&ok, 9=yes!ok
236 //char xloop=0; // general purpose loop variable
237 char xns=0; // copy of ns (arrows or blanks, and subarrows)
238 char xew=0; // copy of ew (arrows or blanks, and subarrows)
239 char arrow=1; // used in arrowsorblanks(and subarrows)
240 char flag=0;
241 char cantake; // can I take? (for computer turn)
242 char route;
243 unsigned char row,col; // used in tile drawing routines and array navigation ( a row in 11x11 grid)
244 //unsigned char col; // used in tile drawing routines and array navigation ( a column in 11x11 grid)
245 unsigned char tiletodraw; // used in tile drawing routines 0-11 (as at 18-10-2011)
246 int pausetime; // amount of time to wait
247 unsigned char* ptr_draw; // ptr to board starting position (e.g. 0xa002)
248 unsigned char* ptr_graph; // pointer to byte values of loaded picture
249 unsigned char points; // points around king
250 char counter; // general purpose counter (*** DO NOT set to UNSIGNED *** NB 24/10/2011)
251 unsigned char uncounter; // general purpose counter (can be negative)
252 //unsigned char lookcol,lookrow; // used in lookbackinanger
253 unsigned char origorient; // original orientation of a piece under test (which way he is heading)
254 unsigned char takerow,takecol; // can I be taken if I stop here?
255 unsigned char paclevel1,paclevel2; // used in pacman/subpacmanx either ns/ew
256 unsigned char surns,surew; // count of attackers surrounding king n/s used in surroundcount()
257 unsigned char takena,takenb,takenc,takend,takene; // used in canbetaken routines
258 unsigned char ezns1,ezew1; // used in surroundcount/enemyzero to reset enemy[][] to zero if surrounded=3
259 // WEIGHTS
260 unsigned char enemyweight=37; // >36. weight of "enemy could get here but piece occupied by attacker"
261 //char defaulttakeweight=5; // default weight assigned to a TAKE
262 unsigned char takeweight; // weight assigned to a TAKE (calculated in "calctakeweight")
263 unsigned char cbtweight=4; // weight to be applied to escape position if can be taken
264 unsigned char pacpointsx,pacpointsy,pacpointsa,pacpointsb; // used to calculate points in subpacmanx
265 unsigned char pcheckns1,pcheckns2; // used in taking pieces and checking for takes
266 unsigned char pcheckew1,pcheckew2; // used in taking pieces and checking for takes
267 unsigned char startrow,startcol; // used in checkroute (returns no of pieces on a given path)
268 unsigned char destrow,destcol; // used in checkroute (returns no of pieces on a given path)
269 unsigned char canmovecursor; // controls wether screen cursor can be moved or not
270 unsigned char hightarget; // contains highest value target
271 unsigned char targetns,targetew; // used to calc takes
272 unsigned char x,y,z,a,b; // general purpose variables
273 //char cannotbetaken,icanbetaken; // used in canbetaken routine
274 /* below used for cursor move routine */
275 unsigned char multiple; // concerning central square (how much to multiply the coords to SKIP the square
276 unsigned char xptrns; // copy of NS
277 unsigned char xptrew; // copy of EW
278 unsigned char skipns; // skip to north/south
279 unsigned char skipew; // skip to east/west
280 unsigned char modeonevalid; // is OK for mode 1? 0=no, 1=yes
281 /* above variables used in cursor move routine */
282 unsigned char gamekey=89; // controls "play again?"
283 unsigned char gameinput=0; // 0=undefined 1=play against computer, 2=human vs human
284 unsigned int startpos; // USED when drawing tiles (position in tile file from which to draw)
285 unsigned char take;
286 unsigned char p1; // piece type comparison (lower) - used for determining takes - default=attacker
287 unsigned char p2; // piece type comparison (upper) - used for determining takes - default=attacker
288 /* playerturn variables */
289 unsigned char xkey; // code of key pressed
290 unsigned char canselect; // 0=no, 1=yes (is the piece selectable?)
291 char cursormovetype; // -1=no, 0=yes (n,s,e,w) 1=(north/south only), 2=(east/west only)
292 unsigned char turn; // determines end of player turn 1=playerturn, 0=end of playerturn
293 unsigned char compass[4]; // used in cantake (if compass[NORTH]=1 then means canbetaken if i move here from NORTH
294 //unsigned char funca,funcb,funcc,funcd,funce,funcf; // general purpose variables used in functions
295 /* end of playerturn variables */
296 /****************** MAIN PROGRAM ***********************************/
297 main()
298 {
299 //gamekey=89; // controls "play again?"
300 //gameinput=0; // 0=undefined 1=play against computer, 2=human vs human
301 paper(0);
302 ink(5); // color of TEXT in text box at bottom
303 hires();
304 ink(6); // boardcolor 0=black, 1=red, 2=green, 3=yellow, 4=blue, 5=magenta, 6=cyan,7=white
305 while (gamekey==89)
306 {
307 playertype=0; // set to 0 as inited later
308 drawboard(); // draw the board
309 printf("%c",19); // turn off screen output (means cursor movement doesn't affect oric cursor
310 while (gamestyle==3)
311 {
312 strcpy(message,"Select Game Type:\nEnter number of humans:");
313 printmessage();
314 gameinput=getchar();
315 if ( gameinput == 49 ) gamestyle=1; // 1=human vs computer (as DEFENDERS)
316 if ( gameinput == 50 ) gamestyle=0; // 0=human vs human
317 if ( gamestyle == 3 ) ping();
318 }
319 while (game>0)
320 {
321 ns=5; // default north/south position of central square
322 ew=5; // default east/west position of central square
323 cx=1+boardx+(boxsize*ew); // cursor x screen position
324 cy=1+boardy+(boxsize*ns); // cursor y screen position
325 playertype++; // playertype inited as 0 so ++ will make it 1 at start of game
326 if ( playertype == 3 ) { playertype = 1; } // was defender, set to attacker player
327 //if (( gamestyle == 0 )||((gamestyle==1)&&(playertype==2))||((gamestyle==2)&&(playertype==1)))
328 if (( gamestyle == 0 )||((gamestyle==1)&&(playertype==2)))
329 {
330 playerturn(); // player input
331 }
332 else
333 {
334 computerturn(); // computer has a go...
335 }
336 checkend(); // check for end of game conditions
337 }
338 if ( game == 0 )
339 {
340 strcpy(message,"KING ESCAPED! King Wins!\nPlay Again Y/N?");
341 printmessage();
342 }
343 else
344 {
345 strcpy(message,"KING CAPTURED! Attacker Wins!\nPlay Again Y/N?");
346 printmessage();
347 }
348 gamekey=getchar();
349 if (gamekey==89) // if "Y"
350 {
351 printf("%c",19); // turn output ON
352 }
353 }
354 }
355 /********************* FUNCTION DEFINITIONS ************************/
356 void computerturn()
357 {
358 //unsigned int xrand=srandom(deek(630)); // seed random number generator
359 //if ( playertype == 1 ) { strcpy(playertext,"ATTACKER");}else{ strcpy(playertext,"KING");}
360 strcpy(message,"ORIC IS THINKING..");
361 printmessage();
362 //printf("\n\n\nORIC IS THINKING..");
363 // 1. initialize target, enemy and computer array to zeroes
364 ClearArrays(); // clear target, enemy and computer arrays
365 // 2. Loop through players array searching for enemy pieces - calculating where they can go
366 //fb=5;
367 //pacman1:
368 for (fb=4;fb<8;fb++)
369 {
370 for (ctns=0;ctns<11;ctns++)
371 {
372 for (ctew=0;ctew<11;ctew++)
373 {
374 ns=ctns;ew=ctew;
375 if ( fb==4 ) // fb=4 means: don't print destinations, just update ENEMY
376 {
377 if (( players[ctns][ctew]==2 )||(players[ctns][ctew]==3)) // if enemy found
378 {
379 printdestinations(); // update enemy array of possible locations
380 }
381 }
382 if ((fb==5)||(fb==7)) // fb=5 (+COMPUTER array):fb=7 (can I be taken)
383 {
384 if ( players[ctns][ctew]==1) // if attacker found
385 {
386 printdestinations();
387 }
388 }
389 if ( fb==6)
390 {
391 if ( computer[ctns][ctew] ) // if computer piece can get here update target values
392 {
393 updatetarget(); // update target value
394 }
395 }
396 }
397 }
398 }
399 // 3. Increment target positions around King (PACMAN)
400 pacman();
401 //if ( playertype == 1 ) {pacman();}
402 // other routines to go here to update the target array
403 // 4,5,6,7..N etc
404 //
405 targetselect(); // Choose the highest value target
406 ns=targetns;ew=targetew; // make computer move compatible with human move selection
407 movepiece(); // make the move
408 }
409 /**************************************************/
410 /*
411 void findpiece()
412 {
413 if ( foundpiece == 0 )
414 {
415 if (players[funca][funcb]==1)
416 {
417 calccantake();
418 if (( cantake==0 )&&(surrounded<3)) canbetaken(); // if cannot take can I be taken?
419 if ((funcc==funcd)&&(funce!=funcd)&&(kingattacker[origorient]==1)) compass[origorient]=1; // don't move from plane of king
420 if (compass[origorient]==0)
421 {
422 foundpiece=1;
423 funcf=funcc;
424 }
425 }
426 if ((players[funca][funcb]==2)||(players[funca][funcb]==3)) {foundpiece=9;}
427 }
428 }
429 */
430 /*********************************************/
431 void findpiecens() // find piece NORTH-SOUTH
432 {
433 if ( foundpiece == 0 )
434 {
435 if (players[mkey][oew]==1)
436 {
437 calccantake();
438 if (( cantake==0 )&&(surrounded<3)) canbetaken(); // if cannot take can I be taken?
439 //if ((mkey==kingns)&&(targetns!=kingns)&&(kingattacker[origorient]==1)) compass[origorient]=1; // don't move from plane of king
440 if (compass[origorient]==0)
441 {
442 foundpiece=1;
443 ons=mkey;
444 }
445 //else {target[targetns][targetew]=hightarget;} // if target=1 then reset it
446 }
447 if ((players[mkey][oew]==2)||(players[mkey][oew]==3)) {foundpiece=9;}
448 }
449 }
450 /**************************************************/
451 void findpieceew() // find piece EAST-WEST
452 {
453 if ( foundpiece == 0 )
454 {
455 if (players[ons][mkey]==1)
456 {
457 calccantake();
458 if (( cantake==0 )&&(surrounded<3)) canbetaken(); // if cannot take can I be taken?
459 //if ((mkey==kingew)&&(targetew!=kingew)&&(kingattacker[origorient]==1)) compass[origorient]=1; // don't move from plane of king
460 if (compass[origorient]==0)
461 {
462 foundpiece=1;
463 oew=mkey;
464 }
465 //else{target[targetns][targetew]=hightarget;} // if target=1 then reset it
466 }
467
468 if ((players[ons][mkey]==2)||(players[ons][mkey]==3)) {foundpiece=9;}
469 }
470 }
471 /*********************************************************/
472 // TARGETSELECT - find the highest scoring TARGET
473 void targetselect()
474 {
475 //unsigned char xloop;
476 NEWTARGET:
477 hightarget=0; // contains highest value target
478 foundpiece=0; // set findpiece to "piece not found"
479 for (ctns=0;ctns<11;ctns++) // find the highest value for target
480 {
481 for (ctew=0;ctew<11;ctew++)
482 {
483 if ( target[ctns][ctew] > hightarget )
484 {
485 hightarget=target[ctns][ctew]; // make hightarget the highest value
486 targetns=ctns;
487 targetew=ctew;
488 ons=ctns; // target is accessible so make ons/oew the default piece position to move
489 oew=ctew; // the ACTUAL piece to move determined below (one of ons or oew will remain same)
490 ns=ctns;
491 ew=ctew;
492 }
493 }
494 }
495 // having found target we need to select a piece to move
496 compass[NORTH]=0;compass[SOUTH]=0;compass[EAST]=0;compass[WEST]=0; // initialize compass array
497 for (mkey=ons; mkey>-1; mkey--) {origorient=NORTH;findpiecens();}
498 if ( foundpiece != 1 ) { foundpiece=0;target[targetns][targetew]=hightarget; }
499 for (mkey=ons; mkey<11; mkey++) {origorient=SOUTH;findpiecens();}
500 if ( foundpiece != 1 ) { foundpiece=0;target[targetns][targetew]=hightarget; }
501 for (mkey=oew; mkey<11; mkey++) {origorient=EAST;findpieceew();}
502 if ( foundpiece != 1 ) { foundpiece=0;target[targetns][targetew]=hightarget; }
503 for (mkey=oew; mkey>-1; mkey--) {origorient=WEST;findpieceew();}
504 if ( foundpiece != 1 ) {target[targetns][targetew]=1;goto NEWTARGET;} // if can still be taken select new target
505
506 cx=1+boardx+(boxsize*oew); // piece x screen position
507 cy=1+boardy+(boxsize*ons); // piece y screen position
508 blinkcursor(); // draw cursor in foreground color at piece to move position cx,cy
509 fb=0;drawcursor(); // blank cursor
510 cx=1+boardx+(boxsize*targetew); // target x screen position
511 cy=1+boardy+(boxsize*targetns); // target y screen position
512 blinkcursor(); // draw cursor in foreground color at target position cx,cy
513 ocx=1+boardx+(boxsize*oew); // piece to move x screen position
514 ocy=1+boardy+(boxsize*ons); // piece to move y screen position
515 //printf("%cNS=%d,EW=%d,ONS=%d,OEW=%d%c",19,ns,ew,ons,oew,19);
516 //loop=getchar();
517 }
518 /************************************************/
519 void subpacmanx() // subroutine of pacman
520 {
521 z=kingattacker[orientation]+kingdefender[orientation]; // count of pieces on route to edge (attackers&defenders)
522 a=pacpointsx+pacpointsy; // count of pieces to two corners
523 b=pacpointsa+pacpointsb; // count of pieces to squares adjacent to corners
524 setpoints();
525 //x=paccount1*3; // x=number of attackers * 3
526 //y=x+paccount2; // y=(number of attackers *3)+(defenders * 1)
527 //if ((points-y) < 0) {points=1;}else{points-=y;} // subtract two points for every attacker and 1 point for every defender
528 if ( z==0 ) // no pieces in the direction from king
529 {
530 doublepoints(); // double points if blank route to edge
531 if (pacpointsx==0){ doublepoints();} // double if route to one corner
532 if (pacpointsy==0){ doublepoints();} // double if route to two corners
533 }
534 if ( z<2 )
535 {
536 if (pacpointsa==0){ doublepoints();} // double if route to one square adjacent to corner
537 if (pacpointsb==0){ doublepoints();} // double if route to two squares adjacent to corners
538 }
539 if ((paclevel2<3)||(paclevel2>7)) { incpoints(); } // if close to an edge in orientation
540 if ((paclevel1<2)||(paclevel2>8)) { incpoints(); } // if "left or rightside" in a "winning position"
541 if ((orientation == NORTH) || (orientation == WEST)) // if north or west
542 {
543 uncounter=paclevel2-1;
544 if ( paclevel2<5 ) { incpoints();} // add weight to north or west if king in north or west side of board
545 }
546 else // if south east
547 {
548 uncounter=paclevel2+1;
549 if ( paclevel2>5 ) { incpoints();} // add weight to south or east if king in south or east side of board
550 }
551 if ( kingattacker[orientation]==0 ) { incpoints();} // inc points if no attackers on path
552 surroundpoints();
553 // default north/south
554 x=uncounter;
555 y=paclevel1;
556 if ( orientation>SOUTH) // if east/west
557 {
558 x=paclevel1;
559 y=uncounter;
560 }
561 flag=1;
562 while (((players[x][y]==0)||(tiles[x][y]==3))&&((uncounter>-1)&&(uncounter<11)))
563 {
564 if (computer[x][y]) // if accessible by attacker
565 { // only update target if cannot be taken OR king has clear route to corner
566 if ((a==0)||(pacpointsx==0)||(pacpointsy==0)||(pacpointsa==0)||(pacpointsb==0))
567 {
568 target[x][y]+=points;
569 flag=0;
570 }
571 else
572 {
573 if (target[x][y]>1){target[x][y]=points;flag=0;}
574 }
575 }
576 else
577 {
578 if ((flag)&&(players[x][y]==0)) // if blank)
579 {
580 if (orientation<EAST) { subpacman();}else{subpacman2();} // if north/south
581 }
582 }
583 decpoints();
584 //if (z){decpoints();} // only decrement points if route to edge is blocked
585 if ( (orientation==NORTH) || (orientation==WEST) ) {uncounter--;}else{uncounter++;}
586 if ( orientation <EAST ) {x=uncounter;}else{y=uncounter;}
587 }
588 }
589 /************************************************/
590 void pacman() // PACMAN ( increment target positions around king )
591 {
592 //int xrand=random()/1000; // random number between 0-32
593 surroundcount(); // updates "surrounded"
594 // NORTH
595 orientation=NORTH;
596 paclevel1=kingew;
597 paclevel2=kingns;
598 startrow=0;startcol=0;destrow=0;destcol=kingew;
599 pacpointsx=checkroute();
600 startcol=kingew;destcol=10;
601 pacpointsy=checkroute();
602 startrow=1;startcol=0;destrow=1;destcol=kingew;
603 pacpointsa=checkroute();
604 startcol=kingew;destcol=10;
605 pacpointsb=checkroute();
606 subpacmanx();
607
608 //SOUTH
609 orientation=SOUTH;
610 startrow=10;startcol=0;destrow=10;destcol=kingew;
611 pacpointsx=checkroute();
612 startcol=kingew;destcol=10;
613 pacpointsy=checkroute();
614 startrow=9;startcol=0;destrow=9;destcol=kingew;
615 pacpointsa=checkroute();
616 startcol=kingew;destcol=10;
617 pacpointsb=checkroute();
618 subpacmanx();
619
620 // EAST
621 orientation=EAST;
622 paclevel1=kingns;
623 paclevel2=kingew;
624 startrow=0;startcol=10;destrow=kingns;destcol=10;
625 pacpointsx=checkroute();
626 startrow=kingns;destrow=10;
627 pacpointsy=checkroute();
628 startrow=0;startcol=9;destrow=kingns;destcol=9;
629 pacpointsa=checkroute();
630 startrow=kingns;destrow=10;
631 pacpointsb=checkroute();
632 subpacmanx();
633
634 // WEST
635 orientation=WEST;
636 startrow=0;startcol=0;destrow=kingns;destcol=0;
637 pacpointsx=checkroute();
638 startrow=kingns;destrow=10;
639 pacpointsy=checkroute();
640 startrow=0;startcol=1;destrow=kingns;destcol=1;
641 pacpointsa=checkroute();
642 startrow=kingns;destrow=10;
643 pacpointsb=checkroute();
644 subpacmanx();
645 }
646
647 /************************************************/
648 void subpacman() // increase target positions that LEAD to a king target
649 {
650 flag=0;
651 for (mkey=kingew-1;mkey>-1;mkey--){subpacman3();}
652 flag=0;
653 for (mkey=kingew+1;mkey<11;mkey++){subpacman3();}
654 }
655 /************************************************/
656 void subpacman2()
657 {
658 flag=0;
659 for (mkey=kingns-1;mkey>-1;mkey--){subpacman4();}
660 flag=0;
661 for (mkey=kingns+1;mkey<11;mkey++){subpacman4();}
662 }
663 /*****************************/
664 void subpacman3()
665 {
666 if ( players[counter][mkey]==0 ) { flag=1;}
667 if ((flag==0)&&(target[counter][mkey]>1 )) { target[counter][mkey]++;}
668 }
669 void subpacman4()
670 {
671 if ( players[mkey][counter]==0 ) { flag=1;}
672 if ((flag==0)&&(target[mkey][counter]>1 )) { target[mkey][counter]++;}
673 }
674 /************************************************/
675 void checkend() // check for endgame conditions
676 {
677 /* Victory Conditions
678 game=0 King escapes. // DONE
679 game=-1 King Surrounded in open play or by central square // DONE
680 game=-2 King surrounded by attackers and corner squares // DONE
681 game=-3 King surrounded by attackers and edge of board // DONE
682 game=-4 defenders cannot move (stalemate) // TBD
683 game=-5 attackers cannot move (stalemate) // TBD
684 game=-6 all attackers eliminated // TBD
685 */
686 //char kingfound=0; // 0=king not found 1=king found
687 // ns and ew contains new board co-ords of last piece moved
688 if (( players[ns][ew] == 3 ) && ( tiles[ns][ew] == 4 )) { game=0; } // king has escaped
689 // check to see if king is surrounded by attackers (first find king)
690 if ( players[ns][ew] == 1 ) // if attacker was last to move
691 {
692 if (((ns>0 )&&(players[ns-1][ew]==3 ))||((ns<10 )&&(players[ns+1][ew]==3 ))||((ew<10 )&&(players[ns][ew+1]==3 ))||((ew>0 )&&(players[ns][ew-1]==3 )))
693 {
694 surroundcount();
695 }
696 if ( surrounded == 4 ) { game=-1;} // king is surrounded on all sides by attackers or king squares
697 }
698 }
699 /************************************************/
700 void cursormodezero()
701 {
702 if ( cursormode == 0 ) { canmovecursor=1;}
703 }
704 /***********************/
705 void movecursor2() // routine to move the cursor
706 {
707 /*
708 cursormode = [0 or 1] 0=unrestricted (move anywhere), 1= restricted (only move to possible destinations)
709 */
710 multiple=1; // concerning central square (how much to multiply the coords to SKIP the square
711 xptrns=ns; // copy of NS
712 xptrew=ew; // copy of EW
713 skipns=ns; // skip to north/south
714 skipew=ew; // skip to east/west
715 modeonevalid=0; // is OK for mode 1? 0=no, 1=yes
716 canmovecursor=0;
717 piecetype=players[ons][oew]; // determines the piece type that is currently selected (used in mode 1)
718 if ((mkey == 8 )&&( ew)) // west
719 {
720 cursormodezero();
721 xptrew--; // decrement copyew
722 skipew-=2;
723 modeonevalid=1;
724 }
725 if ((mkey == 9 )&&( ew<10)) // east
726 {
727 cursormodezero();
728 xptrew++;
729 skipew+=2;
730 modeonevalid=1;
731 }
732 if ((mkey == 10)&&( ns<10)) // south
733 {
734 cursormodezero();
735 xptrns++;
736 skipns+=2;
737 modeonevalid=1;
738 }
739 if ((mkey == 11)&&( ns)) // north
740 {
741 cursormodezero();
742 xptrns--;
743 skipns-=2;
744 modeonevalid=1;
745 }
746 if (( cursormode ) && ( modeonevalid )) // if not at edge of board
747 {
748 if ( players[xptrns][xptrew] == 0 ) {canmovecursor=1;} // ok if square vacant
749 if ( tiles[xptrns][xptrew] == 4 ) {canmovecursor=0;} // !ok if corner
750 if (( piecetype == 3 )&&( tiles[xptrns][xptrew] > 2 )) {canmovecursor=1;} // ok if KING and corner/central
751 if (( xptrns == ons )&&( xptrew == oew )) {canmovecursor=1;} // ok if back to self
752 // need to check that for non-king pieces wether the central square is vacant and can be skipped
753 if (( piecetype < 3 )&&( tiles[xptrns][xptrew] == 3)&&(players[xptrns][xptrew] == 0 )) // tiles=3(central), tiles=4(corner)
754 {
755 if ( players[skipns][skipew] > 0 ) {canmovecursor=0;} // cannot skip if otherside occupied
756 if ((( skipns == ons )&&( skipew == oew ))||( players[skipns][skipew]==0)) // ok to skip to self
757 {
758 canmovecursor=1;
759 multiple=2;
760 }
761 }
762 }
763 if (canmovecursor)
764 {
765 fb=0;
766 drawcursor(); // print blank cursor (effect=remove dots)
767 if ( mkey == 8 ) {cx-=(boxsize*multiple);} // left
768 if ( mkey == 9 ) {cx+=(boxsize*multiple);} // right
769 if ( mkey == 10 ){cy+=(boxsize*multiple);} // down
770 if ( mkey == 11 ){cy-=(boxsize*multiple);} // up
771 fb=1;
772 drawcursor(); // print dotted cursor
773 if ( mkey == 8 ) {ew-=multiple;} // left
774 if ( mkey == 9 ) {ew+=multiple;} // right
775 if ( mkey == 10 ){ns+=multiple;} // down
776 if ( mkey == 11 ){ns-=multiple;} // up
777 }
778 else
779 {
780 flashcolor=1;
781 if ( cursormode == 0 ) {flashback=6;flashscreen();} // flash red: return to cyan:6
782 if ( cursormode == 1 ) {flashback=2;flashscreen();} // flash red: return to green:2)
783 }
784 }
785 /************************************************/
786 void inverse()
787 {
788 /* Draw an inversed colr box to highlight selected box
789 ix=screen x position
790 iy=screen y position
791 */
792 char iz=boxsize-3;
793 for (counter=0;counter<iz;inccounter())
794 {
795 curset(inversex,inversey,3);
796 draw(iz,0,2); // draw inverse line
797 inversey++;
798 }
799 }
800 /************************************************/
801 void printpossiblemoves()
802 {
803 /* kicks off functions that print appropriate arrows at all possible destinations and blanks
804 them out afterwards*/
805 char k; // key entered
806 fb=1;
807 printdestinations(); // print arrows on all destinations
808 strcpy(message,"* press any key to proceed *");
809 printmessage();
810 k=getchar();
811 fb=0;
812 printdestinations(); // blank out arrows on all destinations
813 }
814 /************************************************/
815 void printarrowsorblanks() // used in printdestinations
816 {
817 char xplayers; // player type at square under test
818 //zns=ns; // another copy of ns (for computer turn)
819 //zew=ew; // another copy of ew (for computer turn)
820 origorient=orientation; // original orientation (for computer turn)
821 //char cantake=0; // can I take? (for computer turn)
822 //unsigned char subloop=0;
823 //cantake=0;
824 xns=ns; // copy of ns
825 xew=ew; // copy of ew
826 arrow=1;
827 //arrowsx=cx+1;
828 //arrowsy=cy+1;
829 // orientation 0,1,2,3 = N, S, E, W
830 takerow=ns;takecol=ew; // will set below to be the opposite of the orientation
831 if ( orientation == NORTH ) { xplayers=players[xns-1][xew];takerow=xns+1;} // check north
832 if ( orientation == SOUTH ) { xplayers=players[xns+1][xew];takerow=xns-1;} // check south
833 if ( orientation == EAST ) { xplayers=players[xns][xew+1];takecol=xew-1;} // check east
834 if ( orientation == WEST ) { xplayers=players[xns][xew-1];takecol=xew+1;} // check west
835 if ( xplayers == 0 ) // if adjacent square is OK mode
836 {
837 //arrow=1;
838 while ( arrow == 1 ) // keep checking until cannot move
839 {
840 if (( orientation == NORTH ) && ( xns )) // check north
841 {
842 xns--; // decrement provisional north-south player position
843 subarrows();
844 }
845 if (( orientation == SOUTH ) && ( xns < 10 )) // check south
846 {
847 xns++; // increment provisional north-south player position
848 subarrows();
849 }
850 if ((orientation == EAST ) && ( xew < 10 )) // check east
851 {
852 xew++; // increment provisional east-west player position
853 subarrows();
854 }
855 if ((orientation == WEST ) && ( xew )) // check west
856 {
857 xew--; // decrement provisional east-west player position
858 subarrows();
859 }
860 tiletodraw=tiles[xns][xew]; // obtain type of tile
861 if ( arrow == 1 ) // if MODE is "draw an arrow" (aka: I can move here)
862 {
863 row=xns;
864 col=xew;
865 if (fb==1) {drawarrow();} // draw and arrow
866 if (fb==4) {subarrows2();} // enemy can get here, update enemy array (direction specific)
867 if (fb==5) {computer[xns][xew]++;} // computer can get here, increment computer array
868 if (fb==0) {drawarrow();} // if MODE is "blank an arrow"
869 }
870 // have we reached the end of the board?
871 if (( orientation == NORTH ) && ( xns == 0 )) { arrow=0;} // check north
872 if (( orientation == SOUTH ) && ( xns == 10 )) { arrow=0;} // check south
873 if (( orientation == EAST ) && ( xew == 10 )) { arrow=0;} // check east
874 if (( orientation == WEST ) && ( xew == 0 )) { arrow=0;} // check west
875 }
876 }
877 if ((fb==7)&&(xplayers>1)) // check to see if an attacker can be caught if he stays where he is
878 {
879 if ((players[takerow][takecol]==0)&&(enemy[takerow][takecol])&&(enemy[takerow][takecol]<enemyweight))
880 {
881 if (target[takerow][takecol]>1){target[takerow][takecol]+=4; } // update adjacent target to provide escape route or place for someone else to occupy
882 if (orientation < EAST) // if heading north or south
883 {
884 if ( xew<10 ){if (target[xns][xew+1]>1){target[xns][xew+1]+=4;}}
885 if ( xew ){if (target[xns][xew-1]>1){target[xns][xew-1]+=4;}}
886 }
887 else // if heading east or west
888 {
889 if ( xns<10 ){if (target[xns+1][xew]>1){target[xns+1][xew]+=4;}}
890 if ( xns ){if (target[xns-1][xew]>1){target[xns-1][xew]+=4;}}
891 }
892 }
893 }
894 }
895 /************************************************/
896 void printdestinations()
897 {
898 // print appropriate arrows at all possible destinations (or blanks em out)
899 // check north
900 if ( ns ) { orientation=NORTH;printarrowsorblanks();} // draws arrows/blanks em out (0=north)
901 // check south
902 if ( ns < 10 ){ orientation=SOUTH;printarrowsorblanks();} // draws arrows/blanks em out (1=south)
903 // check east
904 if ( ew < 10 ){ orientation=EAST;printarrowsorblanks();} // draws arrows/blanks em out (2=east)
905 // check west
906 if ( ew ) { orientation=WEST;printarrowsorblanks();} // draws arrows/blanks em out (3=west)
907 }
908 /************************************************/
909 void canpiecemove() // CAN A SELECTED PIECE MOVE?
910 {
911 // returns 0 or 1 depending on wether a piece can move or not
912 // int route=0; // number of possible routes
913 route=0;
914 piecetype=players[ns][ew]; // determine TYPE of selected piece (1=attacker, 2=defendr, 3=king)
915 /* for all piece types determine if adjacent square in any direction is blank or not
916 it won't bother checking a particular direction if piece is at edge of board.
917 */
918 if ( ns ) // check north
919 {
920 if ( players[ns-1][ew] == 0 ) incroute();
921 if (( piecetype == 3 )&&(players[ns-1][ew] == 4 )) incroute(); // KING: corner square OK
922 }
923 if ( ns < 10 ) // check south
924 {
925 if ( players[ns+1][ew] == 0 ) incroute();
926 if (( piecetype == 3 )&&(players[ns+1][ew] == 4 )) incroute(); // KING: corner square OK
927 }
928 if ( ew < 10 ) // check east
929 {
930 if ( players[ns][ew+1] == 0 ) incroute();
931 if (( piecetype == 3 )&&(players[ns][ew+1] == 4 )) incroute(); // KING: corner square OK
932 }
933 if ( ew ) // check west
934 {
935 if ( players[ns][ew-1] == 0 ) incroute();
936 if (( piecetype == 3 )&&(players[ns][ew-1] == 4 )) incroute(); // KING: corner square OK
937 }
938 /* In the case that the central square is unnocupied and a piece is adjacent to that square then - for
939 non-KING Pieces only - we need to check to see if the opposite square is occupied or not.
940 ROUTE will be decremented if that piece is occupied (as no piece can occupy the central square except for
941 the King but all pieces can traverse it */
942 if (( piecetype < 3 ) && ( players[5][5] == 0 )) // if not a king and central sqr unoccupied
943 {
944 if ( ns == 5 )
945 {
946 if ( ew == 4 ) {if ( players[5][6] > 0 ) decroute();} // check east +2 // east occupied, dec route
947 if ( ew == 6 ) {if ( players[5][4] > 0 ) decroute();} // check west +2 // west occupied, dec route
948 }
949 if ( ew == 5 )
950 {
951 if ( ns == 4 ) { if ( players[6][5] > 0 ) decroute();} // check south +2 // south occupied, dec route
952 if ( ns == 6 ) { if ( players[4][5] > 0 ) decroute();} // check north +2 // north occupied, dec route
953 }
954 }
955 if ( route > 0 ) route=1;
956 //return route;
957 }
958 /************************************************/
959 void drawplayers() // DRAW ALL THE PIECES ON THE BOARD
960 {
961 for (row=0;row<11;row++)
962 {
963 for (col=0;col<11;col++)
964 {
965 if (( players[row][col] > 0 )&&(players[row][col] < 4)){drawpiece();}
966 }
967 }
968 }
969 /************************************************/
970 void drawtiles() // DRAW ALL THE TILES ON THE BOARD
971 {
972 for (row=0;row<11;row++)
973 {
974 for (col=0;col<11;col++)
975 {
976 players[row][col]=tiles[row][col]; // populate players array
977 tiletodraw=tiles[row][col];
978 if ( tiletodraw==4 ) { tiletodraw=3;}
979 drawtile();
980 }
981 }
982 }
983 /************************************************/
984 void drawboard() // DRAW THE BOARD
985 {
986 game=1; // game=1 means PLAY GAME
987 gamestyle=3; // 0=play against human, 1=play as DEFENDERS, 2=play as ATTACKERS, 3=nobody
988 kingns=5;kingew=5; // DEFAULT kings board position
989 /*
990 for (counter=0;counter<4;counter++) // this routine uses up more memory (100bytes extra)
991 {
992 kingattacker[counter]=2;
993 kingdefender[counter]=2;
994 }
995 */
996 kingattacker[NORTH]=2; // count of attackers NORTH of king
997 kingattacker[SOUTH]=2; // count of attackers SOUTH of king
998 kingattacker[EAST]=2; // count of attackers EAST of king
999 kingattacker[WEST]=2; // count of attackers WEST of king
1000 kingdefender[NORTH]=2; // count of defenders NORTH of king
1001 kingdefender[SOUTH]=2; // count of defenders SOUTH of king
1002 kingdefender[EAST]=2; // count of defenders EAST of king
1003 kingdefender[WEST]=2; // count of defenders WEST of king
1004 surrounded=0; // reset surrounded back to zero
1005 drawtiles(); // draw the background tiles
1006 //drawborder();
1007 curset(12,198,1);
1008 draw(198,0,1);
1009 draw(0,-198,1);
1010 drawplayers(); // draw the players
1011 //printf("%c",19);// turn output to screen off
1012 }
1013 /************************************************/
1014 void blinkcursor() // blinks the cursor a number of times to attract attention
1015 {
1016 //char curloop;
1017 //unsigned int subloop;
1018 for (counter=0;counter<5;inccounter()) // flash the cursor to draw attention to it
1019 {
1020 fb=0; drawcursor(); // draw cursor in background color at cx,cy
1021 pausetime=250;pause();
1022 fb=1; drawcursor(); // draw cursor in foreground color at cx,cy
1023 pausetime=2000;pause();
1024 }
1025 }
1026 /************************************************/
1027 void flashscreen() // flashes the screen in the selected ink color
1028 {
1029 /* Colors are as follows:
1030 0=black, 1=red, 2=green, 3=yellow, 4=blue, 5=magenta, 6=cyan,7=white
1031 */
1032 ink(flashcolor); // flash in color
1033 pausetime=1500;pause();
1034 ink(flashback); // back to original
1035 }
1036 /************************************************/
1037 void playerturn() // The human players turn : filter keyboard input
1038 {
1039 /*
1040 unsigned char key; // code of key pressed
1041 unsigned char canselect; // 0=no, 1=yes (is the piece selectable?)
1042 char cursormovetype=-1; // -1=no, 0=yes (n,s,e,w) 1=(north/south only), 2=(east/west only)
1043 char turn=1; // determines end of player turn 1=playerturn, 0=end of playerturn
1044 */
1045 cursormovetype=-1; // -1=no, 0=yes (n,s,e,w) 1=(north/south only), 2=(east/west only)
1046 turn=1; // determines end of player turn 1=playerturn, 0=end of playerturn
1047 ons=ns; // original ns board position
1048 oew=ew; // original ew board position
1049 ocx=cx; // original x screen position
1050 ocy=cy; // original y screen position
1051 flashback=6;
1052 if ( playertype == 2 )
1053 {
1054 strcpy(playertext,"King");
1055 }
1056 else
1057 {
1058 strcpy(playertext,"Attacker");
1059 }
1060 blinkcursor();
1061 printturnprompt(); // display instructions
1062 while (turn) // repeat until move is made
1063 {
1064 xkey=getchar(); // get code of pressed key
1065 mkey=xkey;
1066 if (( xkey > 7 ) && ( xkey < 12 )) // 8-11 = cursor keys
1067 {
1068 cursormode=0; // freeform
1069 movecursor2();
1070 }
1071 /*******************************************************/
1072 /* determine if X or P is selected (to select a piece) */
1073 /*******************************************************/
1074 if (( xkey == 88) || ( xkey == 80)) // if 'X' or 'P' is selected (88=X, 80=P)
1075 {
1076 canselect=0; // set piece to NOT SELECTABLE
1077 if (( playertype == 1 )&&(players[ns][ew] == 1 )) { canselect=1;} // piece is selectable
1078 if (( playertype == 2 )&&((players[ns][ew] == 2 )||(players[ns][ew] == 3 ))) { canselect=1;} // piece is selectable
1079 if ( canselect )
1080 {
1081 canpiecemove();
1082 if (route)
1083 {
1084 //piecetype=players[ns][ew];
1085 flashcolor=2;flashscreen(); // flash green
1086 if ( xkey == 80 ) // if P is pressed
1087 {
1088 printpossiblemoves(); // Print possible moves
1089 printturnprompt();
1090 //strcpy(message,playertext);
1091 //strcat(message,turntext);
1092 //printmessage();
1093 //printf ("\n\n\n* %s Turn:Use cursor keys.\nX:Select P:Possible",playertext);
1094 }
1095 }
1096 else
1097 {
1098 flashcolor=1;flashscreen(); // flash red
1099 canselect=0; // unselectable, cannot move
1100 }
1101 }
1102 else { flashcolor=1;flashscreen();} // flash red
1103 if (( mkey == 88 )&&( canselect )) // if piece is SELECTED and CAN move
1104 {
1105 ink(2); // green to indicate piece is selected
1106 flashback=2;
1107 //printmessage();
1108 //strcpy(message,playertext);
1109 strcpy(message,"Place cursor on destination\nX=Select Destination R=Reset/De-Select");
1110 printmessage();
1111 //printf("\n\n\n%s Turn X=Select R=Reset",playertext);
1112 inversex=cx;
1113 inversey=cy+1;
1114 inverse(); // highlight selected square (inverse color)
1115 mkey=0; // ensure mkey at known value
1116 // set Original cursor and board position of selected square
1117 ocx=cx; ocy=cy; ons=ns; oew=ew;
1118 while (( mkey != 88 ) && ( mkey != 82)) // move cursor until X or R selected
1119 {
1120 if (( ons == ns )&&( cursormovetype<0)) { cursormovetype=1; }// cursor allowed north-south
1121 if (( oew == ew )&&( cursormovetype<0)) { cursormovetype=2; }// cursor allowed east-west
1122 if (( ons == ns )&& (oew == ew )) { cursormovetype=0;} // cursor can move
1123 if (( cursormovetype == 2) && (( mkey == 8) ||(mkey == 9))) {cursormovetype=-1;}//!move
1124 if (( cursormovetype == 1) && (( mkey == 10)||(mkey == 11))){cursormovetype=-1;}//!move
1125 if (( cursormovetype == 0) && (( mkey == 8) ||(mkey == 9))) {cursormovetype=1;} //move
1126 if (( cursormovetype == 0) && (( mkey == 10)||(mkey == 11))){cursormovetype=2;} //move
1127 if ( cursormovetype > 0 )
1128 {
1129 cursormode=1; // restricted
1130 movecursor2();
1131 }
1132 if ( cursormovetype < 0) { flashcolor=1;flashscreen();} // flashscreen red
1133 mkey=getchar();
1134 }
1135 if ( mkey == 82 ) // R has been selected, Reset cursor to original positions
1136 {
1137 fb=0;
1138 drawcursor(); // blank out cursor at current position
1139 cx=ocx; // reset coords and board values to original positions
1140 cy=ocy;
1141 ns=ons;
1142 ew=oew;
1143 inversex=cx;
1144 inversey=cy+1;
1145 inverse(); // inverse square
1146 fb=1;
1147 drawcursor(); // draw cursor at original selected position
1148 }
1149 if ( mkey == 88 ) // if X selected
1150 {
1151 inversex=ocx;
1152 inversey=ocy+1;
1153 inverse(); // inverse original position
1154 if (( ons == ns )&&( oew == ew))// X is in original position so return to cursor movement
1155 {
1156 mkey=0; // piece de-selected
1157 }
1158 else{
1159 movepiece(); // move selected piece
1160 turn=0; // player has ended turn
1161 }
1162 }
1163 }
1164 ink(6); // back to cyan
1165 flashback=6;
1166 printturnprompt();
1167 } // key = X or P
1168 } // While player turn
1169 }
1170 /********************************************************/
1171 // Moves selected piece to new location - updating board arrays and re-drawing tiles where necessary
1172 void movepiece()
1173 {
1174 p1=1; // piece type comparison (lower) - used for determining takes - default=attacker
1175 p2=1; // piece type comparison (upper) - used for determining takes - default=attacker
1176 piecetype=players[ons][oew]; // obtain type of piece
1177 // move piece
1178 fb=0;
1179 drawcursor(); // blank out cursor at new selected position
1180 row=ons;
1181 col=oew;
1182 tiletodraw=tiles[row][col];
1183 drawtile(); // draw tile at original location (blank out square)
1184 players[ons][oew]=0; // set original location to zero (unnocupied)
1185 players[ns][ew]=piecetype; // update square with player info
1186 row=ns;
1187 col=ew;
1188 drawpiece(); // draw piece at new location - 18-10-2011
1189 if ( piecetype == 3 ) { kingns=ns;kingew=ew;} // update king position (used by AI)
1190 // having moved piece we now need to check for, and implement any TAKES
1191 if (piecetype > 1 ) // if defender
1192 {
1193 p1=2;
1194 p2=3;
1195 }
1196 tpew=ew;
1197 if ( ns > 1 ) // check north
1198 {
1199 orientation=NORTH;
1200 if ( cantakepiece() ) { tpns=ns-1; takepiece(); }
1201 }
1202 if ( ns < 9 ) // check south
1203 {
1204 orientation=SOUTH;
1205 if ( cantakepiece() ) { tpns=ns+1; takepiece(); }
1206 }
1207 tpns=ns;
1208 if ( ew < 9 ) // check east
1209 {
1210 orientation=EAST;
1211 if ( cantakepiece() ) { tpew=ew+1; takepiece(); }
1212 }
1213 if ( ew > 1 ) // check west
1214 {
1215 orientation=WEST;
1216 if ( cantakepiece() ) { tpew=ew-1; takepiece(); }
1217 }
1218 // update count of attackers around king
1219 /*
1220 for (counter=0;counter<4;counter++) // this routine uses 100 extra bytes than assigning manually
1221 {
1222 kingattacker[counter]=0;
1223 kingdefender[counter]=0;
1224 }
1225 */
1226 kingattacker[NORTH]=0; // count of attackers NORTH of king
1227 kingattacker[SOUTH]=0; // count of attackers SOUTH of king
1228 kingattacker[EAST]=0; // count of attackers EAST of king
1229 kingattacker[WEST]=0; // count of attackers WEST of king
1230 kingdefender[NORTH]=0; // count of defenders NORTH of king
1231 kingdefender[SOUTH]=0; // count of defenders SOUTH of king
1232 kingdefender[EAST]=0; // count of defenders EAST of king
1233 kingdefender[WEST]=0; // count of defenders WEST of king
1234 orientation=NORTH;
1235 cy=kingew;
1236 for (counter=0;counter<kingns;inccounter())
1237 {
1238 cx=counter;incdefatt();
1239 //if (players[counter][kingew]==1) {inckingattacker();}
1240 //if (players[counter][kingew]==2) {inckingdefender();}
1241 }
1242 orientation=SOUTH;
1243 for (counter=kingns+1;counter<11;inccounter())
1244 {
1245 cx=counter; incdefatt();
1246 //if (players[counter][kingew]==1) {inckingattacker();}
1247 //if (players[counter][kingew]==2) {inckingdefender();}
1248 }
1249 orientation=EAST;
1250 cx=kingns;
1251 for (counter=kingew+1;counter<11;inccounter())
1252 {
1253 cy=counter; incdefatt();
1254 //if (players[kingns][counter]==1) {inckingattacker();}
1255 //if (players[kingns][counter]==2) {inckingdefender();}
1256 }
1257 orientation=WEST;
1258 for (counter=0;counter<kingew;inccounter())
1259 {
1260 cy=counter; incdefatt();
1261 //if (players[kingns][counter]==1) {inckingattacker();}
1262 //if (players[kingns][counter]==2) {inckingdefender();}
1263 }
1264 }
1265
1266 /*******************/
1267 void incdefatt()
1268 {
1269 if (players[cx][cy]==1) {inckingattacker();}
1270 if (players[cx][cy]==2) {inckingdefender();}
1271 }
1272 void inckingdefender()
1273 {
1274 kingdefender[orientation]++;
1275 }
1276 void inckingattacker()
1277 {
1278 kingattacker[orientation]++;
1279 }
1280 /************************************************/
1281 /*void subcanbetaken()
1282 {
1283 target[targetns][targetew]=1;
1284 //if ((ns==kingns)||(ew==kingew)) { target[ns][ew]=3;} // means acceptable risk
1285 }
1286 */
1287 /************************************************/
1288 void canbetaken() // can I be taken after moving here?
1289 {
1290 //cannotbetaken=0;
1291 //icanbetaken=0;
1292 if ((targetns>0)&&(targetns<10))
1293 {
1294 takena=targetns-1;takenb=targetew;takenc=targetns+1;takend=targetew;takene=1;
1295 subcanbetaken2();
1296 takena=targetns+1;takenb=targetew;takenc=targetns-1;takend=targetew;takene=5;
1297 subcanbetaken2();
1298 }
1299
1300 if ((targetew>0)&&(targetew<10))
1301 {
1302 takena=targetns;takenb=targetew+1;takenc=targetns;takend=targetew-1;takene=10;
1303 subcanbetaken2();
1304 takena=targetns;takenb=targetew-1;takenc=targetns;takend=targetew+1;takene=20;
1305 subcanbetaken2();
1306 }
1307 //if (cannotbetaken==0) {target[targetns][targetew]=1;}
1308 }
1309 /************************************************/
1310 // Will return a value (take) who's values will be: 0= no, 1=yes
1311 char cantakepiece()
1312 {
1313 //char take=0;
1314 //char p1=1; // piece type comparison (lower) - used for determining takes - default=attacker
1315 //char p2=4; // piece type comparison (upper) - used for determining takes - default=attacker
1316 take=0;
1317 p1=1;
1318 p2=4;
1319 pcheckns1=ns-1; // defaults to north
1320 pcheckns2=ns-2;
1321 pcheckew1=ew;
1322 pcheckew2=ew;
1323 piecetype=players[ns][ew]; // obtain type of piece
1324 //if ( fb==3) { piecetype=players[ctns][ctew];} // if computer turn set piecetype to piece being checked
1325 if ( fb==3 ) { piecetype=1;} // default = ATTACKER
1326 if (piecetype > 1 ) // if defender
1327 {
1328 p1=2;
1329 p2=3;
1330 }
1331 if ( orientation == SOUTH) // if south
1332 {
1333 pcheckns1=ns+1;
1334 pcheckns2=ns+2;
1335 }
1336 if ( orientation > SOUTH) // if east or west
1337 {
1338 pcheckns1=ns;
1339 pcheckns2=ns;
1340 pcheckew1=ew+1;
1341 pcheckew2=ew+2;
1342 if ( orientation == WEST) // if west
1343 {
1344 pcheckew1=ew-1;
1345 pcheckew2=ew-2;
1346 }
1347 }
1348 // if a take is possible increment the take counter - if values fall within bounds...
1349 if ((pcheckns2>-1)&&(pcheckns2<11)&&(pcheckew2>-1)&&(pcheckew2<11))
1350 {
1351 if (( players[pcheckns1][pcheckew1] > 0 )&&(players[pcheckns1][pcheckew1] != p1)&&(players[pcheckns1][pcheckew1] != p2)&&(players[pcheckns1][pcheckew1] != 3))
1352 {
1353 if ((( players[pcheckns2][pcheckew2] == p1 )||(players[pcheckns2][pcheckew2] == p2 )||(players[pcheckns2][pcheckew2] == 4)&&(pcheckns2!=5)&&(pcheckew2!=5))) // the 5 is to EXCLUDE central square
1354 {
1355 take++;
1356 }
1357 if ( computer[pcheckns2][pcheckew2] ) {inctarget();} // 31-10-2011 - can possibly take on next turn
1358 }
1359 }
1360 if ( piecetype == 3 ) // if king and next to attacker and opposite square is a king square
1361 {
1362 if ((players[pcheckns1][pcheckew1] == 1 )&&(tiles[pcheckns2][pcheckew2] > 2)) { take++;}
1363 }
1364 return take;
1365 }
1366 /************************************************/
1367 void takepiece() // performs taking/removing a piece
1368 {
1369 players[tpns][tpew]=0; // zero players
1370 row=tpns;
1371 col=tpew;
1372 ink(6);
1373 explodetile(); // plays animation to "kill" a tile
1374 tiletodraw=tiles[row][col]; // decide tile to draw
1375 drawtile(); // draw tile at location
1376 }
1377 /*****************************/
1378 void subarrows()
1379 {
1380 if (players[xns][xew])
1381 {
1382 arrow = 0; // !ok if piece occupied or corner square
1383 if ((fb==4)&&(players[xns][xew]==1)) {enemy[xns][xew]+=enemyweight;} // means enemy could get here if attacker moved elsewhere
1384 }
1385 if (( players[ns][ew] == 3)&&(tiles[xns][xew] == 4)) { arrow = 1; } // corner ok if king
1386 }
1387 /*****************************/
1388 void subarrows2()
1389 {
1390 if ( orientation==NORTH ) { enemy[xns][xew]+=5; } // means enemy can get here from SOUTH
1391 if ( orientation==SOUTH ) { enemy[xns][xew]+=1; } // means enemy can get here from NORTH
1392 if ( orientation==EAST ) { enemy[xns][xew]+=20; } // means enemy can get here from WEST
1393 if ( orientation==WEST ) { enemy[xns][xew]+=10; } // means enemy can get here from EAST
1394 }
1395 /*****************************/
1396 void inccantake()
1397 {
1398 //unsigned char take;
1399 //cantake+=cantakepiece();
1400 z=cantakepiece();
1401 if (z)
1402 {
1403 cantake+=z;
1404 cantakeadjust(); // decrement take count if taken piece on same plane as king and taker isn't
1405 }
1406 }
1407 /*****************************/
1408 void incroute()
1409 {
1410 route++;
1411 }
1412 /*****************************/
1413 void decroute()
1414 {
1415 route--;
1416 }
1417 /*********************************/
1418 void drawtile() // draws a board tile, player piece or "arrow"
1419 {
1420 ptr_graph=PictureTiles; // pointer to Picture Tiles graphics
1421 //ptr_draw=(unsigned char*)0xa002; // pointer to start of board
1422 //ptr_draw+=(col*3)+(row*720); // 720=18*40 starting screen coordinate
1423 startpos=(tiletodraw*54); // 54=3*18 calc how many lines "down" in the graphic file to print from
1424 ptr_graph+=startpos; // set start position in graphic file
1425 tileloop();
1426 }
1427 /*********************************/
1428 void explodetile() // Explodes a tile
1429 {
1430 //unsigned char b;
1431 ptr_graph=ExplodeTiles; // pointer to byte values of loaded picture
1432 for (b=0;b<8;b++)
1433 {
1434 tileloop();
1435 pausetime=900;
1436 if (b==5) {pausetime=3000;} // pause longer on skull&crossbones
1437 pause(); // add a pause
1438 }
1439 }
1440 /**************************************/
1441 void tileloop()
1442 {
1443 //unsigned char a;
1444 ptr_draw=(unsigned char*)0xa002; // pointer to start of board
1445 ptr_draw+=(col*3)+(row*720); // 720=18*40 starting screen coordinate
1446 for (counter=0;counter<18;inccounter()) // nn = tile height in pixels (e.g. 18)
1447 {
1448 ptr_draw[0]=ptr_graph[0];
1449 ptr_draw[1]=ptr_graph[1];
1450 ptr_draw[2]=ptr_graph[2];
1451 ptr_draw+=40; // number of 6pixel "units" to advance (+40=next line down, same position across)
1452 ptr_graph+=3; // + unit of measurement (how many 6pixel chunks "across" in graphic file)
1453 }
1454 }
1455 /**************************************/
1456 void drawpiece()
1457 {
1458 tiletodraw=players[row][col];
1459 if ( tiletodraw>0) { tiletodraw+=3;}
1460 if ( tiles[row][col]>0 ) { tiletodraw+=3; }
1461 drawtile();
1462 }
1463 /**************************************/
1464 void drawarrow()
1465 {
1466 if ( fb==1 )
1467 {
1468 tiletodraw=10;
1469 if ( tiles[row][col] > 0 ) tiletodraw++; // add another 1 for arrow with background
1470 }
1471 else
1472 {
1473 tiletodraw=tiles[row][col]; // draw original tile (includes blank)
1474 }
1475 drawtile();
1476 }
1477 /**************************************/
1478 void printmessage()
1479 {
1480 //char c;
1481 //PrintChr(); // turn output ON
1482 /*
1483 for (c=0;message[c]!='\0';c++)
1484 {
1485 putchar(c);
1486 }
1487 */
1488 //printf("%c\n\n\n%s%c",19,message,19);
1489 printf("%c\n\n\n%s%c",19,message,19);
1490
1491 //PrintChr(); // TURN OUTPUT off
1492 }
1493 /**************************************/
1494 void printturnprompt()
1495 {
1496 strcpy(message,playertext);
1497 strcat(message,turntext);
1498 printmessage();
1499 //printf("%c\n\n3/1=%d 7/1=%d%c",19,target[3][1],target[7][1],19);
1500 //printf("%cSURROUNDED=%d%c",19,surrounded,19);
1501 }
1502 /**************************************/
1503 void surroundcount()
1504 {
1505 zerocounter();
1506 setpoints();
1507 surrounded=0;
1508 if (( kingns==0)||(kingns==10)||(kingew==0)||(kingew==10)) {incsurround();} // added 18/10/2011
1509 surew=kingew;
1510 if ( kingns > 0 ) { surns=kingns-1;surroundcheck(); }
1511 if ( kingns < 10 ) { surns=kingns+1;surroundcheck(); }
1512 surns=kingns;
1513 if ( kingew > 0 ) { surew=kingew-1;surroundcheck(); }
1514 if ( kingew < 10 ) { surew=kingew+1;surroundcheck(); }
1515 if (surrounded==3) // unset any "enemy and target values"
1516 {
1517 ezew1=kingew;
1518 if ( kingns > 0 )
1519 {
1520 ezns1=kingns-1;
1521 enemyzero();
1522 }
1523 if ( kingns < 10 )
1524 {
1525 ezns1=kingns+1;
1526 enemyzero();
1527 }
1528 ezns1=kingns;
1529 if ( kingew > 0 )
1530 {
1531 ezew1=kingew-1;
1532 enemyzero();
1533 }
1534 if ( kingew < 10 )
1535 {
1536 ezew1=kingew+1;
1537 enemyzero();
1538 }
1539 }
1540 }
1541 /****************************/
1542 void incsurround()
1543 {
1544 surrounded++;
1545 }
1546 /****************************/
1547 void pause()
1548 {
1549 int p;
1550 for (p=0; p<pausetime;p++){};
1551 }
1552 /****************************/
1553 void incpoints()
1554 {
1555 points++;
1556 }
1557 /****************************/
1558 void decpoints()
1559 {
1560 points--;
1561 if (points==0) points=1; // suggested by JamesD
1562 //if ((points-1)==0) {points=1;}else{points--;}
1563 }
1564 /****************************/
1565 void setpoints()
1566 {
1567 points=10;
1568 }
1569 /****************************/
1570 void doublepoints()
1571 {
1572 points+=10; // not really double anymore (10/12/2011)
1573 }
1574 /****************************/
1575
1576
1577 /******************************/
1578 void surroundpoints()
1579 {
1580 //printf("%c* %d *%c",19,(points+(points*surrounded)),19);
1581 points+=10*surrounded; // multiply the points around king depending on the "surrounded" figure
1582 }
1583 /****************************/
1584 void inccounter()
1585 {
1586 counter++;
1587 }
1588 /****************************/
1589 /*
1590 void deccounter()
1591 {
1592 counter--;
1593 }
1594 */
1595 /****************************/
1596 void zerocounter()
1597 {
1598 counter=0;;
1599 }
1600 /****************************/
1601 /*
1602 void LookBackInAnger() // returns the value of the piece "behind" an attacker
1603 {
1604 flag=0; // status of foundpiece 0=no, 1=yes
1605 if ( origorient == 0 )
1606 {
1607 for ( lookrow=mkey-1;lookrow>-1;lookrow--)
1608 {
1609 subLookBackInAnger();
1610 }
1611 }
1612 if ( origorient == 1 )
1613 {
1614 for ( lookrow=mkey+1;lookrow<11;lookrow++)
1615 {
1616 subLookBackInAnger();
1617 }
1618 }
1619 if ( origorient == 2 )
1620 {
1621 for ( lookcol=mkey+1;lookcol<11;lookcol++)
1622 {
1623 subLookBackInAnger();
1624 }
1625 }
1626 if ( origorient == 3 )
1627 {
1628 for ( lookcol=mkey-1;lookcol>-1;lookcol--)
1629 {
1630 subLookBackInAnger();
1631 }
1632 }
1633 }
1634 */
1635 /****************************/
1636 /*
1637 void subLookBackInAnger() // subroutine of LookBackInAnger
1638 {
1639 if (players[lookrow][lookcol]==1) { flag=1;}
1640 if ( (flag==0)&&((players[lookrow][lookcol]==2)||(players[lookrow][lookcol]==3))) { target[ons][oew]=1;}
1641 }
1642 */
1643 /****************************/
1644 void subcanbetaken2()
1645 {
1646 if (players[takena][takenb]>1)
1647 {
1648 //if (( enemy[ns2][ew2]-xvalue > 0 )||(enemy[ns2][ew2]-50 > 50)) // 14-11-2011
1649 if ((enemy[takenc][takend]-takene)&&((enemy[takenc][takend]<enemyweight)||(enemy[takenc][takend]-enemyweight))) // 23-12-2011
1650 {
1651 compass[origorient]=1; // e.g. compass[NORTH]=1 means canbetaken here if moving from NORTH
1652 }
1653 //else
1654 // {
1655 // cannotbetaken++;
1656 // }
1657 }
1658 }
1659 /****************************/
1660 void inctarget()
1661 {
1662 target[targetns][targetew]+=2;
1663 }
1664 /****************************/
1665 void surroundcheck()
1666 {
1667 if (players[surns][surew]==1) {incsurround();} // is attacker n,s,e,w
1668 if (tiles[surns][surew]>2) {incsurround();} // is king square n,s,e,w
1669 }
1670 /****************************/
1671 void calctakeweight() // calculate the weight that should be applied to TAKES
1672 {
1673 //unsigned char x;
1674 takeweight=5; // default
1675 // don't worry about TAKES if the king has unbroken line of sight to edge of board
1676 for (x=0;x<4;x++)
1677 {
1678 if ((kingattacker[x]==0)&&(kingdefender[x]==0)){takeweight=0;}
1679 }
1680 //if (((kingnorth==0)&&(defnorth==0))||((kingsouth==0)&&(defsouth==0))||((kingeast==0)&&(defeast==0))||((kingwest==0) && (defwest==0))) {takeweight=0;}
1681 }
1682 /******************************/
1683 void enemyzero() // calling routine = surroundcount()
1684 {
1685 if (( players[ezns1][ezew1] == 0 )&&(target[ezns1][ezew1])) // if adjacent square n/s/e/w is blank and accessible
1686 {
1687 ClearArrays(); // set all arrays to zero (target, enemy, computer)
1688 target[ezns1][ezew1]=100; // set big target value to final space by king
1689 }
1690 }
1691 /******************************/
1692 char checkroute() // returns number of pieces on a given route
1693 {
1694 //char start=cx;
1695 //char dest=kingns;
1696 //unsigned char x;
1697 z=0;
1698 if (orientation<EAST) // if checking ROWS (crossing the T) (used for NORTH SOUTH checks)
1699 {
1700 for (x=startcol;x<=destcol;x++) // check row
1701 {
1702 if ((players[startrow][x])&&(players[startrow][x]<3)) {z++;}
1703 }
1704 }
1705 else // EAST WEST checks (crossing the T)
1706 {
1707 for (x=startrow;x<=destrow;x++) // check accross
1708 {
1709 if ((players[x][startcol])&&(players[x][startcol]<3)) {z++;}
1710 }
1711 }
1712 return z;
1713 }
1714 /*************************/
1715 void cantakeadjust() // decrements cantake if taken piece is on same plane as king
1716 { // and attacking piece isn't AND only one defender on plane
1717 flag=0;
1718 if ((playertype==1)&&(gamestyle==1)) // if computer playing as attacker and his turn
1719 {
1720 if (pcheckns1==kingns)
1721 {
1722 flag=1;
1723 if (ctew<kingew){orientation=WEST;}else{orientation=EAST;}
1724 //if ((kingattacker[orientation]+kingdefender[orientation])<4){cantake--;}
1725 }
1726 if (pcheckew1==kingew)
1727 {
1728 flag=1;
1729 if (ctns<kingns){orientation=NORTH;}else{orientation=SOUTH;}
1730 //if ((kingattacker[orientation]+kingdefender[orientation])<4){cantake--;}
1731 }
1732 if (flag)
1733 {
1734 if ((kingattacker[orientation]+kingdefender[orientation])<4){cantake--;}
1735 }
1736
1737 }
1738 }
1739 /*************************/
1740 void updatetarget()
1741 {
1742 //unsigned char x;
1743 //unsigned char y;
1744 targetns=ctns;targetew=ctew;
1745 //char orient=1; // 0=north, 1=south, 2=east, 3=west
1746 //char orientA;
1747 //char orientB;
1748 //char z;
1749 target[targetns][targetew]=2; // set target to 2
1750 target[5][5]=0; // set "illegal" squares to zero
1751 target[0][10]=0;
1752 target[0][0]=0;
1753 target[10][0]=0;
1754 target[10][10]=0;
1755 if (target[targetns][targetew]) // only if target is valid (i.e. not a king square)
1756 {
1757 if (enemy[targetns][targetew]){inctarget();} // increase target if blocking an enemy
1758 calccantake(); // calculates how many takes can be made in this position (cantake)
1759 calctakeweight(); // calculate weight that should be applied to takes
1760 y=cantake*takeweight; // value to be added to target
1761 target[targetns][targetew]+=y; // add cantake (will be zero if cannot take)
1762 /*
1763 if ((ctew==1)||(ctew==9))
1764 {
1765 orientation=1; // check south for number of pieces
1766 startcol=ctew;startrow=0;destcol=ctew;destrow=10;
1767 ischeckroutezero(); // if so inctarget
1768 }
1769 if ((ctns==1)||(ctns==9))
1770 {
1771 orientation=2; // check east for number of pieces
1772 startcol=0;startrow=ctns;destcol=10;destrow=ctns;
1773 ischeckroutezero(); // if so inctarget
1774 }
1775 */
1776 //if (cantake==0) {canbetaken();} // sets target to 1 if cannot take but can be taken
1777 }
1778 }
1779 /******************/
1780 void ischeckroutezero()
1781 {
1782 //char a=checkroute();
1783 if ((checkroute())==0) {inctarget();} // if nobody on column, inctarget
1784 }
1785 /********************/
1786 void calccantake() // calculate how many takes can be made
1787 {
1788 //unsigned char x;
1789 cantake=0;
1790 inccantake(); // inc cantake if can take in direction of travel
1791 for (x=0;x<4;x++)
1792 {
1793 if ( x<2 ) // heading north/south
1794 {
1795 orientation=EAST; inccantake();
1796 orientation=WEST; inccantake();
1797 }
1798 if ( x>1 ) // heading east/west
1799 {
1800 orientation=NORTH; inccantake();
1801 orientation=SOUTH; inccantake();
1802 }
1803 }
1804 }

  ViewVC Help
Powered by ViewVC 1.1.26