⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pressup.c

📁 该程序是C语言编写的
💻 C
📖 第 1 页 / 共 2 页
字号:
  while (!move_selected) {

    if (chg_flag) {	/* avoid unneccessary updates */
      print_square(&master, row, col, TRUE);
      refresh();
      chg_flag = FALSE;
    }

    cmd = getch();
    if (islower(cmd)) {
      cmd = toupper(cmd);
    }

    rd = cd = 0;
    switch(cmd) {
      default:		/* Unknown command  */
        BEEP();
        break;

      case ERR:		/* Problem or non-blocking getch() */
	break;		

      case ' ':			/* select current position */
        m  = row*Side + col;
        if (star < 0) { 	/* first move */
          if (master.board[m] == 0) {
            move_selected = TRUE;
          } else {
            BEEP();
          }
        } else {
          dr = abs(row - star/Side);
          dc = abs(col - star%Side);
          if (master.board[m] < 3 && dr < 2 && dc < 2) {
            move_selected = TRUE;
          } else {
            BEEP();
          }
        }
        break;

      case 'H':		/* move left  */
        if (col == 0) {
          BEEP();
        } else {
          cd = -1;
        }
	break;

      case 'J' :
        if (row == Side-1) {
          BEEP();
        } else {
          rd = 1;
        }     
        break;

      case 'K' :
        if (row == 0) {
          BEEP();
        } else {
          rd = -1;
        }
        break;

      case 'L':		/* move right */
        if (col == Side-1) {
          BEEP();
        } else {
          cd = 1;
        }
	break;

      case 'Q':		/* user wants to quit */
        m = -1;
        move_selected = TRUE;
        break;

      case 'Z':		/* He wants help ... */
        m = Help();
        move_selected = TRUE;
        break;
    }

    if (rd != 0 || cd != 0) {
      print_square(&master, row, col, FALSE);
      row += rd; col += cd;
      chg_flag = TRUE;
    }
  }

  return m;
}

/*
 *  Routine:		Help
 *
 *  Description:	Give the poor soul some badly needed assistance
 *
 */

int Help()
{
  move(BOARDY+Side+1, STATUSX);
  addstr("I'm thinking for you...");
  Helpflag = 1;
  search(&master,Depth,-1,-32000,-32000);
  return BestMove;
}

/*
 *  Routine:		main
 *
 *  Description:	...
 *
 */

int main(argc, argv)
int   argc;
char *argv[];
{
  int   ch;		/* option char from argv	*/
  int	errflag;	/* TRUE if something went wrong in arg parsing */
  int   i,j;

  FFlag  = BFlag = 0;
  image = ".rbXRB";
  Depth = 3;
  errflag = FALSE;

  /* Do getopt instead:  */

  while ((ch =getopt(argc, argv, "bd:f")) != EOF) {
    switch(ch) {
      default :		/* unknown value returned from getopt() */
        fprintf(stderr, "fatal: unknown value returned from getopt(): %x\n",
                        ch);
        exit(EXIT_FAILURE);

      case '?':		/* unknown option letter - errmsg already printed */
        errflag = TRUE;
        break;

      case 'b':
        BFlag++;
        break;

      case 'd':		/* depth of search tree */
        Depth = (int) strtol(optarg, (char **)0, 0);
        break;

      case 'f':
        FFlag++;
        break;
    }
  }
  
  if (optind < argc) {
    fprintf(stderr, "unknown argument -- '%s'\n", argv[optind]);
    errflag = TRUE;
  }

  if (errflag) {
    fprintf(stderr, "usage: pressup [-b] [-d depth] [-f]\n");
    exit(EXIT_FAILURE);
  }


  initscr();
  cbreak();
  noecho();

ngame:
  Startflag = 1;
  Helpflag = 0;
  for (i=0; i<(Side*Side); i++) initb.board[i] = 0;
  for (j=1; j<(Side-1); j++) {
    initb.board[j] = 1;
    initb.board[(Side*Side-1)-j] = 1;
    initb.board[Side*j] = 2;
    initb.board[Side*j + Side-1] = 2;
  };
  initb.star = -1; initb.red = 0; initb.blue = 0;

  boardcopy(&initb, &master);
  pboard(&master);
  boardcopy(&master, &savebd);

  for(;;) {
    if (FFlag) {
      FFlag = 0;
      goto Mine;
    }
    if (CheckWin(&master)) {
      asknew();
      goto ngame;
    }
    i = getmove();
    if (i < 0) {	
      move(BOARDY+Side+3, STATUSX);
      addstr("You quit! ");
      asknew();
      goto ngame;
     }
    dmove(i);
    if (CheckWin(&master)) {
      asknew();
      goto ngame;
     }
Mine:
    move(BOARDY+Side+1, STATUSX);
    addstr("I'm thinking...                ");
    i = search(&master, Depth, 1, -32000, -32000);
    if (BFlag) {
      move(EVALX, EVALY); printw("Pos. eval = %4d", i); 
    }
    dmove(BestMove);
    if (i > 500) {
      move(STATUSY+1, STATUSX); addstr("I've got you!"); 
    }
    if (i < -500) {
      move(STATUSY+1, STATUSX); addstr("You've got me!"); 
    }
  }

  /*NOTREACHED*/  /* asknew() exits */
}

