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

  ViewVC Help
Powered by ViewVC 1.1.26