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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26