/*
 *  Routine:		mmove
 *
 *  Description:	Make a move
 *
 */

void mmove(bp,n)
BBOARD *bp;
int     n;
{
  int type;
  type = bp->board[n] += 3;
  if (type == 4) bp->red++;
  else if (type == 5) bp->blue++;
  bp->star = n;
}

/*
 *  Routine:		pboard
 *
 *  Description:	Update screen with new board, status, and everything.
 *
 */

void pboard(bp)
BBOARD *bp;
{
  int row, col;		/*  Board coordinates */

  /*  1.  Program name and version:  */

  move(HDRY, HDRX); addstr(HDR);

  /*  2.  Board:  */

  for (row=0; row<Side; row++) {
    for (col=0; col<Side; col++) {
      print_square(bp, row, col, FALSE);
    }
  }

  /*  3.  Print score, search depth and other info:  */

  move(DEPTHY, DEPTHX);
  printw("Search Depth: %2d moves", Depth);

  move(SCOREY, SCOREX);
  printw("Score:    Blue (me) %2d,   Red (you)  %2d", master.blue, master.red);

  if (Helpflag) {
    move(HELPY, HELPX);
    addstr("You've had help!");
  }
  
  if (Startflag) {
    move(STARTY, STARTX);
    addstr(FFlag ? "I go first" : "You go first");
    Startflag = 0;
  }
}

/*
 *  Routine:		print_square
 *
 *  Description:	Print a square on the given board. 
 *
 */

void print_square(bp, row, col, invert)
BBOARD *bp;
int     row;
int     col;
int     invert;
{
  int	n;	/* internal coordinate */

  move(BOARDY+row, BOARDX+3*col);	/* Each square is 3 char wide */
  
  if (invert) {
    standout();
  }

  n = row*Side + col;      
  if (bp->star == n) {
    addstr(" * ");
  } else {
    printw(" %c ", image[bp->board[n]]);
  }

  if (invert) {
    standend();
  }

 /*
  *  Leave cursor *on* square. 
  *  This is quite good for systems with line cursors. Non-blinking
  *  block cursors give a rather odd impression, though.
  *
  */

  move(BOARDY+row, BOARDX+3*col+1);
}

/*
 *  Routine:		search
 *
 *  Description:	Alpha-beta pruning search
 *
 *			Put best move for 'who' into BestMove. Return
 *			estimated strength of position.
 *
 */

int search (bp,ddepth,who,alpha,beta)
BBOARD *bp;
int ddepth;
int who;
int alpha;
int beta;
{
  int i,j,k;
  int myalpha,hisalpha;
  int best;
  int num;
  int bestmove, ii, jj, n;
  int SavStar;
  int SavBlue;
  int SavRed;
  int Save;
  char moves[9];

  best = -32000;
  SavStar = bp->star;
  SavBlue = bp->blue;
  SavRed  = bp->red;
  BestMove = -1;		/* No best move yet...	*/

  if (SavStar < 0) {		/* special case opening moves	*/
    BestMove = HISFIRST;
    if (who > 0) BestMove = MYFIRST;
    return 0;
  };

  if (!ddepth--)
    return(who * (bp->blue - bp->red));

  if (bp->blue == (Side*2-4) || bp->red == (Side*2-4))
    return(who*(bp->blue - bp->red)*1000);

  /* alpha-beta pruning   */
  if (who>0) {
    myalpha = bp->blue; hisalpha = bp->red; 
  } else {
    myalpha = bp->red; hisalpha = bp->blue; 
  }
  myalpha += ddepth;  /* Most optimistic estimate. */
  if (myalpha > (Side*2-4)) myalpha = (Side*2-4);
  if (myalpha == (Side*2-4)) myalpha = 1000*(myalpha-hisalpha);
  else myalpha -= hisalpha;
  if (myalpha <= alpha) return best;

  k = bp->star;
  i = k%Side;
  j = k/Side;
  num = 0;
  for (n=0; n<8; n++) {		/* Try squares 'around' last move */
    if ((ii = i+Adj[n+n]) < 0 || ii >= Side) continue;
    if ((jj = j+Adj[n+n+1]) < 0 || jj >= Side) continue;
    moves[num] = jj*Side + ii;
    if (bp->board[moves[num]] < 3) num++; 
  }
  if (num == 0) return(who*(bp->blue - bp->red)*1000);
  bestmove = moves[0];
  for (i=0; i<num; i++) {
    Save = bp->board[moves[i]];
    mmove(bp,moves[i]);
    k = -search(bp,ddepth,-who,beta,alpha);
    bp->board[moves[i]] = Save;
    bp->blue = SavBlue; bp->red = SavRed; bp->star = SavStar;
    if (k > alpha) alpha = k;
    if (k > best) { best = k; bestmove = moves[i]; }
    if (k>100) break;
  }
  BestMove = bestmove;
  return best;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -