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

  ViewVC Help
Powered by ViewVC 1.1.26