/[projet1]/users/barnsey123/VIKING-CHESS/main-old-20.c
Defence Force logotype

Contents of /users/barnsey123/VIKING-CHESS/main-old-20.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 679 - (show annotations)
Thu Oct 20 12:49:39 2011 UTC (8 years, 5 months ago) by barnsey123
File MIME type: text/plain
File size: 46917 byte(s)
pre-animations
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 /* IMMEDIATE TODO LIST
58 *** Continue with endgame function to return a value determining victory conditions etc
59 *** routine to detect if all attackers have been captured
60 *** routine to detect stalemate (a side cannot move)
61 */
62 #include <lib.h>
63 extern unsigned char PictureTiles[];
64
65 /******************* Function Declarations ************************/
66 void drawcursor(); // draws cursor
67 void inverse(); // inverse the color in the square
68 void drawtiles(); // draws all tiles at board x,y boxsize z (uses draw*tile functions)
69 void drawboard(); // kicks off drawgrid/drawtiles
70 void playerturn(); // takes user input to move cursor
71 void drawplayers(); // draw playing pieces
72 void flashscreen(); // flashes screen in selected color for a second or so
73 void canpiecemove(); // can a selected piece move? 0=no, 1=yes
74 void printdestinations(); // print arrows on tiles where a piece can move
75 void printpossiblemoves(); // Print possible moves
76 void printarrowsorblanks(); // PRINT ARROWS/BLANK EM OUT
77 void movecursor2(); // move cursor routine
78 void movepiece(); // move a piece
79 char cantakepiece(); // returns 0=no, 1 yes
80 void takepiece(); // takes specified piece
81 void blinkcursor(); // blinks the cursor to attract attention
82 void checkend(); // check for end game conditions
83 void computerturn(); // AI for computer
84 void pacman(); // update target positions around king (need to develop further)
85 void targetselect(); // choose a target square
86 void findpiecens(); // findpiece north-south
87 void findpieceew(); // findpiece east-west
88 void canbetaken(); // can I be taken after moving here? returns value (take) 0=no 1=yes
89 void subarrows(); // subroutine of arrows or blanks
90 void subarrows2(); // subroutine of arrows or blanks (updates ENEMY with direction of enemy)
91 void subpacman(); // subroutine of pacman
92 void subpacman2(); // subroutine of pacman
93 void subpacman3(); // sub of subpacman
94 void subpacman4(); // sub of subpacman2
95 void subpacman5(); // sub of pacman (diagonal points)
96 void subcanbetaken(); // sub of canbetaken
97 char kingupdatens(); // update attacker count around king (ns plane)
98 char kingupdateew(); // update attacker count around king (ew plane)
99 void inccantake(); // increments cantake
100 void incroute(); // incs route
101 void decroute(); // decs route
102 void drawtile(); // draw a tile (subroutine of drawtiles)
103 void drawpiece(); // draws piece
104 void drawarrow(); // draws "arrow"
105 /****************** GLOBAL VARIABLES *******************************/
106 /* Populate array with tile types
107 Tile types:
108 0=blank
109 1=attacker square
110 2=defender square
111 3=king square
112 */
113 extern const unsigned char tiles[11][11];
114
115 /* populate array with places of players
116 Players:
117 0=vacant
118 1=attacker resident
119 2=defender resident
120 3=king resident
121 4=corner square // added 21/04/2011
122 */
123 // *** PROPER STARTING BOARD (comment out TESTING BOARD below before uncommenting this)
124
125 char players[11][11]={
126 {4,0,0,1,1,1,1,1,0,0,4},
127 {0,0,0,0,0,1,0,0,0,0,0},
128 {0,0,0,0,0,0,0,0,0,0,0},
129 {1,0,0,0,0,2,0,0,0,0,1},
130 {1,0,0,0,2,2,2,0,0,0,1},
131 {1,1,0,2,2,3,2,2,0,1,1},
132 {1,0,0,0,2,2,2,0,0,0,1},
133 {1,0,0,0,0,2,0,0,0,0,1},
134 {0,0,0,0,0,0,0,0,0,0,0},
135 {0,0,0,0,0,1,0,0,0,0,0},
136 {4,0,0,1,1,1,1,1,0,0,4}};
137
138 // ***** TESTING BOARD ****
139 /*
140 char players[11][11]={
141 {4,0,1,1,1,1,1,1,3,0,4},
142 {0,3,0,0,0,1,0,0,0,0,0},
143 {2,0,0,0,0,0,0,0,0,0,2},
144 {0,0,0,0,0,0,2,0,0,0,1},
145 {1,2,0,0,0,0,0,0,0,0,1},
146 {1,2,0,2,0,0,3,2,2,1,1},
147 {1,1,0,0,2,1,2,0,1,0,1},
148 {1,0,0,0,0,2,0,0,0,1,2},
149 {0,1,0,0,0,0,0,0,1,0,2},
150 {0,2,0,0,0,0,0,0,2,0,0},
151 {4,0,3,0,0,0,1,1,3,0,4}};
152 */
153
154 // DESIRABILITY-ATTACKER(a table that stores strategically important squares)
155
156 char desireatt[11][11]={
157 {0,3,3,3,2,2,2,3,3,3,0},
158 {3,4,3,2,2,2,2,2,3,4,3},
159 {3,3,2,2,2,2,2,2,2,3,3},
160 {3,2,2,2,2,2,2,2,2,2,3},
161 {2,2,2,2,2,2,2,2,2,2,2},
162 {2,2,2,2,2,0,2,2,2,2,2},
163 {2,2,2,2,2,2,2,2,2,2,2},
164 {3,2,2,2,2,2,2,2,2,2,3},
165 {3,3,2,2,2,2,2,2,2,3,3},
166 {3,4,3,2,2,2,2,2,3,4,3},
167 {0,3,3,3,2,2,2,3,3,3,0}};
168 extern unsigned char target[11][11]; // uninitialized variable (will calc on fly) - target values of square
169
170 // ARRAY ENEMY unititialized variable (will calc on fly) - can enemy reach a square?
171 // values:
172 // +1 Can be reached from NORTH
173 // +5 can be reached from SOUTH
174 // +10 can be reached from EAST
175 // +20 can be reached from WEST
176 extern char enemy[11][11];
177
178 // TIGER
179 const unsigned char boardx=12; // starting x co-ord of board
180 const unsigned char boardy=0; // starting y co-ord of board
181 const char boxsize=18; // set boxsize
182 char playertype=0; // player 1=attacker, 2=defender (set to 0 at start as inited later)
183 char piecetype; // 1=attacker, 2=defender, 3=king
184 char ns; // default north/south position of central square
185 char ew; // default east/west position of central square
186 unsigned char cx; // cursor x screen position (pixels across)
187 unsigned char cy; // cursor y screen position (pixels down)
188 char fb=1; // foreground/background 0=background, 1=foreground, 2=opposite, 3=nothing
189 unsigned char inversex; // x position of square to be inversed
190 unsigned char inversey; // y position of square to be inversed
191 char mkey; // code of key pressed
192 char cursormode; // cursor movement mode 0=freeform 1=restricted
193 char ons; // original north/south board pos
194 char oew; // original east/west board pos
195 unsigned char ocx; // original xpos of piece
196 unsigned char ocy; // original ypos of piece
197 char orientation; // for arrows - 0=north, 1=south 2=east 3=west
198 //unsigned char arrowsx; // xpos for arrows
199 //unsigned char arrowsy; // ypos for arrows
200 char tiletype; // type of tile under inspection (used in arrows)
201 //unsigned char tilex; // xpos of tile to draw
202 //unsigned char tiley; // ypos of tile to draw
203 //unsigned char blankx; // xpos to blank
204 //unsigned char blanky; // ypos to blank
205 //unsigned char size; // size of line to draw or something
206 char tpns; // north-south board location of taken piece (also used for 3)
207 char tpew; // east-west board location of taken piece
208 char flashcolor; // color ink to flashing in
209 char flashback; // color of ink to return to
210 char game=1; // <=0 means endgame (see checkend for values), 1=GAMEON
211 char gamestyle=1; // 0=human vs human; 1=human king vs computer; ** NO!!! 2=human vs computer king**
212 char kingns=5; // kings position North-South
213 char kingew=5; // kings position East-West
214 char kingnorth; // count of attackers NORTH of king
215 char kingsouth; // count of attackers SOUTH of king
216 char kingeast; // count of attackers EAST of king
217 char kingwest; // count of attackers WEST of king
218 char surrounded; // status of king "surrounded" status
219 char ctns=0; // Computer Turn north-south board position
220 char ctew=0; // Computer Turn east-west board position
221 char playertext[]="PLAYER1";
222 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
223 char xloop=0; // general purpose loop variable
224 char xns=0; // copy of ns (arrows or blanks, and subarrows)
225 char xew=0; // copy of ew (arrows or blanks, and subarrows)
226 char arrow=1; // used in arrowsorblanks(and subarrows)
227 //char canibetaken=0; // can I be taken?
228 char flag=0;
229 char cantake; // can I take? (for computer turn)
230 char route;
231 unsigned char row; // used in tile drawing routines and array navigation ( a row in 11x11 grid)
232 unsigned char col; // used in tile drawing routines and array navigation ( a column in 11x11 grid)
233 unsigned char tiletodraw; // used in tile drawing routines 0-11 (as at 18-10-2011)
234 /****************** MAIN PROGRAM ***********************************/
235 main()
236 {
237 paper(0);
238 ink(5);
239 drawboard(); // draw the board
240 while (game>0)
241 {
242 ns=5; // default north/south position of central square
243 ew=5; // default east/west position of central square
244 cx=1+boardx+(boxsize*ew); // cursor x screen position
245 cy=1+boardy+(boxsize*ns); // cursor y screen position
246 playertype++; // playertype inited as 0 so ++ will make it 1 at start of game
247 if ( playertype == 3 ) { playertype = 1; } // was defender, set to attacker player
248 //if (( gamestyle == 0 )||((gamestyle==1)&&(playertype==2))||((gamestyle==2)&&(playertype==1)))
249 if (( gamestyle == 0 )||((gamestyle==1)&&(playertype==2)))
250 {
251 playerturn(); // player input
252 }
253 else
254 {
255 computerturn(); // computer has a go...
256 }
257 checkend(); // check for end of game conditions
258 }
259 printf("%c",19); // turn output to screen
260 if ( game == 0 ) { printf("\n\n\nKING ESCAPED! King Wins!");}
261 else { printf("\n\n\nKING CAPTURED! Attacker Wins!");}
262 getchar();
263 }
264 /********************* FUNCTION DEFINITIONS ************************/
265 void computerturn()
266 {
267 //unsigned int xrand=srandom(deek(630)); // seed random number generator
268 //if ( playertype == 1 ) { strcpy(playertext,"ATTACKER");}else{ strcpy(playertext,"KING");}
269 printf("%c\n\n\nORIC IS THINKING..%c",19,19);
270 // 1. initialize target array to zeroes
271 ClearTargetAndEnemy();
272 // 2. Loop through players array searching for enemy pieces - calculating where they can go
273 fb=5;
274 pacman1:
275 for (ctns=0;ctns<11;ctns++)
276 {
277 for (ctew=0;ctew<11;ctew++)
278 {
279 ew=ctew;
280 ns=ctns;
281 if ( fb==5 ) // fb=5 means: don't print destinations, just update ENEMY
282 {
283 if (( players[ctns][ctew]==2 )||(players[ctns][ctew]==3)) // if enemy found
284 {
285 printdestinations(); // update enemy array of possible locations
286 }
287 }
288 else // fb=3 means: don't print any destinations, just update TARGET!
289 {
290 if ( players[ctns][ctew]==1) // if attacker found
291 {
292 printdestinations();
293 }
294 }
295 }
296 }
297 if (fb==5) { fb=3;goto pacman1;}
298 // 3. Increment target positions around King (PACMAN)
299 pacman();
300 //if ( playertype == 1 ) {pacman();}
301 // other routines to go here to update the target array
302 // 4,5,6,7..N etc
303 //
304 targetselect(); // Choose the highest value target
305 movepiece(); // make the move
306 }
307 /*********************************************/
308 void findpiecens() // find piece NORTH-SOUTH
309 {
310 if ( foundpiece == 0 )
311 {
312 //if ( playertype == 1 )
313 // {
314 if (players[mkey][ew]==1){ foundpiece=1;ons=mkey;}
315 if (players[mkey][ew] > 1) { foundpiece=9;}
316 // }
317 /*
318 if ( playertype == 2 )
319 {
320 if ((players[mkey][ew]==2)||(players[mkey][ew] == 3)) { foundpiece=1;ons=mkey; }
321 //if (players[mkey][ew] == 1) { foundpiece=9; }
322 }
323 */
324 }
325 }
326 /**************************************************/
327 void findpieceew() // find piece EAST-WEST
328 {
329 if ( foundpiece == 0 )
330 {
331 //if ( playertype == 1 )
332 // {
333 if (players[ns][mkey] == 1){ foundpiece=1;oew=mkey;}
334 if (players[ns][mkey] > 1) { foundpiece=9;}
335 // }
336 /*
337 if ( playertype == 2 )
338 {
339 if ((players[ns][mkey] == 2)||(players[ns][mkey] == 3)) { foundpiece=1;oew=mkey; }
340 //if (players[ns][mkey] == 1) { foundpiece=9; }
341 }
342 */
343 }
344 }
345 /*********************************************************/
346 // TARGETSELECT - find the highest scoring TARGET
347 void targetselect()
348 {
349 char hightarget=0; // contains highest value target
350 //int xrand=random(); // random number between 0-32000ish
351 foundpiece=0; // set findpiece to "piece not found"
352 for (ctns=0;ctns<11;ctns++) // find the highest value for target
353 {
354 for (ctew=0;ctew<11;ctew++)
355 {
356 if ( target[ctns][ctew] > hightarget )
357 {
358 hightarget=target[ctns][ctew]; // make hightarget the highest value
359 ns=ctns; // make ns be hightarget
360 ew=ctew; // make ew be hightarget
361 ons=ctns; // target is accessible so make ons/oew the default piece position to move
362 oew=ctew; // the ACTUAL piece to move determined below (one of ons or oew will remain same)
363 }
364 }
365 }
366 // having found target we need to select a piece to move
367 //if ( foundpiece == 0 ) // at this point foundpiece is ALWAYS zero so no need to check...
368 // {
369 for (mkey=ns-1; mkey>-1; mkey-=1) {findpiecens();} // check NORTH
370 // }
371 if ( foundpiece != 1 ) { foundpiece=0;}
372 //if ( foundpiece == 0 )
373 // {
374 for (mkey=ns+1; mkey<11; mkey++) {findpiecens();} // Check SOUTH
375 // }
376 if ( foundpiece != 1 ) { foundpiece=0;}
377 //if ( foundpiece == 0 )
378 // {
379 for (mkey=ew+1; mkey<11; mkey++) {findpieceew();} // Check EAST
380 // }
381 if ( foundpiece != 1 ) { foundpiece=0;}
382 //if ( foundpiece == 0 )
383 // {
384 for (mkey=ew-1; mkey>-1; mkey-=1) {findpieceew();} // Check WEST
385 // }
386 cx=1+boardx+(boxsize*oew); // piece x screen position
387 cy=1+boardy+(boxsize*ons); // piece y screen position
388 blinkcursor(); // draw cursor in foreground color at piece to move position cx,cy
389 fb=0;drawcursor(); // blank cursor
390 cx=1+boardx+(boxsize*ew); // target x screen position
391 cy=1+boardy+(boxsize*ns); // target y screen position
392 blinkcursor(); // draw cursor in foreground color at target position cx,cy
393 ocx=1+boardx+(boxsize*oew); // piece to move x screen position
394 ocy=1+boardy+(boxsize*ons); // piece to move y screen position
395 //printf("%cNS=%d,EW=%d,ONS=%d,OEW=%d%c",19,ns,ew,ons,oew,19);
396 //loop=getchar();
397 }
398 /************************************************/
399 void pacman() // PACMAN ( increment target positions around king )
400 {
401 char loop;
402 char points=100; // counts down the further away from king
403 surrounded=0;
404 xloop=kingns-1; // general purpose counter (default to kings ns position -1)
405 if ( xloop > -1 ) // check north from King
406 {
407 if (( players[xloop][kingew]==1)||(tiles[xloop][kingew]>2)) {surrounded++;}
408 if ( kingnorth==0 ) { points++; }
409 if ((kingew<3)||(kingew>7)) { points++; }
410 if ( kingns<5 ) { points++; } // add weight to north if king in north side of board
411 while (players[xloop][kingew] == 0 )
412 {
413 if ((xloop<3)&&((kingew<3)||(kingew>7))){points++;}
414 if ( target[xloop][kingew] > 1 ) { target[xloop][kingew]+=points;}// inc target only if accessible by attacker
415 subpacman();
416 xloop--;
417 points--;
418 }
419 }
420 points=100;
421 xloop=kingns+1; // reset xyloop and check south
422 if ( xloop < 11 )
423 {
424 if (( players[xloop][kingew]==1)||(tiles[xloop][kingew]>2)) {surrounded++;}
425 if ( kingsouth==0 ) { points++; }
426 if ((kingew<3)||(kingew>7)) { points++; }
427 if ( kingns>5 ) { points++;} // add weight to south if king in south side of board
428 while (players[xloop][kingew] == 0 )
429 {
430 if ((xloop>7)&&((kingew<3)||(kingew>7))){points++;}
431 if ( target[xloop][kingew] > 1 ) { target[xloop][kingew]+=points;}// inc target only if accessible by attacker
432 subpacman();
433 xloop++;
434 points--;
435 }
436 }
437
438 points=100;
439 xloop=kingew+1; // reset xloop and check east
440 if ( xloop < 11 )
441 {
442 if (( players[kingns][xloop]==1)||(tiles[kingns][xloop]>2)) {surrounded++;}
443 if ( kingeast==0 ) { points++; }
444 if ((kingns<3)||(kingns>7)) { points++; }
445 if ( kingew>5 ) { points++;} // add weight to east if king in east side of board
446 while (players[kingns][xloop] == 0 )
447 {
448 if ((xloop>7)&&((kingns<3)||(kingns>7))){points++;}
449 if ( target[kingns][xloop] > 1 ) { target[kingns][xloop]+=points;}// inc target only if accessible by attacker
450 subpacman2();
451 xloop++;
452 points--;
453 }
454 }
455
456 points=100;
457 xloop=kingew-1; // reset xloop and check west
458 if ( xloop > -1 )
459 {
460 if (( players[kingns][xloop]==1)||(tiles[kingns][xloop]>2)) {surrounded++;}
461 if ( kingwest==0 ) { points++; }
462 if ((kingns<3)||(kingns>7)) { points++; }
463 if ( kingew<5 ) { points++;} // add weight to west if king in west side of board
464 while (players[kingns][xloop] == 0 )
465 {
466 if ((xloop<3)&&((kingns<3)||(kingns>7))){points++;}
467 if ( target[kingns][xloop] > 1 ) { target[kingns][xloop]+=points;}// inc target only if accessible by attacker
468 subpacman2();
469 xloop--;
470 points--;
471 }
472 }
473 /* DIAGONAL INCREMENTS - FIXED POINTS */
474
475 if ((kingns>1)&&(kingns<9)&&(kingew>1)&&(kingew<9)) // this version uses least memory
476 {
477 for (loop=1;loop<3;loop++)
478 {
479 ctns=kingns-loop;
480 ctew=kingew-loop;
481 subpacman5();
482 ctew=kingew+loop; subpacman5();
483 ctns=kingns+loop;
484 ctew=kingew-loop; subpacman5();
485 ctew=kingew+loop; subpacman5();
486 }
487 }
488 target[5][5]=0; // make central square unattainable to attackers
489 }
490
491 /************************************************/
492 void subpacman() // increase target positions that LEAD to a king target
493 {
494 flag=0;
495 for (mkey=kingew-1;mkey>-1;mkey--){subpacman3();}
496 flag=0;
497 for (mkey=kingew+1;mkey<11;mkey++){subpacman3();}
498 }
499 /************************************************/
500 void subpacman2()
501 {
502 flag=0;
503 for (mkey=kingns-1;mkey>-1;mkey--){subpacman4();}
504 flag=0;
505 for (mkey=kingns+1;mkey<11;mkey++){subpacman4();}
506 }
507 /*****************************/
508 void subpacman3()
509 {
510 if ( players[xloop][mkey] ) { flag=1;}
511 if ((flag==0)&&(target[xloop][mkey]>1 )) { target[xloop][mkey]++; }
512 }
513 void subpacman4()
514 {
515 if ( players[mkey][xloop] ) { flag=1;}
516 if ((flag==0)&&(target[mkey][xloop]>1 )) { target[mkey][xloop]++; }
517 }
518 void subpacman5()
519 {
520 if (target[ctns][ctew]>1) {target[ctns][ctew]+=5;}
521 }
522 /************************************************/
523 void checkend() // check for endgame conditions
524 {
525 /* Victory Conditions
526 game=0 King escapes. // DONE
527 game=-1 King Surrounded in open play or by central square // DONE
528 game=-2 King surrounded by attackers and corner squares // DONE
529 game=-3 King surrounded by attackers and edge of board // DONE
530 game=-4 defenders cannot move (stalemate) // TBD
531 game=-5 attackers cannot move (stalemate) // TBD
532 game=-6 all attackers eliminated // TBD
533 */
534 //char kingfound=0; // 0=king not found 1=king found
535 // ns and ew contains new board co-ords of last piece moved
536 if (( players[ns][ew] == 3 ) && ( tiles[ns][ew] == 4 )) { game=0; } // king has escaped
537 // check to see if king is surrounded by attackers (first find king)
538 if ( players[ns][ew] == 1 ) // if attacker was last to move
539 {
540 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 )))
541 {
542 surrounded++;
543 }
544 if (( kingns==0)||(kingns==10)||(kingew==0)||(kingew==10)) { surrounded++;}
545 if ( surrounded == 4 ) { game=-1;} // king is surrounded on all sides by attackers or king squares
546 }
547 }
548 /************************************************/
549 void movecursor2() // routine to move the cursor
550 {
551 /*
552 cursormode = [0 or 1] 0=unrestricted (move anywhere), 1= restricted (only move to possible destinations)
553 */
554 char canmovecursor=0;
555 char multiple=1; // concerning central square (how much to multiply the coords to SKIP the square
556 char xptrns=ns; // copy of NS
557 char xptrew=ew; // copy of EW
558 char skipns=ns; // skip to north/south
559 char skipew=ew; // skip to east/west
560 char modeonevalid=0; // is OK for mode 1? 0=no, 1=yes
561 piecetype=players[ons][oew]; // determines the piece type that is currently selected (used in mode 1)
562 if ((mkey == 8 )&&( ew>0)) // west
563 {
564 if ( cursormode == 0 ) { canmovecursor=1;}
565 xptrew--; // decrement copyew
566 skipew-=2;
567 modeonevalid=1;
568 }
569 if ((mkey == 9 )&&( ew<10)) // east
570 {
571 if ( cursormode == 0 ) { canmovecursor=1;}
572 xptrew++;
573 skipew+=2;
574 modeonevalid=1;
575 }
576 if ((mkey == 10)&&( ns<10)) // south
577 {
578 if ( cursormode == 0 ) { canmovecursor=1;}
579 xptrns++;
580 skipns+=2;
581 modeonevalid=1;
582 }
583 if ((mkey == 11)&&( ns>0)) // north
584 {
585 if ( cursormode == 0 ) { canmovecursor=1;}
586 xptrns--;
587 skipns-=2;
588 modeonevalid=1;
589 }
590 if (( cursormode == 1 ) && ( modeonevalid )) // if not at edge of board
591 {
592 if ( players[xptrns][xptrew] == 0 ) {canmovecursor=1;} // ok if square vacant
593 if ( tiles[xptrns][xptrew] == 4 ) {canmovecursor=0;} // !ok if corner
594 if (( piecetype == 3 )&&( tiles[xptrns][xptrew] > 2 )) {canmovecursor=1;} // ok if KING and corner/central
595 if (( xptrns == ons )&&( xptrew == oew )) {canmovecursor=1;} // ok if back to self
596 // need to check that for non-king pieces wether the central square is vacant and can be skipped
597 if (( piecetype < 3 )&&( tiles[xptrns][xptrew] == 3)&&(players[xptrns][xptrew] == 0 )) // tiles=3(central), tiles=4(corner)
598 {
599 if ( players[skipns][skipew] > 0 ) {canmovecursor=0;} // cannot skip if otherside occupied
600 if ((( skipns == ons )&&( skipew == oew ))||( players[skipns][skipew]==0)) // ok to skip to self
601 {
602 canmovecursor=1;
603 multiple=2;
604 }
605 }
606 }
607 if (canmovecursor)
608 {
609 fb=0;
610 drawcursor(); // print blank cursor (effect=remove dots)
611 if ( mkey == 8 ) {cx-=(boxsize*multiple);} // left
612 if ( mkey == 9 ) {cx+=(boxsize*multiple);} // right
613 if ( mkey == 10 ){cy+=(boxsize*multiple);} // down
614 if ( mkey == 11 ){cy-=(boxsize*multiple);} // up
615 fb=1;
616 drawcursor(); // print dotted cursor
617 if ( mkey == 8 ) {ew-=multiple;} // left
618 if ( mkey == 9 ) {ew+=multiple;} // right
619 if ( mkey == 10 ){ns+=multiple;} // down
620 if ( mkey == 11 ){ns-=multiple;} // up
621 }
622 else
623 {
624 flashcolor=1;
625 if ( cursormode == 0 ) {flashback=6;flashscreen();} // flash red: return to cyan:6
626 if ( cursormode == 1 ) {flashback=2;flashscreen();} // flash red: return to green:2)
627 }
628 }
629 /************************************************/
630 void inverse()
631 {
632 /* Draw an inversed colr box to highlight selected box
633 ix=screen x position
634 iy=screen y position
635 */
636 char iz=boxsize-3;
637 char loop; // loop counter
638 for (loop=0;loop<iz;loop++)
639 {
640 curset(inversex,inversey,3);
641 draw(iz,0,2); // draw inverse line
642 inversey++;
643 }
644 }
645 /************************************************/
646 void printpossiblemoves()
647 {
648 /* kicks off functions that print appropriate arrows at all possible destinations and blanks
649 them out afterwards*/
650 char k; // key entered
651 fb=1;
652 printdestinations(); // print arrows on all destinations
653 printf("%c\n\n\n* any key to proceed *%c",19,19);
654 k=getchar();
655 fb=0;
656 printdestinations(); // blank out arrows on all destinations
657 }
658 /************************************************/
659 void printarrowsorblanks() // used in printdestinations
660 {
661 char xplayers; // player type at square under test
662 char zns=ns; // another copy of ns (for computer turn)
663 char zew=ew; // another copy of ew (for computer turn)
664 char origorient=orientation; // original orientation (for computer turn)
665 //char cantake=0; // can I take? (for computer turn)
666 //unsigned char subloop=0;
667 cantake=0;
668 xns=ns;
669 xew=ew;
670 arrow=1;
671 //arrowsx=cx+1;
672 //arrowsy=cy+1;
673 // orientation 0,1,2,3 = N, S, E, W
674 if ( orientation == 0 ) { xplayers=players[xns-1][xew];} // check north
675 if ( orientation == 1 ) { xplayers=players[xns+1][xew];} // check south
676 if ( orientation == 2 ) { xplayers=players[xns][xew+1];} // check east
677 if ( orientation == 3 ) { xplayers=players[xns][xew-1];} // check west
678 if ( xplayers == 0 ) // if adjacent square is OK
679 {
680 //arrow=1;
681 while ( arrow == 1 ) // keep checking until cannot move
682 {
683 if (( orientation == 0 ) && ( xns )) // check north
684 {
685 xns--; // decrement provisional north-south player position
686 subarrows();
687 //arrowsy-=boxsize;
688 }
689 if (( orientation == 1 ) && ( xns < 10 )) // check south
690 {
691 xns++; // increment provisional north-south player position
692 subarrows();
693 //arrowsy+=boxsize;
694 }
695 if ((orientation == 2 ) && ( xew < 10 )) // check east
696 {
697 xew++; // increment provisional east-west player position
698 subarrows();
699 //arrowsx+=boxsize;
700 }
701 if ((orientation == 3 ) && ( xew )) // check west
702 {
703 xew--; // decrement provisional east-west player position
704 subarrows();
705 //arrowsx-=boxsize;
706 }
707 if ((fb==5)&&(arrow==0)&&(players[xns][xew]==1))
708 {
709 subarrows2();
710 }
711 tiletodraw=tiles[xns][xew]; // obtain type of tile
712 if ( arrow == 1 ) // if MODE is "draw an arrow"
713 {
714 row=xns;
715 col=xew;
716 if (fb==1) {drawarrow();}
717 if (fb==5) // computer turn - the enemy can reach this square
718 {
719 subarrows2();
720 }
721 if (fb==3) // computer turn - I can reach this square, is it desirable?
722 {
723 target[xns][xew]=desireatt[xns][xew]; // give target value a default
724 ns=xns;
725 ew=xew;
726 inccantake();
727 if ( orientation<2 ) // heading north/south
728 {
729 orientation=2; inccantake();
730 orientation=3; inccantake();
731 }
732 if ( orientation>1) // heading east/west
733 {
734 orientation=0; inccantake();
735 orientation=1; inccantake();
736 }
737 orientation=origorient; //reset orientation
738
739 target[xns][xew]+=(cantake*10); // add cantake * 10 (will be zero if cannot take)
740 if (cantake==0) {canbetaken();} // sets target to zero if cannot take but can be taken
741 if (((xns==kingns)||(xew==kingew))&&( surrounded == 3 ))
742 {
743 target[xns][xew]=120;
744 }
745 //if ( desireatt[xns][xew]==0 ) { target[xns][xew]=0; } // added 31/08/2011
746 cantake=0; // reset cantake
747 ns=zns; // reset ns
748 ew=zew; // reset ew
749 }
750 if ( fb == 0) // if MODE is "blank an arrow"
751 {
752 row=xns;
753 col=xew;
754 drawarrow();
755 /*
756 if (tiletype > 0)
757 {
758 //fb=1;
759 //tilex=arrowsx;
760 //tiley=arrowsy;
761 row=xns;
762 col=xew;
763 if (( tiletype == 1 )||(tiletype==2)) { drawtile(); } // draw attacker/defender tile
764 if (( tiletype > 2 )&&(piecetype == 3)) { drawtile(); } // print king tile
765 fb=0;
766 }
767 */
768 }
769 }
770 // have we reached the end of the board?
771 if (( orientation == 0 ) && ( xns == 0 )) { arrow=0;} // check north
772 if (( orientation == 1 ) && ( xns == 10 )) { arrow=0;} // check south
773 if (( orientation == 2 ) && ( xew == 10 )) { arrow=0;} // check east
774 if (( orientation == 3 ) && ( xew == 0 )) { arrow=0;} // check west
775 }
776 }
777 }
778 /************************************************/
779 void printdestinations()
780 {
781 // print appropriate arrows at all possible destinations (or blanks em out)
782 // check north
783 if ( ns > 0 ) { orientation=0;printarrowsorblanks();} // draws arrows/blanks em out (0=north)
784 // check south
785 if ( ns < 10 ){ orientation=1;printarrowsorblanks();} // draws arrows/blanks em out (1=south)
786 // check east
787 if ( ew < 10 ){ orientation=2;printarrowsorblanks();} // draws arrows/blanks em out (2=east)
788 // check west
789 if ( ew > 0 ) { orientation=3;printarrowsorblanks();} // draws arrows/blanks em out (3=west)
790 }
791 /*fill box with color
792 void fillbox (unsigned char x, unsigned char y, char effect)
793 {
794 curset(x+2,y,2);
795 fill(14,1,effect);
796 }*/
797 /************************************************/
798 void canpiecemove() // CAN A SELECTED PIECE MOVE?
799 {
800 // returns 0 or 1 depending on wether a piece can move or not
801 // int route=0; // number of possible routes
802 route=0;
803 piecetype=players[ns][ew]; // determine TYPE of selected piece (1=attacker, 2=defendr, 3=king)
804 /* for all piece types determine if adjacent square in any direction is blank or not
805 it won't bother checking a particular direction if piece is at edge of board.
806 */
807 if ( ns ) // check north
808 {
809 if ( players[ns-1][ew] == 0 ) incroute();
810 if (( piecetype == 3 )&&(players[ns-1][ew] == 4 )) incroute(); // KING: corner square OK
811 }
812 if ( ns < 10 ) // check south
813 {
814 if ( players[ns+1][ew] == 0 ) incroute();
815 if (( piecetype == 3 )&&(players[ns+1][ew] == 4 )) incroute(); // KING: corner square OK
816 }
817 if ( ew < 10 ) // check east
818 {
819 if ( players[ns][ew+1] == 0 ) incroute();
820 if (( piecetype == 3 )&&(players[ns][ew+1] == 4 )) incroute(); // KING: corner square OK
821 }
822 if ( ew ) // check west
823 {
824 if ( players[ns][ew-1] == 0 ) incroute();
825 if (( piecetype == 3 )&&(players[ns][ew-1] == 4 )) incroute(); // KING: corner square OK
826 }
827 /* In the case that the central square is unnocupied and a piece is adjacent to that square then - for
828 non-KING Pieces only - we need to check to see if the opposite square is occupied or not.
829 ROUTE will be decremented if that piece is occupied (as no piece can occupy the central square except for
830 the King but all pieces can traverse it */
831 if (( piecetype < 3 ) && ( players[5][5] == 0 )) // if not a king and central sqr unoccupied
832 {
833 if ( ns == 5 )
834 {
835 if ( ew == 4 ) {if ( players[5][6] > 0 ) decroute();} // check east +2 // east occupied, dec route
836 if ( ew == 6 ) {if ( players[5][4] > 0 ) decroute();} // check west +2 // west occupied, dec route
837 }
838 if ( ew == 5 )
839 {
840 if ( ns == 4 ) { if ( players[6][5] > 0 ) decroute();} // check south +2 // south occupied, dec route
841 if ( ns == 6 ) { if ( players[4][5] > 0 ) decroute();} // check north +2 // north occupied, dec route
842 }
843 }
844 if ( route > 0 ) route=1;
845 //return route;
846 }
847 /************************************************/
848 void drawplayers() // DRAW ALL THE PIECES ON THE BOARD
849 {
850 for (row=0;row<11;row++)
851 {
852 for (col=0;col<11;col++)
853 {
854 if (( players[row][col] > 0 )&&(players[row][col] < 4)){drawpiece();}
855 //piecetype=players[row][col];
856 //if (( piecetype > 0 )&&(piecetype < 4)){drawpiece();}
857 }
858 }
859 }
860 /************************************************/
861 void drawtiles() // DRAW ALL THE TILES ON THE BOARD
862 {
863 for (row=0;row<11;row++)
864 {
865 for (col=0;col<11;col++)
866 {
867 tiletodraw=tiles[row][col];
868 if ( tiletodraw==4 ) { tiletodraw=3;}
869 drawtile();
870 }
871 }
872 }
873 /************************************************/
874 void drawboard() // DRAW THE BOARD
875 {
876 hires();
877 ink(6); // boardcolor 0=black, 1=red, 2=green, 3=yellow, 4=blue, 5=magenta, 6=cyan,7=white
878 drawtiles(); // draw the background tiles
879 curset(12,198,1);
880 draw(198,0,1);
881 draw(0,-198,1);
882 drawplayers(); // draw the players
883 //printf("%c",19);// turn output to screen off
884 }
885 /************************************************/
886 void blinkcursor() // blinks the cursor a number of times to attract attention
887 {
888 char curloop;
889 unsigned int subloop;
890 for (curloop=0;curloop<5;curloop++) // flash the cursor to draw attention to it
891 {
892 fb=0; drawcursor(); // draw cursor in background color at cx,cy
893 for (subloop=0;subloop<250;subloop++){;} // wait a bit
894 fb=1; drawcursor(); // draw cursor in foreground color at cx,cy
895 for (subloop=0;subloop<2000;subloop++){;} // wait a bit
896 }
897 }
898 /************************************************/
899 void flashscreen() // flashes the screen in the selected ink color
900 {
901 /* Colors are as follows:
902 0=black, 1=red, 2=green, 3=yellow, 4=blue, 5=magenta, 6=cyan,7=white
903 */
904 unsigned int pause=1500; // flash screen so long...
905 unsigned int p; // pause counter
906 ink(flashcolor); // flash in color
907 for (p=0;p<pause;p++){};
908 ink(flashback); // back to original
909 }
910 /************************************************/
911 void playerturn() // The human players turn : filter keyboard input
912 {
913 unsigned char key; // code of key pressed
914 unsigned char canselect; // 0=no, 1=yes (is the piece selectable?)
915 char cursormovetype=-1; // -1=no, 0=yes (n,s,e,w) 1=(north/south only), 2=(east/west only)
916 char turn=1; // determines end of player turn 1=playerturn, 0=end of playerturn
917 ons=ns; // original ns board position
918 oew=ew; // original ew board position
919 ocx=cx; // original x screen position
920 ocy=cy; // original y screen position
921 flashback=6;
922 if ( playertype == 2 ) { strcpy(playertext,"KINGS");}
923 printf ("%c\n\n\n* %s Turn:Use cursor keys.\nX:Select P:Possible%c",19,playertext,19);
924 blinkcursor();
925 while (turn) // repeat until move is made
926 {
927 key=getchar(); // get code of pressed key
928 mkey=key;
929 if (( key > 7 ) && ( key < 12 )) // 8-11 = cursor keys
930 {
931 cursormode=0; // freeform
932 movecursor2();
933 }
934 /*******************************************************/
935 /* determine if X or P is selected (to select a piece) */
936 /*******************************************************/
937 if (( key == 88) || ( key == 80)) // if 'X' or 'P' is selected (88=X, 80=P)
938 {
939 canselect=0; // set piece to NOT SELECTABLE
940 if (( playertype == 1 )&&(players[ns][ew] == 1 )) { canselect=1;} // piece is selectable
941 if (( playertype == 2 )&&((players[ns][ew] == 2 )||(players[ns][ew] == 3 ))) { canselect=1;} // piece is selectable
942 if ( canselect )
943 {
944 canpiecemove();
945 if (route)
946 {
947 //piecetype=players[ns][ew];
948 flashcolor=2;flashscreen(); // flash green
949 if ( key == 80 ) // if P is pressed
950 {
951 printpossiblemoves(); // Print possible moves
952 printf ("%c\n\n\n* %s Turn:Use cursor keys.\nX:Select P:Possible%c",19,playertext,19);
953 }
954 }
955 else
956 {
957 flashcolor=1;flashscreen(); // flash red
958 canselect=0; // unselectable, cannot move
959 }
960 }
961 else { flashcolor=1;flashscreen();} // flash red
962 if (( mkey == 88 )&&( canselect )) // if piece is SELECTED and CAN move
963 {
964 ink(2); // green to indicate piece is selected
965 flashback=2;
966 printf("%c\n\n\n%s Turn X=Select R=Reset%c",19,playertext,19);
967 inversex=cx;
968 inversey=cy+1;
969 inverse(); // highlight selected square (inverse color)
970 mkey=0; // ensure mkey at known value
971 // set Original cursor and board position of selected square
972 ocx=cx; ocy=cy; ons=ns; oew=ew;
973 while (( mkey != 88 ) && ( mkey != 82)) // move cursor until X or R selected
974 {
975 if (( ons == ns )&&( cursormovetype<0)) { cursormovetype=1; }// cursor allowed north-south
976 if (( oew == ew )&&( cursormovetype<0)) { cursormovetype=2; }// cursor allowed east-west
977 if (( ons == ns )&& (oew == ew )) { cursormovetype=0;} // cursor can move
978 if (( cursormovetype == 2) && (( mkey == 8) ||(mkey == 9))) {cursormovetype=-1;}//!move
979 if (( cursormovetype == 1) && (( mkey == 10)||(mkey == 11))){cursormovetype=-1;}//!move
980 if (( cursormovetype == 0) && (( mkey == 8) ||(mkey == 9))) {cursormovetype=1;} //move
981 if (( cursormovetype == 0) && (( mkey == 10)||(mkey == 11))){cursormovetype=2;} //move
982 if ( cursormovetype > 0 )
983 {
984 cursormode=1; // restricted
985 movecursor2();
986 }
987 if ( cursormovetype < 0) { flashcolor=1;flashscreen();} // flashscreen red
988 mkey=getchar();
989 }
990 if ( mkey == 82 ) // R has been selected, Reset cursor to original positions
991 {
992 fb=0;
993 drawcursor(); // blank out cursor at current position
994 cx=ocx; // reset coords and board values to original positions
995 cy=ocy;
996 ns=ons;
997 ew=oew;
998 inversex=cx;
999 inversey=cy+1;
1000 inverse(); // inverse square
1001 fb=1;
1002 drawcursor(); // draw cursor at original selected position
1003 }
1004 if ( mkey == 88 ) // if X selected
1005 {
1006 inversex=ocx;
1007 inversey=ocy+1;
1008 inverse(); // inverse original position
1009 if (( ons == ns )&&( oew == ew))// X is in original position so return to cursor movement
1010 {
1011 mkey=0; // piece de-selected
1012 }
1013 else{
1014 movepiece(); // move selected piece
1015 turn=0; // player has ended turn
1016 }
1017 }
1018 }
1019 ink(6); // back to cyan
1020 flashback=6;
1021 } // key = X or P
1022 } // While player turn
1023 }
1024 /************************************************/
1025 char kingupdatens()
1026 {
1027 char x;
1028 char count=0; // count of pieces around king
1029 for (x=xloop;x<ctns;x++)
1030 {
1031 if (players[x][kingew]){count++;}
1032 }
1033 return count;
1034 }
1035 /***************************/
1036 char kingupdateew()
1037 {
1038 char x;
1039 char count=0; // count of pieces around king
1040 for (x=xloop;x<ctew;x++)
1041 {
1042 if (players[kingns][x]){count++;}
1043 }
1044 return count;
1045 }
1046 /********************************************************/
1047 // Moves selected piece to new location - updating board arrays and re-drawing tiles where necessary
1048 void movepiece()
1049 {
1050 char p1=1; // piece type comparison (lower) - used for determining takes - default=attacker
1051 char p2=1; // piece type comparison (upper) - used for determining takes - default=attacker
1052 piecetype=players[ons][oew]; // obtain type of piece
1053 //if (piecetype==1)
1054 // {
1055 xloop=0;ctns=kingns;kingnorth=kingupdatens();
1056 xloop=kingns;ctns=11;kingsouth=kingupdatens();
1057 xloop=0;ctew=kingew;kingwest=kingupdateew();
1058 xloop=kingew;ctew=11;kingeast=kingupdateew();
1059 // }
1060 // move piece
1061 fb=0;
1062 drawcursor(); // blank out cursor at new selected position
1063 row=ons;
1064 col=oew;
1065 tiletodraw=tiles[row][col];
1066 drawtile(); // draw tile at original location (blank out square)
1067 players[ons][oew]=0; // set original location to zero (unnocupied)
1068 players[ns][ew]=piecetype; // update square with player info
1069 row=ns;
1070 col=ew;
1071 drawpiece(); // draw piece at new location - 18-10-2011
1072 if ( piecetype == 3 ) { kingns=ns;kingew=ew;} // update king position (used by AI)
1073 // having moved piece we now need to check for, and implement any TAKES
1074 if (piecetype > 1 ) // if defender
1075 {
1076 p1=2;
1077 p2=3;
1078 }
1079 tpew=ew;
1080 if ( ns > 1 ) // check north
1081 {
1082 orientation=0;
1083 if ( cantakepiece() ) { tpns=ns-1; takepiece(); }
1084 }
1085 if ( ns < 9 ) // check south
1086 {
1087 orientation=1;
1088 if ( cantakepiece() ) { tpns=ns+1; takepiece(); }
1089 }
1090 tpns=ns;
1091 if ( ew < 9 ) // check east
1092 {
1093 orientation=2;
1094 if ( cantakepiece() ) { tpew=ew+1; takepiece(); }
1095 }
1096 if ( ew > 1 ) // check west
1097 {
1098 orientation=3;
1099 if ( cantakepiece() ) { tpew=ew-1; takepiece(); }
1100 }
1101 }
1102 /************************************************/
1103 void subcanbetaken()
1104 {
1105 target[ns][ew]=1;
1106 //if ((ns==kingns)||(ew==kingew)) { target[ns][ew]=3;} // means acceptable risk
1107 }
1108 /************************************************/
1109 void canbetaken() // can I be taken after moving here?
1110 {
1111 if ((ns>0)&&(ns<10))
1112 {
1113 if ((players[ns-1][ew]==2)||(players[ns-1][ew]==3))
1114 {
1115 if ( enemy[ns+1][ew]-1 ) // >0 removed 31/08/11 if enemy is immediately north and south accessible by enemy
1116 {
1117 subcanbetaken();
1118 }
1119 }
1120 if ((players[ns+1][ew]==2)||(players[ns+1][ew]==3))
1121 {
1122 if ( enemy[ns-1][ew]-5 ) // if enemy is immediately south and north is accessible by enemy
1123 {
1124 subcanbetaken();
1125 }
1126 }
1127 }
1128 if ((ew>0)&&(ew<10))
1129 {
1130 if ((players[ns][ew+1]==2)||(players[ns][ew+1]==3))
1131 {
1132 if ( enemy[ns][ew-1]-10 ) // if enemy is immediately east and west accessible by enemy
1133 {
1134 subcanbetaken();
1135 }
1136 }
1137 if ((players[ns][ew-1]==2)||(players[ns][ew-1]==3))
1138 {
1139 if ( enemy[ns][ew+1]-20 ) // if enemy is immediately west and east accessible by enemy
1140 {
1141 subcanbetaken();
1142 }
1143 }
1144 }
1145 }
1146 /************************************************/
1147 // Will return a value (take) who's values will be: 0= no, 1=yes
1148 char cantakepiece()
1149 {
1150 char take=0;
1151 char taketotal=0;
1152 char p1=1; // piece type comparison (lower) - used for determining takes - default=attacker
1153 char p2=1; // piece type comparison (upper) - used for determining takes - default=attacker
1154 char pcheckns1=ns-1; // defaults to north
1155 char pcheckns2=ns-2;
1156 char pcheckew1=ew;
1157 char pcheckew2=ew;
1158 piecetype=players[ns][ew]; // obtain type of piece
1159 //if ( fb==3) { piecetype=players[ctns][ctew];} // if computer turn set piecetype to piece being checked
1160 if ( fb==3 ) { piecetype=1;} // default = ATTACKER
1161 if (piecetype > 1 ) // if defender
1162 {
1163 p1=2;
1164 p2=3;
1165 }
1166 if ( orientation == 1) // if south
1167 {
1168 pcheckns1=ns+1;
1169 pcheckns2=ns+2;
1170 }
1171 if ( orientation > 1) // if east or west
1172 {
1173 pcheckns1=ns;
1174 pcheckns2=ns;
1175 pcheckew1=ew+1;
1176 pcheckew2=ew+2;
1177 if ( orientation == 3) // if west
1178 {
1179 pcheckew1=ew-1;
1180 pcheckew2=ew-2;
1181 }
1182 }
1183 // if a take is possible increment the take counter - if values fall within bounds...
1184 if ((pcheckns2>-1)&&(pcheckns2<11)&&(pcheckew2>-1)&&(pcheckew2<11))
1185 {
1186 if (( players[pcheckns1][pcheckew1] > 0 )&&(players[pcheckns1][pcheckew1] != p1)&&(players[pcheckns1][pcheckew1] != p2)&&(players[pcheckns1][pcheckew1] != 3))
1187 {
1188 if ((( players[pcheckns2][pcheckew2] == p1 )||(players[pcheckns2][pcheckew2] == p2 ))&&(players[pcheckns1][pcheckew1] < 3))
1189 {
1190 take++;
1191 }
1192 }
1193 }
1194 if ( piecetype == 3 ) // if king and next to attacker and opposite square is a king square
1195 {
1196 if ((players[pcheckns1][pcheckew1] == 1 )&&(tiles[pcheckns2][pcheckew2] > 2)) { take++;}
1197 }
1198 return take;
1199 }
1200 /************************************************/
1201 void takepiece() // performs taking/removing a piece
1202 {
1203 players[tpns][tpew]=0; // zero players
1204 row=tpns;
1205 col=tpew;
1206 tiletodraw=tiles[row][col]; // decide tile to draw
1207 drawtile(); // draw tile at location
1208 }
1209 /*****************************/
1210 void subarrows()
1211 {
1212 if (players[xns][xew])
1213 {
1214 arrow = 0; // !ok if piece occupied or corner square
1215 }
1216 if (( players[ns][ew] == 3)&&(tiles[xns][xew] == 4)) { arrow = 1; } // corner ok if king
1217 }
1218 /*****************************/
1219 void subarrows2()
1220 {
1221 if ( orientation==0 ) { enemy[xns][xew]+=5; } // means enemy can get here from SOUTH
1222 if ( orientation==1 ) { enemy[xns][xew]+=1; } // means enemy can get here from NORTH
1223 if ( orientation==2 ) { enemy[xns][xew]+=20; } // means enemy can get here from WEST
1224 if ( orientation==3 ) { enemy[xns][xew]+=10; } // means enemy can get here from EAST
1225 }
1226 /*****************************/
1227 void inccantake()
1228 {
1229 cantake+=cantakepiece();
1230 }
1231 /*****************************/
1232 void incroute()
1233 {
1234 route++;
1235 }
1236 /*****************************/
1237 void decroute()
1238 {
1239 route--;
1240 }
1241 /*********************************/
1242 void drawtile() // draws a board tile, player piece or "arrow"
1243 {
1244 unsigned char a;
1245 unsigned char* ptr_draw=(unsigned char*)0xa002; // ptr to board starting position (e.g. 0xa002)
1246 unsigned char* ptr_graph=PictureTiles; // pointer to byte values of loaded picture
1247 unsigned int startpos; // position in tile file from which to draw
1248 ptr_draw+=(col*3)+(row*720); // 720=18*40 starting screen coordinate
1249 startpos=(tiletodraw*54); // 54=3*18 calc how many lines "down" in the graphic file to print from
1250 ptr_graph+=startpos; // set start position in graphic file
1251 for (a=0;a<18;a++) // nn = tile height in pixels (e.g. 18)
1252 {
1253 ptr_draw[0]=ptr_graph[0];
1254 ptr_draw[1]=ptr_graph[1];
1255 ptr_draw[2]=ptr_graph[2];
1256 ptr_draw+=40; // number of 6pixel "units" to advance (+40=next line down, same position across)
1257 ptr_graph+=3; // + unit of measurement (how many 6pixel chunks "across" in graphic file)
1258 }
1259 }
1260 /**************************************/
1261 void drawpiece()
1262 {
1263 tiletodraw=players[row][col];
1264 if ( tiletodraw>0) { tiletodraw+=3;}
1265 if ( tiles[row][col]>0 ) { tiletodraw+=3; }
1266 drawtile();
1267 }
1268 /**************************************/
1269 void drawarrow()
1270 {
1271 if ( fb==1 )
1272 {
1273 tiletodraw=10;
1274 if ( tiles[row][col] > 0 ) tiletodraw++; // add another 1 for arrow with background
1275 }
1276 else
1277 {
1278 tiletodraw=tiles[row][col]; // draw original tile (includes blank)
1279 }
1280 drawtile();
1281 }

  ViewVC Help
Powered by ViewVC 1.1.26