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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 540 - (show annotations)
Wed Jun 15 21:16:30 2011 UTC (8 years, 9 months ago) by barnsey123
File MIME type: text/plain
File size: 48649 byte(s)
old AI
1 // main.c by Neil Barnes (a.k.a. Barnsey123)
2 // 22-03-2011 prog to draw a grid (for viking game)
3 // 23-03-2011 create new drawgrid function
4 // 01-04-2011 create new drawtile functions and use compact code (char instead of int etc)
5 // 02-04-2011 routine to read keyboard
6 // 06-04-2011 cursor drawing correct
7 // 11-04-2011 request help from DBUG - bug in OSDK. Have banged head against wall for far too long!
8 // 14-04-2011 DBUG fixed OSDK bug! :-)
9 // 15-04-2011 tidied code up
10 // 15-04-2011 tiles as a global variable, (will be used everywhere)
11 // 16-04-2011 Changed numeric settings for board (0=blank, 1=attackers tile, 2=defenders tile, 3=kings tile)
12 // 16-04-2011 drawing players
13 // 17-04-2011 improving tile drawing (saving few bytes in each routine and having different styles)
14 // 19-04-2011 added flashscreen (to flash screen with desired color - e.g. GREEN for OK, RED for !OK)
15 // 19-04-2011 context sensitive piece selection
16 // 19-04-2011 canpiecemove function (can a selected piece MOVE or not?)
17 // 21-04-2011 numerous bug-fixes to do with x,y co-ords vs north-south/east-west array positions
18 // 21-04-2011 brilliant arrow printing function (hover over one of your pieces and press 'P')
19 // 25-04-2011 fixed bugs in arrow printing routine and reduced code required (TOTAL 817 lines versus 957)
20 // 27-04-2011 fixed some other (all?) bugs in arrow printing routines (new, neater routines)
21 // 29-04-2011 saved a whole bunch of code (789 lines)
22 // 29-04-2011 changed flashscreen so that color can be returned to previous color mode
23 // 29-04-2011 Using POINTERS Huzzah! (never thought that would happen!) 786 lines!
24 // 01-05-2011 Once a piece is selected restrict cursor movement to legal destinations
25 // 02-05-2011 handle "skipping" of central square (if square beyond it is available)
26 // 02-05-2011 900 lines of code (including comments) versus 917 (more efficient and more features)
27 // 02-05-2011 907 lines including refinements
28 // 02-05-2011 CAN now move pieces (taking turns between attacker/defender) 935 lines
29 // 04-05-2011 Can now TAKE pieces (but king squares can't yet take part...) 1012 lines
30 // 04-05-2011 Re-design to save memory/complexity (987 lines)
31 // 05-05-2011 re-design to save memory/complexity (966 lines)
32 // 05-05-2011 add the take rule (of King being able to take attackers with the aid of the king squares)
33 // 06-05-2011 saved a few bytes
34 // 07-05-2011 saved a few bytes (962 lines, 30311 bytes)
35 // 10-05-2011 fixed bug in central square Skipping (could not return to self if adjacent to square)
36 // 10-05-2011 fixed bug allowing defender to select corner square to move!
37 // 10-05-2011 Continuing glabalization (few bugs sorted)
38 // 11-05-2011 Finished Globalizing (23639 bytes)
39 // 13-05-2011 Bug Hunt (23504 bytes) - some tidying up (not 100% byte efficient I'm sure)
40 // 14-05-2011 Bug in printpossiblemoves resolved (arrow WILL print on corner square if piece is KING)
41 // 14-05-2011 checkend function to check if king escapes or is captured (not complete) (26815)
42 // 18-05-2011 developing attacker move (running out of memory! 31213!) hardly started
43 // 26-05-2011 1st attempt at computer moving piece (since Amiga days! 1990/1991?)
44 // 31-05-2011 fixed bug in board update position? (phantom attackers!)
45 // 06-06-2011 incorporated printdestinations into computerturn saving wedges of code
46 // 08-06-2011 fixed bug in computer targetselection (cantake wasn't resetting to 0)
47 /* 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