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

📄 yahtzee.c

📁 该程序是C语言编写的
💻 C
📖 第 1 页 / 共 2 页
字号:
/*-							-*- Fundamental -*-
 *
 *  Facility:			yahtzee
 *
 *  File:			yahtzee.c
 *
 *  Associated files:		yahtzee.hlp 	-- man page
 *
 *  Description:		Dice game yahtzee
 *
 *  Portability:		Conforms to X/Open Portability Guide, ed. 3,
 *				I hope ...
 *
 *  Author:			Steve Ward
 *
 *  Editor:			Anders Thulin
 *				Rydsvagen 288
 *				S-582 50 Linkoping
 *				SWEDEN
 *
 *
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
 *
 *  Edit history :
 *
 *  Vers  Ed   Date	   By		     Comments
 *  ----  ---  ----------  ----------------  -------------------------------
 *   1.0    0  19xx-xx-xx  Steve Ward
 *   1.1    1  1988-10-25  Anders Thulin     Original for H89 computer -
 *					     changed to curses. Cleaned
 *					     up user interface a bit.
 *
 */

/* - - Configuration options: - - - - - - - - - - - - - - - - - - - - - - */

/*
 *  Compile-time environment:
 *
 *	ANSI		ANSI C
 *	BSD		BSD Unix, SunOS 3.5
 *	SV2		AT&T UNIX System V.2
 *	XPG3		X/Open Portability Guide, ed. 3
 *	ZTC205		Zortech C 2.05
 *
 *  If you have an ANSI C conformant compiler, use ANSI. Otherwise choose
 *  the environment that best matches yours.
 *
 */

#define	ANSI		0
#define	BSD		0
#define	SV2		0
#define	XPG3		0
#define ZTC205		1

/* - - end of configuration - - - - - - - - - - - - - - - - - - - - - - - - */

/* --- Known problems: --------------------------------------------------

curses

	Some older implementation of curses dows not have any of the
	functions beep(), nodelay() and delay_output().

	It may be possible to emulate beep() through calls similar to
	fputc(0x07, stderr).

	It will, in general, not be possible to emulate nodelay(), as
	it changes the behaviour of getch() from blocking to non-blocking(),
	that is, if no character is immediately available, return ERR.

	delay_output() just waits for a number of seconds. It is only
	used in self-play mode, so it can safely be ignored.

------------------------------------------------------------------------*/

#if ANSI
# include <ctype.h>
# include <curses.h>
# include <stdlib.h>
# include <string.h>
# include <time.h>
#endif

#if BSD
# include <ctype.h>
# include <curses.h>
# include <string.h>
typedef long time_t;
#endif

#if SV2
# include <ctype.h>
# include <curses.h>
# include <string.h>
typedef long time_t;
#endif

#if XPG3
# include <ctype.h>
# include <curses.h>
# include <stdlib.h>
# include <string.h>
# include <time.h>
#endif

#if ZTC205
# include <ctype.h>
# include <curses.h>
# include <string.h>
# include <time.h>
#endif


/* Command characters used only by auto player:  */

#define	PASSC	-1	/* Accept roll */
#define	ROLLC	-2	

/* Coordinates for screen output - assumes 24 x 80 screen */

#define	GOX	45		/* Coordinates for prompt.		*/
#define	GOY	22
#define	GAMEY	20

#define	SCOREX	30		/* leftmost column for scores		*/
#define	DIEY	22

#define	PLAYERS	10		/* Max number of players		*/

#define	NONE	(-1)		/* illegal value.		*/

#define	TOP	0
#define	MID	8
#define	BOT	16

/*  Various variables:	*/

int	 AutoPar[10];	/* heuristic parameters -HA#, -HB#, etc.	*/
int      Dice[5];	/* current roll					*/
int	 DTime;		/* delay time between moves (in seconds)	*/
int	 nplayers;	/* number of players				*/
unsigned rand_seed;	/* random number seed				*/
int 	 ShowTot;

char Potent[13];		/* Potential score...			*/
char PotKind, PotSum, PotStr;	/* Filled by Pot			*/
char PotMax, PotCnt;
int  *ShowSc;
char ShowX, ShowY;

