/[projet1]/users/barnsey123/HNEFATAFL/main.c
Defence Force logotype

Contents of /users/barnsey123/HNEFATAFL/main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 779 - (show annotations)
Wed Jan 11 18:08:03 2012 UTC (8 years ago) by barnsey123
File MIME type: text/plain
File size: 68942 byte(s)
first stab at a title screen
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 // 17-06-2011-11-07-2011 various tomfoolery to reduce memory footprint
53 // 12-07-2011 New variables to check for pieces NSEW of King
54 // 31-08-2011 prevent attackers occupying corner squares
55 // 12-10-2011 using 18x18 squares (unfinished...needs LOTS of work!!!)
56 // 17-10-2011 using new routine to draw tiles
57 // 18-10-2011 tidied up graphic routines (reduced size of code/executable)
58 // 20-10-2011 Added expodetile function (playes animation to "kill" a piece) plus pause function (reduces executable size)
59 // 20-10-2011 made graphics drawing more efficient (saved 300bytes)
60 // 21-10-2011 added STEELDIAMOND function (create higher target values in a diamond shape around king)
61 // 24-10-2011 Fixed bug with crashes at south-east corner of board (counter must be SIGNED)
62 // 24-10-2011 Fixed a bug regarding counter - much stronger AI!
63 // 24-10-2011 Play again? (needs work)
64 // 27-10-2011 Fixing the "enemy one space away ENEMY UDATE issue" - set value=50
65 // 31-10-2011 Added the COMPUTER array (where the computers's pieces can get to)
66 // 02-11-2011 Added Select gamestyle (human vs computer or human vs human selection)
67 // 02-11-2011 GONZO! the -50 behaviour is interesting - still crashing though...
68 // 09-11-2011 LookBackInAnger routine (attackers to check behind their original position)
69 // 10-11-2011 Now checks to see if a piece can be taken if it stays where it is (needs some finessing)
70 // 14-11-2011 Improved the above routine
71 // 16-11-2011 compress routines more (free up some memory)
72 // 06-12-2011 fixed a couple of bugs (I think)
73 // 08-12-2011 got rid of baseplayers as unnecessary (it's just a copy of tiles)
74 // 08-12-2011 shrunk code still further - added calctakeweight routine
75 // 08-12-2011 shrunk code again (33524) - added enemyzero routine and simplified surrounded routines
76 // 08-12-2011 found/fixed bug in the previous surrounded routine during simplification
77 // 10-12-2011 subpacmanx(made smaller), added checkroute function
78 // 10-12-2011 enemyzero made more effective (and smaller) by zeroing entire enemy array
79 // 12-12-2011 lots of changes (seperated out "updatetarget" from "printarrowsorblanks"
80 // 14-12-2011 Test of replacing PACMAN with something else (see updatetarget)
81 // 20-12-2011 Oh Christ!
82 // 21-12-2011 Added nifty, don't take a defender if on same plane as king routine...
83 // 22-12-2011 above, wont take if LAST defender on plane (added inckingattacker etc)
84 // 22-12-2011 kingsouth/defsouth replaced by arrays (kingattacker, kingdefender)
85 // 23-12-2011 reduced code, fixed a couple of bugs
86 // 04-01-2012 introduced calcantake function (also beefed up the hightarget routines "findpiecens/findpieceew")
87 // 05-01-2012 reduced memory requirements - using unsigned char where possible (34457)
88 // 05-01-2012 removed all local variables (replaced with globals) (34338)
89 // 05-01-2012 got rid of LookBackInAnger (plus some other changes) (33670)
90 // 06-01-2012 fixed bug in subcanbetaken2
91 // 07-01-2012 found out why some pieces commit suicide but the fix don't work...perhaps other factors are at work
92 // 09-01-2012 HUZZAH! Fixed the suicide issue.
93 /* from subcanbetaken2...
94 NEW: if ((players[takenc][takend]==0)||(enemy[takenc][takend]>ENEMYWEIGHT))
95 OLD: if (players[takenc][takend]==0)
96 in the OLD condition, if the piece was only one space away, players would always be 1
97 */
98 // 09-01-2012 BOOOOO!!! Above fix causing another issue...will be a bastard to fix.
99 // 10-01-2012 HUZZAH - above issue resolved (not such a bastard after all but took 24 hrs thinking! 34865)
100 // 11-01-2012 TITLE SCREEN (36743)
101 /* TO DO LIST
102 *** Continue with endgame function to return a value determining victory conditions etc
103 *** routine to detect if all attackers have been captured
104 *** routine to detect stalemate (a side cannot move)
105 */
106 #include <lib.h>
107 //#include <math.h>
108 //#define CHAR_BIT 8
109 #define NORTH 0
110 #define SOUTH 1
111 #define EAST 2
112 #define WEST 3
113 #define ENEMYWEIGHT 37
114 extern unsigned char PictureTiles[]; // standard graphics for pieces and backgrounds
115 extern unsigned char ExplodeTiles[]; // extra graphics to "explode" a piece (animation)
116 extern unsigned char BorderTiles[]; // border on title screens/version screens etc
117 extern unsigned char TitleTiles[]; // Defence-Force presents...
118 /******************* Function Declarations ************************/
119 void drawcursor(); // draws cursor
120 void inverse(); // inverse the color in the square
121 void drawtiles(); // draws all tiles at board x,y boxsize z (uses draw*tile functions)
122 void drawboard(); // kicks off drawgrid/drawtiles
123 void playerturn(); // takes user input to move cursor
124 void drawplayers(); // draw playing pieces
125 void flashscreen(); // flashes screen in selected color for a second or so
126 void canpiecemove(); // can a selected piece move? 0=no, 1=yes
127 void printdestinations(); // print arrows on tiles where a piece can move
128 void printpossiblemoves(); // Print possible moves
129 void printarrowsorblanks(); // PRINT ARROWS/BLANK EM OUT
130 void movecursor2(); // move cursor routine
131 void movepiece(); // move a piece
132 char cantakepiece(); // returns 0=no, 1 yes
133 void takepiece(); // takes specified piece
134 void blinkcursor(); // blinks the cursor to attract attention
135 void checkend(); // check for end game conditions
136 void computerturn(); // AI for computer
137 void pacman(); // update target positions around king (need to develop further)
138 void targetselect(); // choose a target square
139 //void findpiece();
140 void findpiecens(); // findpiece north-south
141 void findpieceew(); // findpiece east-west
142 void canbetaken(); // can I be taken after moving here? returns value (take) 0=no 1=yes
143 void subarrows(); // subroutine of arrows or blanks
144 void subarrows2(); // subroutine of arrows or blanks (updates ENEMY with direction of enemy)
145 void subpacman(); // subroutine of pacman
146 void subpacman2(); // subroutine of pacman
147 void subpacman3(); // sub of subpacman
148 void subpacman4(); // sub of subpacman2
149 void subpacmanx(); // grand sub of pacman
150 //void subcanbetaken(); // sub of canbetaken
151 void inccantake(); // increments cantake
152 void incroute(); // incs route
153 void decroute(); // decs route
154 void drawtile(); // draw a tile (subroutine of drawtiles)
155 void drawpiece(); // draws piece
156 void drawarrow(); // draws "arrow"
157 void printmessage(); // prints message to screen
158 void printturnprompt(); // prints "your turn" message
159 void surroundcount(); // counts the number of attackers surrounding KING (or edges, or central square)
160 void incsurround(); // increment "surrounded" variable
161 void explodetile(); // explodes a piece (plays an animation)
162 void pause(); // wait a certain period of time (pausetime)
163 void tileloop(); // subdir of explodetile and drawtile
164 void surroundpoints(); // increment points around king depending on "surrounded" figure
165 void incpoints(); // increment points variable
166 void decpoints(); // decrement points variable
167 void setpoints(); // set points to default value
168 void zerocounter(); // set counter=0
169 void inccounter(); // inc counter
170 //void deccounter(); // decrement counter
171 void doublepoints(); // doubles points
172 //void LookBackInAnger(); // runs subcanbetaken if the piece "behind" an attacker is defender/king and prospective target adjacent to defender/king
173 //void subLookBackInAnger(); // runs the various "lookbackinanger" checks
174 void inctarget(); // inc target[xns][xew]
175 void subcanbetaken2(); // attempt to reduce memory footprint
176 void surroundcheck(); // inc surrounded under various conditions
177 void calctakeweight(); // calculate the weight of "takeweight"
178 void enemyzero(); // set enemy value to zero when surrounded=3
179 char checkroute(); // sets counter to be number of pieces on a given route
180 void updatetarget(); // updates target array
181 void cantakeadjust(); // decrement cantake if taken piece is on same plane as king
182 void inckingattacker(); // increments count of attackers round king
183 void inckingdefender(); // increments count of defenders round king
184 void incdefatt(); // increments count of attacker/defenders round king (calls incking...)
185 void cursormodezero(); // set cursor mode to 1 if 0
186 void cursormodevalid(); // sets modevalid to 1
187 void calccantake(); // can take be made (how many)
188 void printborder(); // print the border screen (used in titles/menus etc)
189 void printtitles(); // print the border screen and titles
190 /****************** GLOBAL VARIABLES *******************************/
191 /* Populate array with tile types
192 Tile types:
193 0=blank
194 1=attacker square
195 2=defender square
196 3=king square
197 */
198 extern const unsigned char tiles[11][11]; // tile description on board
199 extern unsigned char target[11][11]; // uninitialized variable (will calc on fly) - target values of square
200 extern const unsigned char border[9][9]; // border (of title screens/menus etc)
201 /* populate array with places of players
202 Players:
203 0=vacant
204 1=attacker resident
205 2=defender resident
206 3=king resident
207 4=corner square // added 21/04/2011
208 */
209 //extern char baseplayers[11][11]; // BASEPLAYERS - the starting board positions. PLAYERS is the working COPY of BASEPLAYERS
210
211 // ARRAY ENEMY unititialized variable (will calc on fly) - can enemy reach a square?
212 // values:
213 // +1 Can be reached from NORTH
214 // +5 can be reached from SOUTH
215 // +10 can be reached from EAST
216 // +20 can be reached from WEST
217 extern char enemy[11][11]; // where the defenders can get to
218 extern char computer[11][11]; // where the attackers can get to
219 char players[11][11]; // to be the working copy of baseplayers
220 const unsigned char boardx=12; // starting x co-ord of board (for cursor drawing purposes)
221 const unsigned char boardy=0; // starting y co-ord of board (for cursor drawing purposes)
222 const char boxsize=18; // set boxsize (for cursor drawing purposes)
223 unsigned char playertype,piecetype; // player 1=attacker, 2=defender
224 unsigned char ns,ew; // default north/south position of central square (0-10)
225 unsigned char cx,cy; // cursor x screen position (pixels across)
226 unsigned char fb=1; // foreground/background 0=background, 1=foreground, 2=opposite, 3=nothing
227 unsigned char inversex; // x position of square to be inversed (to highlight a selected piece)
228 unsigned char inversey; // y position of square to be inversed (to highlight a selected piece)
229 char mkey; // code of key pressed (plus loops)
230 unsigned char cursormode; // cursor movement mode 0=freeform 1=restricted
231 unsigned char ons,oew; // original north/south board pos
232 unsigned char ocx,ocy; // original xpos of piece
233 unsigned char orientation; // for arrows - 0=north, 1=south 2=east 3=west
234 unsigned char tiletype; // type of tile under inspection (used in arrows)
235 unsigned char tpns,tpew; // north-south board location of taken piece (also used for 3) NB:no idea 20/10/2011
236 unsigned char flashcolor; // color of ink to flash in
237 unsigned char flashback; // color of ink to return to
238 char game; // *** MUST NOT BE UNSIGNED ***<=0 means endgame (see checkend for values), 1=GAMEON
239 unsigned char gamestyle; // 0=human vs human; 1=human king vs computer; ** NO!!! 2=human vs computer king**; 3=undefined
240 unsigned char kingns,kingew; // kings position North-South
241 unsigned char kingattacker[4]; // number of attackers in all four directions from king
242 unsigned char kingdefender[4]; // number of defenders in all four directsions from king
243 unsigned char surrounded; // status of king "surrounded" status //
244 unsigned char ctns=0; // Computer Turn north-south board position
245 unsigned char ctew=0; // Computer Turn east-west board position
246 char playertext[]="Attacker";
247 char turntext[]=" Turn:Use cursor keys.\nX:Select Piece P:Possible Moves";
248 char message[]="*";
249 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
250 //char xloop=0; // general purpose loop variable
251 char xns=0; // copy of ns (arrows or blanks, and subarrows)
252 char xew=0; // copy of ew (arrows or blanks, and subarrows)
253 char arrow=1; // used in arrowsorblanks(and subarrows)
254 char flag=0;
255 char cantake; // can I take? (for computer turn)
256 char route;
257 unsigned char row,col; // used in tile drawing routines and array navigation ( a row in 11x11 grid)
258 //unsigned char col; // used in tile drawing routines and array navigation ( a column in 11x11 grid)
259 unsigned char tiletodraw; // used in tile drawing routines 0-11 (as at 18-10-2011)
260 int pausetime; // amount of time to wait
261 unsigned char* ptr_draw; // ptr to board starting position (e.g. 0xa002)
262 unsigned char* ptr_graph; // pointer to byte values of loaded picture
263 unsigned char points; // points around king
264 char counter; // general purpose counter (*** DO NOT set to UNSIGNED *** NB 24/10/2011)
265 char uncounter; // *** MUST BE SIGNED *** general purpose counter (can be negative)
266 //unsigned char lookcol,lookrow; // used in lookbackinanger
267 unsigned char origorient; // original orientation of a piece under test (which way he is heading)
268 unsigned char takerow,takecol; // can I be taken if I stop here?
269 unsigned char paclevel1,paclevel2; // used in pacman/subpacmanx either ns/ew
270 unsigned char surns,surew; // count of attackers surrounding king n/s used in surroundcount()
271 unsigned char takena,takenb,takenc,takend,takene; // used in canbetaken routines
272 unsigned char ezns1,ezew1; // used in surroundcount/enemyzero to reset enemy[][] to zero if surrounded=3
273 // WEIGHTS
274 //unsigned char enemyweight=37; // >36. weight of "enemy could get here but piece occupied by attacker"
275 //char defaulttakeweight=5; // default weight assigned to a TAKE
276 unsigned char takeweight; // weight assigned to a TAKE (calculated in "calctakeweight")
277 //unsigned char cbtweight=4; // weight to be applied to escape position if can be taken
278 unsigned char pacpointsx,pacpointsy,pacpointsa,pacpointsb; // used to calculate points in subpacmanx
279 unsigned char pcheckns1,pcheckns2; // used in taking pieces and checking for takes
280 unsigned char pcheckew1,pcheckew2; // used in taking pieces and checking for takes
281 unsigned char startrow,startcol; // used in checkroute (returns no of pieces on a given path)
282 unsigned char destrow,destcol; // used in checkroute (returns no of pieces on a given path)
283 unsigned char canmovecursor; // controls wether screen cursor can be moved or not
284 unsigned char hightarget; // contains highest value target
285 unsigned char targetns,targetew; // used to calc takes
286 unsigned char x,y,z,a,b; // general purpose variables
287 //char cannotbetaken,icanbetaken; // used in canbetaken routine
288 /* below used for cursor move routine */
289 unsigned char multiple; // concerning central square (how much to multiply the coords to SKIP the square
290 unsigned char xptrns; // copy of NS
291 unsigned char xptrew; // copy of EW
292 unsigned char skipns; // skip to north/south
293 unsigned char skipew; // skip to east/west
294 unsigned char modeonevalid; // is OK for mode 1? 0=no, 1=yes
295 /* above variables used in cursor move routine */
296 unsigned char gamekey=89; // controls "play again?"
297 unsigned char gameinput=0; // 0=undefined 1=play against computer, 2=human vs human
298 unsigned int startpos; // USED when drawing tiles (position in tile file from which to draw)
299 unsigned char take;
300 unsigned char p1; // piece type comparison (lower) - used for determining takes - default=attacker
301 unsigned char p2; // piece type comparison (upper) - used for determining takes - default=attacker
302 /* playerturn variables */
303 unsigned char xkey; // code of key pressed
304 unsigned char canselect; // 0=no, 1=yes (is the piece selectable?)
305 char cursormovetype; // -1=no, 0=yes (n,s,e,w) 1=(north/south only), 2=(east/west only)
306 unsigned char turn; // determines end of player turn 1=playerturn, 0=end of playerturn
307 unsigned char compass[4]; // used in cantake (if compass[NORTH]=1 then means canbetaken if i move here from NORTH
308 //unsigned char funca,funcb,funcc,funcd,funce,funcf; // general purpose variables used in functions
309 /* end of playerturn variables */
310 unsigned char xplayers;
311 unsigned char tileheight; // height of tile in pixles
312 unsigned char tilewidth; // width of tile in 6 pixel chunks
313 /****************** MAIN PROGRAM ***********************************/
314 main()
315 {
316 //gamekey=89; // controls "play again?"
317 //gameinput=0; // 0=undefined 1=play against computer, 2=human vs human
318 paper(0);
319 ink(5); // color of TEXT in text box at bottom
320 hires();
321 printtitles();
322 ink(6); // boardcolor 0=black, 1=red, 2=green, 3=yellow, 4=blue, 5=magenta, 6=cyan,7=white
323 while (gamekey==89)
324 {
325 playertype=0; // set to 0 as inited later
326 drawboard(); // draw the board
327 printf("%c",19); // turn off screen output (means cursor movement doesn't affect oric cursor
328 while (gamestyle==3)
329 {
330 strcpy(message,"Select Game Type:\nEnter number of humans:");
331 printmessage();
332 gameinput=getchar();
333 if ( gameinput == 49 ) gamestyle=1; // 1=human vs computer (as DEFENDERS)
334 if ( gameinput == 50 ) gamestyle=0; // 0=human vs human
335 if ( gamestyle == 3 ) ping();
336 }
337 while (game>0)
338 {
339 ns=5; // default north/south position of central square
340 ew=5; // default east/west position of central square
341 cx=1+boardx+(boxsize*ew); // cursor x screen position
342 cy=1+boardy+(boxsize*ns); // cursor y screen position
343 playertype++; // playertype inited as 0 so ++ will make it 1 at start of game
344 if ( playertype == 3 ) { playertype = 1; } // was defender, set to attacker player
345 //if (( gamestyle == 0 )||((gamestyle==1)&&(playertype==2))||((gamestyle==2)&&(playertype==1)))
346 if (( gamestyle == 0 )||((gamestyle==1)&&(playertype==2)))
347 {
348 playerturn(); // player input
349 }
350 else
351 {
352 computerturn(); // computer has a go...
353 }
354 checkend(); // check for end of game conditions
355 }
356 if ( game == 0 )
357 {
358 strcpy(message,"KING ESCAPED! King Wins!\nPlay Again Y/N?");
359 printmessage();
360 }
361 else
362 {
363 strcpy(message,"KING CAPTURED! Attacker Wins!\nPlay Again Y/N?");
364 printmessage();
365 }
366 gamekey=getchar();
367 if (gamekey==89) // if "Y"
368 {
369 printf("%c",19); // turn output ON
370 }
371 }
372 }
373 /********************* FUNCTION DEFINITIONS ************************/
374 void computerturn()
375 {
376 //unsigned int xrand=srandom(deek(630)); // seed random number generator
377 //if ( playertype == 1 ) { strcpy(playertext,"ATTACKER");}else{ strcpy(playertext,"KING");}
378 strcpy(message,"ORIC IS THINKING..");
379 printmessage();
380 //printf("\n\n\nORIC IS THINKING..");
381 // 1. initialize target, enemy and computer array to zeroes
382 ClearArrays(); // clear target, enemy and computer arrays
383 // 2. Loop through players array searching for enemy pieces - calculating where they can go
384 //fb=5;
385 //pacman1:
386 for (fb=4;fb<8;fb++)
387 {
388 for (ctns=0;ctns<11;ctns++)
389 {
390 for (ctew=0;ctew<11;ctew++)
391 {
392 ns=ctns;ew=ctew;
393 if ( fb==4 ) // fb=4 means: don't print destinations, just update ENEMY
394 {
395 if (( players[ctns][ctew]==2 )||(players[ctns][ctew]==3)) // if enemy found
396 {
397 printdestinations(); // update enemy array of possible locations
398 }
399 }
400 if ((fb==5)||(fb==7)) // fb=5 (+COMPUTER array):fb=7 (can I be taken)
401 {
402 if ( players[ctns][ctew]==1) // if attacker found
403 {
404 printdestinations();
405 }
406 }
407 if ( fb==6)
408 {
409 if ( computer[ctns][ctew] ) // if computer piece can get here update target values
410 {
411 updatetarget(); // update target value
412 }
413 }
414 }
415 }
416 }
417 // 3. Increment target positions around King (PACMAN)
418 pacman();
419 //if ( playertype == 1 ) {pacman();}
420 // other routines to go here to update the target array
421 // 4,5,6,7..N etc
422 //
423 targetselect(); // Choose the highest value target
424 ns=targetns;ew=targetew; // make computer move compatible with human move selection
425 movepiece(); // make the move
426 }
427 /**************************************************/
428 /*
429 void findpiece()
430 {
431 if ( foundpiece == 0 )
432 {
433 if (players[funca][funcb]==1)
434 {
435 calccantake();
436 if (( cantake==0 )&&(surrounded<3)) canbetaken(); // if cannot take can I be taken?
437 if ((funcc==funcd)&&(funce!=funcd)&&(kingattacker[origorient]==1)) compass[origorient]=1; // don't move from plane of king
438 if (compass[origorient]==0)
439 {
440 foundpiece=1;
441 funcf=funcc;
442 }
443 }
444 if ((players[funca][funcb]==2)||(players[funca][funcb]==3)) {foundpiece=9;}
445 }
446 }
447 */
448 /*********************************************/
449 void findpiecens() // find piece NORTH-SOUTH
450 {
451 if ( foundpiece == 0 )
452 {
453 if (players[mkey][oew]==1)
454 {
455 ns=targetns;ew=targetew;orientation=origorient;calccantake();
456 if (( cantake==0 )&&(surrounded<3)) canbetaken(); // if cannot take can I be taken?
457 //if ((mkey==kingns)&&(targetns!=kingns)&&(kingattacker[origorient]<3)) compass[origorient]=1; // don't move from plane of king if less than 3 attackers
458 if (compass[origorient]==0)
459 {
460 foundpiece=1;
461 ons=mkey;
462 }
463 }
464 if ((players[mkey][oew]==2)||(players[mkey][oew]==3)) {foundpiece=9;}
465 }
466 }
467 /**************************************************/
468 void findpieceew() // find piece EAST-WEST
469 {
470 if ( foundpiece == 0 )
471 {
472 if (players[ons][mkey]==1)
473 {
474 ns=targetns;ew=targetew;orientation=origorient;calccantake();
475 if (( cantake==0 )&&(surrounded<3)) canbetaken(); // if cannot take can I be taken?
476 //if ((mkey==kingew)&&(targetew!=kingew)&&(kingattacker[origorient]<3)) compass[origorient]=1; // don't move from plane of king if less than 3 attackers
477 if (compass[origorient]==0)
478 {
479 foundpiece=1;
480 oew=mkey;
481 }
482 }
483
484 if ((players[ons][mkey]==2)||(players[ons][mkey]==3)) {foundpiece=9;}
485 }
486 }
487 /*********************************************************/
488 // TARGETSELECT - find the highest scoring TARGET
489 void targetselect()
490 {
491 //unsigned char xloop;
492 NEWTARGET:
493 hightarget=0; // contains highest value target
494 for (ctns=0;ctns<11;ctns++) // find the highest value for target
495 {
496 for (ctew=0;ctew<11;ctew++)
497 {
498 if ( target[ctns][ctew] > hightarget )
499 {
500 hightarget=target[ctns][ctew]; // make hightarget the highest value
501 targetns=ctns;
502 targetew=ctew;
503 ons=ctns; // target is accessible so make ons/oew the default piece position to move
504 oew=ctew; // the ACTUAL piece to move determined below (one of ons or oew will remain same)
505 ns=ctns;
506 ew=ctew;
507 }
508 }
509 }
510 // having found target we need to select a piece to move
511 compass[NORTH]=0;compass[SOUTH]=0;compass[EAST]=0;compass[WEST]=0; // initialize compass array
512 fb=9;foundpiece=0; // set findpiece to "piece not found"
513 origorient=NORTH;
514 for (mkey=ons-1; mkey>-1; mkey--){findpiecens();}
515 if ( foundpiece != 1 ) { foundpiece=0;target[targetns][targetew]=hightarget; }
516 origorient=SOUTH;
517 for (mkey=ons+1; mkey<11; mkey++){findpiecens();}
518 if ( foundpiece != 1 ) { foundpiece=0;target[targetns][targetew]=hightarget; }
519 origorient=EAST;
520 for (mkey=oew+1; mkey<11; mkey++){findpieceew();}
521 if ( foundpiece != 1 ) { foundpiece=0;target[targetns][targetew]=hightarget; }
522 origorient=WEST;
523 for (mkey=oew-1; mkey>-1; mkey--){findpieceew();}
524 if ( foundpiece != 1 ) {target[targetns][targetew]=1;goto NEWTARGET;} // if can still be taken select new target
525
526 cx=1+boardx+(boxsize*oew); // piece x screen position
527 cy=1+boardy+(boxsize*ons); // piece y screen position
528 blinkcursor(); // draw cursor in foreground color at piece to move position cx,cy
529 fb=0;drawcursor(); // blank cursor
530 cx=1+boardx+(boxsize*targetew); // target x screen position
531 cy=1+boardy+(boxsize*targetns); // target y screen position
532 blinkcursor(); // draw cursor in foreground color at target position cx,cy
533 ocx=1+boardx+(boxsize*oew); // piece to move x screen position
534 ocy=1+boardy+(boxsize*ons); // piece to move y screen position
535 //printf("%cNS=%d,EW=%d,ONS=%d,OEW=%d%c",19,ns,ew,ons,oew,19);
536 //loop=getchar();
537 }
538 /************************************************/
539 void subpacmanx() // subroutine of pacman
540 {
541 z=kingattacker[orientation]+kingdefender[orientation]; // count of pieces on route to edge (attackers&defenders)
542 a=pacpointsx+pacpointsy; // count of pieces to two corners
543 b=pacpointsa+pacpointsb; // count of pieces to squares adjacent to corners
544 setpoints();
545 //x=paccount1*3; // x=number of attackers * 3
546 //y=x+paccount2; // y=(number of attackers *3)+(defenders * 1)
547 //if ((points-y) < 0) {points=1;}else{points-=y;} // subtract two points for every attacker and 1 point for every defender
548 if ( z==0 ) // no pieces in the direction from king
549 {
550 doublepoints(); // double points if blank route to edge
551 if (pacpointsx==0){ doublepoints();} // double if route to one corner
552 if (pacpointsy==0){ doublepoints();} // double if route to two corners
553 }
554 if ( z<2 )
555 {
556 if (pacpointsa==0){ doublepoints();} // double if route to one square adjacent to corner
557 if (pacpointsb==0){ doublepoints();} // double if route to two squares adjacent to corners
558 }
559 if ((paclevel2<3)||(paclevel2>7)) { incpoints(); } // if close to an edge in orientation
560 if ((paclevel1<2)||(paclevel2>8)) { incpoints(); } // if "left or rightside" in a "winning position"
561 if ((orientation == NORTH) || (orientation == WEST)) // if north or west
562 {
563 uncounter=paclevel2-1;
564 if ( paclevel2<5 ) { incpoints();} // add weight to north or west if king in north or west side of board
565 }
566 else // if south east
567 {
568 uncounter=paclevel2+1;
569 if ( paclevel2>5 ) { incpoints();} // add weight to south or east if king in south or east side of board
570 }
571 if ( kingattacker[orientation]==0 ) { incpoints();} // inc points if no attackers on path
572 surroundpoints();
573 // default north/south
574 x=uncounter;
575 y=paclevel1;
576 if ( orientation>SOUTH) // if east/west
577 {
578 x=paclevel1;
579 y=uncounter;
580 }
581 flag=1;
582 while (((players[x][y]==0)||(tiles[x][y]==3))&&((uncounter>-1)&&(uncounter<11)))
583 {
584 if (computer[x][y]) // if accessible by attacker
585 { // only update target if cannot be taken OR king has clear route to corner
586 if ((a==0)||(pacpointsx==0)||(pacpointsy==0)||(pacpointsa==0)||(pacpointsb==0))
587 {
588 target[x][y]+=points;
589 flag=0;
590 }
591 else
592 {
593 if (target[x][y]>1){target[x][y]=points;flag=0;}
594 }
595 }
596 else
597 {
598 if ((flag)&&(players[x][y]==0)) // if blank)
599 {
600 if (orientation<EAST) { subpacman();}else{subpacman2();} // if north/south else east/west
601 }
602 }
603 decpoints();
604 //if (z){decpoints();} // only decrement points if route to edge is blocked
605 if ( (orientation==NORTH) || (orientation==WEST) ) {uncounter--;}else{uncounter++;}
606 if ( orientation <EAST ) {x=uncounter;}else{y=uncounter;}
607 }
608 }
609 /************************************************/
610 void pacman() // PACMAN ( increment target positions around king )
611 {
612 //int xrand=random()/1000; // random number between 0-32
613 surroundcount(); // updates "surrounded"
614 // NORTH
615 orientation=NORTH;
616 paclevel1=kingew;
617 paclevel2=kingns;
618 startrow=0;startcol=0;destrow=0;destcol=kingew;
619 pacpointsx=checkroute();
620 startcol=kingew;destcol=10;
621 pacpointsy=checkroute();
622 startrow=1;startcol=0;destrow=1;destcol=kingew;
623 pacpointsa=checkroute();
624 startcol=kingew;destcol=10;
625 pacpointsb=checkroute();
626 subpacmanx();
627
628 //SOUTH
629 orientation=SOUTH;
630 startrow=10;startcol=0;destrow=10;destcol=kingew;
631 pacpointsx=checkroute();
632 startcol=kingew;destcol=10;
633 pacpointsy=checkroute();
634 startrow=9;startcol=0;destrow=9;destcol=kingew;
635 pacpointsa=checkroute();
636 startcol=kingew;destcol=10;
637 pacpointsb=checkroute();
638 subpacmanx();
639
640 // EAST
641 orientation=EAST;
642 paclevel1=kingns;
643 paclevel2=kingew;
644 startrow=0;startcol=10;destrow=kingns;destcol=10;
645 pacpointsx=checkroute();
646 startrow=kingns;destrow=10;
647 pacpointsy=checkroute();
648 startrow=0;startcol=9;destrow=kingns;destcol=9;
649 pacpointsa=checkroute();
650 startrow=kingns;destrow=10;
651 pacpointsb=checkroute();
652 subpacmanx();
653
654 // WEST
655 orientation=WEST;
656 startrow=0;startcol=0;destrow=kingns;destcol=0;
657 pacpointsx=checkroute();
658 startrow=kingns;destrow=10;
659 pacpointsy=checkroute();
660 startrow=0;startcol=1;destrow=kingns;destcol=1;
661 pacpointsa=checkroute();
662 startrow=kingns;destrow=10;
663 pacpointsb=checkroute();
664 subpacmanx();
665 }
666
667 /************************************************/
668 void subpacman() // increase target positions that LEAD to a king target
669 {
670 flag=0;
671 for (mkey=kingew-1;mkey>-1;mkey--){subpacman3();}
672 flag=0;
673 for (mkey=kingew+1;mkey<11;mkey++){subpacman3();}
674 }
675 /************************************************/
676 void subpacman2()
677 {
678 flag=0;
679 for (mkey=kingns-1;mkey>-1;mkey--){subpacman4();}
680 flag=0;
681 for (mkey=kingns+1;mkey<11;mkey++){subpacman4();}
682 }
683 /*****************************/
684 void subpacman3()
685 {
686 if ( players[counter][mkey]==0 ) { flag=1;}
687 if ((flag==0)&&(target[counter][mkey]>1 )) { target[counter][mkey]++;}
688 }
689 void subpacman4()
690 {
691 if ( players[mkey][counter]==0 ) { flag=1;}
692 if ((flag==0)&&(target[mkey][counter]>1 )) { target[mkey][counter]++;}
693 }
694 /************************************************/
695 void checkend() // check for endgame conditions
696 {
697 /* Victory Conditions
698 game=0 King escapes. // DONE
699 game=-1 King Surrounded in open play or by central square // DONE
700 game=-2 King surrounded by attackers and corner squares // DONE
701 game=-3 King surrounded by attackers and edge of board // DONE
702 game=-4 defenders cannot move (stalemate) // TBD
703 game=-5 attackers cannot move (stalemate) // TBD
704 game=-6 all attackers eliminated // TBD
705 */
706 //char kingfound=0; // 0=king not found 1=king found
707 // ns and ew contains new board co-ords of last piece moved
708 if (( players[ns][ew] == 3 ) && ( tiles[ns][ew] == 4 )) { game=0; } // king has escaped
709 // check to see if king is surrounded by attackers (first find king)
710 if ( players[ns][ew] == 1 ) // if attacker was last to move
711 {
712 if (((ns>0 )&&(players[ns-1][ew]==3 ))||((ns<10 )&&(players[ns+1][ew]==3 ))||((ew<10 )&&(players[ns][ew+1]==3 ))||((ew>0 )&&(players[ns][ew-1]==3 )))
713 {
714 surroundcount();
715 }
716 if ( surrounded == 4 ) { game=-1;} // king is surrounded on all sides by attackers or king squares
717 }
718 }
719 /************************************************/
720 void cursormodezero()
721 {
722 if ( cursormode == 0 ) { canmovecursor=1;}
723 }
724 /***********************/
725 void movecursor2() // routine to move the cursor
726 {
727 /*
728 cursormode = [0 or 1] 0=unrestricted (move anywhere), 1= restricted (only move to possible destinations)
729 */
730 multiple=1; // concerning central square (how much to multiply the coords to SKIP the square
731 xptrns=ns; // copy of NS
732 xptrew=ew; // copy of EW
733 skipns=ns; // skip to north/south
734 skipew=ew; // skip to east/west
735 modeonevalid=0; // is OK for mode 1? 0=no, 1=yes
736 canmovecursor=0;
737 piecetype=players[ons][oew]; // determines the piece type that is currently selected (used in mode 1)
738 if ((mkey == 8 )&&( ew)) // west
739 {
740 cursormodezero();
741 xptrew--; // decrement copyew
742 skipew-=2;
743 modeonevalid=1;
744 }
745 if ((mkey == 9 )&&( ew<10)) // east
746 {
747 cursormodezero();
748 xptrew++;
749 skipew+=2;
750 modeonevalid=1;
751 }
752 if ((mkey == 10)&&( ns<10)) // south
753 {
754 cursormodezero();
755 xptrns++;
756 skipns+=2;
757 modeonevalid=1;
758 }
759 if ((mkey == 11)&&( ns)) // north
760 {
761 cursormodezero();
762 xptrns--;
763 skipns-=2;
764 modeonevalid=1;
765 }
766 if (( cursormode ) && ( modeonevalid )) // if not at edge of board
767 {
768 if ( players[xptrns][xptrew] == 0 ) {canmovecursor=1;} // ok if square vacant
769 if ( tiles[xptrns][xptrew] == 4 ) {canmovecursor=0;} // !ok if corner
770 if (( piecetype == 3 )&&( tiles[xptrns][xptrew] > 2 )) {canmovecursor=1;} // ok if KING and corner/central
771 if (( xptrns == ons )&&( xptrew == oew )) {canmovecursor=1;} // ok if back to self
772 // need to check that for non-king pieces wether the central square is vacant and can be skipped
773 if (( piecetype < 3 )&&( tiles[xptrns][xptrew] == 3)&&(players[xptrns][xptrew] == 0 )) // tiles=3(central), tiles=4(corner)
774 {
775 if ( players[skipns][skipew] > 0 ) {canmovecursor=0;} // cannot skip if otherside occupied
776 if ((( skipns == ons )&&( skipew == oew ))||( players[skipns][skipew]==0)) // ok to skip to self
777 {
778 canmovecursor=1;
779 multiple=2;
780 }
781 }
782 }
783 if (canmovecursor)
784 {
785 fb=0;
786 drawcursor(); // print blank cursor (effect=remove dots)
787 if ( mkey == 8 ) {cx-=(boxsize*multiple);} // left
788 if ( mkey == 9 ) {cx+=(boxsize*multiple);} // right
789 if ( mkey == 10 ){cy+=(boxsize*multiple);} // down
790 if ( mkey == 11 ){cy-=(boxsize*multiple);} // up
791 fb=1;
792 drawcursor(); // print dotted cursor
793 if ( mkey == 8 ) {ew-=multiple;} // left
794 if ( mkey == 9 ) {ew+=multiple;} // right
795 if ( mkey == 10 ){ns+=multiple;} // down
796 if ( mkey == 11 ){ns-=multiple;} // up
797 }
798 else
799 {
800 flashcolor=1;
801 if ( cursormode == 0 ) {flashback=6;flashscreen();} // flash red: return to cyan:6
802 if ( cursormode == 1 ) {flashback=2;flashscreen();} // flash red: return to green:2)
803 }
804 }
805 /************************************************/
806 void inverse()
807 {
808 /* Draw an inversed colr box to highlight selected box
809 ix=screen x position
810 iy=screen y position
811 */
812 char iz=boxsize-3;
813 for (counter=0;counter<iz;inccounter())
814 {
815 curset(inversex,inversey,3);
816 draw(iz,0,2); // draw inverse line
817 inversey++;
818 }
819 }
820 /************************************************/
821 void printpossiblemoves()
822 {
823 /* kicks off functions that print appropriate arrows at all possible destinations and blanks
824 them out afterwards*/
825 char k; // key entered
826 fb=1;
827 printdestinations(); // print arrows on all destinations
828 strcpy(message,"* press any key to proceed *");
829 printmessage();
830 k=getchar();
831 fb=0;
832 printdestinations(); // blank out arrows on all destinations
833 }
834 /************************************************/
835 void printarrowsorblanks() // used in printdestinations
836 {
837 //char xplayers; // player type at square under test
838 //zns=ns; // another copy of ns (for computer turn)
839 //zew=ew; // another copy of ew (for computer turn)
840 origorient=orientation; // original orientation (for computer turn)
841 //char cantake=0; // can I take? (for computer turn)
842 //unsigned char subloop=0;
843 //cantake=0;
844 xns=ns; // copy of ns
845 xew=ew; // copy of ew
846 arrow=1;
847 //arrowsx=cx+1;
848 //arrowsy=cy+1;
849 // orientation 0,1,2,3 = N, S, E, W
850 takerow=ns;takecol=ew; // will set below to be the opposite of the orientation
851 if ( orientation == NORTH ) { xplayers=players[xns-1][xew];takerow=xns+1;} // check north
852 if ( orientation == SOUTH ) { xplayers=players[xns+1][xew];takerow=xns-1;} // check south
853 if ( orientation == EAST ) { xplayers=players[xns][xew+1];takecol=xew-1;} // check east
854 if ( orientation == WEST ) { xplayers=players[xns][xew-1];takecol=xew+1;} // check west
855 while (( arrow == 1 )&&(fb!=7)) // keep checking until cannot move
856 {
857 if (( orientation == NORTH ) && ( xns )) // check north
858 {
859 xns--; // decrement provisional north-south player position
860 subarrows();
861 }
862 if (( orientation == SOUTH ) && ( xns < 10 )) // check south
863 {
864 xns++; // increment provisional north-south player position
865 subarrows();
866 }
867 if ((orientation == EAST ) && ( xew < 10 )) // check east
868 {
869 xew++; // increment provisional east-west player position
870 subarrows();
871 }
872 if ((orientation == WEST ) && ( xew )) // check west
873 {
874 xew--; // decrement provisional east-west player position
875 subarrows();
876 }
877 tiletodraw=tiles[xns][xew]; // obtain type of tile
878 if ( arrow == 1 ) // if MODE is "draw an arrow" (aka: I can move here)
879 {
880 row=xns;
881 col=xew;
882 if (fb==1) {drawarrow();} // draw arrow
883 if (fb==4) {subarrows2();} // enemy can get here, update enemy array (direction specific)
884 if (fb==5) {computer[xns][xew]++;} // computer can get here, increment computer array
885 if (fb==0) {drawarrow();} // if MODE is "blank an arrow"
886 }
887 // have we reached the end of the board?
888 if (( orientation == NORTH ) && ( xns == 0 )) { arrow=0;} // check north
889 if (( orientation == SOUTH ) && ( xns == 10 )) { arrow=0;} // check south
890 if (( orientation == EAST ) && ( xew == 10 )) { arrow=0;} // check east
891 if (( orientation == WEST ) && ( xew == 0 )) { arrow=0;} // check west
892 }
893 if ((fb==7)&&(xplayers>1)) // check to see if an attacker can be caught if he stays where he is
894 {
895 if ((players[takerow][takecol]==0)&&(enemy[takerow][takecol]))
896 {
897 target[takerow][takecol]+=4; // update adjacent target to provide escape route or place for someone else to occupy
898 if (orientation < EAST) // if heading north or south
899 {
900 if ( xew<10 ){if (target[xns][xew+1]>1){target[xns][xew+1]+=4;}}
901 if ( xew ){if (target[xns][xew-1]>1){target[xns][xew-1]+=4;}}
902 }
903 else // if heading east or west
904 {
905 if ( xns<10 ){if (target[xns+1][xew]>1){target[xns+1][xew]+=4;}}
906 if ( xns ){if (target[xns-1][xew]>1){target[xns-1][xew]+=4;}}
907 }
908 }
909 }
910 }
911 /************************************************/
912 void printdestinations()
913 {
914 // print appropriate arrows at all possible destinations (or blanks em out)
915 // check north
916 if ( ns ) { orientation=NORTH;printarrowsorblanks();} // draws arrows/blanks em out (0=north)
917 // check south
918 if ( ns < 10 ){ orientation=SOUTH;printarrowsorblanks();} // draws arrows/blanks em out (1=south)
919 // check east
920 if ( ew < 10 ){ orientation=EAST;printarrowsorblanks();} // draws arrows/blanks em out (2=east)
921 // check west
922 if ( ew ) { orientation=WEST;printarrowsorblanks();} // draws arrows/blanks em out (3=west)
923 }
924 /************************************************/
925 void canpiecemove() // CAN A SELECTED PIECE MOVE?
926 {
927 // returns 0 or 1 depending on wether a piece can move or not
928 // int route=0; // number of possible routes
929 route=0;
930 piecetype=players[ns][ew]; // determine TYPE of selected piece (1=attacker, 2=defendr, 3=king)
931 /* for all piece types determine if adjacent square in any direction is blank or not
932 it won't bother checking a particular direction if piece is at edge of board.
933 */
934 if ( ns ) // check north
935 {
936 if ( players[ns-1][ew] == 0 ) incroute();
937 if (( piecetype == 3 )&&(players[ns-1][ew] == 4 )) incroute(); // KING: corner square OK
938 }
939 if ( ns < 10 ) // check south
940 {
941 if ( players[ns+1][ew] == 0 ) incroute();
942 if (( piecetype == 3 )&&(players[ns+1][ew] == 4 )) incroute(); // KING: corner square OK
943 }
944 if ( ew < 10 ) // check east
945 {
946 if ( players[ns][ew+1] == 0 ) incroute();
947 if (( piecetype == 3 )&&(players[ns][ew+1] == 4 )) incroute(); // KING: corner square OK
948 }
949 if ( ew ) // check west
950 {
951 if ( players[ns][ew-1] == 0 ) incroute();
952 if (( piecetype == 3 )&&(players[ns][ew-1] == 4 )) incroute(); // KING: corner square OK
953 }
954 /* In the case that the central square is unnocupied and a piece is adjacent to that square then - for
955 non-KING Pieces only - we need to check to see if the opposite square is occupied or not.
956 ROUTE will be decremented if that piece is occupied (as no piece can occupy the central square except for
957 the King but all pieces can traverse it */
958 if (( piecetype < 3 ) && ( players[5][5] == 0 )) // if not a king and central sqr unoccupied
959 {
960 if ( ns == 5 )
961 {
962 if ( ew == 4 ) {if ( players[5][6] > 0 ) decroute();} // check east +2 // east occupied, dec route
963 if ( ew == 6 ) {if ( players[5][4] > 0 ) decroute();} // check west +2 // west occupied, dec route
964 }
965 if ( ew == 5 )
966 {
967 if ( ns == 4 ) { if ( players[6][5] > 0 ) decroute();} // check south +2 // south occupied, dec route
968 if ( ns == 6 ) { if ( players[4][5] > 0 ) decroute();} // check north +2 // north occupied, dec route
969 }
970 }
971 if ( route > 0 ) route=1;
972 //return route;
973 }
974 /************************************************/
975 void drawplayers() // DRAW ALL THE PIECES ON THE BOARD
976 {
977 for (row=0;row<11;row++)
978 {
979 for (col=0;col<11;col++)
980 {
981 if (( players[row][col] > 0 )&&(players[row][col] < 4)){drawpiece();}
982 }
983 }
984 }
985 /************************************************/
986 void drawtiles() // DRAW ALL THE TILES ON THE BOARD
987 {
988 for (row=0;row<11;row++)
989 {
990 for (col=0;col<11;col++)
991 {
992 players[row][col]=tiles[row][col]; // populate players array
993 tiletodraw=tiles[row][col];
994 if ( tiletodraw==4 ) { tiletodraw=3;}
995 drawtile();
996 }
997 }
998 }
999 /************************************************/
1000 void drawboard() // DRAW THE BOARD
1001 {
1002 game=1; // game=1 means PLAY GAME
1003 gamestyle=3; // 0=play against human, 1=play as DEFENDERS, 2=play as ATTACKERS, 3=nobody
1004 kingns=5;kingew=5; // DEFAULT kings board position
1005 /*
1006 for (counter=0;counter<4;counter++) // this routine uses up more memory (100bytes extra)
1007 {
1008 kingattacker[counter]=2;
1009 kingdefender[counter]=2;
1010 }
1011 */
1012 kingattacker[NORTH]=2; // count of attackers NORTH of king
1013 kingattacker[SOUTH]=2; // count of attackers SOUTH of king
1014 kingattacker[EAST]=2; // count of attackers EAST of king
1015 kingattacker[WEST]=2; // count of attackers WEST of king
1016 kingdefender[NORTH]=2; // count of defenders NORTH of king
1017 kingdefender[SOUTH]=2; // count of defenders SOUTH of king
1018 kingdefender[EAST]=2; // count of defenders EAST of king
1019 kingdefender[WEST]=2; // count of defenders WEST of king
1020 surrounded=0; // reset surrounded back to zero
1021 drawtiles(); // draw the background tiles
1022 //drawborder();
1023 curset(12,198,1);
1024 draw(198,0,1);
1025 draw(0,-198,1);
1026 drawplayers(); // draw the players
1027 //printf("%c",19);// turn output to screen off
1028 }
1029 /************************************************/
1030 void blinkcursor() // blinks the cursor a number of times to attract attention
1031 {
1032 //char curloop;
1033 //unsigned int subloop;
1034 for (counter=0;counter<5;inccounter()) // flash the cursor to draw attention to it
1035 {
1036 fb=0; drawcursor(); // draw cursor in background color at cx,cy
1037 pausetime=250;pause();
1038 fb=1; drawcursor(); // draw cursor in foreground color at cx,cy
1039 pausetime=2000;pause();
1040 }
1041 }
1042 /************************************************/
1043 void flashscreen() // flashes the screen in the selected ink color
1044 {
1045 /* Colors are as follows:
1046 0=black, 1=red, 2=green, 3=yellow, 4=blue, 5=magenta, 6=cyan,7=white
1047 */
1048 ink(flashcolor); // flash in color
1049 pausetime=1500;pause();
1050 ink(flashback); // back to original
1051 }
1052 /************************************************/
1053 void playerturn() // The human players turn : filter keyboard input
1054 {
1055 /*
1056 unsigned char key; // code of key pressed
1057 unsigned char canselect; // 0=no, 1=yes (is the piece selectable?)
1058 char cursormovetype=-1; // -1=no, 0=yes (n,s,e,w) 1=(north/south only), 2=(east/west only)
1059 char turn=1; // determines end of player turn 1=playerturn, 0=end of playerturn
1060 */
1061 cursormovetype=-1; // -1=no, 0=yes (n,s,e,w) 1=(north/south only), 2=(east/west only)
1062 turn=1; // determines end of player turn 1=playerturn, 0=end of playerturn
1063 ons=ns; // original ns board position
1064 oew=ew; // original ew board position
1065 ocx=cx; // original x screen position
1066 ocy=cy; // original y screen position
1067 flashback=6;
1068 if ( playertype == 2 )
1069 {
1070 strcpy(playertext,"King");
1071 }
1072 else
1073 {
1074 strcpy(playertext,"Attacker");
1075 }
1076 blinkcursor();
1077 printturnprompt(); // display instructions
1078 while (turn) // repeat until move is made
1079 {
1080 xkey=getchar(); // get code of pressed key
1081 mkey=xkey;
1082 if (( xkey > 7 ) && ( xkey < 12 )) // 8-11 = cursor keys
1083 {
1084 cursormode=0; // freeform
1085 movecursor2();
1086 }
1087 /*******************************************************/
1088 /* determine if X or P is selected (to select a piece) */
1089 /*******************************************************/
1090 if (( xkey == 88) || ( xkey == 80)) // if 'X' or 'P' is selected (88=X, 80=P)
1091 {
1092 canselect=0; // set piece to NOT SELECTABLE
1093 if (( playertype == 1 )&&(players[ns][ew] == 1 )) { canselect=1;} // piece is selectable
1094 if (( playertype == 2 )&&((players[ns][ew] == 2 )||(players[ns][ew] == 3 ))) { canselect=1;} // piece is selectable
1095 if ( canselect )
1096 {
1097 canpiecemove();
1098 if (route)
1099 {
1100 //piecetype=players[ns][ew];
1101 flashcolor=2;flashscreen(); // flash green
1102 if ( xkey == 80 ) // if P is pressed
1103 {
1104 printpossiblemoves(); // Print possible moves
1105 printturnprompt();
1106 //strcpy(message,playertext);
1107 //strcat(message,turntext);
1108 //printmessage();
1109 //printf ("\n\n\n* %s Turn:Use cursor keys.\nX:Select P:Possible",playertext);
1110 }
1111 }
1112 else
1113 {
1114 flashcolor=1;flashscreen(); // flash red
1115 canselect=0; // unselectable, cannot move
1116 }
1117 }
1118 else { flashcolor=1;flashscreen();} // flash red
1119 if (( mkey == 88 )&&( canselect )) // if piece is SELECTED and CAN move
1120 {
1121 ink(2); // green to indicate piece is selected
1122 flashback=2;
1123 //printmessage();
1124 //strcpy(message,playertext);
1125 strcpy(message,"Place cursor on destination\nX=Select Destination R=Reset/De-Select");
1126 printmessage();
1127 //printf("\n\n\n%s Turn X=Select R=Reset",playertext);
1128 inversex=cx;
1129 inversey=cy+1;
1130 inverse(); // highlight selected square (inverse color)
1131 mkey=0; // ensure mkey at known value
1132 // set Original cursor and board position of selected square
1133 ocx=cx; ocy=cy; ons=ns; oew=ew;
1134 while (( mkey != 88 ) && ( mkey != 82)) // move cursor until X or R selected
1135 {
1136 if (( ons == ns )&&( cursormovetype<0)) { cursormovetype=1; }// cursor allowed north-south
1137 if (( oew == ew )&&( cursormovetype<0)) { cursormovetype=2; }// cursor allowed east-west
1138 if (( ons == ns )&& (oew == ew )) { cursormovetype=0;} // cursor can move
1139 if (( cursormovetype == 2) && (( mkey == 8) ||(mkey == 9))) {cursormovetype=-1;}//!move
1140 if (( cursormovetype == 1) && (( mkey == 10)||(mkey == 11))){cursormovetype=-1;}//!move
1141 if (( cursormovetype == 0) && (( mkey == 8) ||(mkey == 9))) {cursormovetype=1;} //move
1142 if (( cursormovetype == 0) && (( mkey == 10)||(mkey == 11))){cursormovetype=2;} //move
1143 if ( cursormovetype > 0 )
1144 {
1145 cursormode=1; // restricted
1146 movecursor2();
1147 }
1148 if ( cursormovetype < 0) { flashcolor=1;flashscreen();} // flashscreen red
1149 mkey=getchar();
1150 }
1151 if ( mkey == 82 ) // R has been selected, Reset cursor to original positions
1152 {
1153 fb=0;
1154 drawcursor(); // blank out cursor at current position
1155 cx=ocx; // reset coords and board values to original positions
1156 cy=ocy;
1157 ns=ons;
1158 ew=oew;
1159 inversex=cx;
1160 inversey=cy+1;
1161 inverse(); // inverse square
1162 fb=1;
1163 drawcursor(); // draw cursor at original selected position
1164 }
1165 if ( mkey == 88 ) // if X selected
1166 {
1167 inversex=ocx;
1168 inversey=ocy+1;
1169 inverse(); // inverse original position
1170 if (( ons == ns )&&( oew == ew))// X is in original position so return to cursor movement
1171 {
1172 mkey=0; // piece de-selected
1173 }
1174 else{
1175 movepiece(); // move selected piece
1176 turn=0; // player has ended turn
1177 }
1178 }
1179 }
1180 ink(6); // back to cyan
1181 flashback=6;
1182 printturnprompt();
1183 } // key = X or P
1184 } // While player turn
1185 }
1186 /********************************************************/
1187 // Moves selected piece to new location - updating board arrays and re-drawing tiles where necessary
1188 void movepiece()
1189 {
1190 p1=1; // piece type comparison (lower) - used for determining takes - default=attacker
1191 p2=1; // piece type comparison (upper) - used for determining takes - default=attacker
1192 piecetype=players[ons][oew]; // obtain type of piece
1193 // move piece
1194 fb=0;
1195 drawcursor(); // blank out cursor at new selected position
1196 row=ons;
1197 col=oew;
1198 tiletodraw=tiles[row][col];
1199 drawtile(); // draw tile at original location (blank out square)
1200 players[ons][oew]=0; // set original location to zero (unnocupied)
1201 players[ns][ew]=piecetype; // update square with player info
1202 row=ns;
1203 col=ew;
1204 //printf("%cENEMY[%d][%d]=%d%c\n",19,ons,oew,enemy[ons][oew],19);getchar();
1205 drawpiece(); // draw piece at new location - 18-10-2011
1206 if (piecetype==3) { kingns=ns;kingew=ew;} // update king position (used by AI)
1207 // having moved piece we now need to check for, and implement any TAKES
1208 if (piecetype > 1 ) // if defender
1209 {
1210 p1=2;
1211 p2=3;
1212 }
1213 tpew=ew;
1214 if ( ns > 1 ) // check north
1215 {
1216 orientation=NORTH;
1217 if ( cantakepiece() ) { tpns=ns-1; takepiece(); }
1218 }
1219 if ( ns < 9 ) // check south
1220 {
1221 orientation=SOUTH;
1222 if ( cantakepiece() ) { tpns=ns+1; takepiece(); }
1223 }
1224 tpns=ns;
1225 if ( ew < 9 ) // check east
1226 {
1227 orientation=EAST;
1228 if ( cantakepiece() ) { tpew=ew+1; takepiece(); }
1229 }
1230 if ( ew > 1 ) // check west
1231 {
1232 orientation=WEST;
1233 if ( cantakepiece() ) { tpew=ew-1; takepiece(); }
1234 }
1235 // update count of attackers around king
1236 /*
1237 for (counter=0;counter<4;counter++) // this routine uses 100 extra bytes than assigning manually
1238 {
1239 kingattacker[counter]=0;
1240 kingdefender[counter]=0;
1241 }
1242 */
1243 kingattacker[NORTH]=0; // count of attackers NORTH of king
1244 kingattacker[SOUTH]=0; // count of attackers SOUTH of king
1245 kingattacker[EAST]=0; // count of attackers EAST of king
1246 kingattacker[WEST]=0; // count of attackers WEST of king
1247 kingdefender[NORTH]=0; // count of defenders NORTH of king
1248 kingdefender[SOUTH]=0; // count of defenders SOUTH of king
1249 kingdefender[EAST]=0; // count of defenders EAST of king
1250 kingdefender[WEST]=0; // count of defenders WEST of king
1251 orientation=NORTH;
1252 cy=kingew;
1253 for (counter=0;counter<kingns;inccounter())
1254 {
1255 cx=counter;incdefatt();
1256 }
1257 orientation=SOUTH;
1258 for (counter=kingns+1;counter<11;inccounter())
1259 {
1260 cx=counter; incdefatt();
1261 }
1262 orientation=EAST;
1263 cx=kingns;
1264 for (counter=kingew+1;counter<11;inccounter())
1265 {
1266 cy=counter; incdefatt();
1267 }
1268 orientation=WEST;
1269 for (counter=0;counter<kingew;inccounter())
1270 {
1271 cy=counter; incdefatt();
1272 }
1273 }
1274
1275 /*******************/
1276 void incdefatt()
1277 {
1278 if (players[cx][cy]==1) {inckingattacker();}
1279 if (players[cx][cy]==2) {inckingdefender();}
1280 }
1281 void inckingdefender()
1282 {
1283 kingdefender[orientation]++;
1284 }
1285 void inckingattacker()
1286 {
1287 kingattacker[orientation]++;
1288 }
1289 /************************************************/
1290 /*void subcanbetaken()
1291 {
1292 target[targetns][targetew]=1;
1293 //if ((ns==kingns)||(ew==kingew)) { target[ns][ew]=3;} // means acceptable risk
1294 }
1295 */
1296 /************************************************/
1297 void canbetaken() // can I be taken after moving here?
1298 {
1299 if ((targetns>0)&&(targetns<10))
1300 {
1301 takena=targetns-1;takenb=targetew;takenc=targetns+1;takend=targetew;takene=1;
1302 subcanbetaken2();
1303 takena=targetns+1;takenb=targetew;takenc=targetns-1;takend=targetew;takene=5;
1304 subcanbetaken2();
1305 }
1306
1307 if ((targetew>0)&&(targetew<10))
1308 {
1309 takena=targetns;takenb=targetew+1;takenc=targetns;takend=targetew-1;takene=10;
1310 subcanbetaken2();
1311 takena=targetns;takenb=targetew-1;takenc=targetns;takend=targetew+1;takene=20;
1312 subcanbetaken2();
1313 }
1314 }
1315 /************************************************/
1316 // Will return a value (take) who's values will be: 0= no, 1=yes
1317 char cantakepiece()
1318 {
1319 take=0;
1320 p1=1; // piece type comparison (lower) - used for determining takes - default=attacker
1321 p2=4; // piece type comparison (upper) - used for determining takes - default=attacker
1322 pcheckns1=ns-1; // defaults to north
1323 pcheckns2=ns-2;
1324 pcheckew1=ew;
1325 pcheckew2=ew;
1326 piecetype=players[ns][ew]; // obtain type of piece
1327 //if ( fb==3) { piecetype=players[ctns][ctew];} // if computer turn set piecetype to piece being checked
1328 if ((fb==3)||(fb==9)) { piecetype=1;} // default = ATTACKER
1329 if (piecetype > 1 ) // if defender
1330 {
1331 p1=2;
1332 p2=3;
1333 }
1334 if ( orientation == SOUTH) // if south
1335 {
1336 pcheckns1=ns+1;
1337 pcheckns2=ns+2;
1338 }
1339 if ( orientation > SOUTH) // if east or west
1340 {
1341 pcheckns1=ns;
1342 pcheckns2=ns;
1343 pcheckew1=ew+1;
1344 pcheckew2=ew+2;
1345 if ( orientation == WEST) // if west
1346 {
1347 pcheckew1=ew-1;
1348 pcheckew2=ew-2;
1349 }
1350 }
1351 // if a take is possible increment the take counter - if values fall within bounds...
1352 if ((pcheckns2>-1)&&(pcheckns2<11)&&(pcheckew2>-1)&&(pcheckew2<11))
1353 {
1354 if (( players[pcheckns1][pcheckew1] > 0 )&&(players[pcheckns1][pcheckew1] != p1)&&(players[pcheckns1][pcheckew1] != p2)&&(players[pcheckns1][pcheckew1] != 3))
1355 {
1356 if ((( players[pcheckns2][pcheckew2] == p1 )||(players[pcheckns2][pcheckew2] == p2 )||(players[pcheckns2][pcheckew2] == 4)&&(pcheckns2!=5)&&(pcheckew2!=5))) // the 5 is to EXCLUDE central square
1357 {
1358 take++;
1359 }
1360 if ( computer[pcheckns2][pcheckew2] ) {inctarget();} // 31-10-2011 - can possibly take on next turn
1361 }
1362 }
1363 if ( piecetype == 3 ) // if king and next to attacker and opposite square is a king square
1364 {
1365 if ((players[pcheckns1][pcheckew1] == 1 )&&(tiles[pcheckns2][pcheckew2] > 2)) { take++;}
1366 }
1367 return take;
1368 }
1369 /************************************************/
1370 void takepiece() // performs taking/removing a piece
1371 {
1372 players[tpns][tpew]=0; // zero players
1373 row=tpns;
1374 col=tpew;
1375 ink(6);
1376 explodetile(); // plays animation to "kill" a tile
1377 tiletodraw=tiles[row][col]; // decide tile to draw
1378 drawtile(); // draw tile at location
1379 }
1380 /*****************************/
1381 void subarrows()
1382 {
1383 if (players[xns][xew])
1384 {
1385 arrow = 0; // !ok if piece occupied or corner square
1386 if ((fb==4)&&(players[xns][xew]==1)) {enemy[xns][xew]+=ENEMYWEIGHT;} // means enemy could get here if attacker moved elsewhere
1387 }
1388 if (( players[ns][ew] == 3)&&(tiles[xns][xew] == 4)) { arrow = 1; } // corner ok if king
1389 }
1390 /*****************************/
1391 void subarrows2()
1392 {
1393 if ( orientation==NORTH ) { enemy[xns][xew]+=5; } // means enemy can get here from SOUTH
1394 if ( orientation==SOUTH ) { enemy[xns][xew]+=1; } // means enemy can get here from NORTH
1395 if ( orientation==EAST ) { enemy[xns][xew]+=20; } // means enemy can get here from WEST
1396 if ( orientation==WEST ) { enemy[xns][xew]+=10; } // means enemy can get here from EAST
1397 }
1398 /*****************************/
1399 void inccantake()
1400 {
1401 z=cantakepiece();
1402 if (z)
1403 {
1404 cantake+=z;
1405 cantakeadjust(); // decrement take count if taken piece on same plane as king and taker isn't
1406 }
1407 }
1408 /*****************************/
1409 void incroute()
1410 {
1411 route++;
1412 }
1413 /*****************************/
1414 void decroute()
1415 {
1416 route--;
1417 }
1418 /*********************************/
1419 void drawtile() // draws a board tile, player piece or "arrow"
1420 {
1421 ptr_graph=PictureTiles; // pointer to Picture Tiles graphics
1422 startpos=(tiletodraw*54); // 54=3*18 calc how many lines "down" in the graphic file to print from
1423 ptr_graph+=startpos; // set start position in graphic file
1424 tileloop();
1425 }
1426 /*********************************/
1427 void explodetile() // Explodes a tile
1428 {
1429 //unsigned char b;
1430 ptr_graph=ExplodeTiles; // pointer to byte values of loaded picture
1431 for (b=0;b<8;b++)
1432 {
1433 tileloop();
1434 pausetime=900;
1435 if (b==5) {pausetime=3000;} // pause longer on skull&crossbones
1436 pause(); // add a pause
1437 }
1438 }
1439 /**************************************/
1440 void tileloop()
1441 {
1442 //unsigned char a;
1443 ptr_draw=(unsigned char*)0xa002; // pointer to start of board
1444 ptr_draw+=(col*3)+(row*720); // 720=18*40 starting screen coordinate
1445 for (counter=0;counter<tileheight;inccounter()) //tileheight=pixels (e.g. 18)
1446 {
1447 for (x=0;x<tilewidth;x++)
1448 {
1449 ptr_draw[x]=ptr_graph[x];
1450 }
1451 //ptr_draw[0]=ptr_graph[0];
1452 //ptr_draw[1]=ptr_graph[1];
1453 //ptr_draw[2]=ptr_graph[2];
1454 ptr_draw+=40; // number of 6pixel "units" to advance (+40=next line down, same position across)
1455 ptr_graph+=tilewidth; // + unit of measurement (how many 6pixel chunks "across" in graphic file)
1456 }
1457 }
1458 /**************************************/
1459 void drawpiece()
1460 {
1461 tiletodraw=players[row][col];
1462 if ( tiletodraw>0) { tiletodraw+=3;}
1463 if ( tiles[row][col]>0 ) { tiletodraw+=3; }
1464 drawtile();
1465 }
1466 /**************************************/
1467 void drawarrow()
1468 {
1469 if ( fb==1 )
1470 {
1471 tiletodraw=10;
1472 if ( tiles[row][col] > 0 ) tiletodraw++; // add another 1 for arrow with background
1473 }
1474 else
1475 {
1476 tiletodraw=tiles[row][col]; // draw original tile (includes blank)
1477 }
1478 drawtile();
1479 }
1480 /**************************************/
1481 void printmessage()
1482 {
1483 printf("%c\n\n\n%s%c",19,message,19);
1484 }
1485 /**************************************/
1486 void printturnprompt()
1487 {
1488 strcpy(message,playertext);
1489 strcat(message,turntext);
1490 printmessage();
1491 //printf("%c\n\n3/1=%d 7/1=%d%c",19,target[3][1],target[7][1],19);
1492 //printf("%cSURROUNDED=%d%c",19,surrounded,19);
1493 }
1494 /**************************************/
1495 void surroundcount()
1496 {
1497 zerocounter();
1498 setpoints();
1499 surrounded=0;
1500 if (( kingns==0)||(kingns==10)||(kingew==0)||(kingew==10)) {incsurround();} // added 18/10/2011
1501 surew=kingew;
1502 if ( kingns > 0 ) { surns=kingns-1;surroundcheck(); }
1503 if ( kingns < 10 ) { surns=kingns+1;surroundcheck(); }
1504 surns=kingns;
1505 if ( kingew > 0 ) { surew=kingew-1;surroundcheck(); }
1506 if ( kingew < 10 ) { surew=kingew+1;surroundcheck(); }
1507 if (surrounded==3) // unset any "enemy and target values"
1508 {
1509 ezew1=kingew;
1510 if ( kingns > 0 )
1511 {
1512 ezns1=kingns-1;
1513 enemyzero();
1514 }
1515 if ( kingns < 10 )
1516 {
1517 ezns1=kingns+1;
1518 enemyzero();
1519 }
1520 ezns1=kingns;
1521 if ( kingew > 0 )
1522 {
1523 ezew1=kingew-1;
1524 enemyzero();
1525 }
1526 if ( kingew < 10 )
1527 {
1528 ezew1=kingew+1;
1529 enemyzero();
1530 }
1531 }
1532 }
1533 /****************************/
1534 void incsurround()
1535 {
1536 surrounded++;
1537 }
1538 /****************************/
1539 void pause()
1540 {
1541 int p;
1542 for (p=0; p<pausetime;p++){};
1543 }
1544 /****************************/
1545 void incpoints()
1546 {
1547 points++;
1548 }
1549 /****************************/
1550 void decpoints()
1551 {
1552 points--;
1553 if (points==0) points=1; // suggested by JamesD
1554 }
1555 /****************************/
1556 void setpoints()
1557 {
1558 points=10;
1559 }
1560 /****************************/
1561 void doublepoints()
1562 {
1563 points+=10; // not really double anymore (10/12/2011)
1564 }
1565 /****************************/
1566
1567
1568 /******************************/
1569 void surroundpoints()
1570 {
1571 points+=10*surrounded; // multiply the points around king depending on the "surrounded" figure
1572 }
1573 /****************************/
1574 void inccounter()
1575 {
1576 counter++;
1577 }
1578 /****************************/
1579 /*
1580 void deccounter()
1581 {
1582 counter--;
1583 }
1584 */
1585 /****************************/
1586 void zerocounter()
1587 {
1588 counter=0;;
1589 }
1590 /****************************/
1591 /*
1592 void LookBackInAnger() // returns the value of the piece "behind" an attacker
1593 {
1594 flag=0; // status of foundpiece 0=no, 1=yes
1595 if ( origorient == 0 )
1596 {
1597 for ( lookrow=mkey-1;lookrow>-1;lookrow--)
1598 {
1599 subLookBackInAnger();
1600 }
1601 }
1602 if ( origorient == 1 )
1603 {
1604 for ( lookrow=mkey+1;lookrow<11;lookrow++)
1605 {
1606 subLookBackInAnger();
1607 }
1608 }
1609 if ( origorient == 2 )
1610 {
1611 for ( lookcol=mkey+1;lookcol<11;lookcol++)
1612 {
1613 subLookBackInAnger();
1614 }
1615 }
1616 if ( origorient == 3 )
1617 {
1618 for ( lookcol=mkey-1;lookcol>-1;lookcol--)
1619 {
1620 subLookBackInAnger();
1621 }
1622 }
1623 }
1624 */
1625 /****************************/
1626 /*
1627 void subLookBackInAnger() // subroutine of LookBackInAnger
1628 {
1629 if (players[lookrow][lookcol]==1) { flag=1;}
1630 if ( (flag==0)&&((players[lookrow][lookcol]==2)||(players[lookrow][lookcol]==3))) { target[ons][oew]=1;}
1631 }
1632 */
1633 /****************************/
1634 void subcanbetaken2() // DO NOT MESS with this (NBARNES 10-01-2012)
1635 {
1636 if (players[takena][takenb]>1)
1637 {
1638 if ((players[takenc][takend]==0)||(enemy[takenc][takend]>ENEMYWEIGHT))
1639 {
1640 if ((enemy[takenc][takend]-takene)&&((enemy[takenc][takend]<ENEMYWEIGHT)||(enemy[takenc][takend]-ENEMYWEIGHT))) // 23-12-2011
1641 {
1642 compass[origorient]=1; // e.g. compass[NORTH]=1 means canbetaken here if moving from NORTH
1643 if (enemy[takenc][takend]>ENEMYWEIGHT) // THIS is the business!!!
1644 {
1645 if ((origorient<EAST)&&(mkey!=takenc)&&(oew!=takend)) {compass[origorient]=0;}
1646 if ((origorient>SOUTH)&&(ons!=takenc)&&(mkey!=takend)) {compass[origorient]=0;}
1647 }
1648 }
1649 }
1650 }
1651 }
1652 /****************************/
1653 void inctarget()
1654 {
1655 target[targetns][targetew]+=2;
1656 }
1657 /****************************/
1658 void surroundcheck()
1659 {
1660 if (players[surns][surew]==1) {incsurround();} // is attacker n,s,e,w
1661 if (tiles[surns][surew]>2) {incsurround();} // is king square n,s,e,w
1662 }
1663 /****************************/
1664 void calctakeweight() // calculate the weight that should be applied to TAKES
1665 {
1666 takeweight=5; // default
1667 // don't worry about TAKES if the king has unbroken line of sight to edge of board
1668 for (x=0;x<4;x++)
1669 {
1670 if ((kingattacker[x]==0)&&(kingdefender[x]==0)){takeweight=0;}
1671 }
1672 //if (((kingnorth==0)&&(defnorth==0))||((kingsouth==0)&&(defsouth==0))||((kingeast==0)&&(defeast==0))||((kingwest==0) && (defwest==0))) {takeweight=0;}
1673 }
1674 /******************************/
1675 void enemyzero() // calling routine = surroundcount()
1676 {
1677 if (( players[ezns1][ezew1] == 0 )&&(target[ezns1][ezew1])) // if adjacent square n/s/e/w is blank and accessible
1678 {
1679 ClearArrays(); // set all arrays to zero (target, enemy, computer)
1680 target[ezns1][ezew1]=100; // set big target value to final space by king
1681 }
1682 }
1683 /******************************/
1684 char checkroute() // returns number of pieces on a given route
1685 {
1686 z=0;
1687 if (orientation<EAST) // if checking ROWS (crossing the T) (used for NORTH SOUTH checks)
1688 {
1689 for (x=startcol;x<=destcol;x++) // check row
1690 {
1691 if ((players[startrow][x])&&(players[startrow][x]<3)) {z++;}
1692 }
1693 }
1694 else // EAST WEST checks (crossing the T)
1695 {
1696 for (x=startrow;x<=destrow;x++) // check accross
1697 {
1698 if ((players[x][startcol])&&(players[x][startcol]<3)) {z++;}
1699 }
1700 }
1701 return z;
1702 }
1703 /*************************/
1704 void cantakeadjust() // decrements cantake if taken piece is on same plane as king
1705 { // and attacking piece isn't AND only one defender on plane
1706 flag=0;
1707 if ((playertype==1)&&(gamestyle==1)) // if computer playing as attacker and his turn
1708 {
1709 if (pcheckns1==kingns)
1710 {
1711 flag=1;
1712 if (ctew<kingew){orientation=WEST;}else{orientation=EAST;}
1713 //if ((kingattacker[orientation]+kingdefender[orientation])<4){cantake--;}
1714 }
1715 if (pcheckew1==kingew)
1716 {
1717 flag=1;
1718 if (ctns<kingns){orientation=NORTH;}else{orientation=SOUTH;}
1719 //if ((kingattacker[orientation]+kingdefender[orientation])<4){cantake--;}
1720 }
1721 if (flag)
1722 {
1723 if ((kingattacker[orientation]+kingdefender[orientation])<4){cantake--;}
1724 }
1725
1726 }
1727 }
1728 /*************************/
1729 void updatetarget()
1730 {
1731 targetns=ctns;targetew=ctew;
1732 target[targetns][targetew]=2; // set target to 2
1733 target[5][5]=0; // set "illegal" squares to zero
1734 target[0][10]=0;
1735 target[0][0]=0;
1736 target[10][0]=0;
1737 target[10][10]=0;
1738 if (target[targetns][targetew]) // only if target is valid (i.e. not a king square)
1739 {
1740 if (enemy[targetns][targetew]){inctarget();} // increase target if blocking an enemy
1741 if ((enemy[targetns][targetew]==6)||(enemy[targetns][targetew]==11)||(enemy[targetns][targetew]==21)||(enemy[targetns][targetew]==15)||(enemy[targetns][targetew]==25)||(enemy[targetns][targetew]==30)){inctarget();}
1742 if ((enemy[targetns][targetew]==35)||(enemy[targetns][targetew]==16)||(enemy[targetns][targetew]==26)){target[targetns][targetew]+=2;}
1743 calccantake(); // calculates how many takes can be made in this position (cantake)
1744 calctakeweight(); // calculate weight that should be applied to takes
1745 y=cantake*takeweight; // value to be added to target
1746 target[targetns][targetew]+=y; // add cantake (will be zero if cannot take)
1747 //if (cantake==0) {canbetaken();} // sets target to 1 if cannot take but can be taken
1748 }
1749 }
1750 /********************/
1751 void calccantake() // calculate how many takes can be made
1752 {
1753 //unsigned char x;
1754 cantake=0;
1755 inccantake(); // inc cantake if can take in direction of travel
1756 for (x=0;x<4;x++)
1757 {
1758 if ( x<2 ) // heading north/south
1759 {
1760 orientation=EAST; inccantake();
1761 orientation=WEST; inccantake();
1762 }
1763 if ( x>1 ) // heading east/west
1764 {
1765 orientation=NORTH; inccantake();
1766 orientation=SOUTH; inccantake();
1767 }
1768 }
1769 }
1770 /***********************/
1771 void printborder() // print the border around title screen/menus etc
1772 {
1773 ink(3); // yellow, erm...gold
1774 row=1;
1775 for (a=0;a<9;a++)
1776 {
1777 col=1;
1778 for(b=0;b<9;b++)
1779 {
1780 tiletodraw=border[a][b];
1781 if ( tiletodraw<12)
1782 {
1783 ptr_graph=BorderTiles; // pointer to Border Tiles graphics
1784 startpos=(tiletodraw*54); // 54=3*18 calc how many lines "down" in the graphic file to print from
1785 ptr_graph+=startpos; // set start position in graphic file
1786 tileloop(); // draw tile
1787 }
1788 col++;
1789 }
1790 row++;
1791 }
1792 }
1793 /*****************************/
1794 void printtitles() // print the title screen
1795 {
1796 tileheight=18;tilewidth=3;
1797 printborder();
1798 row=3;col=2;
1799 startpos=0;
1800 ptr_graph=TitleTiles;
1801 tileheight=36;tilewidth=21;
1802 tileloop();
1803 tileheight=18;tilewidth=3;
1804 }

  ViewVC Help
Powered by ViewVC 1.1.26