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

📄 yahtzee.c

📁 该程序是C语言编写的
💻 C
📖 第 1 页 / 共 2 页
字号:
int count;
{
  int i;

  if (count != 0) {
    attron(A_REVERSE);
  }

  for (i=0; i<3; i++) {			/* Once for each row on the die */
    move(DIEY+i, 4+(7*number));
    switch (i*8 + count) {
      case TOP+0:	/* count is 0 (empty) for re-rolled */
      case MID+0:
      case BOT+0:
      case TOP+1:
      case BOT+1:
      case MID+2:
      case MID+4:
        addstr("     ");
        break;
      case TOP+2:
      case TOP+3:
        addstr("*    ");
        break;
      case MID+1:
      case MID+3:
      case MID+5:
        addstr("  *  ");
        break;
      case BOT+2:
      case BOT+3:
        addstr("    *");
        break;
      case TOP+4:
      case BOT+4:
      case TOP+5:
      case BOT+5:
      case TOP+6:
      case MID+6:
      case BOT+6:
        addstr("*   *");
        break;
    }
  }
  Dice[number] = count;

  if (count != 0) {
    attroff(A_REVERSE);
  }
}

/*
 *  Routine:		Go
 *
 *  Description:	Command interpreter. Accepts commands either
 *			from player or auto-player and performs them.
 *
 *  Note:		Auto-player does some internal command handling
 *
 */

int Go(rolls, player)
int rolls, player;
{
  int  ch;		/* command */
  int  i;
  int  save[5];		/* copy of latest roll  */
  int  reroll;		/* true if user has selected dice to reroll */

  Pot(player);
  for (i=0; i<5; i++) {
    Dice[i] = 0;
  }
  Roll();
  Who[player].Select = 12;

  if (!Cycle(player, 1)) return 0;

Top:
  for (i=0; i<5; i++) save[i] = Dice[i];

  Show(player);
  reroll = FALSE;

  for (;;) {
    move(GOY, GOX);
    printw("%s's move: %d rolls left. ", Who[player].Name, rolls);
    clrtoeol();
esc:
    /*  n.  Get and execute command:  */

    refresh();
    if (Who[player].Name[0] == '=') {
      ch = Auto(player, rolls);
    } else {
      ch = toupper(getch());
    }

    switch (ch) {
      case 033:
        goto esc;

      case ' ':			/* Go 'down' */
        Cycle(player, 1);
        Show(player);
        continue;

      case '1':			/* select die to be rerolled */
      case '2':
      case '3':
      case '4':
      case '5':
        if (rolls == 0) {	/* sorry - no rolls left */
          beep();
        } else {
          Die(ch - '1', 0);
	  reroll = TRUE;
        }
        continue;

      case 0x08:		/* Backspace */
      case 0x7F:		/* Delete == undo selection */
        for (i=0; i<5; i++) Die(i, save[i]);
        continue;

      case ROLLC:		/* make new roll - from Auto() */
          if (rolls>0) { Roll(); rolls--; }
	  else beep();
          goto Top;

      case '\r':
      case '\n':
      case PASSC:
	if (reroll) {	/* Make new roll */
          if (rolls>0) { Roll(); rolls--; }
	  else beep();
          goto Top;
	} else {	/* Accept latest roll & selection */
          Play(player);
          Who[player].Select = NONE;
          Show(player);
          return ch;
        }

      default:		/* unknown input */
        beep();
        continue;
    }
  }
}


/*
 *  Routine:		iplayer
 *
 *  Description:	Initialize a player
 *
 */

void iplayer(name, pl)
char          *name;
struct Player *pl;
{
  char i, *fake;

  fake = "==0==";
  if (!name[1] && *name == '=') {
    name = fake; name[3]++;
  }
  for (i=0; i<13; i++) {
    pl->Scores[i] = NONE;
  }
  pl->Select = NONE;

  strcpy(pl->Name, name);  
}

/*
 *  Routine:		Kind
 *
 *  Description:	Gives number of dice of count die
 *
 */

int Kind(die)		
int die;
{
  int count, i;

  count = 0;
  for (i=0; i<5; i++) {
    if (die == Dice[i]) {
      count++;
    }
  }

  return count;
}


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