struct Player {
   int  Scores[13];		/* Scores, or 127 iff none yet.		*/
   int  Select;			/* Currently selected category.		*/
   int  Col;			/* Column number, for scores.		*/
   char Name[40];		/* Name of player.			*/
   int  Total;			/* total score.				*/
   int  Games;
 } Who[PLAYERS];

/*  Local routines:  */

#if __STDC__
  int  Auto(int pl, int rolls);
  void Bd(int f);
  void Board(void);
  void Center(char *text, int centx, int y, int xsize);
  int  Cycle(int pl, int delta);
  void Delay(int sec);
  void Die(int number, int count);
  int  Go(int rolls, int player);
  void iplayer(char *name, struct Player *pl);
  int  Kind(int die);
  void Play(int pl);
  void Pot(int pl);
  void Roll(void);
  void Show(int pl);
  void Show1(int n, int flag);
  int  Straight(int die);
#else
  int  Auto();
  void Bd();
  void Board();
  void Center();
  int  Cycle();
  void Delay();
  void Die();
  int  Go();
  void iplayer();
  int  Kind();
  void Play();
  void Pot();
  void Roll();
  void Show();
  void Show1();
  int  Straight();
#endif

/*
 *  Routine:		Auto
 *
 *  Description:	Make move for a computer player.  
 *
 *			Note that the routine handles selection of dice
 *			to reroll internally, without bothering to 
 *			go through 'Go()'.
 *
 *			Strategy is somewhat unclear.
 *
 */

int Auto(pl, rolls)
int  pl;
char rolls;
{
  int  choice;
  int i;
  int *sc;
  char gofor, j;
  int value[13], target[6], best, n;

  sc = Who[pl].Scores;
  Pot(pl);
  mvaddstr(GOY+1, GOX, "Hmmm ... lemme think."); clrtoeol();
  Delay(DTime);

  for (i=0; i<13; i++) {
    if (sc[i] != NONE) value[i] = i-99;
    else if (i<6) value[i] = 2*(Potent[i]-3*(i+1));/* face counts */
    else if (i==6) value[i] = Potent[i]-20;	/* 3 of a kind */
    else if (i==7) value[i] = Potent[i]-15;	/* 4 of a kind */
    else if (i==9) value[i] = Potent[i]-12;	/* 4 straight  */
    else if (i==10) value[i] = Potent[i]-10;	/* 5 straight  */
    else if (i==12) value[i] = Potent[i]-21-AutoPar[5];	/* CHANCE */
    else value[i] = Potent[i]-10;
  }

  for (i=0; i<6; i++) {
    if (sc[12] == NONE) target[i] = i+i; else target[i] = 0;
    if (sc[i] == NONE) target[i] += i<<2; else target[i] -= 15;
    if ((sc[8] == NONE) && (Kind(i+1) == 3)) target[i] += 6;
    if (sc[11] == NONE) target[i] += 1<<(Kind(i+1));
    target[i] += Kind(i+1)<<3;
  }

  best = -99; gofor = PotCnt; choice = Who[pl].Select;

  for (i=0; i<13; i++) {
    if (value[i] > best) {
      best = value[i]; choice = i;
    }
  }
  Who[pl].Select = choice;
  Show(pl);

  if (rolls &&		/* Convert a straight??		*/
      (Potent[9] > 0) &&
      (Potent[10] == 0) &&
      (sc[10] == NONE)) {
    for (i=0; i<5; i++) {	/* Find the useless die.	*/
      j = Dice[i];
      Dice[i] = 0;
      Pot(pl);
      Dice[i] = j;
      if (Potent[9] > 0) {
        Die(i, 0);
        goto rollit;
      }
    }
  }

  Pot(pl);
  if ((choice > 7) && (choice < 12)) goto hit; /* End the inning.	*/

  if (rolls) {
    for (i=0; i<6; i++) {
      if ((n=(target[i]-27-AutoPar[0])) > best)	{
        gofor = i;
        choice = 255;
        best=n;
      }
    }
  }

  if ((choice == 255) || (choice < 8))
    goto maxim;		/* See if we can help.	*/


  if (!rolls) goto hit;		/* Least of evils...	*/
  for (i=0; i<5; i++) Die(i,0);	/* Re-roll entire hand.	*/
  goto rollit;

maxim:
  if (!rolls) goto hit;		/* Maximize number of chosen dice. */
  for (i=0; i<5; i++)
    if (Dice[i] && (Dice[i] != (gofor+1)))
      Die(i, 0);

rollit:
  move(GOY+1, GOX);
  printw("Baby needs shoes ... %d/%d", choice, best);
  clrtoeol();
  Delay(DTime/2);
  return ROLLC;

hit:
  move(GOY+1, GOX);
  printw("I've decided ... %d/%d", choice, best); 
  clrtoeol();
  Delay(DTime);
  return PASSC;
}

