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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26