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

Annotation of /users/barnsey123/VIKING-CHESS/main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 674 - (hide annotations)
Tue Oct 18 15:50:59 2011 UTC (8 years, 7 months ago) by barnsey123
File MIME type: text/plain
File size: 46917 byte(s)
30696 bytes executable - need  to remove printf
1 barnsey123 674 // 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