/*
 *  Routine:		Bd
 *
 *  Description:	Display empty board line.  Type of line depends
 *			on argument.
 *
 */

void Bd(f)
int f;
{
  char *cc;
  int   i;

  cc = " . ";
  if (f == 1) {
    cc = "===";
  } else if (!f) { 
#if 0
    puts("\033q");	/* normal mode */
#endif
  }
  for (i=((COLS-SCOREX)/3); i--;) {
    addstr(cc);
  }
#if 0
  puts("\033p\033G");	/* inverse mode, no graphics */
#endif
}

/*
 *  Routine:		Board
 *
 *  Description:	Print empty score-sheet
 *
 */

void Board()
{
  int i;

  clear();
  addstr("   YAHTZEE 1.1              ");
  for (i=48; i--;) {
    addch('=');
  }
  move( 1, 0); addstr("        ACES        ADD 1's "); Bd(0);
  move( 2, 0); addstr("        TWOS        ADD 2's "); Bd(0);
  move( 3, 0); addstr("        THREES      ADD 3's "); Bd(0);
  move( 4, 0); addstr("        FOURS       ADD 4's "); Bd(0);
  move( 5, 0); addstr("        FIVES       ADD 5's "); Bd(0);
  move( 6, 0); addstr("        SIXES       ADD 6's "); Bd(0);
  move( 7, 0); addstr("   Subtotal  .  .  .  .  .  "); Bd(2);
  move( 8, 0); addstr("   Bonus iff >= 63       35 "); Bd(2);
  move( 9, 0); addstr("TOTAL ABOVE   .  .  .  .  . "); Bd(2);

  move(11, 0); addstr("        3 of a kind     SUM "); Bd(0);
  move(12, 0); addstr("        4 of a kind     SUM "); Bd(0);
  move(13, 0); addstr("        Full House       25 "); Bd(0);
  move(14, 0); addstr("        4 Straight       30 "); Bd(0);
  move(15, 0); addstr("        5 Straight       40 "); Bd(0);
  move(16, 0); addstr("        YAHTZEE          50 "); Bd(0);
  move(17, 0); addstr("        Chance          SUM "); Bd(0);
  move(18, 0); addstr("TOTAL SCORE   .  .  .  .  . "); Bd(2);

  move(GAMEY, 0); addstr("GAMES   .  .  .  .  .  .  . "); Bd(1);
}

/*
 *  Routine:		Center
 *
 *  Description:	Write a string centered about the x coordinate.
 *
 */

void Center(text, centx, y, xsize)
char *text;
int   centx, y, xsize;
{
  int l;

  l = strlen(text);
  if (l > xsize) l = xsize;

  move(y, centx - l/2);
  addch(' ');
  while (*text && l--) addch(*text++);
  addch(' ');
}

/*
 *  Routine:		Cycle
 *
 *  Description:	Alter the screen selection of a player. The
 *			delta parameter is 1 for moving downwards, or
 *			-1 for upwards.
 *
 */

int Cycle(pl, delta)	
int pl;
int delta;
{
  int tries;	/* Remaining nr of tries to find empty selection */
  int s;	/* Player's current/new selection */

  s  = Who[pl].Select;
  tries = 14;
  do {
    s += delta;
    if (s < 0) {
      s = 12;
    } else if (s > 12) {
      s = 0;
    }
  } while (--tries > 0 && (Who[pl].Scores[s] != NONE));
  Who[pl].Select = s;

  return tries;	/* 0 if no more selections available */
}

/*
 *  Routine:		Delay
 *
 *  Description:	Wait for a number of seconds
 *
 */

void Delay(s)
int s;
{
#ifndef __POWERC
  delay_output(1000*s);
#endif
}

/*
 *  Routine:		Die
 *
 *  Description:	Print a die face with COUNT dots in the NUMBER
 *			place.
 *
 */

void Die(number, count)
int number;

⌨️ 快捷键说明

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