int main(argc, argv)
int   argc;
char *argv[];
{
  int arg;
  int i;
  char j,*carg;
  int n;

  /*  0.  Initialize:  */

  for (i=0; i<PLAYERS; i++) Who[i].Games = 0;

  for (i=0; i<10; i++) AutoPar[i] = 0;	
  DTime = 2;		

  initscr();
  cbreak();			/* return keypresses immediately */
  nodelay(stdscr, FALSE);	/* read blocks */
  
  rand_seed = time((time_t *)0);

  for (arg=1; (arg<argc) && (*(carg = argv[arg]) == '-'); arg++) {
    switch (*++carg) {
      case 'R':
	rand_seed = atoi(++carg);
        continue;
      case 'H':
        i = (*++carg)-'A';
	AutoPar[i] = atoi(++carg);
        continue;
      case 'D':
        DTime = atoi(++carg)|1;
        continue;
      default:
        continue;
    }
  }

  srand(rand_seed);

Again:
  nplayers = 0;
  for (i=arg; i<argc; i++) {
    iplayer(argv[i], &Who[nplayers++]);
  }
  if (nplayers == 0) {
    iplayer("You", &Who[nplayers++]);
  }
  n = (80-SCOREX)/nplayers;
  for (i=SCOREX+(n/2), j=0; j<nplayers; j++, i += n) Who[j].Col = i;
  Board();
  for (j=0; j<nplayers; j++) Center(Who[j].Name, Who[j].Col, 0, n-1);
  for (i=0; i<nplayers; i++) Show(i);

  for (;;) {
    for (i=0; i<nplayers; i++) {
      if (!Go(2, i)) {
        for (i=n=0; i<nplayers; i++)
          if (Who[i].Total > n)
            n = Who[i].Total;
        for (i=0; i<nplayers; i++)
          if (Who[i].Total >= n) {
            move(GAMEY, Who[i].Col);
            standout();	  
            printw("%3d", ++(Who[i].Games));
          }
        move(GOY+1, GOX);
        for (i=0; i<nplayers; i++)
	  if (Who[i].Total >= n)
            printw("%s ", Who[i].Name);
        beep();
        addstr("WINS!"); 
        standend();
        addstr(" Play again?"); clrtoeol();
        if (toupper(getch()) == 'Y') goto Again;
        endwin();
        exit(0);
      }
    }
  }
}

/*
 *  Routine:		Play
 *
 *  Description:	Make a player's move.
 *
 */

void Play(pl)		
int pl;
{
  Pot(pl);
  Who[pl].Scores[Who[pl].Select] = Potent[Who[pl].Select];
}

/*
 *  Routine:		Pot
 *
 *  Description:	Compute potential scores for player.
 *
 *  Notes:		A. Thulin:
 *			Odd that the parameter isn't used ...
 */

void Pot(pl)		
int pl;
{
  int i,j,k;

  for (i=0; i<13; i++) Potent[i] = 0;
  for (i=0; i<5; i++) if (((j = Dice[i])>0) && (j<7)) Potent[j-1] += j;
  for (PotMax=PotSum=i=PotKind=0; i<5; i++)
   { PotKind |= (1<<(j=Kind(k=Dice[i]))); PotSum += Dice[i];
     if (j>PotMax) { PotMax=j; PotCnt=k; }}
  Potent[12] = PotSum;
  if ((PotKind & 0xC) == 0xC) Potent[8] = 25;
  if (PotKind & 0x38) Potent[6] = PotSum;
  if (PotKind & 0x30) Potent[7] = PotSum;
  if (PotKind & 0x20) Potent[11] = 50;
  for (i=PotStr=0; i<5; i++) if ((j = Straight(Dice[i])) > PotStr)
  	PotStr=j;
  if (PotStr >= 4) Potent[9] = 30;
  if (PotStr == 5) Potent[10] = 40;
}

/*
 *  Routine:		Roll
 *
 *  Description:	Roll the dice ...
 *
 */

void Roll()
{
  int i;
  for (i=0; i<5; i++) {
    if (Dice[i] == 0) {
      Die(i, 1+rand()%6);
    }
  }
}

/*
 *  Routine:		Show
 *
 *  Description:	Show the scores of a player
 *
 */

void Show(pl)
char pl;
{
  int            f;
  struct Player *p;
  int cc;
  char tot, j;

  Pot(pl);
  p = &Who[pl];
  ShowX = p->Col-1;	ShowY = 1;	ShowTot = 0;
  ShowSc = p->Scores;	cc = 0;		f = p->Select;
  Show1(cc++,f--);
  Show1(cc++,f--);
  Show1(cc++,f--);
  Show1(cc++,f--);
  Show1(cc++,f--);
  Show1(cc++,f--);
  tot = ShowTot;
  Show1(255,44);
  ShowTot = j = tot>=63? 35:0;
  Show1(255,44);
  tot = ShowTot = tot+j;
  Show1(255,44);
  ShowTot = tot;
  ShowY++;
  Show1(cc++,f--);
  Show1(cc++,f--);
  Show1(cc++,f--);
  Show1(cc++,f--);
  Show1(cc++,f--);
  Show1(cc++,f--);
  Show1(cc++,f--);
  p->Total = ShowTot;
  Show1(255,44);
}

/*
 *  Routine:		Show1
 *
 *  Description:	...
 *
 */

void Show1(n, flag)
int n, flag;
{
  int val;

  move(ShowY++, ShowX);

  if (n == 255) {
    val = ShowTot;
  } else {
    val = ShowSc[n];
  }

  if (!flag) { 
    standout();
    val = Potent[n];
  } else if (flag == 44) { 
    standout();
  }
  if (val == NONE) { 
    addstr("  ? ");
  } else { 
    printw(" %2d", val);
    ShowTot += val;
  }
  if (!flag || (flag == 44)) {
    standend();
  }
}

/*
 *  Routine:		Straight
 *
 *  Description:	Gives longest straight starting at die
 *
 */

int Straight(die)	
int die;
{
  int i, j;

  for (i=1; i<6; i++) {
    die++;
    for (j=0; j<5; j++) {
      if (Dice[j] == die) goto hit;
    }
    break;
hit:
    continue;
  }
  return i;
}




⌨️ 快捷键说明

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