home *** CD-ROM | disk | FTP | other *** search
- #name "DewSoft Stones v1.0"
- /*
- This file is copyright 1997 by Jeremy Dewey.
- */
-
- #include "usglib.h"
- #include "lib\tabline.c"
- #include "lib\sprite.c"
- #include "lib\sprite_x.c"
- #include "lib\rand.c"
- #include "lib\disp_dec.c"
-
- #define true 1
- #define false 0
-
- #define P_BLOCK 25
- #define P_HUMAN -10
- #define P_CPU 10
-
- /* Sprites - actual data at end of file */
- extern char icon_h[], icon_hi[], icon_c[], icon_ci[], icon_sq[];
- extern char wait_L1[], wait_0[], icon_0[], icon_b[], square[];
- /* Various pointers */
- char *brd, *newbrd, *p_wait, i_wait;
- /* Human's current cursor position */
- int cx, cy;
- /* Current scores */
- char numci, numc, numhi, numh, nummt;
- char onumci, onumc, onumhi, onumh;
- extern char* _frstmem(0x8b27);
-
- main() {
- char i;
- i_wait = 0;
- cx = 8;
- cy = 5;
-
- // To allocate board space, this game requires 352 bytes free
- brd = _frstmem;
- newbrd = _frstmem + 176;
-
- while (true) {
- clrscr;
- //graphpage(); - Usgard now does this automatically
- tabline("Stones v1.0");
- /* Print my name */
- my_name();
-
- /* Draw message window */
- vline(9,63,92);
-
- /* Populate message window */
- setxy_m(100,8);
- puts_m("Human");
- for (i=9;i<15;i++) hline(93,127,i);
- setxy_m(103,15);
- puts_m("0 ");
- sprite(icon_h,_menu_x, 16,5,5);
- setxy_m(103,21);
- puts_m("0 ");
- sprite(icon_hi,_menu_x, 22,5,5);
- setxy_m(103,27);
- puts_m("0 Total");
-
- setxy_m(95,36);
- puts_m("CPU stats");
- for (i=36;i<43;i++) hline(93,127,i);
- setxy_m(103,43);
- puts_m("0 ");
- sprite(icon_c,_menu_x, 44,5,5);
- setxy_m(103,49);
- puts_m("0 ");
- sprite(icon_ci,_menu_x, 50,5,5);
- setxy_m(103,55);
- puts_m("0 Total");
-
- // Check for amount of free memory
- if (free_mem() < 352) {
- setxy_m(4,10);
- puts_m("Stones requires 352 bytes");
- setxy_m(20,16);
- puts_m("of free memory");
- getkey();
- _exit();
- }
- init_brd();
- draw_brd();
- // Change the text at the top of the screen
- play();
- my_name();
- game_over();
- if (getkey() == K_EXIT) _exit();
- // Change the text back
- game_over();
- my_name();
- }
- }
-
- free_mem() {
- asm(" call FREEMEM\n");
- }
-
- my_name() {
- setxy_m(70, 1);
- puts_m("by Jeremy Dewey");
- }
-
- game_over() {
- setxy_m(50,1);
- puts_m("Game Over - press a key");
- }
-
- /* Run the game until there are no more empty spaces with cookie jars */
-
- play() {
- nummt=1;
- while (nummt) {
- if (human()) return; // If human() returns 1, exit game early
- draw_brd();
- if (nummt) {
- cpu();
- draw_brd();
- }
- }
- }
-
- /* Wait cursor */
-
- waitcycl() {
- p_wait = wait_L1 + i_wait * 10;
- sprite(p_wait ,48,2,8,5);
- sprite(p_wait+5,56,2,8,5);
- if (++i_wait >=4) i_wait=0;
- }
-
- waitoff() {
- sprite(wait_0, 48,2,8,5);
- sprite(wait_0, 56,2,8,5);
- }
-
- /* Initialize the board (with blocks surrounding the visible area */
-
- init_brd() {
- int x,y,b;
-
- for(y=0;y<11;y++) {
- /*waitcycl();*/
- for(x=0;x<16;x++) {
- b = bindex(x,y);
- if (!x || x==15 || !y || y==10 || rand16() < 5000) {
- brd[b] = P_BLOCK;
- }
- else brd[b] = 0;
- }
- }
- }
-
- /* Draw the board */
-
- draw_brd() {
- int xx,yy,x,y,b;
- char* spr;
-
- yy = 10;
- onumci = numci;
- onumc = numc;
- onumhi = numhi;
- onumh = numh;
-
- numci = numc = numhi = numh = nummt = 0;
- for(y=1;y<10;y++) {
- waitcycl();
- xx = 1;
- for(x=1;x<15;x++) {
- b = bindex(x,y);
- if (brd[b]==P_BLOCK) spr = icon_b;
- else if (brd[b]==P_HUMAN) { spr = icon_h; numh++;}
- else if (brd[b]==P_CPU) { spr = icon_c; numc++;}
- else if (brd[b]>127) { spr = icon_hi; numhi++;}
- else if (!brd[b]) { spr = icon_0; nummt++;}
- else { spr = icon_ci; numci++;}
- sprite(spr,xx,yy,5,5);
- xx+=6;
- }
- yy+=6;
- }
- waitoff();
- draw_scr(15,onumh,numh);
- draw_scr(21,onumhi,numhi);
- draw_scr(27, onumh+onumhi,numh+numhi);
-
- draw_scr(43,onumc,numc);
- draw_scr(49,onumci,numci);
- draw_scr(55,onumc+onumci,numc+numci);
- }
-
- draw_scr(y,os,ns) char y,os,ns; {
- draw_sc2(y,os); // erase old score
- draw_sc2(y,ns); // draw new score
- }
-
- draw_sc2(y,scr) char y,scr; {
- setxy_m(95, y);
- disp_char(scr);
- }
-
- /* Let human choose their move */
-
- human() {
- int c,done,xx,yy;
- done = 0;
-
- do {
- xx = cx*6-6;
- yy = cy*6+3;
- sprite_x(square,xx,yy,7,7);
- c = getkey();
- sprite_x(square,xx,yy,7,7);
- if (c == K_DOWN) {
- if (cy < 9) cy++;
- else cy = 1;
- } else if (c == K_UP) {
- if (cy > 1) cy--;
- else cy = 9;
- } else if (c == K_LEFT) {
- if (cx > 1) cx--;
- else cx = 14;
- } else if (c == K_RIGHT) {
- if (cx < 14) cx++;
- else cx = 1;
- } else if (c == K_EXIT)
- return 1;
- else if (c == K_SECOND) {
- if (islegal(cx,cy,P_HUMAN)) {
- done = 1;
- execute(cx,cy,P_HUMAN,brd);
- }
- }
- } while (!done);
- draw_brd();
- return 0;
- }
-
- /* Find the best legal move */
-
- cpu() {
- int val, x,y;
- int bestVal, bestX, bestY;
-
- bestVal=0;
- for (y=1;y<10;y++)
- for (x=1;x<15;x++) {
- if (islegal(x,y,P_CPU)) {
- if (checkkey() == K_EXIT) _exit();
- copy_brd();
- execute(x,y,P_CPU,newbrd);
- val = eval_brd();
- if (val>bestVal) { bestX=x; bestY=y; bestVal=val; }
- waitcycl();
- }
- }
- execute(bestX,bestY,P_CPU,brd);
- waitoff();
- }
-
- /* Helper functions */
- sign(a) char a; {
- if (a>127) return -1;
- return 1;
- }
-
- bindex(x,y) int x,y; {
- return (y<<4)+x;
- }
-
- abs(a) char a; {
- if (a>127) return -a;
- return a;
- }
-
- islegal(x,y,p) int x,y,p; {
- char b;
- b = brd[bindex(x,y)];
- if (!b || (sign(b)==sign(p) && b!=p && b!=P_BLOCK))
- return true;
- return false;
- }
-
- /* Modify the board with a CPU or human move */
-
- execute(x,y,p,b) int x,y,p; char* b; {
- int i,j,xx,yy,bb;
-
- for(i=0;i<3;i++)
- for(j=0;j<3;j++) {
- xx = x + j - 1;
- yy = y + i - 1;
- bb = bindex(xx,yy);
- if (j==1 && i==1) b[bb] = p;
- else if (abs(b[bb]) < 10) b[bb]+=sign(p);
- }
- }
-
- can_cpu_place(bi) int bi; {
- char spot;
- spot = newbrd[bi];
- if (!spot || (sign(spot)==1 && spot<10)) return true;
- return false;
- }
-
- /* This function is never actually called
- can_human_place(bi) int bi; {
- char spot;
- spot = newbrd[bi];
- if (!spot || (sign(spot)==-1 && abs(spot)<10)) return true;
- return false;
- }
- */
-
- eval_brd() {
- int x,y,nbi,i,j,bi;
- int score, factor, vuln;
-
- score = 5000;
- for (y=1;y<10;y++) {
- for (x=1;x<15;x++) {
- bi = bindex(x,y);
- // Score each taken block
- if (!newbrd[bi]) continue; // No need to score an empty space
- if (newbrd[bi]==P_BLOCK) continue; // It's a block!
- if (newbrd[bi]==P_CPU) { score+=10; continue; }
- if (newbrd[bi]==P_HUMAN) { score-=10; continue; }
-
- // Score each influenced block
-
- /* This code takes to long to run...
-
- vuln=0; // vulnerability
- if (can_cpu_place(bi)) factor = 1;
- else factor = -1;
-
- for (j=0;j<3;j++)
- for (i=0;i<3;i++) {
- if (i==1 && j==1) continue;
- nbi = bindex(x+i-1,y+j-1);
- if (factor==1 && can_human_place(nbi) ||
- factor==-1 && can_cpu_place(nbi)) vuln++;
- }
- // Now vuln becomes the strength of the position
- vuln = factor * newbrd[bi] - vuln;
- if (vuln > 0) score+=10*factor;
- else score+=8*factor;
-
- It can be approximated thusly...
- */
- if (can_cpu_place(bi)) {
- if (newbrd[bi] > 1) score+=10;
- else score+=8;
- } else { /* human can place */
- if (newbrd[bi] < -1) score-=10;
- else score-=8;
- }
-
- }
- }
- return score;
- }
-
- copy_brd() {
- // make a quick copy of the board for modification
- #asm
- ld hl,(brd) ;source
- ld de,(newbrd) ;dest
- ld bc,176 ;board size
- ldir
- #endasm
- }
-
- checkkey() {
- #asm
- call GET_KEY
- ld hl,0
- ld l,a
- #endasm
- }
-
- /* Sprite data */
- #asm
- icon_h:
- .db %00100000
- .db %01110000
- .db %11111000
- .db %01110000
- .db %00100000
- icon_hi:
- .db %00100000
- .db %01010000
- .db %10001000
- .db %01010000
- .db %00100000
- icon_c:
- .db %01110000
- .db %11111000
- .db %11111000
- .db %11111000
- .db %01110000
- icon_ci:
- .db %01110000
- .db %10001000
- .db %10001000
- .db %10001000
- .db %01110000
- icon_b:
- .db %11111000
- .db %10101000
- .db %11011000
- .db %10101000
- .db %11111000
- icon_0:
- .db %00000000
- .db %00000000
- .db %00000000
- .db %00000000
- .db %00000000
- square:
- .db %11111110
- .db %10000010
- .db %10000010
- .db %10000010
- .db %10000010
- .db %10000010
- .db %11111110
- wait_0:
- .db %00000000
- .db %00000000
- .db %00000000
- .db %00000000
- .db %00000000
- wait_L1:
- .db %11111111
- .db %10011001
- .db %10110011
- .db %11100110
- .db %11111111
- wait_1R:
- .db %11111111
- .db %10011001
- .db %00110011
- .db %01100111
- .db %11111111
- wait_2L:
- .db %11111111
- .db %10110011
- .db %11100110
- .db %11001100
- .db %11111111
- wait_2R:
- .db %11111111
- .db %00110011
- .db %01100111
- .db %11001101
- .db %11111111
- wait_3L:
- .db %11111111
- .db %11100110
- .db %11001100
- .db %10011001
- .db %11111111
- wait_3R:
- .db %11111111
- .db %01100111
- .db %11001101
- .db %10011001
- .db %11111111
- wait_4L:
- .db %11111111
- .db %11001100
- .db %10011001
- .db %10110011
- .db %11111111
- wait_4R:
- .db %11111111
- .db %11001101
- .db %10011001
- .db %00110011
- .db %11111111
- #endasm
-
-
-