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

  ViewVC Help
Powered by ViewVC 1.1.26