📄 gammontool.c
字号:
#ifndef lintstatic char sccsid[] = "@(#)gammontool.c 1.1 92/07/30 Copyr 1985 Sun Micro";#endif/* * Copyright (c) 1985 by Sun Microsystems, Inc. */#include <suntool/tool_hs.h>#include <suntool/wmgr.h>#include <suntool/panel.h>#include <sunwindow/cms.h>#include <sunwindow/win_ioctl.h>#include <sys/stat.h>#include <ctype.h>#include "defs.h"static short icon_data[256]={#include <images/gammon.icon>};#include "cursors.h"#define MINBRDHT (22 * msgfont->pf_defaultsize.y)#define OPTHT (2 * (msgfont->pf_defaultsize.y + 10))#define MSGHT (2 * msgfont->pf_defaultsize.y)mpr_static(gammon_pr, 64, 64, 1, icon_data);struct icon gammon_icon = { TOOL_ICONWIDTH, TOOL_ICONHEIGHT, 0, {0, 0, TOOL_ICONWIDTH, TOOL_ICONHEIGHT}, &gammon_pr, {0, 0, 0, 0}, 0, 0, 0};static struct tool *tool;struct toolsw *optsw, *msgsw, *brdsw;struct pixwin *msgwin, *brdwin;struct pixfont *msgfont;struct rect msgrect, brdrect;static tool_sigwinchhandler(), quit(), gammonpipeready(), msg_sigwinch(), (*cached_toolselected)(), brd_sigwinch(), brd_selected();static int double_proc(), accept_proc(), refuse_proc(), showmove_proc(), redo_proc(), redoall_proc(), forfeit_proc(), quit_proc(), newgame_proc(), newcolor_proc();Panel_item panelitems[10];char *cached_msg[2] = {"", ""};#define NUMPOINTS 4int humanpieces[NUMPOINTS][2] = { {6, 5}, {8, 3}, {13, 5}, {24, 2} };int computerpieces[NUMPOINTS][2] = { {1, 2}, {12, 5}, {17, 3}, {19, 5} };int minwidth, minheight;static char tool_name[] = "gammontool";gammontool_main(argc, argv)int argc;char **argv;{ char **tool_attrs = NULL; if (tool_parse_all(&argc, argv, &tool_attrs, tool_name) == -1) { tool_usage(tool_name); exit(1); } execbkg = 0; while (--argc) { ++argv; if (execbkg) fprintf(stderr, "Only one binary allowed!\n"); else { gammonbin = *argv; execbkg++; } } msgfont = pw_pfsysopen(); tool = tool_make(WIN_NAME_STRIPE, 1, WIN_LABEL, tool_name, WIN_ATTR_LIST, tool_attrs, WIN_ICON, &gammon_icon, 0, 0); if (tool == NULL) { fprintf(stderr, "Couldn't create tool\n"); exit(1); } tool_free_attribute_list(tool_attrs); optsw = panel_create(tool, PANEL_HEIGHT, OPTHT, 0); initopt(); msgsw = tool_createsubwindow(tool, "messages", -1, MSGHT); initmsg(); message(MSG, "To begin the game, roll the dice by clicking the left or middle buttons."); message(ERR, "(The mouse cursor may be anywhere over the board when rolling the dice.)"); brdsw = tool_createsubwindow(tool, "board", -1, -1); initbrd(); initmatch(); signal(SIGWINCH, tool_sigwinchhandler); signal(SIGINT, quit); signal(SIGQUIT, quit); signal(SIGTERM, quit); tool_install(tool); cached_toolselected = tool->tl_io.tio_selected; tool->tl_io.tio_selected = gammonpipeready; FD_SET(tool->tl_windowfd, &tool->tl_io.tio_inputmask); startgammon(); FD_SET(gammonfd, &tool->tl_io.tio_inputmask); tool_select(tool, 0); signal(SIGWINCH, SIG_IGN); signal(SIGINT, SIG_IGN); tool_destroy(tool); if (logfp != NULL) fprintf(logfp, "Match over.\n"); killpg(getpgrp(), SIGINT); exit(0);}initopt(){ Panel psw = (Panel)optsw->ts_data; int n = 0, x, y; x = y = 4; panelitems[n++] = panel_create_item(psw, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(psw, "Double", 6, NULL), PANEL_ITEM_X, x, PANEL_ITEM_Y, y, PANEL_NOTIFY_PROC, double_proc, 0); x += 6 * msgfont->pf_defaultsize.x + 21; panelitems[n++] = panel_create_item(psw, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(psw, "Accept Double", 13, NULL), PANEL_ITEM_X, x, PANEL_ITEM_Y, y, PANEL_NOTIFY_PROC, accept_proc, 0); x += 13 * msgfont->pf_defaultsize.x + 21; panelitems[n++] = panel_create_item(psw, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(psw, "Refuse Double", 13, NULL), PANEL_ITEM_X, x, PANEL_ITEM_Y, y, PANEL_NOTIFY_PROC, refuse_proc, 0); x += 13 * msgfont->pf_defaultsize.x + 21; panelitems[n++] = panel_create_item(psw, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(psw, "Show Last Move", 14, NULL), PANEL_ITEM_X, x, PANEL_ITEM_Y, y, PANEL_NOTIFY_PROC, showmove_proc, 0); x += 14 * msgfont->pf_defaultsize.x + 21; panelitems[n++] = panel_create_item(psw, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(psw, "Redo Move", 9, NULL), PANEL_ITEM_X, x, PANEL_ITEM_Y, y, PANEL_NOTIFY_PROC, redo_proc, 0); x = 4; y += msgfont->pf_defaultsize.y + 8; panelitems[n++] = panel_create_item(psw, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(psw, "Redo Entire Move", 16, NULL), PANEL_ITEM_X, x, PANEL_ITEM_Y, y, PANEL_NOTIFY_PROC, redoall_proc, 0); x += 16 * msgfont->pf_defaultsize.x + 21; panelitems[n++] = panel_create_item(psw, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(psw, "Forfeit", 7, NULL), PANEL_ITEM_X, x, PANEL_ITEM_Y, y, PANEL_NOTIFY_PROC, forfeit_proc, 0); x += 7 * msgfont->pf_defaultsize.x + 21; panelitems[n++] = panel_create_item(psw, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(psw, "Quit", 4, NULL), PANEL_ITEM_X, x, PANEL_ITEM_Y, y, PANEL_NOTIFY_PROC, quit_proc, 0); x += 4 * msgfont->pf_defaultsize.x + 21; panelitems[n++] = panel_create_item(psw, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(psw, "New Game", 8, NULL), PANEL_ITEM_X, x, PANEL_ITEM_Y, y, PANEL_NOTIFY_PROC, newgame_proc, 0); x += 8 * msgfont->pf_defaultsize.x + 21; panelitems[n++] = panel_create_item(psw, PANEL_CHOICE, PANEL_LABEL_STRING, "Color:", PANEL_ITEM_X, x, PANEL_ITEM_Y, y, PANEL_CHOICE_STRINGS, "White", "Black", 0, PANEL_NOTIFY_PROC, newcolor_proc, 0);}initmsg(){ msgwin = pw_open(msgsw->ts_windowfd); msgsw->ts_io.tio_handlesigwinch = msg_sigwinch;}initbrd(){ struct inputmask im; brdwin = pw_open(brdsw->ts_windowfd); brdsw->ts_io.tio_handlesigwinch = brd_sigwinch; brdsw->ts_io.tio_selected = brd_selected; input_imnull(&im); win_setinputcodebit(&im, MS_LEFT); win_setinputcodebit(&im, MS_MIDDLE); win_setinputcodebit(&im, LOC_MOVEWHILEBUTDOWN); win_setinputcodebit(&im, LOC_WINEXIT); im.im_flags = IM_NEGEVENT; win_setinputmask(brdsw->ts_windowfd, &im, 0, WIN_NULLLINK);}staticinitmatch(){ struct stat buf; char logfile[512]; srandom(time(0)); getscore(humanname, &humanscore, &computerscore); win_getcursor(brdsw->ts_windowfd, &cursors[ORIGINAL_CUR]); humancolor = NONE; state = STARTGAME; humancolor = WHITE; /* for drawing purposes these must be set */ initpieces(); /* they will be updated when game starts */ numhdice = numcdice = 0; lastroll[0][0] = lastroll[1][0] = 0; lastdoubled = NOBODY; lastmoved = NOBODY; alreadyrolled = 0; minwidth = 2 * tool_borderwidth(tool) + 72 * msgfont->pf_defaultsize.x; minheight = OPTHT + MSGHT + MINBRDHT + 2 * tool_subwindowspacing(tool); /* open the log file only if it is already there */ sprintf(logfile, "%s/gammonlog", getenv("HOME")); if (stat(logfile, &buf) == 0) { if ((logfp = fopen(logfile, "a")) != NULL) { setbuf(logfp, NULL); if (buf.st_size > 0) putc('\n', logfp); fprintf(logfp, "New match.\n"); } }}statictool_sigwinchhandler(){ int toosmall = 0; struct rect r; win_getrect(tool->tl_windowfd, &r); if (r.r_width < minwidth) { r.r_width = minwidth; toosmall++; } if (r.r_height < minheight) { r.r_height = minheight; toosmall++; } if (toosmall && (tool->tl_flags & TOOL_ICONIC) == 0 && (win_getuserflags(tool->tl_windowfd) & WMGR_ICONIC) == 0) win_setrect(tool->tl_windowfd, &r); else tool_sigwinch(tool);}staticmsg_sigwinch(){ win_getrect(msgsw->ts_windowfd, &msgrect); pw_damaged(msgwin); redisplay_message(); pw_donedamaged(msgwin);}staticbrd_sigwinch(){ struct rect r; win_getsize(brdsw->ts_windowfd, &r); if (!rect_equal(&r, &brdrect)) { /* * the following call to pw_damaged is necessary on color * monitors (to initialize bit planes); the pw_donedamaged * call discards the clip list so the whole board is redrawn */ pw_damaged(brdwin); pw_donedamaged(brdwin); brdrect.r_left = r.r_left; brdrect.r_top = r.r_top; brdrect.r_width = r.r_width; brdrect.r_height = r.r_height; changeboardsize(); redisplay(); } else { pw_damaged(brdwin); redisplay(); pw_donedamaged(brdwin); }}staticquit(){ tool_done(tool);}staticgammonpipeready(data, ibits, obits, ebits, timer)caddr_t data;int *ibits, *obits, *ebits;struct timeval **timer;{ if (*ibits & (1 << gammonfd)) { readfromgammon(); *ibits &= ~(1 << gammonfd); } cached_toolselected(data, ibits, obits, ebits, timer); *ibits |= (1 << tool->tl_windowfd); *ibits |= (1 << gammonfd);}staticbrd_selected(data, ibits, obits, ebits, timer)caddr_t data;int *ibits, *obits, *ebits;struct timeval **timer;{ struct inputevent ie; input_readevent(brdsw->ts_windowfd, &ie); gammon_reader(&ie); *ibits = *obits = *ebits = 0;}staticdouble_proc(item, event) Panel_item item; struct intputevent *event;{ message(ERR, ""); switch (state) { case STARTGAME: message(ERR, "The game hasn't started yet!"); break; case COMPUTERDOUBLING: message(ERR, "You must accept or refuse the computer's double first!"); break; case HUMANDOUBLING: message(ERR, "Hold on, the computer is thinking about whether to accept your double!"); break; case ROLL: if (lastdoubled == HUMAN) { message(ERR, "You don't have the cube!"); } else if (gamevalue >= 64) { message(ERR, "You can't double any higher!"); } else { sendtogammon(DOUBLEREQ); state = HUMANDOUBLING; diddouble = 1; if (logfp != NULL) fprintf(logfp, "Human doubled.\n"); } break; case MOVE: message(ERR, "You can only double before you roll the dice!"); break; case THINKING: message(ERR, "It's not your turn!"); break; case GAMEOVER: message(ERR, "The game is over!"); break; }}staticaccept_proc(item, event) Panel_item item; struct intputevent *event;{ message(ERR, ""); switch (state) { case STARTGAME: message(ERR, "The game hasn't started yet!"); break; case COMPUTERDOUBLING: gamevalue *= 2; lastdoubled = COMPUTER; drawcube(); sendtogammon(ACCEPT_DBLE); message(MSG, "Thinking..."); startcomputerturn(); break; case HUMANDOUBLING: message(ERR, "Hold on, the computer is thinking about whether to accept your double!"); break; case ROLL: message(ERR, "The computer hasn't doubled you!"); break; case MOVE: message(ERR, "The computer hasn't doubled you!"); break; case THINKING: message(ERR, "It's not your turn!"); break; case GAMEOVER: message(ERR, "The game is over!"); break; }}staticrefuse_proc(item, event) Panel_item item; struct intputevent *event;{ message(ERR, ""); switch (state) { case STARTGAME: message(ERR, "The game hasn't started yet!"); break; case COMPUTERDOUBLING: win(COMPUTER, REFUSEDDBLE); break; case HUMANDOUBLING: message(ERR, "Hold on, the computer is thinking about whether to accept your double!"); break; case ROLL: message(ERR, "The computer hasn't doubled you!"); break; case MOVE: message(ERR, "The computer hasn't doubled you!"); break; case THINKING: message(ERR, "It's not your turn!"); break; case GAMEOVER: message(ERR, "The game is over!"); break; }}staticshowmove_proc(item, event) Panel_item item; struct intputevent *event;{ message(ERR, ""); if (state == STARTGAME) { message(ERR, "The game hasn't started yet!"); } else { if (lastmoved == HUMAN && movesmade > 0) showlasthumanmove(); else showlastcomputermove(); }}staticredo_proc(item, event) Panel_item item; struct intputevent *event;{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -